#include "CPlayerObject.h"
#include "CTextReader.h"
#include "CBlockObject.h"
#include "CBombObject.h"
#include "CObjectManager.h"
#include "CGame.h"
#include "CExplosionObject.h"


//----------------------------------------------------------------//
//	Constructor/Deconstructor
//----------------------------------------------------------------//

CPlayerObject::CPlayerObject()
{


}

CPlayerObject::~CPlayerObject()
{



}

void CPlayerObject::Init(STRINGC fn)
{
	this->typ=typPlayer;		//IMPORTANT!!!

	//You MUST set these to zero before setting the bounding box!!!	
	m_Position.x=0;
	m_Position.y=0;

	//Set up the animations. I choose to store the animations in an array and keep a pointer to the "current" one. This part
	//load them all up. CTextReader is a class to extract name/value pairs from a text file.

	m_Animations[walkN].Init(CTextReader::getString("walkN",fn));
	m_Animations[walkE].Init(CTextReader::getString("walkE",fn));
	m_Animations[walkS].Init(CTextReader::getString("walkS",fn));
	m_Animations[walkW].Init(CTextReader::getString("walkW",fn));
	m_Animations[die].Init(CTextReader::getString("die",fn));

	m_currentAnimation=walkS;	
	
	//Hard coding this cause I suck. This is hopefully just temporary.
	//SetRect(&m_boundingBox, 8, 60, 72, 124);
	SetRect(&m_boundingBox, 0, 0, g_Game.getTileSize(), g_Game.getTileSize());
	
	//This is really shitty :( I am ashamed
	m_AnchorDisplacement.x = 8  / (double(64/g_Game.getTileSize()));
	m_AnchorDisplacement.y = 60 / (double(64/g_Game.getTileSize()));


	//Ok the bounding box is set. Now whenever we move the player we move the bounding box. And everything takes care of itself.
	//(this is done in the CGameObject's default method of setX and setY)

	m_lastBombPlaced=NULL;
	m_lastBombPlaced2=NULL;
	m_bomb1ID=0;
	m_bomb2ID=0;

	m_maxBombs=2;
	m_currentBombsPlaced=0;
	m_bombStrength=5;

	
}

//----------------------------------------------------------------//
//	Draw/Update
//----------------------------------------------------------------//

void CPlayerObject::Draw()
{

	//Fetch the current Animation
	CImage* img = m_Animations[m_currentAnimation].getCurrentImage();

	
	
	//We may not draw the player. If thats the case. Dont worry!
	//This would be in the case that the player has died or something
	//(if that is the case it should take another frame and it should
	// remove itself from the list. But thats not something the draw method
	// should worry about).

	//JUST Dont try a CImage that is pointing to NULL! (you'll get an assertion error)
	if(img==NULL)
		return;


	//this->drawBoundingBox();

	g_GraphicSystem.DrawCImage(img, m_Position.x - m_AnchorDisplacement.x, m_Position.y  - m_AnchorDisplacement.y);

	


}

void CPlayerObject::Update()
{

	//Important stuff will go here!


	m_lastBombPlaced  = (CBombObject*)g_ObjectManager.GetObjectID(m_bomb1ID);
	m_lastBombPlaced2 = (CBombObject*)g_ObjectManager.GetObjectID(m_bomb2ID);



	if(m_lastBombPlaced)
	{
		//see if we are still touching it
		if(this->isInside(m_lastBombPlaced)==false)
		{			
			m_lastBombPlaced=NULL;
			m_bomb1ID=0;
		}

	}
	if(m_lastBombPlaced2)
	{
		//see if we are still touching it
		if(this->isInside(m_lastBombPlaced2)==false)
		{
			m_lastBombPlaced2=NULL;
			m_bomb2ID=0;
		}

	}

	if(m_currentAnimation==die)
	{	
		if(m_Animations[die].Update()==Done)
		{
			g_ObjectManager.RemoveObjectSafe(this->ID); //not quite safe yet...
		}
	}

	doAI();	//Overwritten method by CAIPlayerObject


}

void CPlayerObject::setLastBombPlaced(CBombObject* i)
{
	Assert(i!=NULL, "Placing a NULL Bomb?");

	m_lastBombPlaced2 = m_lastBombPlaced; 
	m_lastBombPlaced = i; 

	m_bomb1ID = m_lastBombPlaced->ID;

	if(m_lastBombPlaced2)
		m_bomb2ID = m_lastBombPlaced2->ID;
	else
		m_bomb2ID = 0;





}


