/////////////////////////////////////////////////////////////
//	File	:	"CBase.h"
//
//	Author	:	Sean Murray (SM)
//
//	Purpose	:	The base object for our class hierarchy
//				and implements our base interface.
//				Note: for this game all our objects act the same
//				      and contain the same amount of data, so it
//					  will derive from our listener class as well.
/////////////////////////////////////////////////////////////
#pragma once

#include "IBaseInterface.h"
#include "SGD_Math.h"
#include "CSGD_MessageSystem.h"
#include <windows.h>

// The include files for Direct3D9
#include <d3d9.h>
#include <d3dx9.h>

#include "IListener.h"


// The library files for Direct3D9
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment (lib, "dxguid.lib")

class CAnimInstance;

class CBase : public IBaseInterface, public IListener
{
protected:
	unsigned int m_unRefCount;	//	Number of references to the obejct.
	
	tVector2D	m_vPos;			//	The position of the object.
	tVector2D	m_vVel;			//	The velocity of the object.
	float	m_fZPosition;		//
	int		m_nWidth;			//	The width of the object.
	int		m_nHeight;			//	The height of the object.
	int		m_nImageID;			//	The image ID of the object.
	int		m_nType;			//	The type of the object.
	float	m_fScale;			//	The scale of the object.
	float	m_fRotation;		//	The rotation of the object.
	RECT	m_rImageArea;		//	The image area of the texture to render for the object.
	RECT    m_rCollisionRect;	//	The collision rect of the object.
	D3DXCOLOR m_dxcMyColor;		//	The color of the object.
	CAnimInstance* m_pCurrentAnim;
	bool	m_bIsAnimated;

public:
	enum { OBJECT_GOOD_NOTE=0, OBJECT_BAD_NOTE, OBJECT_SOUND_WAVE, OBJECT_PLAYER, NUMOBJECTS};
		   

	///////////////////////////////////////////////////////////////////////////////////
	//  Function: Constructor
	//
	//  Purpose : Initializes the data in the object.
	///////////////////////////////////////////////////////////////////////////////////
	CBase(void);
	///////////////////////////////////////////////////////////////////////////////////
	//  Function: Destructor
	//
	//  Purpose : Cleans up any dynamic memory.
	///////////////////////////////////////////////////////////////////////////////////
	virtual ~CBase(void);

	///////////////////////////////////////////////////
	//	Function:	Accessors
	//
	//	Purpose: Gets the specified type
	///////////////////////////////////////////////////
	inline float GetPosX(void) const	{ return m_vPos.fX; }
	inline float GetPosY(void) const	{ return m_vPos.fY; }
	inline float GetPosZ(void) const	{ return m_fZPosition; }
	inline float GetVelX(void) const	{ return m_vVel.fX; }
	inline float GetVelY(void) const	{ return m_vVel.fY; }
	inline tVector2D GetPos(void) const { return m_vPos; }
	inline tVector2D GetVel(void) const { return m_vVel; }
	inline int GetWidth(void) const			  { return m_nWidth;  }
	inline int GetHeight(void) const		  { return m_nHeight; }
	inline int GetImageID(void)	const { return m_nImageID; }
	inline int GetType(void) const { return m_nType; }
	inline float GetScale(void) const { return m_fScale; }
	inline float GetRotation(void) const { return m_fRotation; }
	inline RECT GetImageArea(void) const { return m_rImageArea; }
	inline D3DXCOLOR GetColor(void) const {return m_dxcMyColor;}
	inline CAnimInstance* GetAnimInstance(void) {return m_pCurrentAnim;}
	inline bool IsAnimated(void) {return m_bIsAnimated;}
	///////////////////////////////////////////////////////////////////////
	//	Function:	GetCollisionRect
	//
	//	Purpose:	Gets the collision rect of the object based on its 
	//				position and width/height.
	///////////////////////////////////////////////////////////////////////
	RECT GetCollisionRect(void);

	//////////////////////////////////
	//	Function:	Mutators
	//
	//	Purpose: Sets the specified type
	/////////////////////////////////
	inline void SetIsAnimated(bool bAnimated) {m_bIsAnimated = bAnimated;}
	inline void SetCollisionRect(RECT rectangle) {m_rCollisionRect = rectangle;}
	inline void SetMyColor(D3DXCOLOR dxcColor) {m_dxcMyColor = dxcColor;}
	inline void SetMyColor(float alpha, float red, float green, float blue)	
	{
		m_dxcMyColor.a = alpha;
		m_dxcMyColor.r = red;
		m_dxcMyColor.g = green;
		m_dxcMyColor.b = blue;
	}
	inline void SetPosX(float fPosX)	{ m_vPos.fX = fPosX; }
	inline void SetPosY(float fPosY)	{ m_vPos.fY = fPosY; }
	inline void SetPosZ(float fPosZ)	{ m_fZPosition = fPosZ; }
	inline void SetVelX(float fVelX)	{ m_vVel.fX = fVelX; }
	inline void SetVelY(float fVelY)	{ m_vVel.fY = fVelY; }
	inline void SetPos(tVector2D vPos)
	{
		SetPosX(vPos.fX);
		SetPosY(vPos.fY);
	}
	inline void SetVel(tVector2D vVel)
	{
		SetVelX(vVel.fX);
		SetVelY(vVel.fY);
	}
	inline void SetWidth(int nWidth)	{m_nWidth = nWidth;}
	inline void SetHeight(int nHeight)	{m_nHeight = nHeight;}
	inline void SetImageID(int nImageID)	{ m_nImageID = nImageID; }
	inline void SetType(int nType) { m_nType = nType; }
	inline void SetScale(float fScale) { m_fScale = fScale; }
	inline void SetRotation(float fRotation) { m_fRotation = fRotation; }
	void SetImageArea(RECT rImageArea) { m_rImageArea = rImageArea; }

	///////////////////////////////////////////////////////////////////////////////
	//	Function:	"Update"
	//
	//	Purpose:	Updates the objects position based on its velocity
	///////////////////////////////////////////////////////////////////////////////
	virtual void Update(float fElapsedTime);
	///////////////////////////////////////////////////////////////////////////////
	//	Function:	Render
	//
	//	Purpose:	Renders the object
	///////////////////////////////////////////////////////////////////////////////
	void Render(void);
	///////////////////////////////////////////////////////////////////////////////
	//	Function:	AddRef
	//
	//	Purpose:	Increments the object's reference count by 1.
	///////////////////////////////////////////////////////////////////////////////
	void AddRef(void)
	{
		m_unRefCount++;	
	}
	///////////////////////////////////////////////////////////////////////////////
	//	Function:	Release
	//
	//	Purpose:	Decrements the object's reference count by 1.
	///////////////////////////////////////////////////////////////////////////////
	void Release(void)
	{
		m_unRefCount--;

		//	Delete self when no more references.
		if (m_unRefCount == 0)
			delete this;
	}
	///////////////////////////////////////////////////////////////////////////////
	//	Function:	CheckCollisions
	//
	//	Purpose:	Checked collisions on this object against every other object.
	///////////////////////////////////////////////////////////////////////////////
	virtual bool CheckCollisions(CBase * pBase) ;


	/////////////////////////////////
	//	Function:	HandleEvent
	//  Last Modified: July 23, 2008
	//	Purpose: handles an event
	/////////////////////////////////
	virtual void HandleEvent(CEvent* pEvent);

};
