/* 3d.h
	Header file for the 3D engine written by Thoooms!
*/
#ifndef __ENGINE_H_INCLUDED__
#define __ENGINE_H_INCLUDED__

/////////////////////////////////////////////////////
// ENGINE INCLUDES //////////////////////////////////
/////////////////////////////////////////////////////

#include "Matrix.h"

/////////////////////////////////////////////////////
// ENGINE GLOBAL VARS ///////////////////////////////
/////////////////////////////////////////////////////

//constants
const unsigned int TM_NUM_VERTICES = 20;
const unsigned int TM_NUM_OBJECTS = 20;

//flags
#define TM_MOVE_TO 2
#define TM_LINE_TO 1
#define TM_NOT_USED 0
#define TM_LOCAL 500	//the operation shoulb be done on the objects position in the space
#define TM_WORLD  600  //the operation applies to all vertices excecp world position

#define TM_DEFAULT_DISTANCE_FROM_SCREEN 0.0f
#define TM_DEFAULT_DISTANCE_FROM_PROJECTION_TO_OBJECT_COORDINATE_SYSTEM 0 //disabled
#define TM_COORDINATESYSTEM_OBJECT (TM_NUM_OBJECTS-1)
#define TM_VERTEX_MARK true
#define TM_VERTEX_UNMARK false
/////////////////////////////////////////////////////
// ENGINE STRUCTURES ////////////////////////////////
/////////////////////////////////////////////////////

typedef struct ColorStruct
{
	float r,g,b;
} ColorStruct;


typedef struct Object	//could be made into a class!
{
	Matrix4x1 Position;	//position in world coordinatesystem
	Matrix4x1 Vertices[TM_NUM_VERTICES];	//vertices specified in local coordinatesystem
	float r, g, b;
	ColorStruct Color;
	bool MarkVertices;	//should vertices be drawn with a bok
} Object;

typedef struct WorldStruct
{
	Object Objects[TM_NUM_OBJECTS];	//number of objects in world!
} WorldStruct;


typedef struct ViewParameters
{
	Matrix4x1 VRP;
	Matrix4x1 VPN;
	Matrix4x1 VUP;
	Matrix4x1 PRP;
	float Q;
	float dx;
	float dy;
	float dz;
	float zp;
	float umax;
	float umin;
	float vmax;
	float vmin;

	float xmax;
	float xmin;
	float ymax;
	float ymin;
	float zmin;
	float zmax;
	float B;
	float F;


} ViewParameters;

/////////////////////////////////////////////////////
// ENGINE CLASS /////////////////////////////////////
/////////////////////////////////////////////////////

class C3DEngine
{
private:
	WorldStruct World;	//objects in the world
	Matrix4x4 ViewingMatrix;
	float Distance;
	float DistanceProjectionToWorld;
	Matrix4x4 Step1;
	Matrix4x4 Step2;
	Matrix4x4 Step3;
	Matrix4x4 WorldToViewport;

	Matrix4x4 SH;
	Matrix4x4 S;
	Matrix4x4 T_PRP;
	Matrix4x4 T_VRP;
	Matrix4x4 R;
	Matrix4x4 M;
	
//	ViewParameters ViewingParameters;
public:

	//WORLD TO VIEWPORT
	Matrix4x4 LastScale;
	Matrix4x4 T1;
	Matrix4x4 TXYZ;
	Matrix4x4 SVW;

	//END OF WORLD TO VIEWPORT PARAMS
	
	ViewParameters ViewingParameters;
	C3DEngine();
	Object Projected[TM_NUM_OBJECTS];	//projected objects

	//Parameters
	Matrix4x4 CalculateAndSetViewingMatrix(float Q, float dx, float dy, float dz, float zp);
	void SetViewingMatrix( Matrix4x4 * matrix);
	void SetViewingParameters(Matrix4x1 VRP, Matrix4x1 VPN, Matrix4x1 VUP, Matrix4x1 PRP);
	void SetWorldToViewportMatrix(float xmin, float xmax, float ymin, float ymax);

	//World Manipulation
	void ProjectWorld( void );	//display all objects
	void ClipWorld( void );		//NOT IMPLEMENTED
	void InsertObject( Object* Obj, unsigned int pos);
	void InsertVertex( Matrix4x1 *vert,unsigned int obj,  unsigned int num, int params = TM_LINE_TO);
	
	//GET functions
	ColorStruct GetColor(unsigned int obj);
	Matrix4x1* GetVertex(unsigned int obj,unsigned int num, int params = TM_WORLD);
	Matrix4x1* GetProjectedVertex(unsigned int obj,unsigned int num, int params = TM_WORLD);
	bool GetMarkVertexState(unsigned int);
	Object* GetObject(unsigned int obj);
	Matrix4x1 GetObjectPosition(unsigned int obj);

	//Object Manipulation
	void TranslateObject(unsigned int obj, float dx, float dy, float dz, int params = TM_LOCAL);
	void RotateObject(unsigned int obj, float angle, Matrix4x1 *p1,  Matrix4x1 *p2, int params = TM_WORLD);
	void RotateObjectX(unsigned int obj, float Angle, int params = TM_WORLD);
	void RotateObjectY(unsigned int obj, float Angle, int params = TM_WORLD);
	void RotateObjectZ(unsigned int obj, float Angle, int params = TM_WORLD);	
	void ScaleObject(unsigned int obj, float sx, float sy, float sz, int params = TM_WORLD);
	void SetObjectColor(unsigned int obj, ColorStruct* Color);
	void SetVertexMark(unsigned int obj, bool mark);
	void SetObjectPosition(unsigned int obj, Matrix4x1* pos);
	
	//TEMP FUNCTIONS!! FOR DEBUGGING!
	void PrintCoordinates();	
	void PrintProjectedCoordinates();
};

#endif __ENGINE_H_INCLUDED__
