///////////////////////////////////////////////////////////////////////////////
/// @file de2D_priv.hpp
///
/// @brief private header for de2D library
///
/// @author 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 Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DE2D_PRIV_HPP
#define DE2D_PRIV_HPP

#include "de2D.hpp"
#include "deList.hpp"
#include "deRenderStates.hpp"

class de2DObject : public Ide2DObject, public deRefCountBase
{
protected:
	virtual ~de2DObject();
public:
	de2DObject(	IdeVertexBuffer * VBuffer, 
		IdeRenderTexture * Texture, deFloat Depth, 
		deBoolean ExpireNow = DE_FALSE);
	
	IdeVertexBuffer * GetVBuffer() const;
	IdeRenderTexture* GetTexture() const;
	deBoolean HasExpired() const;
	deFloat GetDepth() const;

	void MakeExpire();
	deBoolean SetDepth(deFloat Depth);
	
	deBoolean Move(deVertex DeltaXY);
	deBoolean Update(deDouble DeltaTime);
	
private:
	IdeVertexBuffer *	m_VBuffer;
	IdeRenderTexture *	m_Texture;
	deBoolean			m_Expire;
	IdeDriver *			m_Driver;
	deFloat				m_Depth;
	
protected:
	virtual deBoolean UpdateObject(deDouble DeltaTime);
	void SetVBuffer(IdeVertexBuffer * VBuffer);
	void SetTexture(IdeRenderTexture * Texture);
};

class de2DOverlay : public de2DObject
{
public:
	de2DOverlay(deRect *ScreenRect, deFloatRect *TexCoords,
		IdeRenderTexture * Texture, deFloat Depth = 10.0f, 
		deARGB color = 0xFFFFFFFF, deDouble FadePerSecond = 0.0);
	
protected:
	virtual ~de2DOverlay();
	
	virtual deBoolean UpdateObject(deDouble DeltaTime);
	
	deDouble m_Alpha, m_FadePerSecond;
};

class de2DCorona : public de2DOverlay
{
public:
	de2DCorona(	deRect *SizeRect, deFloatRect *TexCoords,
		IdeRenderTexture * Texture, IdeCamera * ScreenCamera,
		deFloat Depth = 10.0f, deARGB color = 0xFFFFFFFF);
	
	void SetPosition(deVec3d WorldPosition);
	
protected:
	virtual ~de2DCorona();
	
	virtual deBoolean UpdateObject(deDouble DeltaTime);
	
	deVec3d m_WorldPosition;
	deVertex m_ScreenPosition;
	deBoolean m_OnScreen;
	IdeCamera * m_Camera;
};

class de2DLine : public de2DObject
{
public:
	de2DLine(	deVec3d PointList[], long NumPoints,
		deARGB color = 0xFFFFFFFF,
		deDouble FadePerSecond = 0.0, deFloat Depth = 10.0f);
	de2DLine(	deVec3d Start, deVec3d End, 
		deARGB color = 0xFFFFFFFF,
		deDouble FadePerSecond = 0.0, deFloat Depth = 10.0f);
	de2DLine(	deRect & LineRect,
		deARGB color = 0xFFFFFFFF,
		deDouble FadePerSecond = 0.0, deFloat Depth = 10.0f);
protected:
	virtual ~de2DLine();
	
	virtual deBoolean UpdateObject(deDouble DeltaTime);
	
	deDouble m_Alpha, m_FadePerSecond;
};

class de2DCollection : public Ide2DCollection, public deRefCountBase
{
protected:
	virtual ~de2DCollection();
public:
	de2DCollection();

	void		SetParent(Ide2DCollection* ParentCollection);
	
	const deRect&	GetRect() const;
	void		SetRect(deRect & rect);

	void		SetBGColor(deARGB color);
	deARGB		GetBGColor();

	void		SetEnabled(deBoolean Enable);
	deBoolean	IsEnabled() const;
	
	void		GetScrollValue(deVec3d & scroll) const;
	void		SetScrollValue(const deVec3d & scroll);
	
	deBoolean	AddObject(Ide2DObject * object);
	deBoolean	RemoveObject(Ide2DObject * object);
	deBoolean	AdjustObjectDepth(Ide2DObject * object, deFloat Depth);
	
	deBoolean	AddSubCollection(Ide2DCollection * collection);
	deBoolean	RemoveSubCollection(Ide2DCollection * collection);
	deFloat		GetDepth() const;
	deBoolean	SetDepth(deFloat Depth);

	deBoolean	Render(	IdeDriver * Driver, deDouble DeltaTime, 
						IdeRenderTexture *NullTex, IdeRender::deRenderStats * RenderStats,
						deBoolean DoOcclusion);
	
	void		DestroyAllObjects(deBoolean SubCollectionsAlso);
	
	static IdeVertexBuffer*		s_CompositeFor2D;
private:
	static long					s_NumCollections;
	static IdeVertexBuffer*		s_BackdropQuad;
	static IdeRenderTexture*	s_BackdropTexture;
	
	// for storing things in our list
	struct de2DObjectUnion
	{
		union
		{
			Ide2DObject		*Object;
			Ide2DCollection	*Collection;
		};
		deBoolean IsObject;
	};
	deBoolean	AddItem(const de2DObjectUnion & NewItem);
	deBoolean	Set2DViewport(short FullWidth, short FullHeight, const deRect & SubRect, IdeDriver * pDriver);
	deBoolean	FillBGColor(IdeDriver * pDriver, const deRect & Rect, const deVec3d & Scroll, deARGB BGColor, IdeRenderTexture* &PrevTexture);

	// used in the Render function
	struct CollectionState_t
	{
		deTList <de2DObjectUnion>	*List;
		void						*Entry;
		deRect						ViewRect;
		deVec3d						Scroll;
		deARGB						BGColor;
	};
	struct RenderStateValue_t
	{
		IdeDriver::RenderState		State;
		long						Value;
	};
	
	deTList < de2DObjectUnion > m_ChildList;

	// the rect we clip to
	deRect				m_ClipRect;
	deVec3d				m_Scroll;

	Ide2DCollection*	m_pParent;
	deFloat				m_Depth;
	deARGB				m_BGColor;
	deBoolean			m_Enabled;
	
};

#endif

