//	ConfigLoader.cpp - Class to load the config file.
//  ----------------------------------------------------------------------------
//	This file is part of 'GameTemplate', a game.
//	Copyright (C) 2009  Niall Moody
//	
//	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 "ConfigLoader.h"

#include <fstream>
#include <sstream>
#include <iostream>

#ifdef WIN32
#include <shlobj.h>
#include <direct.h>
#define lineEnd '\r' << endl
#endif

#ifdef LINUX
#include <cstdlib>
#include <unistd.h>
#include <dirent.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define lineEnd endl
#endif

#ifdef OSX
#include <unistd.h>
#include <dirent.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define lineEnd endl
#endif

using namespace std;

//------------------------------------------------------------------------------
ConfigLoader::ConfigLoader():
width(800),
height(600),
aa(6),
fullscreen(false),
noSound(false),
noMusic(false),
sdl(false)
{
	stringstream path;

	path << getFilePath() << "/GameTemplate.conf";

	{
		ifstream tempFile(path.str().c_str(), ios::binary);

		if(!tempFile.good())
			createFile();
	}

	ifstream infile(path.str().c_str(), ios::binary);

	if(infile.good())
	{
		char buffer[128];

		while(!infile.eof())
		{
			infile.getline(buffer, 128);

			//Screen width.
			if(buffer[0] == 'w')
			{
				stringstream tempstr(string(buffer+2));

				tempstr >> width;
			}
			//Screen height.
			else if(buffer[0] == 'h')
			{
				stringstream tempstr(string(buffer+2));

				tempstr >> height;
			}
			//Antialiasing.
			else if(buffer[0] == 'a')
			{
				stringstream tempstr(string(buffer+2));

				tempstr >> aa;
			}
			//Fullscreen.
			else if(buffer[0] == 'f')
			{
				stringstream tempstr(string(buffer+2));

				tempstr >> fullscreen;
			}
			//No sound.
			else if(buffer[0] == 'n')
			{
				stringstream tempstr(string(buffer+3));

				if(buffer[1] == 's')
					tempstr >> noSound;
				else if(buffer[1] == 'm')
					tempstr >> noMusic;
			}
			else if(buffer[0] == 's')
			{
				stringstream tempstr(string(buffer+2));

				tempstr >> sdl;
			}
		}
	}
}

//------------------------------------------------------------------------------
ConfigLoader::~ConfigLoader()
{
	
}

//------------------------------------------------------------------------------
void ConfigLoader::createFile() const
{
	stringstream path;

	path << getFilePath() << "/GameTemplate.conf";
	ofstream outfile(path.str().c_str(), ios::binary|ios::trunc);

	if(!outfile.fail())
	{
		outfile << "w 800" << lineEnd;// << endl;
		outfile << "h 600" << lineEnd;// << endl;
#ifndef LINUX
		outfile << "a 0" << lineEnd;// << endl;
#else
		outfile << "a 0" << lineEnd;// << endl;
#endif
		outfile << "f 0" << lineEnd;// << endl;
		outfile << "ns 0" << lineEnd;// << endl;
		outfile << "nm 0" << lineEnd;// << endl;
		outfile << "sdl 0" << lineEnd;// << endl;
	}
	else
		cout << "Could not create " << path.str() << endl;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
string getFilePath()
{
#ifdef WIN32
	char tempstr[MAX_PATH + 256];

	if(SHGetSpecialFolderPath(0,
							  tempstr,
							  CSIDL_APPDATA,
							  0))
	{
		stringstream tempstr2;

		tempstr2 << tempstr << "\\GameTemplate";

		//Check if directory exists, create it if it doesn't.
		DWORD dwAttr = GetFileAttributes(tempstr2.str().c_str());
		if(dwAttr == 0xffffffff)
		{
			DWORD dwError = GetLastError();

			if((dwError == ERROR_FILE_NOT_FOUND) || (dwError == ERROR_PATH_NOT_FOUND))
			{
				if(_mkdir(tempstr2.str().c_str()) == 0)
					cout << "Created " << tempstr2.str() << " path." << endl;
			}
			else
				cout << "Could not create " << tempstr2.str() << " path." << endl;
		}

		return tempstr2.str();
	}
	else
	{
		cout << "Error: Could not find Application Data directory." <<endl;
		return string(".GameTemplate");
	}
#elif defined(LINUX)
	//This is partly borrowed from JUCE.
	const char* homeDir = getenv("HOME");
	stringstream tempstr;
	DIR *dir;

	if(homeDir == 0)
	{
		struct passwd* const pw = getpwuid (getuid());
		if (pw != 0)
			homeDir = pw->pw_dir;
	}

	tempstr << homeDir << "/.GameTemplate";

	//Make sure the directory exists.
	dir = opendir(tempstr.str().c_str());
	if(!dir)
	{
		if(mkdir(tempstr.str().c_str(), S_IFDIR|S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == 0)
			cout << "Created directory " << tempstr.str() << endl;
		else
			cout << "Could not create directory " << tempstr.str() << endl;
	}

	return tempstr.str();
#elif defined(OSX)
	const char* homeDir = getenv("HOME");
	stringstream tempstr;
	DIR *dir;

	if(homeDir == 0)
	{
		struct passwd* const pw = getpwuid (getuid());
		if (pw != 0)
			homeDir = pw->pw_dir;
	}

	tempstr << homeDir << "/Library/Application Support/GameTemplate";

	//Make sure the directory exists.
	dir = opendir(tempstr.str().c_str());
	if(!dir)
	{
		if(mkdir(tempstr.str().c_str(), S_IFDIR|S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == 0)
			cout << "Created directory " << tempstr.str() << endl;
		else
			cout << "Could not create directory " << tempstr.str() << endl;
	}

	return tempstr.str();
#endif
}
