// SDirectX.h: interface for the SDirectX class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SDIRECTX_H__AC180CAE_6F6F_467F_9D36_468C051B0AF7__INCLUDED_)
#define AFX_SDIRECTX_H__AC180CAE_6F6F_467F_9D36_468C051B0AF7__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define ROBOTFILE "C:\\JPROJECT\\simulator\\models\\robot.x"
#define SONARFILE "C:\\JPROJECT\\simulator\\models\\sonar.x"
#define FLOORTEXTURE "C:\\JPROJECT\\simulator\\textures\\floor.bmp"
#define TREADTEXTURE "C:\\JPROJECT\\simulator\\textures\\Tread.bmp"
#define WALLTEXTURE "C:\\JPROJECT\\simulator\\textures\\wall.bmp"
#define JFPETERSTEXTURE "C:\\JPROJECT\\simulator\\textures\\jfpeters.bmp"


// standard includes
#include <D3D8.h>
#include "D3DApp.h"
#include "D3DUtil.h"
#include "D3DFile.h"
#include "DXUtil.h"
#include "D3DRes.h"
#include "DirectXWnd.h"

#include "ULinearAlgebra.h"
#include "SQuadTree.h"
#include "GenericModel.h"	// Added by ClassView
#include "SDirectXTread.h"	// Added by ClassView

#define DEFAULTHEIGHT 100 // 30 meters why not?

#define DEFAULTBUMPERHEIGHT 15 

#define MAXVERTEXCOUNT 50000 // this should be enough

class SDirectX :public CD3DApplication  
{
public:
	void RCToggleAltTexture();
    struct Model
    {
        CD3DMesh* Mesh;
        BOOL Valid;
		BOOL SonarValid;
		// the moveable treads
		SDirectXTread RightTread;
		SDirectXTread LeftTread;
		CD3DMesh* Sonar; // the sonar
		float ModelOffCenterZ; // the model is offcenter a bit.
    };

	BOOL EnableAltTexture; // enable the alternate texture scheme


    Model Robot;

	void SetCameraType(int CameraType);
	void AdjustCameraPosition(float &dx, float &dy, float &dz, float AngleX, float AngleY, float Radius);
	void OnResetMouse();
	void OnMouseMove(CPoint Point);

    // standard 2D linear algebra library
	ULinearAlgebra LAUtils;

    // used to adjust the camera position
    CPoint OldMousePoint;
	void OnResetChar();
	void OnChar(UINT Char);
	void AdjustCameraPosition();
    void RCSetZoomPoint(CPoint Point);
	void RCZoom(CPoint Point);
	void ResetView();
    
    // model rendering stuff    	
	SGenericModel *SModel;
    void RenderModel();
    void RenderFormBumper(VERTEX* pVertex,FPoint Start, FPoint End);


    // used when loading the map (only once though
    void LoadWalls();  
    // adds the objects into a temperary buffer
    void RenderAddRoof(FPoint Point1, FPoint Point2, FPoint Point3);  
    void RenderAddWall(FPoint Start, FPoint End);
    void RenderAddFloor(FRect Floor);
    // forms the vertices from other information
    void RenderFormRoof(VERTEX* pVertex,FPoint Start, FPoint End, FPoint Extra);
    void RenderFormFloor(VERTEX *pVertex, FPoint Start, FPoint End,DWORD Color);
	void RenderFormWall(VERTEX *pVertex, FPoint Start, FPoint End);
    //actually loads the information into the vertex buffer
	void RenderCreateWallVertexBuffer();
    // general reset
	void RenderResetWalls();

	// render sensor subroutine
	void RenderSensors();

	// load model mesh from xfile
	void LoadModels();

    SQuadTree *MapPtr; // a mapPtr

    struct WALLSTRUCT;

    typedef struct WALLSTRUCT *WallStructPtr;

    typedef enum WallType {Wall, Floor, Roof};

    struct WALLSTRUCT
    {
        FPoint Start,End,Extra; // note the "extra" one is for the roof which takes 3 points
        WallType Type;
        WallStructPtr Next;
    };

    struct WALLRENDERSTRUCT
    {
        // the one and only wall ptr
        WallStructPtr WallPtr;
        // the one and only riif ptr
        WallStructPtr RoofPtr;
        int WallBufferCount;  //Contains the number of walls in the linked list structure
		int RoofBufferCount;
		int FloorBufferCount;
        LPDIRECT3DVERTEXBUFFER8 WallBuffer; //The wall vertix buffer
        BOOL isReady; // is ready to render
    };

    WALLRENDERSTRUCT WallStruct;


    typedef enum CAMERAMODE {FixedAngle,Game3D, Chase};
	typedef enum LASTKEY {KNone,KUp,KDown,KRight,KLeft};

    struct CAMERA
    {
        D3DXVECTOR3 Eye; // the current position of the camera
        D3DXVECTOR3 At; // the point at which to look at
        D3DXVECTOR3 Orientation;
        BOOL MoveUp;
        BOOL MoveLeft;
        BOOL MoveRight;
        BOOL MoveDown;

		LASTKEY LastKey;	// for keypress movement accleration
		int KeyAccleration;
		
        FPoint ModelCenter; // locks the center in the start of the render
        float ModelAngle; // the model current angle
        float ChaseDistance;
        float ChaseAngleX; // angle for the plane of viewing
        float ChaseAngleY; // angle for going around the robot
        FPoint ChaseOffset; // offset from center of model.
        float XAngle,YAngle;
        CAMERAMODE CameraMode;
    };

    CAMERA TheCamera; // the one and only camera

    struct RENDERCONTROL
    {
         CPoint PrevZoomedPoint; // current point of zoom movement
         float ZoomRatio;    
    };

    RENDERCONTROL RenderControl;

    enum { VERTEX_TYPE = D3DFVF_XYZ|D3DFVF_DIFFUSE |D3DFVF_TEX1};

    // is the window enabled?
	BOOL Enabled;
    
    // display window paramters, identical to the gdi window
    CPoint RelativeWindowPos;
	CRect WindowSize;
    // the display window
	DirectXWnd FrameWindow;

    //. render call
	virtual HRESULT Render();
    //external call
	void OnRender(FPoint ModelCenter, float ModelAngle);

    // pointers
	CWnd *LParent;
    CWnd *FramePtr;

    // intial create
	void Create();

	SDirectX();
	virtual ~SDirectX();
     DWORD   m_dwFogColor;

     LPDIRECT3DVERTEXBUFFER8 g_pFloorVB; // Buffer to hold vertices
	 LPDIRECT3DVERTEXBUFFER8 g_pWallVB; // Buffer to hold vertices
	 LPDIRECT3DVERTEXBUFFER8 g_pRoofVB;  // buffer to hold the model vertices
     LPDIRECT3DVERTEXBUFFER8 g_pModelVB;  // buffer to hold the model vertices
	 LPDIRECT3DTEXTURE8 m_pFloorTexture; // floor texture
	 LPDIRECT3DTEXTURE8 m_pTreadTexture; // tread texture
	 LPDIRECT3DTEXTURE8 m_pWallTexture; // tread texture
	 LPDIRECT3DTEXTURE8 m_pJFPetersTexture; // tread texture

};

#endif // !defined(AFX_SDIRECTX_H__AC180CAE_6F6F_467F_9D36_468C051B0AF7__INCLUDED_)
