#include <allegro.h>
#include <winalleg.h>
#include "erkMap.h"

gbInt eu_dwvMaxHealth[EU_UT_COUNT] = {
	3000,
	4000,
	6000,
	8000,
	10000,
	12000,
	16000,
	24000,
};

gbInt eu_dwvDamage[EU_UT_COUNT] = {
	1,
	2,
	2,
	3,
	3,
	4,
	4,
	5,
};

gbInt eu_dwvTileDamage[EU_UT_COUNT] = {
	2,
	1,
	1,
	1,
	1,
	1,
	2,
	3,
};

erkUnit::erkUnit() :
	m_dwType(EU_UT_WORKER),
	m_dwColor(0),
	m_bSide(false),
	m_dwHealth(eu_dwvMaxHealth[0]),
	m_dwExp(0)
{
	m_fvPos[0] = (rand()%20001)/10000.0f-1.0f;
	m_fvPos[1] = (rand()%20001)/10000.0f-1.0f;
	m_fvVel[0] = (rand()%20001)/10000.0f-1.0f;
	m_fvVel[1] = (rand()%20001)/10000.0f-1.0f;
}

erkUnit::~erkUnit()
{
}

void erkUnit::Draw(BITMAP* pDest, gbInt dwX, gbInt dwY)
{
	dwX += (gbInt)(m_fvPos[0]*(EM_TILE_SIZE/2));
	dwY += (gbInt)(m_fvPos[1]*(EM_TILE_SIZE/2));
	rectfill(pDest, dwX-1, dwY-1, dwX+1, dwY+1, m_dwColor);

	switch(m_dwType)
	{
	case EU_UT_WORKER:
		{
			break;
		}
	case EU_UT_SOLDIER_4:
		{
			putpixel(pDest, dwX-2, dwY+2, m_dwColor);
		}
	case EU_UT_SOLDIER_3:
		{
			putpixel(pDest, dwX+2, dwY+2, m_dwColor);
		}
	case EU_UT_SOLDIER_2:
		{
			putpixel(pDest, dwX+2, dwY-2, m_dwColor);
		}
	case EU_UT_SOLDIER_1:
		{
			putpixel(pDest, dwX-2, dwY-2, m_dwColor);
			break;
		}
	case EU_UT_COMMANDER:
		{
			hline(pDest, dwX-2, dwY-3, dwX+2, m_dwColor);
			hline(pDest, dwX-2, dwY+3, dwX+2, m_dwColor);
			break;
		}
	case EU_UT_ADMIRAL:
		{
			vline(pDest, dwX-3, dwY-2, dwY+2, m_dwColor);
			vline(pDest, dwX+3, dwY-2, dwY+2, m_dwColor);
			hline(pDest, dwX-5, dwY, dwX-4, m_dwColor);
			hline(pDest, dwX+4, dwY, dwX+5, m_dwColor);
			break;
		}
	case EU_UT_QUEEN:
		{
			hline(pDest, dwX-2, dwY-3, dwX+2, m_dwColor);
			hline(pDest, dwX-2, dwY+3, dwX+2, m_dwColor);
			vline(pDest, dwX-3, dwY-2, dwY+2, m_dwColor);
			vline(pDest, dwX+3, dwY-2, dwY+2, m_dwColor);
			break;
		}
	}
}

