/*
 * Config.cpp
 *
 *  Created on: 2009-07-11
 *      Author: wasyl
 */

#include <cstdio>
#include <string>
#include "Config.h"

Config *Config::instance = NULL;

const double timeAttackTimes[] =
{
	15.00, 21.00,
	13.5, 12.5,
	20.0, 29.0,
	10.6, 21.5,
	16.1, 19.8,
	33.0, 27.0,
	41.0, 18.00,
	100.0, 100.0
};

/******************************************/

LevelInfo::LevelInfo(int i)
{
	unlocked = i < 3;
	complete = complete100 = timeattack = false;
	bestTime = 999.00;
}

/******************************************/

void LevelInfo::load(FILE *f)
{
	unlocked = fgetc(f);
	complete = fgetc(f);
	complete100 = fgetc(f);
	timeattack = fgetc(f);
	fread(&bestTime, 1, sizeof(double), f);
}

/******************************************/

void LevelInfo::save(FILE *f)
{
	fputc(unlocked, f);
	fputc(complete, f);
	fputc(complete100, f);
	fputc(timeattack, f);
	fwrite(&bestTime, 1, sizeof(double), f);
}

/******************************************/

void Config::initialize(int numLevels)
{
	std::string filename = "garbagequest.dat";
	int levInFile;

	FILE *f = fopen(filename.c_str(), "rb");
	if (!f)
	{
		deaths = 0;
		levInFile = 0;
	}
	else
	{
		fread(&deaths, 1, sizeof(int), f);
		levInFile = fgetc(f);

		for (int i = 0; i < levInFile; i++)
		{
			LevelInfo li(i);
			li.load(f);
			level.push_back(li);
		}

		fclose(f);
	}

	for (int i = levInFile; i < numLevels; i++)
	{
		LevelInfo li(i);
		level.push_back(li);
	}
}

/******************************************/

void Config::save()
{
	std::string filename = "garbagequest.dat";
	FILE *f = fopen(filename.c_str(), "wb");
	fwrite(&deaths, 1, sizeof(int), f);
	fputc(level.size(), f);
	for (unsigned int i = 0; i < level.size(); i++)
		level[i].save(f);
	fclose(f);
}

void Config::levelComplete(int no, bool perfect, double time)
{
	if (no == -1)
		return;
	level[no].complete = true;
	level[no].complete100 |= perfect;
	level[no].timeattack |= perfect && (time < timeAttackTimes[no]);
	if (perfect)
		if (time < level[no].bestTime)
			level[no].bestTime = time;

	int unlockCount = completions();
	for (int i = unlockCount; i < level.size() && i < unlockCount + 3; i++)
		level[i].unlocked = true;
}

int Config::unlockPoints()
{
	int pointCount = 0;
	for (int i = 0; i < level.size(); i++)
	{
		if (level[i].timeattack)
			pointCount++;
		if (level[i].complete)
			pointCount++;
		if (level[i].complete100)
			pointCount++;
	}
	return pointCount;
}

int Config::completions()
{
	int pointCount = 0;
	for (int i = 0; i < level.size(); i++)
	{
		if (level[i].complete)
			pointCount++;
	}
	return pointCount;
}

double Config::timeAttackTime(int no)
{
	return timeAttackTimes[no];
}
