// BlinkenSisters - Hunt for the Lost Pixels
//     Bringing back the fun of the 80s
//
// (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
//
// See License.txt for licensing information
//

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __WIN32__
#include <direct.h>
#else // NO WIN32
#include <dirent.h>
#include <unistd.h>
#include <pwd.h>
#endif // WIN32
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "globals.h"
#include "showloading.h"
#include "monstersprites.h"
#include "playersprite.h"
#include "extractmetabmf.h"
#include "errorhandler.h"

bool startupComplete = false;

/* What is the name of the current addon? "LostPixels", if no addon but the base game is played... */
char currentAddonName[PATH_MAX] = "" ;

char file[PATH_MAX];
bool configHasRunInit = false;


#ifdef __WIN32__
/* Convert a Path with unix directory separators (/) to windows style directory separators (\) */
/* probably not necessary, because windows should understand unix style separators - but cavac says, it does not hurt... */
char* adjustdirectoryseparator(const char* path) {
    static char adjustedPath[PATH_MAX];
    sprintf(adjustedPath, "%s", path);
	char *ptr;
	
	while((ptr = strchr(adjustedPath, '/'))) {
		*ptr = '\\';
	}
	return adjustedPath ;
}
#else
char* adjustdirectoryseparator(char* path) {
	// do nothing in Unix, probably better than a function call - an empty macro?
	return path;
}
#endif // __WIN32__

/* returns the home directory */
char* gethomepath() {
	static char homepath[1000];
    char *bshomedir;
#ifdef __WIN32__
	if(!Win32_GetDocPath(homepath)) {
		DIE(ERROR_HOME, "Windows API");
	}
	return(homepath) ;
#else // Unix 
#ifdef OLPCBUILD
    // OLPC uses the "Rainbow" security suite...every time the
    // program is called under a  different user. Persistend
    // and temporary space is accessed through the environment
    // variable SUGAR_ACTIVITY_ROOT, which is bound to the UNCHANGING
    // USER-GROUP if the Activity
	if (!(bshomedir = getenv("SUGAR_ACTIVITY_ROOT"))){
		DIE(ERROR_HOME, "OLPC homedirectory not  found");
    }
    sprintf(homepath, "%s/data", bshomedir);
    return(homepath);
#else //  No OLPC, instead wehave ordinary Unix with sane setting
	struct passwd *passwd;
	/* should we try to evaluate $HOME at all? */
	if (!getuid() || !(bshomedir = getenv("HOME"))){
		// Fallback if $HOME is undefined
		passwd = getpwuid (getuid());
		bshomedir=passwd->pw_dir;
		if (!bshomedir){
			DIE(ERROR_HOME, "Unix homedirectory is not defined");
		}
		printf("bshomedir: %s\n", bshomedir); 
	}
	if (strlen(bshomedir) > PATH_MAX - sizeof("/" PROGRAMDIRECTORY "/" VERSION "/ADDON/LostPixels/fx_altemark__digitalpitchup.wav")){ /* the longest path we want to create in .lostpixels */
		DIE(ERROR_HOME, "Unix homedirectory is excessively long.");
	}
	return (bshomedir);
#endif // not OLPCBUILD
#endif // not __WIN32__
}

/* Create directory structure in homedirectory, extract base files (images, fonts, ...) */
void configInit(const bool forceUpdate) {
    configHasRunInit = true;
	configResetAddOn();
	
	// Try to open VERSION file in home dir
	FILE* ifh = 0;
	if(!forceUpdate) {
        	ifh = fopen(configGetPath("VERSION"), "r");
	}
	if(ifh) {
		fclose(ifh);
		return;
	} else {

	// We need to install our local copy of the basedata files
	char dirname[PATH_MAX];
	sprintf(dirname, "%s/%s", gethomepath(), PROGRAMDIRECTORY);
	printf("%s \n", dirname);
	MKDIR(adjustdirectoryseparator(dirname));
	sprintf(dirname, "%s/%s/V%s", gethomepath(), PROGRAMDIRECTORY, VERSION);
	MKDIR(adjustdirectoryseparator(dirname));
	sprintf(dirname, "%s/%s/V%s/ADDON", gethomepath(), PROGRAMDIRECTORY, VERSION);
	MKDIR(adjustdirectoryseparator(dirname));

	// Write the VERSION file
	printf("%s\n", configGetPath("VERSION"));
	FILE* ofh = fopen(configGetPath("VERSION"), "w");
	if(!ofh) {
		DIE(ERROR_FILE_WRITE, configGetPath("VERSION"));
	}
	fprintf(ofh, "Version: " VERSION "\n");
	fclose(ofh);
	
	configInstallAddOn("basedata.bmf");
		
#ifdef CDEDITION
        configInstallAddOn("mz_escape.bmf");
        configInstallAddOn("mz_xmas2007.bmf");
        configInstallAddOn("s23_ivorytower.bmf");
        configInstallAddOn("icy.bmf");
		configInstallAddOn("24c3.bmf");
        configInstallAddOn("mz_pnog.bmf");
        configInstallAddOn("mz_moviepack.bmf");
        configInstallAddOn("mz_testlevel.bmf");
        configInstallAddOn("mz_template.bmf");
#endif // CDEDITION
		
	}
}

#ifdef CDEDITION
void configInstallAddOn(const char* fname) {
	char addonfile[PATH_MAX];
	if(strlen(RESPATH) > 0) {
        sprintf(addonfile, "%s/%s", RESPATH, fname);
    } else {
        sprintf(addonfile, "%s", fname);
    }
	extractMetaBMF(adjustdirectoryseparator(addonfile), true);
}
#endif // CDEDITION

void configStartupComplete() {
	startupComplete = true;
}


/* return the path to files in the users homedirectory */
char* configGetPath(const char* fname) {
    if(!configHasRunInit) {
        sprintf(file, "%s", fname);
        return file;
    }
    if(strlen(currentAddonName) > 0) {
	   sprintf(file, "%s/%s/V%s/ADDON/%s/%s", gethomepath(), PROGRAMDIRECTORY, VERSION, currentAddonName, fname);
    } else {
        sprintf(file, "%s/%s/V%s/%s", gethomepath(), PROGRAMDIRECTORY, VERSION, fname);
    }
	
	return file; // MUST return the full path!
	/*
	if (filetest = fopen(adjustdirectoryseparator(file), "r")) { // check if file is in addon directory
		fclose(filetest);
		return file ;
	} else { // File not found - return the base directory
		sprintf(file, "%s/%s/V%s/%s", gethomepath(), PROGRAMDIRECTORY, VERSION, fname);
		return file ; 
	}
    */
}

/* Set the name of the used addon ("Lostpixels" if no addon) */
/* show the showloading-screen for some time, if the addon has changed */
void configSetAddOn(const char* addOnName) {
	strcpy(currentAddonName, addOnName) ; /* set the addon-name to the current one */
printf("addon: %s \n",addOnName);
#ifndef __OGGPLAYER
	if(startupComplete) {
		deInitShowLoading();
		initShowLoading("loading.jpg");
		showLoading();	
	}
#endif // __OGGPlAYER
}

