// C Source File
// Created 30.06.2008; 16:40:20

#include "standart.h"
#include "fileio.h"

const Hiscore std_hiscores[MAX_HISCORES] = {
	{"Boscop",50},
	{"Boscop",40},
	{"Boscop",30},
	{"Boscop",20},
	{"Boscop",10},
	{"Boscop",5},
	{"Boscop",4},
	{"Boscop",3},
	{"Boscop",2},
	{"Boscop",1},
};

Hiscore *hiscores;


static inline void Read(const void **src, void *dest, unsigned short size) {
	memcpy(dest, *src, size);
	*src += size;
}

static inline void Write(const void *src, void **dest, unsigned short size) {
	memcpy(*dest, src, size);
	*dest += size;
}

static inline void AddExtension(void *p, const char *e) {
	*(unsigned char *)p++ = 0;
	Write(e, &p, strlen(e));
	*(unsigned char *)p++ = 0;
	*(unsigned char *)p++ = OTH_TAG;
}

unsigned char LoadGameData(void) {
	if(!(hiscores = malloc(MAX_HISCORES * sizeof(*hiscores)))) {
		Error = ERR_MEM;
		return 0;
	}
	
	SYM_ENTRY *SymPtr;
	if((SymPtr = SymFindFirst(SYMSTR(SAVE_FILE_NAME), FO_RECURSE)) == NULL) {
		
		memcpy(&prefs, &std_prefs, sizeof(prefs));
		memcpy(hiscores, std_hiscores, 10 * sizeof(*hiscores));
		
	} else {
		const void *file = NULL;
		if((file = (unsigned char *) HeapDeref(SymPtr->handle)) == NULL) {
			return 0;
		}
		file += 2;
		
		Read(&file, &prefs, sizeof(prefs));
		Read(&file, hiscores, 10 * sizeof(*hiscores));
	}
	return 1;
}

unsigned char SaveGameData(void) {
	unsigned short size = 2 
		+ sizeof(prefs)
		+ 10 * sizeof(*hiscores)
		+ ((unsigned short)strlen(SAVE_FILE_EXT)) + 3;
	
	SYM_ENTRY *symPtr = SymFindFirst(SYMSTR(SAVE_FILE_NAME), FO_RECURSE);
	HANDLE handle = H_NULL;
	if(symPtr != NULL) {
		if(symPtr->flags.bits.archived) {
			if(!EM_moveSymFromExtMem(SYMSTR(SAVE_FILE_NAME), HS_NULL)) {
				return 0;
			}
		}
		if((handle = HeapRealloc(symPtr->handle, size)) == H_NULL) {
			return 0;
		}
		symPtr = SymFindFirst(SYMSTR(SAVE_FILE_NAME), FO_RECURSE);
	} else {
		HSym hsym = SymAdd(SYMSTR(SAVE_FILE_NAME));
		handle = HeapAlloc(size);
		if(handle != H_NULL) {
			symPtr = DerefSym(hsym);
			symPtr->handle = handle;
			//*(long *)HeapDeref(symPtr->handle) = 0x00010000;
		} else {
			SymDel(SYMSTR(SAVE_FILE_NAME));
			return 0;
		}
	}
	void *file = NULL;
	if((file = (unsigned char *) HeapDeref(symPtr->handle)) == NULL) {
		return 0;
	}
	*(unsigned short *) file = size - 2;
	
	//	skip size
	file += 2;
	
	Write(&prefs, &file, sizeof(prefs));
	Write(hiscores, &file, 10 * sizeof(*hiscores));
	AddExtension(file, SAVE_FILE_EXT);
	
	#ifndef DEBUG
		//	archive file
		if(EM_findEmptySlot(*(unsigned short *)HeapDeref(symPtr->handle)) != NULL) {
			EM_moveSymToExtMem(SYMSTR(SAVE_FILE_NAME), HS_NULL);
		}
	#endif
	
	return 1;
}