void CPlayerObject::Move(Direction d)
{

	if(m_currentAnimation==die)
		return;

	//Switch directions?
	if(m_Direction != d)
	{
		//reset the current animations
		m_Animations[m_currentAnimation].Reset();

		m_Direction = d;
		switch(m_Direction)
		{

		case N:
			m_currentAnimation = walkN;
			break;
		
		case W:
			m_currentAnimation = walkW;
			break;
		
		case S:
			m_currentAnimation = walkS;
			break;
		
		case E:
			m_currentAnimation = walkE;
			break;


		}

	}


	//We are going to have to change this a bit incase of the dieing animation
	//Should work for now though.
	switch(m_Animations[m_currentAnimation].Update())
	{
	
	case Updating:

		 //Move him properly
		 m_lastPosition=m_Position;		//Save last position
		 setX(m_Position.x + m_Animations[m_currentAnimation].getCurrentDisplacement().x);
		 setY(m_Position.y + m_Animations[m_currentAnimation].getCurrentDisplacement().y);
		
		break;

	}		
	
}

void CPlayerObject::dropBomb()
{
	if(m_currentBombsPlaced >= m_maxBombs)
	{
		return;
	}

	int tileSize = g_Game.getTileSize();
	

	int x = ((getX()+(tileSize/2))/tileSize) * tileSize;
	int y = ((getY()+(tileSize/2))/tileSize) * tileSize;

	//Double check that we arent putting this on one of the previously placed bombs...
	if(m_lastBombPlaced)
	{
		if(m_lastBombPlaced->getX() == x && m_lastBombPlaced->getY() == y)
			return;		
	}
	if(m_lastBombPlaced2)
	{
		if(m_lastBombPlaced2->getX() == x && m_lastBombPlaced2->getY() == y)
			return;		
	}

	CBombObject* bomb = (CBombObject*)g_ObjectManager.CreateObject(typBomb);	

	bomb->Init("art/bomb.tga",x ,y, m_bombStrength, this->ID);
	this->setLastBombPlaced(bomb);

	m_currentBombsPlaced++;
}


void CPlayerObject::Collision(CGameObject* obj)
{
	//This is called when the player's bounding box (m_boundingBox) collides with another objects bounding box.


	switch(obj->typ)	//figure out what type it is.
	{

	case typBlock:		
		{		
		

		//Stop right there
		CBlockObject* block = (CBlockObject*)obj;

		setX(m_lastPosition.x);
		setY(m_lastPosition.y);

		RECT rBlock = block->getBoundingBox();		
		int Width  = block->getBoundingBox().right - block->getBoundingBox().left;
		int Height = block->getBoundingBox().top - block->getBoundingBox().bottom;

		switch(m_Direction)
		{			

		case S:
		case N:
			

			if(rBlock.right < m_boundingBox.right)
			{
				setX(m_Position.x + 4);				
			}
			else if(rBlock.left > m_boundingBox.left)
			{
				setX(m_Position.x - 4);
			}

			break;
			

		case E:			
		case W:

			if(rBlock.bottom > m_boundingBox.bottom)
			{
				setY(m_Position.y - 4);				
			}
			else if(rBlock.top < m_boundingBox.top)
			{
				setY(m_Position.y + 4);
			}


			break;

		
		
		
		}

		}	
		
		break;
	case typExplosion:
		{
			//If he is already dieing... just let him be
			if(m_currentAnimation!=die)
			{			
				m_Animations[m_currentAnimation].Reset();
				m_currentAnimation = die;
			}
		}

		break;

	case typBomb:
		{
			

			if(m_lastBombPlaced == NULL || (m_lastBombPlaced->ID != obj->ID))
			{			
				if(m_lastBombPlaced2 == NULL || (m_lastBombPlaced2->ID != obj->ID))
				{				
					setX(m_lastPosition.x);
					setY(m_lastPosition.y);
				}
				
			}
		}

		break;

	case typPlayer:

		//setX(m_lastPosition.x);
		//setY(m_lastPosition.y);

		break;

	default:

		break;

	}


	doAICollision(obj);

}

//----------------------------------------------------------------//
//	Methods called by powers
//----------------------------------------------------------------//

void CPlayerObject::modifyCurrentBombs(int nbr)
{
	m_currentBombsPlaced += nbr;
}

void CPlayerObject::modifyBombStrength(int nbr)
{
	m_bombStrength += nbr;
}

void CPlayerObject::modifyMaxBombs(int nbr)
{
	m_maxBombs += nbr;
}