///////////////////////////////////////////////////////////////////////////////
/// @file deDriver_priv.hpp
///
/// @brief private driver implementations
///
/// @author Lightning, Assassin
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date May 2002
/// @author Assassin
/// @remarks Initial Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEDRIVER_PRIV_HPP
#define DEDRIVER_PRIV_HPP

#include "deDriver.hpp"
#include "deRenderStates.hpp"
//#include <windows.h> // for various stuff (RECT, etc)

class deDriver : public IdeDriver
{
protected:
	//the constructors
	deDriver();
	virtual ~deDriver();
public:
	virtual deBoolean Init(HWND WindowHandle) = 0;
	//display modification functions

	//set the current display
	virtual deBoolean SetDisplay(deDisplay *Display) = 0;
	virtual deBoolean Reset(deDisplay *Display = NULL) = 0;
	const deDisplay *GetDisplay() const;
	virtual deBoolean GetCurrentDisplay(long Adapter, deDisplay * Display) const = 0;
	virtual deBoolean GetDisplayMode(long Adapter, long Mode, deDisplay *Display) const = 0;
	virtual const deDriverCaps* GetCaps(long Adapter) const = 0;
	deRect UpdateWindowRect();
	deRect GetDisplayRect() const;
	
	//adapter and mode counts for adapters
	virtual long GetAdapterCount() const = 0;
	virtual long GetModeCount(long Adapter) const = 0;
	virtual deBoolean WindowedAllowed(long Adapter) const = 0;
	virtual deBoolean ValidFormat(long Adapter, Resource ResourceType, BPP BPPType, ZPP ZPPType, BPP FrontBuffer, long ExtraFlag) const = 0;
	long BitDepth(BPP BPPType) const;
	long BitDepth(ZPP ZPPType) const;
	long StencilDepth(ZPP ZPPType) const;
	deBoolean HasStencil(ZPP ZPPType) const;
	BPP DownSampleFormat(BPP OriginalFormat) const;
	
	//vertex buffer functions
	virtual deBoolean AddVertexBuffer(IdeVertexBuffer *Vertex) = 0;
	virtual deBoolean RemoveVertexBuffer(IdeVertexBuffer *Vertex) = 0;
	virtual deBoolean UpdateVertexBuffer(IdeVertexBuffer *Vertex) = 0;

	// Shader functions
	virtual deBoolean AddShader(IdeShader * Shader) = 0;
	virtual deBoolean SetShader(IdeShader * Shader) = 0;
	virtual deBoolean RemoveShader(IdeShader * Shader) = 0;

	//frame functions
	virtual	deBoolean BeginFrame() = 0;								//BeginFrame must be called to start rendering
	virtual deBoolean EndFrame() = 0;								//finish off the frame
	
	//allow clearing of the frame with a color
	virtual deBoolean ClearFrame(deARGB Color, deBoolean ClearTarget = deTRUE, deBoolean ClearZBuffer = deTRUE, deBoolean ClearStencil = deTRUE) = 0;
	virtual deBoolean Render(IdeVertexBuffer *Vertex, long IndexOffset, IdeVertexBuffer *IndexOverride) = 0;			//render a frame

	//viewport/FOV functions
	virtual deBoolean SetViewport(long X, long Y, long Width, long Height, deFloat MinZ, deFloat MaxZ) = 0;
	virtual deBoolean SetFOVClipping(deFloat FOV, deFloat Aspect, deFloat ClipNear, deFloat ClipFar) = 0;
	virtual deBoolean SetOrthoClipping(deFloat Width, deFloat Height, deFloat ClipNear, deFloat ClipFar, deBoolean Invert = deFALSE) = 0;
	virtual deBoolean SetFOVClippingSubRect(deFloat FOVY, deFloat Aspect, deFloat ClipNear, deFloat ClipFar, deRect SubRect) = 0;
	virtual deBoolean SetFOVClippingSubRectFloat(deFloat FOVY, deFloat Aspect, deFloat ClipNear, deFloat ClipFar, deFloatRect SubRect) = 0;
	virtual deBoolean SetOrthoClippingSubRect(deFloat Width, deFloat Height, deFloat ClipNear, deFloat ClipFar, deBoolean Invert, deRect SubRect) = 0;
	virtual deBoolean SetOrthoClippingSubRectFloat(deFloat Width, deFloat Height, deFloat ClipNear, deFloat ClipFar, deBoolean Invert, deFloatRect SubRect) = 0;
	virtual deBoolean SetScissorRect(deRect ScissorRect) = 0;

