#ifndef DEF_PRIMITIVES
 #define DEF_PRIMITIVES
//------------------------------------------//
//	TKA4 CEngine and basis Graph classes	//
//				19. 04. 2007				//
//------------------------------------------//


//--- Includes
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <math.h>

#include "TX_Engine.h"
//=== Includes 


//--- Pragma 
#pragma comment (lib, "opengl32.lib")  
#pragma comment (lib, "glu32.lib")     

#pragma warning(disable:4305) 
//=== Pragma 


//--- TX Point Type ---//
// 2D
struct txpoint_real2d { GLfloat x,y; };
struct txpoint_int2d { GLint x,y; };
union txpoint2d { 
	public:
		txpoint_real2d r; txpoint_int2d i; 
	
		txpoint2d() { i.x=0; i.y=0; };
		txpoint2d(GLint x, GLint y = 0) { i.x=x; i.y=y; };
		txpoint2d(GLfloat x, GLfloat y = 0) { r.x=x; r.y=y; };

		inline GLfloat* Addr(float) { return &r.x; };
		inline GLint* Addr(int) { return &i.x; };
		inline GLfloat* Addr() { return &r.x; };
};


// 3D
struct txpoint_real3d { GLfloat x,y,z; };
struct txpoint_int3d { GLint x,y,z; };
union txpoint3d { 
	public :
		txpoint_real3d r; txpoint_int3d i; 
		
		txpoint3d() { i.x=0; i.y=0; i.z=0; };

		txpoint3d(GLint x, GLint y = 0, GLint z = 0) 
			{ i.x=x; i.y=y; i.z=z; };

		txpoint3d(GLfloat x, GLfloat y = 0, GLfloat z = 0) 
			{ r.x=x; r.y=y; r.z=z; };

		txpoint3d(txpoint2d p) 
			{ r.x=p.r.x; r.y=p.r.y; r.z=0; };

		inline GLfloat* Addr(float) { return &r.x; };
		inline GLint* Addr(int) { return &i.x; };
		inline GLfloat* Addr() { return &r.x; };

};


// Color 4D
struct txcolor_real4d { GLfloat r,g,b,a; };
struct txcolor_int4d { GLint r,g,b,a; };
union txcolor4d { 
	public :
		txcolor_real4d r; txcolor_int4d i; 
		
		txcolor4d() { r.r=0; r.g=0; r.b=0; r.a = 1; };

		/*txcolor4d(GLint x, GLint y = 0, GLint z = 0, GLint a = 255) 
			{ i.r=x; i.g=y; i.b=z; i.a = a; };*/

		txcolor4d(GLfloat x, GLfloat y = 0, GLfloat z = 0, GLfloat a = 1.0) 
			{ r.r=x; r.g=y; r.b=z; r.a=a; };

		inline GLfloat* Addr(float) { return &r.r; };
		inline GLint* Addr(int) { return &i.r; };
		inline GLfloat* Addr() { return &r.r; };
};



// View Matrix 
class txview_matrix { 
	public: 
		txpoint3d  scale, tran, rot;

		txview_matrix () 
			{ scale.r.x = 1; scale.r.y = 1; scale.r.z = 1; 
			  tran.r.x = 0; tran.r.y = 0; tran.r.z = 0; 
			  rot.r.x = 0; rot.r.y = 0; rot.r.z = 0; 
			};
};


//---------------------------------------------------------------------


//---  Background  ---//
class txObj_Background : public txObject {
	public :
		txpoint2d p[4];
		txcolor4d c[4];
		
		txObj_Background() 
		{ p[0].r.x = -1.0; p[0].r.y = -1.0; 
		  p[1].r.x =  1.0; p[1].r.y = -1.0;
		  p[2].r.x =  1.0; p[2].r.y =  1.0;
		  p[3].r.x = -1.0; p[3].r.y =  1.0;
		};

	//--- txObj_Background :: Execute Forward
	virtual void Execute_Forward()
	{
		//glEnable(GL_BLEND);
		glTranslatef(0,0,-20);
		//glRotatef(20, 1,0,0);

		glColor4f(1,1,1,1);
		glutSolidCube(10);
		

		glBegin(GL_QUADS);
		for (int i = 0; i<4; i++)
		{
			glColor4fv(c[i].Addr());
			glVertex2fv(p[i].Addr());
		}
		glEnd();

		glDisable(GL_BLEND);
	}

};



//---  Real Ground  ---//
class txObj_RealGround : public txObject {
	public :
			
		txObj_RealGround() 
		{ };

	//--- txObj_Background :: Execute Forward
	virtual void Execute_Forward()
	{
		GLfloat fExtent = 20.0f;
		GLfloat fStep = 1.0f;
		GLfloat y = -0.4f;
		GLint iStrip, iRun;
		
		glColor3f(0.60f, .40f, .10f);

		for(iStrip = -fExtent; iStrip <= fExtent; iStrip += fStep) {
			glBegin(GL_TRIANGLE_STRIP);
				glNormal3f(0.0f, 1.0f, 0.0f);   // All Point up
            
				for(iRun = fExtent; iRun >= -fExtent; iRun -= fStep) {
					glVertex3f(iStrip, y, iRun);
					glVertex3f(iStrip + fStep, y, iRun);
				}
			glEnd();
        }

	}

};



//------------------------- :: Functions :: ---------------------------


#endif