void erkUnit::Move()
{
	if(!m_pTile)
		return;

	if(ABS(m_fvVel[0]) > 0.7f  ||  ABS(m_fvVel[1]) > 0.7f)
	{
		m_fvVel[0] *= 0.995f;
		m_fvVel[1] *= 0.995f;
	}

	if((rand()>>8) == 0)
	{
		m_fvVel[0] += ((rand()*2-RAND_MAX)/(float)RAND_MAX)*1.25f;
		m_fvVel[1] += ((rand()*2-RAND_MAX)/(float)RAND_MAX)*1.25f;
	}

	erkTile_p pNorth = m_pTile->GetNeighbour(ET_N_NORTH);
	erkTile_p pEast = m_pTile->GetNeighbour(ET_N_EAST);
	erkTile_p pSouth = m_pTile->GetNeighbour(ET_N_SOUTH);
	erkTile_p pWest = m_pTile->GetNeighbour(ET_N_WEST);

	if(pNorth)
	{
		if(!pNorth->IsSolid()  &&  m_pTile->IsLit() != m_bSide  &&  pNorth->IsLit() == m_bSide)
		{
			m_fvVel[1] -= 0.01f;
		}
	}
	if(pEast)
	{
		if(!pEast->IsSolid()  &&  m_pTile->IsLit() != m_bSide  &&  pEast->IsLit() == m_bSide)
		{
			m_fvVel[0] += 0.01f;
		}
	}
	if(pSouth)
	{
		if(!pSouth->IsSolid()  &&  m_pTile->IsLit() != m_bSide  &&  pSouth->IsLit() == m_bSide)
		{
			m_fvVel[1] += 0.01f;
		}
	}
	if(pWest)
	{
		if(!pWest->IsSolid()  &&  m_pTile->IsLit() != m_bSide  &&  pWest->IsLit() == m_bSide)
		{
			m_fvVel[0] -= 0.01f;
		}
	}

	m_fvPos[0] += m_fvVel[0]*0.01f;
	m_fvPos[1] += m_fvVel[1]*0.01f;

	if(m_fvPos[0] < -1.0f)
	{
		if(pWest  &&  !pWest->IsSolid())
		{
			m_fvPos[0] += 2.0f;
			m_pTile->MoveUnit(this, ET_N_WEST);
			m_pTile = pWest;
		}
		else
		{
			m_fvPos[0] = -1.0f;
			m_fvVel[0] = -m_fvVel[0];
			if(pWest  &&  pWest->GetCommand(m_bSide))
				pWest->GetCommand(m_bSide)->Collision(m_bSide);
		}
	}
	else if(m_fvPos[0] >= 1.0f)
	{
		if(pEast  &&  !pEast->IsSolid())
		{
			m_fvPos[0] -= 2.0f;
			m_pTile->MoveUnit(this, ET_N_EAST);
			m_pTile = pEast;
		}
		else
		{
			m_fvPos[0] = 1.0f;
			m_fvVel[0] = -m_fvVel[0];
			if(pEast  &&  pEast->GetCommand(m_bSide))
				pEast->GetCommand(m_bSide)->Collision(m_bSide);
		}
	}
	else if(m_fvPos[1] < -1.0f)
	{
		if(pNorth  &&  !pNorth->IsSolid())
		{
			m_fvPos[1] += 2.0f;
			m_pTile->MoveUnit(this, ET_N_NORTH);
			m_pTile = pNorth;
		}
		else
		{
			m_fvPos[1] = -1.0f;
			m_fvVel[1] = -m_fvVel[1];
			if(pNorth  &&  pNorth->GetCommand(m_bSide))
				pNorth->GetCommand(m_bSide)->Collision(m_bSide);
		}
	}
	else if(m_fvPos[1] >= 1.0f)
	{
		if(pSouth  &&  !pSouth->IsSolid())
		{
			m_fvPos[1] -= 2.0f;
			m_pTile->MoveUnit(this, ET_N_SOUTH);
			m_pTile = pSouth;
		}
		else
		{
			m_fvPos[1] = 1.0f;
			m_fvVel[1] = -m_fvVel[1];
			if(pSouth  &&  pSouth->GetCommand(m_bSide))
				pSouth->GetCommand(m_bSide)->Collision(m_bSide);
		}
	}

	erkTileType_p pType = m_pTile->GetType();
	if(pType)
	{
		pType->EffectUnit(this, m_pTile);
	}

	if(m_dwHealth < 0)
	{
		m_pTile->RemoveUnit(this);
		m_pTile = NULL;
	}
}

void erkUnit::SetTile(erkTile_p pTile)
{
	m_pTile = pTile;
}

void erkUnit::SetColor(gbInt dwColor)
{
	m_dwColor = dwColor;
}

void erkUnit::SetSide(gbBool bSide)
{
	m_bSide = bSide;
}

erkTile_p erkUnit::GetTile()
{
	return m_pTile;
}

gbInt erkUnit::GetColor()
{
	return m_dwColor;
}

gbBool erkUnit::GetSide()
{
	return m_bSide;
}

void erkUnit::IncHealth(gbInt dwAmount)
{
	m_dwHealth = MIN(eu_dwvMaxHealth[m_dwType], m_dwHealth+dwAmount);
}

void erkUnit::DecHealth(gbInt dwAmount)
{
	m_dwHealth -= dwAmount;
}

void erkUnit::SetType(gbInt dwType)
{
	m_dwType = dwType;
}

gbInt erkUnit::GetType()
{
	return m_dwType;
}

void erkUnit::IncExp()
{
	m_dwExp++;
	if(m_dwType < EU_UT_COUNT-1  &&  m_dwExp >= (m_dwType+((m_dwType>EU_UT_SOLDIER_4)?4:1)*2000))
	{
		m_dwExp = 0;
		m_dwType++;
		m_dwHealth = eu_dwvMaxHealth[m_dwType];
	}
}

void erkUnit::AddVel(gbFloat fX, gbFloat fY)
{
	m_fvVel[0] += fX;
	m_fvVel[1] += fY;
}