	//camera translation functions
	virtual deBoolean SetCameraTransform(deTransformInfo *M) = 0;
	virtual deBoolean SetCameraTransform(deVertex *Eye, deVertex *At, deVertex *Up) = 0;
	virtual deBoolean SetCameraTranslation(deVertex *Translation) = 0;
	virtual deBoolean SetCameraRotation(deVertex *Rotation) = 0;
	virtual deBoolean ResetCameraIdentity() = 0;

	//world translation functions
	virtual deBoolean SetWorldTransform(deVertex *Eye, deVertex *At, deVertex *Up) = 0;
	virtual deBoolean SetWorldTransform(deTransformInfo * Mat) = 0;
	virtual deBoolean SetWorldTranslation(deVertex *Translation) = 0;
	virtual deBoolean SetWorldRotation(deVertex *Rotation) = 0;
	virtual deBoolean ResetWorldIdentity() = 0;
	
	//texture functions
	virtual deBoolean AddBitmap(IdeBitmap *Bitmap) = 0;
	virtual deBoolean AddBitmapProxy(IdeBitmapProxy *BitmapProxy) = 0;
	virtual deBoolean RemoveBitmap(IdeBitmap *Bitmap) = 0;
	
	//render-to-texture functions
	virtual deBoolean RenderTo(IdeBitmap *Bitmap, long CubeMapFace) = 0;
	virtual deBoolean ScreenShot(IdeBitmap * &pBitmap, deBoolean GrabWindow) = 0;
	virtual deBoolean GetVideoTexture(IdeBitmap* pBitmap, long CubeMapFace) = 0;
	
	//render states
	virtual unsigned long GetRenderState(RenderState State) = 0;
	virtual deBoolean SetRenderState(const IdeRenderState *State) = 0;
	virtual deBoolean SetRenderState(RenderState State, unsigned long Value) = 0;
	virtual deBoolean EnableLight(long LightID, deBoolean Enable) = 0;
	virtual deBoolean DisableAllLights() = 0;

	unsigned long GetQualityFlag(QualityFlag Flag);
	deBoolean SetQualityFlag(QualityFlag Flag, unsigned long Value);
	
	//driver info
	virtual IdeDriver::Types GetType() const = 0;
	virtual deDriverInfo *GetInfo() const = 0;
	long GetCount();

	//logging info
	void LogInfo(char *Data, ...);
	deDriverStats* GetDriverStats();
	void ResetDriverStats();
	
protected:
	//set the default renderstates for the driver
	void SetDefaultRenderstates();
	virtual void InvalidateRenderStates(deBoolean Valid) = 0;

	deDisplay		m_CurrentDisplay;		//current display for this driver
	HWND			m_CurWindowHandle;		//handle to the window this display is using
	long			m_UniqueID;				//unique ID for the driver entry
	deRect			m_ClientRect;			//client rect to use if in windowed mode
	deRect			m_SourceRect;			//source rect to draw from
	unsigned long	m_RenderStates[RENDER_COUNT];	//current state of the renderstates
	unsigned long	m_QualityFlags[QUALITY_FLAG_COUNT];
	deDriverStats	m_Stats;
	struct deViewport
	{
		long X, Y, Width, Height;
		deFloat MinZ, MaxZ;
	} m_CurrentViewport;		//current viewport rect
};

class deDriverLoad : public IdeDriverLoad
{
protected:
	deDriverLoad::~deDriverLoad();	
public:
	//init and destroy functions
	deDriverLoad::deDriverLoad(char const *Path);
	long Release();
	
	//basic driver info functions
	long GetCount();
	const deDriverInfo *GetInfo(long DriverNumber);
	const deDriverInfo *GetInfo(char *DriverName);
	IdeDriver *GetDriver(long DriverNumber);
	IdeDriver *GetDriver(char *DriverName);
	
private:
	//a structure to hold each driver entry (internal struct)
	typedef struct DriverEntry
	{
		HMODULE				DriverHandle;	//handle to driver
		ISDESTINY3DDRIVER	DriverProc;		//handle to IsDestiny3DDriver function
		GETDRIVERINSTANCE	DriverInstance;	//handle to GetDriverInstance function
		GETDRIVERINFO		DriverInfo;		//handle to GetDriverName function
		char *				DLLName;		//name of DLL
		char *				DriverName;		//name of driver
		DriverEntry *		Next;			//pointer to next driver
	} DriverEntry;
	
	//private function
	DriverEntry *GetEntry(long EntryNumber);
	DriverEntry *GetEntry(char *DriverName);
	
	DriverEntry *	m_DriverList;
	long			m_DriverCount;
	
	long			m_UniqueDriverID;
};


#endif