// **********************************************************************
//                            OpenAlchemist
//                        ---------------------
//
//  File        : Application.cpp
//  Description : Application main class
//  Author      : Guillaume Delhumeau <guillaume.delhumeau@gmail.com>
//  License     : GNU General Public License 2 or higher
//
// **********************************************************************

#include <SDL.h>
#include <SDL_mixer.h>
#include <boost/filesystem.hpp>
#include "Application.h"
#include "memory.h"
#include "AudioManager.h"
#include "Preferences.h"
#include "CommonResources.h"
#include "GameEngine.h"
#include "misc.h"
#ifdef HAVE_GAMERZILLA
#include <gamerzilla.h>
#endif

/************************************************************************/
/* Init                                                                 */
/************************************************************************/
void Application::_init()
{
	init_memory();
	common_resources_init();
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0)
	{
		std::cout << "Failed - SDL_Init" << std::endl;
		exit(0);
	}
	Mix_Init(MIX_INIT_FLAC | MIX_INIT_OGG);
	g_audio_manager.init();
#ifdef HAVE_GAMERZILLA
	if (!alchemyQuest)
	{
		std::string save_dir = get_save_path() + "/";
		GamerzillaStart(false, save_dir.c_str());
		game_id = GamerzillaSetGameFromFile((get_data_path() + "gamerzilla/openalchemist.game").c_str(), get_data_path().c_str());
	}
#endif
}

/************************************************************************/
/* Term                                                                 */
/************************************************************************/
void Application::_term()
{
	common_resources_term();		
	g_audio_manager.term();
	my_delete(pref_get_instance());
	term_memory();
	Mix_Quit();
	SDL_Quit();
#ifdef HAVE_GAMERZILLA
	if (game_id != -1)
		GamerzillaQuit();
#endif
}

/************************************************************************/
/* Main function                                                        */
/************************************************************************/
int Application::app_main(const std::vector<std::string>& args)
{
	// Checking alchemyquest
	if (args.size() > 0)
	{
		boost::filesystem::path p(args[0]);
		if (strstr(p.stem().string().c_str(), "alchemyquest") != NULL)
			alchemyQuest = true;
	}
	for(unsigned int i = 0; i < args.size(); ++i)
	{
		if (args[i] == "--alchemyquest")
		{
			alchemyQuest = true;
		}
		else if (args[i] == "--openalchemist")
		{
			alchemyQuest = false;
		}
	}

	_init();
	bool b_run_game = _check_args(args);
	if(b_run_game)
	{
//		try
		{
			GameEngine game;
			game.init();
			game.run();
			game.term();
		}
		// Catch any errors from ClanLib
/*		catch(CL_Exception& exception)
		{
			CL_ConsoleWindow console("OpenAlchemist Console", 80, 300);
			CL_Console::write_line("Exception caught:");
			CL_Console::write_line(exception.message);

			CL_Console::write_line("--------------------");

			// Display the stack trace (if available)
			std::vector<CL_String> stacktrace = exception.get_stack_trace();
			size_t size = stacktrace.size();
			if (size > 0)
			{
				CL_Console::write_line("Stack Trace:");
				for (unsigned int cnt=0; cnt < size; cnt++)
				{
					CL_Console::write_line(stacktrace[cnt]);
				}
			}
			console.display_close_message();
			return -1;
		}*/

	}
	_term();

	return 0;
}

/************************************************************************/
/* Check args                                                           */
/************************************************************************/
bool Application::_check_args(const std::vector<std::string>& args)
{
	bool run_game = true;

	Preferences* p_pref = pref_get_instance();

	// Checking parameters
	for(unsigned int i = 0; i < args.size(); ++i)
	{
		// Help
		if((args[i] =="--help"))
		{
			_print_help();
			run_game = false;
		}

		// License
		if((args[i] =="--license"))
		{
			_print_license();
			run_game = false;
		}

		// FPS limit
		if((args[i] =="--maxfps") && i < args.size()-1)
		{
			int maxfps = atol(args[i+1].c_str());
			if(maxfps)
			{
				p_pref -> maxfps = maxfps;
			}
			else
			{
				run_game = false;
				std::cout << "Option maxfps must be followed by a number." << std::endl;
			}

		}

		// Colorblind mode
		if((args[i] =="--cb"))
		{
			p_pref -> colorblind = true;
			p_pref -> write();

		}
		if((args[i] =="--nocb"))
		{
			p_pref -> colorblind = false;
			p_pref -> write();

		}
		if ((args[i] == "--alchemyquest"))
		{
			// Already processed.
		}

	}

	return run_game;
}

/************************************************************************/
/* Help                                                                 */
/************************************************************************/
void Application::_print_help()
{
	std::cout << "OpenAlchemist " << get_version() << " -- Help" << std::endl
		<< "Usage: openalchemist [OPTIONS]"  << std::endl  << std::endl
		<< "Options:"  << std::endl
		<< "\t--alchemyquest : Enable Alchemy Quest user interface"  << std::endl
		<< "\t--cb           : Active colorblind mode"  << std::endl
		<< "\t--help         : Show this message"  << std::endl
		<< "\t--license      : Show the license of this program"  << std::endl
		<< "\t--maxfps X     : Limit framerate to X"  << std::endl
		<< "\t--nocb         : Disable colorblind mode"  << std::endl;
}

/************************************************************************/
/* License                                                              */
/************************************************************************/
void Application::_print_license()
{
	std::cout << " * OpenAlchemist "<< get_version() << " -- License\n" << std::endl
		<< " * Copyright (C) 2006,2009 Guillaume Delhumeau <guillaume.delhumeau at gmail.com>" << std::endl
		<< " *"  << std::endl
		<< " * This program is free software; you can redistribute it and/or modify " << std::endl
		<< " * it under the terms of the GNU General Public License as published by" << std::endl
		<< " * the Free Software Foundation; either version 2 of the License, or" << std::endl
		<< " * (at your option) any later version." << std::endl
		<< " *" << std::endl
		<< " * This program is distributed in the hope that it will be useful," << std::endl
		<< " * but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl
		<< " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" << std::endl
		<< " * GNU General Public License for more details." << std::endl
		<< " *" << std::endl
		<< " * You should have received a copy of the GNU General Public License" << std::endl
		<< " * along with this program; if not, write to the Free Software" << std::endl
		<< " * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA." <<std::endl
		<< " *" << std::endl << std::endl;
}
