#ifndef DEF_PRIMITIVES
 #define DEF_PRIMITIVES
//------------------------------------------//
//	TKA4 CEngine and basis Graph classes	//
//				02. 11. 2007				//
//------------------------------------------//


//--- Includes
#include <windows.h>
#include <stdio.h>
#include <math.h>

#include "TX_Object.h"
//=== Includes 


//--- Pragma 
#pragma warning(disable:4305) 
//=== Pragma 


//---------------------------------------------------------------------


//---  Real Ground  ---//
class txObj_RealGround : public txObject {
public :
	GLuint  tex_number;
	txcBorderBox  bbox;

	GLfloat fExtent;
	GLfloat fStep;
	GLfloat y;
	
	txObj_RealGround() 
	{ fExtent = 70.0f; fStep = 1.0f;  y = -0.1f; };

	//--- txObj_ :: Init
	virtual void Execute_Init() {
		tex_number = createTexture2D(true, "../Resources/Images/Rocks.jpg");
		bbox = txcBorderBox(-fExtent*0.5, 0.5, -fExtent*0.5 , fExtent*0.5, 30.0, fExtent*0.5); 		
		World->Collision.AddTXC(&bbox);

		color.diff[0] = 0.7;
		color.diff[1] = 0.7;
		color.diff[2] = 0.2;

		color.spec[0] = 0.7;
		color.spec[1] = 0.7;
		color.spec[2] = 0.2;
	}

	//--- txObj_ :: Execute Forward
	virtual void Execute_Forward()
	{
		

		glEnable(GL_DEPTH_TEST);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_COLOR_MATERIAL);
		glBindTexture(GL_TEXTURE_2D, tex_number);
		
		color.Apply();
		//---------------------------
		GLfloat c = 40;
		GLint iStrip, iRun;
		for (iStrip = -fExtent; iStrip <= fExtent; iStrip += fStep) {
			
			glBegin(GL_TRIANGLE_STRIP);
							
			GLTVector3 n;
			GLTVector3 p1, p2, p3;
			
				for (iRun = fExtent; iRun >= -fExtent; iRun -= fStep) {

					GLfloat y1 = -1-sin((iStrip)/fExtent*3.14) +y;
					GLfloat y2 = -1-sin((iStrip + fStep)/fExtent*3.14) +y;
					
					p1[0] = iStrip; p1[1] = y1; p1[2] = iRun;
					p2[0] = iStrip + fStep; p2[1] = y2; p2[2] = iRun;
					p3[0] = iStrip; p3[1] = y2; p3[2] = iRun-fStep;
					gltGetNormalVector(p1, p2, p3, n);
					
					n[0]=-n[0]; n[1]=-n[1]; n[2]=-n[2];
					glNormal3fv(n);

					glTexCoord2d(iStrip/c, iRun/c);
					glVertex3fv(p1);
					
					glTexCoord2d(p2[0]/c, iRun/c);
					glVertex3fv(p2);
				}
			glEnd();
        }
		//---------------------------

		glDisable(GL_TEXTURE_2D);
	}
};



//---  Sky 101001  ---//
class txObj_Sky : public txObject {
public :
	GLuint  tex_number;
	GLfloat size;
	GLUquadric	*q;
	
	txObj_Sky() 
	{ size = 60; q = gluNewQuadric(); };

	~txObj_Sky()
	{ gluDeleteQuadric(q); };


	//--- txObj_ :: Init
	virtual void Execute_Init() {
		tex_number = createTexture2D(true, "../Resources/Images/Sky.bmp");

		
		glNewList(1, GL_COMPILE);
		
		glPushMatrix();
		
		matrix.r[0]=90.0;
		matrix.t[1]=size-3;
		matrix.s[1]=matrix.s[0]=size;
		matrix.s[2]=size*2;
		matrix.Apply();
		
		glDisable(GL_FOG);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, tex_number);
		
		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

		GLfloat x1, x2, y1, y2;
		GLfloat step = 0.1;
		GLfloat c = -PI2/10;
		GLfloat c2 = -0.1;
		
		glBegin(GL_QUADS);
			
