#ifndef DEF_TX_GRAPHWINDOW
 #define DEF_TX_GRAPHWINDOW

//------------------------------------------//
//			   TKA4 CGraphWin				//
//				03. 07. 2007				//
//------------------------------------------//


//--- Pragma 
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "glut32.lib")
//=== Pragma 


//--- Includes
#include <windows.h>
#include <stdio.h>
#include <time.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include "../GL/glut.h"

#include "TX_Engine.h"
//=== Includes 


//--- Defines
#define DEFAULT_TITLE  "tx"

#define BEGIN_X 0
#define BEGIN_Y 0
#define BEGIN_W 640
#define BEGIN_H 480


#define USING_GLUT  true
//=== Defines


//--- Classes
class txGraphWindow;
//=== Classes 

//--- Vars
txGraphWindow  *GraphWin;
//=== Vars


//---  Class Graph TX  ---//
//	Graph TX is window    // 
//	with OpenGL context.  // 
class txGraphWindow {
public:
	HDC  hDC;

	//---
	int x, y, w, h;
	char* title;
	int win_code;
	GLTFrame  *Camera;

public:	
	//--- MOUSE ---
	class txMouse {
	public:
		bool LeftButton;
		float rotz, rotx;
		int oldX, oldY;
	
		txMouse(){ rotx=-60.0; }
	} mouse;
	//=== MOUSE ===


public:
	txEngine *Eng;
	

public:
	txGraphWindow() { 
		title = DEFAULT_TITLE; 
		Eng = NULL;
		x = BEGIN_X; y = BEGIN_Y; w = BEGIN_W; h = BEGIN_H;
	};
	 
	txGraphWindow(txEngine *Eng_, char* s = DEFAULT_TITLE, 
		int x_ = 100, int y_ = 100, int w_ = 640, int h_ = 480)
			: x(x_), y(y_), w(w_), h(h_), title(s)
	{ 
		SetEngine(Eng_);
		Activate();
		Camera = &GraphWin->Eng->World->Camera;
	};

	~txGraphWindow() { if (title != NULL) delete title; }

	virtual inline void  SetEngine(txEngine *eng) { Eng = eng; }

	virtual inline HDC  GetHDC() { return hDC; }

	virtual inline void  Activate() { GraphWin = this; }

	virtual inline void  WinMain();
	virtual inline void  WinExit();
};

void WinExit();

//------------------------- :: Functions :: ---------------------------

//--- CGraphTX - On Paint
void  OnPaint() 
{
int begin_time = clock();
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	
	gltApplyCameraTransform(&GraphWin->Eng->World->Camera);

	GraphWin -> Eng -> SceneGo();
	
	glPopMatrix();
	glutSwapBuffers();
		
int res_time = clock() - begin_time;
};


//--- On Mouse
void  OnMouse(int but, int state, int x, int y)
{
	

	switch (but) {
		case GLUT_WHEEL_UP : gltMoveFrameUp(GraphWin->Camera, 0.1); break;
		case GLUT_WHEEL_DOWN : gltMoveFrameUp(GraphWin->Camera, -0.1); break;

		case GLUT_LEFT_BUTTON : break;
	};

	glutPostRedisplay();
};


//--- On Special Key
void OnSpecialKey(int k1,int k2,int k3)
{
	GLTFrame  *Camera = &GraphWin->Eng->World->Camera;

	switch (k1) {
		case GLUT_KEY_UP    : gltMoveFrameForward(Camera,  0.2f); break;
		case GLUT_KEY_DOWN  : gltMoveFrameForward(Camera, -0.2f); break;
		case GLUT_KEY_LEFT  : gltRotateFrameLocalY(Camera, 0.05f); break;
		case GLUT_KEY_RIGHT : gltRotateFrameLocalY(Camera,-0.05f); break;
	}

/*	char s[20];
	itoa(k1,s,10);
	*GraphWin ->Eng->Log + txError(0,"KEY",s); */

	glutPostRedisplay();     
}


//--- On Key
void OnKeyboard(unsigned char k1,int k2,int k3)
{	
	switch (k1) {
		case 27 : GraphWin -> WinExit();	break;
	}
}


//--- On Resize
void OnResize(int w, int h)
{
	GraphWin -> Eng -> SceneResize(w,h);
}


//--- On Motion
void OnMotion(int x, int y)
{
	float dx = 0.01;
	int tx = x - GraphWin -> mouse.oldX;
	if (tx > 0) 
		dx = -dx;
	else if (tx==0) dx = 0;
	
	float dy = 0.005;
	int ty = y - GraphWin -> mouse.oldY;
	if (ty > 0) 
		dy = -dy;
	else if (ty=0) dy = 0;
		
	GraphWin -> mouse.oldX = x; 
	GraphWin -> mouse.oldY = y;

	GLTFrame  *Camera = &GraphWin->Eng->World->Camera;

	gltRotateFrameLocalX(Camera, dy);
	gltRotateFrameLocalY(Camera, dx);

	glutPostRedisplay();
}


//--- CGraphTX - WIN EXIT
void  txGraphWindow :: WinExit()
{
	glutDestroyWindow(GraphWin -> win_code);
	exit(0);
}


//--- CGraphTX - WIN MAIN Function
void  txGraphWindow :: WinMain()
{
	int a = 1;
	char **s = new char*;
	(*s) = new char;

	glutInit( &a, s);
	glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );

	glutInitWindowPosition(x, y);
	glutInitWindowSize(w, h);
	win_code = glutCreateWindow(title);
	
	glutReshapeFunc( OnResize );
	glutDisplayFunc( OnPaint );
		
	glutKeyboardFunc( OnKeyboard );
	glutSpecialFunc( OnSpecialKey );

	glutMouseFunc( OnMouse );
	glutMotionFunc( OnMotion );
	
	glutFullScreen();

	Eng -> SceneInit();
	
	glutMainLoop();

	WinExit();
};


#endif

