/*
   core/application.h
   This file is part of the Osirion project and is distributed under
   the terms of the GNU General Public License version 2.
*/

#ifndef __INCLUDED_CORE_APPLICATION_H__
#define __INCLUDED_CORE_APPLICATION_H__

#include "sys/sys.h"
#include "sys/timer.h"

#include "core/commandbuffer.h"
#include "core/cvar.h"
#include "core/func.h"
#include "core/message.h"
#include "core/gameinterface.h"

namespace core
{

/// core interface for the client and server Application classes
class Application
{
public:
	/// default constructor
	Application();

	/// default destructor
	virtual ~Application();

	/*-----  inspectors ----------------------------------------------- */

	/// the current application time, in milliseconds
	inline unsigned long timestamp() const {
		return application_timer.timestamp();
	}
	
	/**
	 * @brief return the current application time, in seconds.
	 * */
	inline float time() const {
		return (float) application_timer.timestamp() / 1000.0f;
	}

	/// true if the core is connected to a running game interface
	inline bool connected() const {
		return (application_game && application_game->running());
	}

	/// return the game interface, returns 0 if the application is not connected to a game
	inline GameInterface *game() {
		return application_game;
	}

	/*-----  mutators ------------------------------------------------- */

	/// start the server or connect to remote host
	void connect(std::string const &host);

	/// disconnect from the game module
	void disconnect();

	/// load a module
	bool load(std::string const &module_name);

	/*-----  virtual mutators ------------------------------------------ */

	/// initialize the application
	virtual void init(int count, char **arguments);

	/// shutdown the application
	virtual void shutdown();

	/// quit the application without proper shutdown
	virtual void quit(int status);

	/*-----  notifications --------------------------------------------- */

	/// text notifications from the core to the application
	virtual void notify_message(const core::Message::Channel channel, const std::string &message);

	/// loading message notification
	virtual void notify_loader(const std::string &message);
	
	/// messagebox notifications
	virtual void notify_messagebox(const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2);
	
	/// messagebox notifications
	void messagebox(const char *text, const char *label1 = 0, const char *command1 = 0, const char *label2 = 0, const char *command2 = 0);

	/// connect notification
	virtual void notify_connect();

	/// disconnect notification
	virtual void notify_disconnect();

	/// zone change notification
	virtual void notify_zonechange();

	/// a pointer to the current application instance
	static inline Application *instance() {
		return application_instance;
	}

protected:
	/// run a core frame
	virtual void frame();

	/// load cvar config
	void load_config();

	/// load exra config
	void load_autoexec();

	/// save cvar config
	void save_config();

	/// load command line arguments
	void load_commandline(int count, char **argments);

private:
	/// main loop timer
	sys::Timer		application_timer;

	GameInterface		*application_game;

	static Application	*application_instance;

protected:
	/*-- engine functions --*/

	static void func_help(std::string const &args);
	static void func_quit(std::string const  &args);
	static void func_connect(std::string const &args);
	static void func_disconnect(std::string const  &args);
	static void func_shout(std::string const &args);
	static void func_say(std::string const &args);
	static void func_module(std::string const &args);
	static void func_msg(std::string const &args);
	static void func_rcon(std::string const &args);
	static void func_info(std::string const &args);
};

/// pointer to the application
inline Application *application()
{
	return Application::instance();
}

/// pointer to the console
inline sys::ConsoleInterface *console()
{
	return sys::ConsoleInterface::instance();
}

/// pointer to the game interface
inline GameInterface *game()
{
	return Application::instance()->game();
}

}


#endif // __INCLUDED_CORE_APPLICATION_H__