//////////////////////////////////////////////////////////////////////////////
/// @file deRenderStates_priv.hpp
///
/// @brief private renderstate implementations
///
/// @author Lightning
///
/// 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 Lightning
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DERENDERSTATES_PRIV_HPP
#define DERENDERSTATES_PRIV_HPP

#include "deRenderStates.hpp"
#include "deFile.hpp"
#include "deWorld_Helper.hpp"

class deRenderState : public deWorldObject, virtual public IdeRenderState
{
protected:
	deRenderState();
	virtual ~deRenderState();
	deBoolean	Lock();
	deBoolean	Unlock();
	void*		GetWOInterface(long interface_id);
	long		m_LockFlag;		//flag if it is locked
};

//the texture renderstate class
class deRenderTexture : public deRenderState, public IdeRenderTexture
{
	//constructor/destructor
protected:
	~deRenderTexture();
public:
	deRenderTexture();

#if defined(DESTINY3D_STATIC_LINK)
	friend deBoolean IdeRenderState_SetDefaultTextureFilters(long MinFilter, long MagFilter, long MipFilter, deBoolean EnableMip);	
#else
	friend __declspec(dllexport) deBoolean IdeRenderState_SetDefaultTextureFilters(long MinFilter, long MagFilter, long MipFilter, deBoolean EnableMip);	
#endif
	IdeRenderState::Type GetRSType() const;
	void *		GetRSInterface(IdeRenderState::Type type) const;
	WorldObjectClassDef;
	deBoolean DeSerializeLoad();
	
	//functions for setting/returning texture operations
	deBoolean SetColorOperation(long Stage, TextureOp ColorOp);
	deBoolean SetAlphaOperation(long Stage, TextureOp AlphaOp);
	TextureOp GetColorOperation(long Stage) const;
	TextureOp GetAlphaOperation(long Stage) const;
	deBoolean SetResultTarget(long Stage, TextureArg Target);
	TextureArg GetResultTarget(long Stage);
	
	//functions for setting the arguments
	deBoolean SetColorArg(long Stage, long ArgNum, TextureArg Arg);
	deBoolean SetAlphaArg(long Stage, long ArgNum, TextureArg Arg);
	TextureArg GetColorArg(long Stage, long ArgNum) const;
	TextureArg GetAlphaArg(long Stage, long ArgNum) const;

	//texture information
	deBoolean SetBitmap(long Stage, IdeBitmapProxy* Bitmap);
	IdeBitmapProxy*GetBitmap(long Stage) const;

	//functions to set how the texture looks
	deBoolean SetTextureAddressU(long Stage, TextureAddress Address);
	deBoolean SetTextureAddressV(long Stage, TextureAddress Address);
	TextureAddress GetTextureAddressU(long Stage) const;
	TextureAddress GetTextureAddressV(long Stage) const;

	// functions to set how the texture magnifies and minifies
	// ie, linear filter to magnify is very common
	deBoolean SetTextureMinFilter(long Stage, TextureFilter Filter);
	deBoolean SetTextureMagFilter(long Stage, TextureFilter Filter);
	deBoolean SetTextureMipFilter(long Stage, TextureFilter Filter);
	TextureFilter GetTextureMinFilter(long Stage) const;
	TextureFilter GetTextureMagFilter(long Stage) const;
	TextureFilter GetTextureMipFilter(long Stage) const;
	
	deBoolean SetTexCoordSource(long Stage, long SourceStage);
	deBoolean SetTexCoordGen(long Stage, TextureCoordSource SourcePipe, long CopyWrapModeStage);
	deBoolean GetTexCoordSource(long Stage, long &SourceStage, TextureCoordSource &SourceFlags);
	long GetTexCoordSourceCombined(long Stage);
	
	deBoolean SetTextureProjection(long Stage, deBoolean Enable);
	deBoolean GetTextureProjection(long Stage);
	
