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

erkMap::erkMap()
{
	m_dwvSize[0] = m_dwvSize[1] = 0;
	m_dwvTeamCounts[0] = m_dwvTeamCounts[1] = 0;
}

erkMap::~erkMap()
{
}

void erkMap::Draw(BITMAP* pDest, gbInt dwX, gbInt dwY)
{
	gbInt dwX1 = MAX(0, (-dwX)/EM_TILE_SIZE-1);
	gbInt dwY1 = MAX(0, (-dwY)/EM_TILE_SIZE-1);
	gbInt dwX2 = MIN(m_dwvSize[0]-1, ((-dwX)+pDest->w-1)/EM_TILE_SIZE);
	gbInt dwY2 = MIN(m_dwvSize[1]-1, ((-dwY)+pDest->h-1)/EM_TILE_SIZE);

	erkTile_p pTile;
	for(int ly=dwY1; ly<=dwY2; ly++)
	{
		for(int lx=dwX1; lx<=dwX2; lx++)
		{
			pTile = GetTileEx(lx, ly);
			if(pTile)
			{
				pTile->Draw(pDest, lx*EM_TILE_SIZE+dwX, ly*EM_TILE_SIZE+dwY);
			}
		}
	}
	for(int ly=dwY1; ly<=dwY2; ly++)
	{
		for(int lx=dwX1; lx<=dwX2; lx++)
		{
			pTile = GetTileEx(lx, ly);
			if(pTile)
			{
				pTile->DrawUnits(pDest, lx*EM_TILE_SIZE+dwX, ly*EM_TILE_SIZE+dwY);
			}
		}
	}
}

void erkMap::Update()
{
	for(gbListIter(erkTile_p) iPos=m_pvTiles.begin(); iPos!=m_pvTiles.end(); ++iPos)
	{
		if(*iPos)
			(*iPos)->Update();
	}

	m_dwvTeamCounts[0] = m_dwvTeamCounts[1] = 0;
	for(gbLinkListIter(erkUnit_p) iPos=m_pvUnits.begin(); iPos!=m_pvUnits.end(); )
	{
		(*iPos)->Move();
		if((*iPos)->GetTile())
		{
			m_dwvTeamCounts[(*iPos)->GetSide()?1:0]++;
			++iPos;
		}
		else
		{
			m_pvUnits.erase(iPos++);
		}
	}
}

void erkMap::SetSize(gbInt dwWidth, gbInt dwHeight)
{
	gbList(erkTile_p) pvTemp(m_pvTiles);
	m_pvTiles.clear();
	m_pvTiles.resize(dwWidth*dwHeight, NULL);
	int dwCX = MIN(dwWidth, m_dwvSize[0]);
	int dwCY = MIN(dwHeight, m_dwvSize[1]);

	for(int ly=0; ly<dwCY; ly++)
	{
		for(int lx=0; lx<dwCX; lx++)
		{
			m_pvTiles[lx+ly*dwWidth] = pvTemp[lx+ly*m_dwvSize[0]];
		}
	}

	pvTemp.clear();

	m_dwvSize[0] = dwWidth;
	m_dwvSize[1] = dwHeight;
}

void erkMap::SetTile(gbInt dwX, gbInt dwY, erkTile_p pTile)
{
	if(dwX < 0  ||  dwY < 0  ||  dwX >= m_dwvSize[0]  ||  dwY >= m_dwvSize[1])
		return;

	gbInt dwIndex = dwX+dwY*m_dwvSize[0];
	if(m_pvTiles[dwIndex])
		delete m_pvTiles[dwIndex];
	m_pvTiles[dwIndex] = pTile;
	pTile->SetMap(this);

	erkTile_p pNorth = GetTile(dwX, dwY-1);
	erkTile_p pEast = GetTile(dwX+1, dwY);
	erkTile_p pSouth = GetTile(dwX, dwY+1);
	erkTile_p pWest = GetTile(dwX-1, dwY);

	pTile->SetNeighbour(ET_N_NORTH, pNorth);
	pTile->SetNeighbour(ET_N_EAST, pEast);
	pTile->SetNeighbour(ET_N_SOUTH, pSouth);
	pTile->SetNeighbour(ET_N_WEST, pWest);

	if(pNorth)
	{
		pNorth->SetNeighbour(ET_N_SOUTH, pTile);
		pNorth->CheckNeighbours();
	}
	if(pEast)
	{
		pEast->SetNeighbour(ET_N_WEST, pTile);
		pEast->CheckNeighbours();
	}
	if(pSouth)
	{
		pSouth->SetNeighbour(ET_N_NORTH, pTile);
		pSouth->CheckNeighbours();
	}
	if(pWest)
	{
		pWest->SetNeighbour(ET_N_EAST, pTile);
		pWest->CheckNeighbours();
	}

	pTile->CheckNeighbours();
}

void erkMap::SetTile(gbInt dwX, gbInt dwY, erkTileType_p pType)
{
	if(dwX < 0  ||  dwY < 0  ||  dwX >= m_dwvSize[0]  ||  dwY >= m_dwvSize[1])
		return;

	gbInt dwIndex = dwX+dwY*m_dwvSize[0];
	if(m_pvTiles[dwIndex])
	{
		m_pvTiles[dwIndex]->SetType(pType);
	}
	else
	{
		erkTile_p pTile = new erkTile();
		pTile->SetType(pType);
		SetTile(dwX, dwY, pTile);
	}
}

void erkMap::SetTileLit(gbInt dwX, gbInt dwY, gbBool bLit)
{
	if(dwX < 0  ||  dwY < 0  ||  dwX >= m_dwvSize[0]  ||  dwY >= m_dwvSize[1])
		return;

	gbInt dwIndex = dwX+dwY*m_dwvSize[0];
	if(m_pvTiles[dwIndex])
	{
		m_pvTiles[dwIndex]->SetLit(bLit);
	}
}

void erkMap::FillBlanks(erkTileType_p pType)
{
	for(int ly=0; ly<m_dwvSize[1]; ly++)
	{
		for(int lx=0; lx<m_dwvSize[0]; lx++)
		{
			if(!GetTile(lx, ly))
			{
				SetTile(lx, ly, pType);
			}
		}
	}
}

void erkMap::AddUnit(erkUnit_p pUnit)
{
	m_pvUnits.push_back(pUnit);
}

void erkMap::RemoveUnit(erkUnit_p pUnit)
{
	gbLinkListIter(erkUnit_p) iPos = std::find(m_pvUnits.begin(), m_pvUnits.end(), pUnit);
	if(iPos == m_pvUnits.end())
		return;

	m_pvUnits.erase(iPos);
}

gbBool erkMap::CheckLOS(gbInt dwX1, gbInt dwY1, gbInt dwX2, gbInt dwY2)
{
}

void erkMap::Store(PACKFILE* pFile)
{
}

void erkMap::Load(PACKFILE* pFile)
{
}
