/*
  File name: CytadelaSaveFile.cpp
  Copyright: (C) 2005 - 2009 Tomasz Kazmierczak

  Creation date: 16.07.2005 01:50
  Last modification date: 12.06.2009

  This file is part of Cytadela

 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program. If not, see <http://www.gnu.org/licenses/>.  *

*/

#include "CytadelaSaveFile.h"
#include "cmf/fileio.h"
#include <stdio.h>
#include <memory.h>

const uint16_t SaveFileVersion = 66;

bool CytadelaSaveFile::read(const char *sysDirPath)
{
	char saveFilePath[FILENAME_MAX];
	sprintf(saveFilePath, "%s/sav", sysDirPath);
	FILE *saveFile = fopen(saveFilePath, "rb");
	if(saveFile == 0) {
		fprintf(stderr,"CCytadelaSave::readSaveFile(): !fopen(\"%s\")\n", saveFilePath);
		return false;
	}
	uint16_t version;
	if(not fioRead(version, saveFile)) {
		fprintf(stderr,"CCytadelaSave::read(): !fioRead(\"%s\")\n", saveFilePath);
		fclose(saveFile);
	}
	if(version != SaveFileVersion) {
		fprintf(stderr,"CCytadelaSave::read(): ERROR: incorrect save file version!\n");
		fclose(saveFile);
		return false;
	}

	for(uint32_t i = 0; i < NumberOfSaves; i++) {
		fioRead(this->saveEntries[i].weapons, saveFile);
		for(int j = 0; j < NumberOfWeaponTypes; j++)
			fioRead(this->saveEntries[i].ammo[j], saveFile);
		fioRead(this->saveEntries[i].energy, saveFile);
		fioRead(this->saveEntries[i].cplxCounter, saveFile);
		fioRead(this->saveEntries[i].level, saveFile);
		for(int j = 0; j < NumberOfComplexes; j++)
			fioRead(this->saveEntries[i].cplxStatus[j], saveFile);
		fioRead(this->saveEntries[i].actualComplex, saveFile);
		fioRead(this->saveEntries[i].bomb, saveFile);
		uint8_t byte;
		fioRead(byte, saveFile);
		this->saveEntries[i].difficult = (bool)byte;
		if(not fioRead(byte, saveFile)) {
			fprintf(stderr,"CCytadelaSave::read(): !fioRead(\"%s\")\n", saveFilePath);
			fclose(saveFile);
			return false;
		}
		this->saveEntries[i].visionNoise = (bool)byte;
	}
	fclose(saveFile);
	return true;
}

bool CytadelaSaveFile::write(const char *sysDirPath)
{
	char saveFilePath[FILENAME_MAX];
	sprintf(saveFilePath, "%s/sav", sysDirPath);
	FILE *saveFile = fopen(saveFilePath, "wb");
	if(saveFile == 0) {
		fprintf(stderr,"CCytadelaSave::write(): !fopen(\"%s\")\n", saveFilePath);
		return false;
	}
	if(not fioWrite(SaveFileVersion, saveFile)) {
		fprintf(stderr,"CCytadelaSave::write(): !fioWrite(\"%s\")\n", saveFilePath);
		fclose(saveFile);
	}

	for(uint32_t i = 0; i < NumberOfSaves; i++) {
		fioWrite(this->saveEntries[i].weapons, saveFile);
		for(int j = 0; j < NumberOfWeaponTypes; j++)
			fioWrite(this->saveEntries[i].ammo[j], saveFile);
		fioWrite(this->saveEntries[i].energy, saveFile);
		fioWrite(this->saveEntries[i].cplxCounter, saveFile);
		fioWrite(this->saveEntries[i].level, saveFile);
		for(int j = 0; j < NumberOfComplexes; j++)
			fioWrite(this->saveEntries[i].cplxStatus[j], saveFile);
		fioWrite(this->saveEntries[i].actualComplex, saveFile);
		fioWrite(this->saveEntries[i].bomb, saveFile);
		uint8_t byte = this->saveEntries[i].difficult;
		fioWrite(byte, saveFile);
		byte = this->saveEntries[i].visionNoise;
		if(not fioWrite(byte, saveFile)) {
			fprintf(stderr,"CCytadelaSave::write(): !fioWrite(\"%s\")\n", saveFilePath);
			fclose(saveFile);
			return false;
		}
	}
	fclose(saveFile);
	return true;
}

void CytadelaSaveFile::reset()
{
	memset(this->saveEntries, 0, sizeof(this->saveEntries));
	for(uint32_t i = 0; i < NumberOfSaves; ++i)
		saveEntries[i].level = NO_LEVEL;
}