	deBoolean CopyStageSettings(IdeRenderTexture* Target, long SourceStage, long TargetStage) const;

private:
	deBoolean		m_EnableMipMaps;
	deBoolean		m_TextureProjection[TEXTURESTAGE_COUNT];
	TextureArg		m_ColorArgs[TEXTURESTAGE_COUNT][4];		//color arguments and result target
	TextureArg		m_AlphaArgs[TEXTURESTAGE_COUNT][3];		//alpha arguments
	TextureOp		m_ColorOperation[TEXTURESTAGE_COUNT];	//color operation
	TextureOp		m_AlphaOperation[TEXTURESTAGE_COUNT];	//alpha operation
	IdeBitmapProxy*	m_Bitmaps[TEXTURESTAGE_COUNT];			//texture bitmap class
	TextureAddress	m_TextureAddressU[TEXTURESTAGE_COUNT];	//the texture address U
	TextureAddress	m_TextureAddressV[TEXTURESTAGE_COUNT];	//the texture address V
	TextureFilter	m_TextureFilterMin[TEXTURESTAGE_COUNT];	//texture minification filter
	TextureFilter	m_TextureFilterMag[TEXTURESTAGE_COUNT];	//texture magnification filter
	TextureFilter	m_TextureFilterMip[TEXTURESTAGE_COUNT];	//texture magnification filter
	long			m_TexCoordSource[TEXTURESTAGE_COUNT];
	deIDPair		m_CachedBitmapIDs[TEXTURESTAGE_COUNT];

	static TextureFilter DefaultMinFilter, DefaultMagFilter, DefaultMipFilter;
	static deBoolean DefaultToMip;
};

//the material renderstate class
class deRenderMaterial : public deRenderState, public IdeRenderMaterial
{
	//constructor/destructor
protected:
	~deRenderMaterial();
public:
	deRenderMaterial();

	IdeRenderState::Type GetRSType() const;
	void *		GetRSInterface(IdeRenderState::Type type) const;
	WorldObjectClassDef;
	
	//color information
	deBoolean SetAmbientColor(deColor *AmbientColor);
	deBoolean GetAmbientColor(deColor *AmbientColor) const;
	
	deBoolean SetDiffuseColor(deColor *DiffuseColor);
	deBoolean GetDiffuseColor(deColor *DiffuseColor) const;
	
	deBoolean SetSpecularColor(deColor *SpecularColor);
	deBoolean GetSpecularColor(deColor *SpecularColor) const;
	
	deBoolean SetEmissiveColor(deColor *EmissiveColor);
	deBoolean GetEmissiveColor(deColor *EmissiveColor) const;

	// base source info
	deBoolean SetAmbientSource(MatSource_t Source);
	MatSource_t GetAmbientSource() const;

	deBoolean SetDiffuseSource(MatSource_t Source);
	MatSource_t GetDiffuseSource() const;

	deBoolean SetSpecularSource(MatSource_t Source);
	MatSource_t GetSpecularSource() const;

	deBoolean SetEmissiveSource(MatSource_t Source);
	MatSource_t GetEmissiveSource() const;
	
	//power of the light
	deBoolean SetSpecularPower(float Power);
	float GetSpecularPower() const;
	
	const MatData* GetAllData() const;
	deBoolean SetAllData(const MatData* Data);

private:
	MatData	m_Data;
};

//the light renderstate class
class deRenderLight : public deRenderState, public IdeRenderLight
{
	//constructor/destructor
protected:
	~deRenderLight();
public:
	deRenderLight();

	IdeRenderState::Type GetRSType() const;
	void *		GetRSInterface(IdeRenderState::Type type) const;
	WorldObjectClassDef;
	
	//the light type
	deBoolean SetLightType(LightType_t Type);
	LightType_t GetLightType() const;

	//color information
	deBoolean SetAmbientColor(deColor *AmbientColor);
	deBoolean GetAmbientColor(deColor *AmbientColor) const;

	deBoolean SetDiffuseColor(deColor *DiffuseColor);
	deBoolean GetDiffuseColor(deColor *DiffuseColor) const;

	deBoolean SetSpecularColor(deColor *SpecularColor);
	deBoolean GetSpecularColor(deColor *SpecularColor) const;

	//position/direction information
	deBoolean SetPosition(deVertex *Position);
	deBoolean GetPosition(deVertex *Position) const;

	deBoolean SetDirection(deVertex *Direction);
	deBoolean GetDirection(deVertex *Direction) const;

	//anything that affects the way the light looks/acts
	deBoolean SetRange(float MaxRange);
	float GetRange() const;

	deBoolean SetFallOff(float FallOff);
	float GetFallOff() const;

	deBoolean SetAttenuation(long Number, float Value);
	float GetAttenuation(long Number) const;

	deBoolean SetTheta(float Theta);
	float GetTheta() const;

	deBoolean SetPhi(float Phi);
	float GetPhi() const;

	//which light number it is
	deBoolean SetID(long Number);
	long GetID() const;

	//light status (on/off)
	deBoolean SetStatus(deBoolean On);
	deBoolean GetStatus() const;

	const LightData* GetAllData() const;
	deBoolean SetAllData(const LightData* Data);

private:
	LightData	m_Data;
};

#endif