#ifndef ERK_TILE_H
#define ERK_TILE_H

#include "erkUnit.h"
#include "erkCommand.h"

#define ET_N_NORTH				0
#define ET_N_EAST				1
#define ET_N_SOUTH				2
#define ET_N_WEST				3

#define ET_CT_NONE				0
#define ET_CT_BUILD				1
#define ET_CT_MOVE				1

#define ET_HEALTH				8192

class erkTileType {
public:
								erkTileType();
	virtual						~erkTileType();

	virtual void				Build(BITMAP* pBase);
	virtual void				Update(class erkTile* pTile);
	virtual void				EffectUnit(class erkUnit* pUnit, class erkTile* pTile);

	virtual BITMAP*				GetLit();
	virtual BITMAP*				GetUnlit(gbInt dwNeighbourType);

	virtual void				SetBmp(gbInt dwIndex, BITMAP* pBmp);
	virtual void				SetSolid(gbBool bSolid);

	virtual BITMAP*				GetBmp(gbInt dwIndex);
	virtual gbBool				IsSolid();

protected:
	gbList(BITMAP*)				m_pvBmps;
	gbBool						m_bSolid;

};
typedef erkTileType *erkTileType_p;

class erkTile {
public:
								erkTile();
								~erkTile();

	void						Draw(BITMAP* pDest, gbInt dwX, gbInt dwY);
	void						DrawUnits(BITMAP* pDest, gbInt dwX, gbInt dwY);
	void						Update();

	void						SetType(erkTileType_p pType);
	void						SetLit(gbBool bLit);

	void						CheckNeighbours();
	void						SetNeighbour(gbInt dwDirection, erkTile* pTile);
	erkTile*					GetNeighbour(gbInt dwDirection);
	gbBool						IsSolid();
	gbBool						IsLit();

	void						AddUnit(class erkUnit* pUnit);
	void						MoveUnit(class erkUnit* pUnit, gbInt dwDirection);
	void						RemoveUnit(class erkUnit* pUnit);

	void						DecHealth(gbInt dwAmount);
	void						IncHealth(gbInt dwAmount);
	void						SetHealth(gbInt dwHealth);
	gbInt						GetHealth();

public: // inlines
	inline void					SetMap(class erkMap* pMap)
	{
		m_pMap = pMap;
	}

	inline erkTileType_p		GetType()
	{
		return m_pType;
	}
	inline class erkMap*		GetMap()
	{
		return m_pMap;
	}

	inline gbLinkListIter(erkUnit_p)	UnitsBegin()
	{
		return m_pvUnits.begin();
	}
	inline gbLinkListIter(erkUnit_p)	UnitsEnd()
	{
		return m_pvUnits.end();
	}

	inline class erkCommand*	GetCommand(gbBool bSide)
	{
		return m_pvCommand[bSide?1:0];
	}
	inline void					SetCommand(gbBool bSide, class erkCommand* pCmd)
	{
		if(pCmd != m_pvCommand[bSide?1:0])
			delete m_pvCommand[bSide?1:0];
		m_pvCommand[bSide?1:0] = pCmd;
		if(m_pvCommand[bSide?1:0])
			m_pvCommand[bSide?1:0]->SetTile(this);
	}

protected:
	erkTileType_p				m_pType;
	gbBool						m_bLit;
	gbInt						m_dwHealth;

	class erkMap*				m_pMap;

	gbInt						m_dwNeighbourType;
	erkTile*					m_pvNeighbours[4];

	gbLinkList(erkUnit_p)		m_pvUnits;
	gbInt						m_dwvUnitCounts[EU_UT_COUNT*2];
	gbInt						m_dwvTeamCounts[2];

	class erkCommand*			m_pvCommand[2];

};
typedef erkTile *erkTile_p;

#endif // ERK_TILE_H