		GLTVector3 n;
		GLTVector3 p1, p2, p3;

		for (GLfloat j=0; j<PI2; j+=step)
			for (GLfloat k=0; k<size; k+=step)
			{
				x1 = sin(j);
				y1 = cos(j);
				if (j+step>PI2) {
					x2 = 0.0;
					y2 = 1.0;
				} else {
					x2 = sin(j+step); 
					y2 = cos(j+step);
				}

				glNormal3f((x1+x2)/2,(y1+y2)/2, k+step/2);
								
				p1[0] = x1; p1[1] = y1; p1[2] = k;
				p2[0] = x1; p2[1] = y1; p2[2] = k+step;
				p3[0] = x2; p3[1] = y2; p3[2] = p2[2] ;
				
				gltGetNormalVector(p1, p2, p3, n);
				
				glTexCoord2f(j/c,k/c2);
				glVertex3fv(p1);

				glTexCoord2f(j/c,(p2[2])/c2);
				glVertex3fv(p2);

				glTexCoord2f((j+step)/c, (p2[2])/c2);
				glVertex3fv(p3);

				glTexCoord2f((j+step)/c,k/c2);
				glVertex3f(x2,y2,k);
			}
		glEnd();

		glEnable(GL_FOG);

		glPopMatrix();

		glEndList();
	}

	//--- txObj_ :: Forward
	virtual void Execute_Forward()
	{		
		glCallList(1);
	}
};




//---  Sphere in center  ---//
class txObj_Sphere : public txObject {
public :
	GLuint		tex_number;
	txcSphere	sphere;
	GLfloat		minisize;
	
		
	txObj_Sphere() 
	{ minisize=5; };
	~txObj_Sphere(){  };

	//--- txObj_ :: Init
	virtual void Execute_Init() {
		tex_number = createTexture2D(true, "../Resources/Images/Sky.bmp");
		
		sphere = txcSphere(0,0,0,minisize,txc_outside); 		
		World->Collision.AddTXC(&sphere);

		color.diff[0] = 0.1;
		color.diff[1] = 0.7;
		color.diff[2] = 0.2;

		color.spec[0] = 0.4;
		color.spec[1] = 0.1;
		color.spec[2] = 0.1;
	}

	//--- txObj_ :: Forward
	virtual void Execute_Forward()
	{		
		color.Apply();

		glEnable(GL_CULL_FACE);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, tex_number);
		
		glEnable(GL_TEXTURE_GEN_S);
		glEnable(GL_TEXTURE_GEN_T);

		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		
		GLfloat tmp =  0.8 ;
		glColor4f(1.0f, 1.0f, 1.0f, tmp);
		
		glCullFace(GL_FRONT);
		glutSolidSphere (minisize, 50, 50);
		
		glCullFace(GL_BACK);
		glutSolidSphere(minisize, 50, 50);
	
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);

		glDisable(GL_TEXTURE_2D);

	}
};




//---  Sky Up  ---//
class txObj_Hot : public txObject {
	int  tex_number;
public :

	virtual void Execute_Init() {
		tex_number = createTexture2D(true, "../Resources/Images/Hot.bmp");	
	}

	virtual void Execute_Forward()
	{
		
		glPushMatrix();
		
		glDisable(GL_FOG);

		matrix.r[0] = 90;
		matrix.s[0]=matrix.s[1]=matrix.s[2]=60;
		matrix.t[1] = 50;
		matrix.Apply();
		 
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, tex_number); 
		
		glColor4f(0, 0.6, 0, 1);

		glBegin(GL_QUADS);
		
		glTexCoord2f(0.0, 0.0);
		glVertex2f(-1.0, -1.0);
		
		glTexCoord2f(1.0, 0.0);
		glVertex2f(1.0, -1.0);
		
		glTexCoord2f(1.0, 1.0);
		glVertex2f(1.0, 1.0);
		
		glTexCoord2f(0.0,  1.0);
		glVertex2f(-1.0, 1.0);
		
		glEnd();

		glEnable(GL_FOG);
		glPopMatrix();
	}

};
//------------------------- :: Functions :: ---------------------------


#endif



