//=================================================
//HighTide 
//Gos2 Test App
//
//Written by Matt Bronder
//Ported to GOS2 by Bob Crocco 8/2000
//=================================================
//-----------------------------
//Preprocessor Defs
//-----------------------------
//Misc
#define FVF_HHVERTEX        (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
#define FVF_TLVERTEX        (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)
#define FVF_LVERTEX         (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)
#define FVF_VERTEX          (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
//Beach
#define BEACH_GRID_DIM_X	80
#define BEACH_GRID_DIM_Y	40
#define BEACH_GRID_WIDTH    24.0f
#define BEACH_GRID_HEIGHT   10.0f
#define BEACH_GRID_DEPTH    1.0f
#define BEACH_GRID_OFFSET   0.05f

//Cliff
#define CLIFF_GRID_WIDTH    30.0f
#define CLIFF_GRID_HEIGHT   3.0f
#define CLIFF_GRID_OFFSET   0.2f
#define CLIFF_GRID_DIM_X    10
#define CLIFF_GRID_DIM_Y    10

//Waves

#define WAVE_GRID_WIDTH     16.0f
#define WAVE_GRID_HEIGHT    12.0f
// WAVE_GRID_DIM's must be greater than 50 unless the sqrt lookup table's range 
// is expanded
#define WAVE_GRID_DIM_X     75
#define WAVE_GRID_DIM_Y     75
#define WAVE_UNIT_LENGTH_X  0.16f
#define WAVE_UNIT_LENGTH_Y  0.12f
#define NUM_WAVE_SOURCES    1

#define SQRT_TABLE_SIZE     1024

//light cone
#define LIGHT_CONE_ANGLE    1.121997376282f
#define MAX_LIGHT_ELEVATION     0
#define MIN_LIGHT_ELEVATION     0
#define LIGHT_ELEVATION_DELTA   (M_PI / 25.0f)
#define LIGHT_ROTATION_DELTA1   (M_PI / 50.0f)
#define LIGHT_ROTATION_DELTA2   (M_PI / 25.0f)
//-----------------------------
// Macros
//-----------------------------
#define D3DLIGHT_RANGE_MAX          ((float)sqrt(FLT_MAX))


//------------------------------
//Structures
//------------------------------
//HHVERTEX
typedef struct _HHVERTEX 
{  
	float x;
    float y;
    float z;
    float nx;
    float ny;
    float nz;
    float tu;
    float tv;

    _HHVERTEX() {}
    _HHVERTEX(const D3DVECTOR& v, const D3DVECTOR& n, float _u0, float _v0) 
	{ 
        x = v.x; y = v.y; z = v.z;
        nx = n.x; ny = n.y; nz = n.z;
        tu = _u0; tv = _v0;
    }

}HHVERTEX, *PHHVERTEX;


//TLVERTEX
typedef struct _TLVERTEX {
    D3DXVECTOR3 vPosition;
    float       fRHW;
    D3DCOLOR    cDiffuse;
    D3DCOLOR    cSpecular;
    float       u0, v0;

    _TLVERTEX() {}
    _TLVERTEX(const D3DVECTOR& v, float _fRHW, D3DCOLOR _cDiffuse, 
              D3DCOLOR _cSpecular, float _u0, float _v0) 
    { 
        vPosition.x = v.x; vPosition.y = v.y; vPosition.z = v.z; fRHW = _fRHW;
        cDiffuse = _cDiffuse; cSpecular = _cSpecular;
        u0 = _u0; v0 = _v0;
    }
} TLVERTEX, *PTLVERTEX;


//PVERTEX
typedef struct _VERTEX {
    D3DXVECTOR3 vPosition;
    D3DXVECTOR3 vNormal;
    float       u0, v0;

    _VERTEX() {}
    _VERTEX(const D3DVECTOR& v, const D3DVECTOR& n, float _u0, float _v0) { 
        vPosition.x = v.x; vPosition.y = v.y; vPosition.z = v.z;
        vNormal.x = n.x; vNormal.y = n.y; vNormal.z = n.z;
        u0 = _u0; v0 = _v0;
    }
} VERTEX, *PVERTEX;


//******************************************************************************
typedef struct _LVERTEX {
    D3DXVECTOR3 vPosition;
    D3DCOLOR    cDiffuse;
    D3DCOLOR    cSpecular;
    float       u0, v0;

    _LVERTEX() { }
    _LVERTEX(const D3DVECTOR& v, D3DCOLOR _cDiffuse, D3DCOLOR _cSpecular, float _u0, float _v0) { 
        vPosition.x = v.x; vPosition.y = v.y; vPosition.z = v.z;
        cDiffuse = _cDiffuse; cSpecular = _cSpecular;
        u0 = _u0; v0 = _v0;
    }
} LVERTEX, *PLVERTEX;

// Generated vertices defining a revolved mesh
typedef struct _REVOLUTION {
    PVERTEX         prCenter;
    PVERTEX         prTop;
    PVERTEX         prBottom;
    LPWORD          pwCenter;
    UINT            uCenterVertices;
    UINT            uCenterIndices;
    UINT            uTopVertices;
    UINT            uBottomVertices;
} REVOLUTION, *PREVOLUTION;

