// __author__ = Juan Carlos De Abreu (jcabreur@gmail.com)

/**
 * TODO(jcabreur): write a general comment here
 */

#ifndef APP_H__
#define APP_H__

#include "global.h"
#include "GUI/Window.h"
#include "Base/Singleton.h"
#include "Base/LogManagement.h"

BEGIN_TEG_NAMESPACE();

// TODO: el mouse draw creo que no deberia tener una ventana ..
//       en tal caso un a aputador a void y un identificador del tipo para porde hacer el castin adecuado ..

// TODO: the attributes of this class will be protected, then I needed methods to access this attributes.. 

// TODO: create a input class, who is the base class for the raster, keys and mouse ...
// mouse and keys are fixed, but raster there be a dll, to has a structure for another future devices
// si en el archivo de escena se define un dispositivo el parser tendra que buscar en los dll si tiene
// uno que maneje dicha estructura para asignarselo...
// todos los dispositivos deberian tener una interfaz comun de acceso, por ejemplo set(int) and get
// en el caso del mouse el int podria tomar 3 valores, mientras que el key como 70 (las teclas del teclado)

// Define a short access way for the values of AppWindow.
#define WIDTH_SCREEN AppWindow::GetInstance().width
#define HEIGHT_SCREEN AppWindow::GetInstance().height
#define FULLSCREEN AppWindow::GetInstance().fullScreen

// Define the global setting for the application.
class AppWindow : public Singleton<AppWindow> {
public:
	// Attributes.
	int width, height;		// ...()
	int captionBarHeight;	// ...()
	bool fullScreen;		// Fullscreen flag set to fullscreen mode
	bool isRunning;

	int gameState;
enum { START_SLIDE=0, START_SLIDE1, START_SLIDE2, START_SLIDE3, START_SLIDE4, GAME_RUN, WIN, LOOSE};

	// Constructor.
	AppWindow();

	// Destructor
	~AppWindow();

	// Methods.
	void abort();
	void exit_();
};

// Function to cancel the execution of the app.
inline void AppWindow::abort() {
	// Cancel the execution of the app and report an error.
//	isRunning = FALSE;
//	PRINT_LOG(TYPE_ERROR, "Ocurr a error in the app!");
//	exit(1);
// TODO: create other mechanish to proccess a error in the file ...

}

// Function to exit the app.
inline void AppWindow::exit_() {
	isRunning = FALSE;
}

// Define a data entry for the app.
class Input : public Singleton<Input> {
public:
	// Attributes.
	// ...

	// Constructor.
	Input();

	// Destructor.
	virtual ~Input();

	// Methods.
	virtual void update() = 0;
};

// Define a short access way for the values of the KeyBoard.
#define KEY KeyBoard::GetInstance().keyStates

// TODO: el teclado deberia tener internamente otro arreglo
// uno al que se refiera la tecla que fue presionada y 
// otro que esta asociada a los valores de los caracteres
// estos arreglos ser protegidos y tener funciones que verifiquen
// para acceasrlos, asi como funciones para actualizar el estado de los mismos
// pasar lo que tengo el sceneNavigator.cpp a este archivo


// Define a data input for the keyboard.
class KeyBoard : public Singleton<KeyBoard> {
public:
	// Attributes
	bool keyStates[256];		// ...()

	// Constructor
	KeyBoard();

	// Destructor
	~KeyBoard();
};

// Define a short access way for the values of the Mouse.
#define MOUSE_X Mouse::GetInstance().x
#define MOUSE_Y Mouse::GetInstance().y
#define MOUSE_BUTTON Mouse::GetInstance().button

// Define a data input for the Mouse.
class Mouse : public Singleton<Mouse> {
public:
	// Attributes
	int x, y;					// posicion actual del mouse
	int button;					// 1=left, 2=right, 3=middle
	bool isLeftButtonPressed, isRightButtonPressed, isMiddleButtonPressed;

	int initX, initY;		// Allow know the start position of a drag mouse ....

	// Constructor
	Mouse();

	// Destructor
	~Mouse();
};

// Define a short access way for the values of the MouseDrag.
#define MOUSE_DRAG_X MouseDrag::GetInstance().x
#define MOUSE_DRAG_Y MouseDrag::GetInstance().y
#define IS_MOUSE_DRAG MouseDrag::GetInstance().drag
#define MOUSE_DRAG_WINDOW MouseDrag::GetInstance().window

// Define a data input for the MouseDrag.
class MouseDrag : public Singleton<MouseDrag> {
public:
	// Attributes
	bool drag;					// window draggin enable?
	int x, y;					// coordenadas x,y cuando comenzo el arratre de la ventana
	gui::Window *window;		// apuntador a la ventana que esta siendo arratrada
	//int window;	// WindowIndex ..
};

END_TEG_NAMESPACE();

#endif  // APP_H__