//Lighthouse
typedef struct _LIGHTHOUSE {
    D3DXMATRIX          mWorld;
    REVOLUTION          rvBase;
    REVOLUTION          rvTrunk;
    REVOLUTION          rvBalcony;
    REVOLUTION          rvPortal;
    REVOLUTION          rvRoof;
    PLVERTEX            prPortal;
    D3DMATERIAL8        material;
    GosTexture*         pd3dtTrunk;
    GosTexture*         pd3dtRoof;
} LIGHTHOUSE, *PLIGHTHOUSE;

//Wavesource
typedef struct _WAVESOURCE {
    D3DXVECTOR3 vPos;
    float       fWavelength;
    float       fFrequency;     // Phase shift in radians per render
    float       fAmplitude;
    float       fPhase;
} WAVESOURCE, *PWAVESOURCE;

//The App
class HighTideApp : public GosApp
{
public:
	// Functions which the app must provide
	virtual bool	Initialize( _TCHAR *pCommandLine );			// Initialize the application's state
	virtual void	Render();				// Render a single frame
	virtual bool	Step();					// Move the scene forward one frame
	virtual void	Shutdown();				// Called at game shutdown time
	virtual TCHAR	*Name();				// Name of the game
	virtual void	PreferredDisplay( int &Windowed, unsigned int &Width, unsigned int &Height, D3DFORMAT &Format );

	// The following is specific to this app
	
	//Misc
	DWORD			m_bgColor;			//Background Color
	D3DXMATRIX		m_WorldMatrix;			
	D3DXMATRIX		m_ViewMatrix;
	D3DXMATRIX		m_ProjectionMatrix;
	float           m_pfSinLookup[1024];				//sin lookup table
    float           m_pfSqrtLookup[SQRT_TABLE_SIZE];	//sqrt lookup table


	//Materials
	D3DMATERIAL8	m_matWhite;

	//Background
	TLVERTEX		m_prBackground[4];	//Background Vertices
	GosTexture*		m_ptBgStars;		//Background Texture

	//Beach
	GosTexture*		m_ptBeach;				//Beach Texture
	UINT			m_uNumBeachVertices;	//Number of Beach vertices
	PHHVERTEX		m_prBeach;				//Beach Vertices
 	UINT			m_uNumBeachIndices;		//Number of Beach Indices
	LPWORD			m_pwBeach;				//Beach Indices
	
	//Cliff
	UINT			m_uNumCliffVertices;	//Number of Cliff vertices
	PHHVERTEX		m_prCliff;				//Cliff Vertices
 	UINT			m_uNumCliffIndices;		//Number of Cliff Indices
	LPWORD			m_pwCliff;				//Cliff Indices

	//LightHouse
	LIGHTHOUSE      m_lhLighthouse;			//Lighthouse
	float			m_fIntensity;			//Intensity of the lighthouse portal
	
	//waves
	PWAVESOURCE                     m_pws;				//Wavesource
    PHHVERTEX                       m_prWave;			//Wave Vertices
    UINT                            m_uNumWaveVertices;	//Number of wave vertices
    LPWORD                          m_pwWave;			//Wave Indices
    UINT                            m_uNumWaveIndices;	//Number of of Wave Indices
	float*                          m_pfBaseAngle;		// ?
	D3DMATERIAL8					m_matWave;			//Wave Texture

	//Lighthouse Cone
	float							m_fLightElevation;	//Current elevation
    float                           m_fLightRotation;	//Current rotation
    BOOL                            m_bRotateLight;		//Should light rotate?
    float                           m_fRotationDelta;	//Light rotation direction controlled by input
    float                           m_fElevationDelta;  //Light elevation direction controlled by input
    D3DXMATRIX                      m_mConeRotation;
	D3DXMATRIX						m_mConePosition;
    D3DXMATRIX                      m_mLightDirection;
	D3DXMATRIX						m_mLightCone;
    D3DLIGHT8                       m_ConeLight;
    D3DMATERIAL8                    m_matLightCone;
	REVOLUTION                      m_rvLightCone;
	float							m_fMaxIntensity;

	GosFont3D						*m_pOneFont;
	GosFont3D						*m_pTwoFont;
	GosFont3D						*m_pRedFont;
	GosFont3D						*m_pBluFont;
	GosFont3D						*m_pComicFont;

	//Light
	D3DLIGHT8						m_DefLight;				//Light
		
	//Input
	long							m_jX;				//joystick x
	long							m_jY;				//joystick y
	DWORD							m_jButtons;			//joystick buttons
//	int								m_lastButton;		//last button pressed

	//Functions for the App
	void			SetupBeach();			//Prepares the beach
	void			SetupCliff();			//Prepares the cliff
	void			SetupLighthouse();		//Prepares the lighthouse
	void			SetupWaves();			//Setup Waves
	void			RenderLighthouse();		//Renders the lighthouse
	void			ReleaseLighthouse();	//Cleans up the lighthouse 

	
};

