#include <iostream>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string>
using namespace std;

#include "common.h"
#include "zombie.h"

void zombie::init(position playerPos)
{
	square *sq=NULL;

	moveDelay=0;
	lastMoveTick=0;

	// find an empty grid square (at random) and stand there
	bool goodPos=false;
	do
	{
		myPosition.row=rand() % GRID_ROWS;
		myPosition.col=rand() % GRID_COLS;
		sq=gridSquare(myPosition);
		if ( sq->sqIcon == EMPTY_ICON && calcDistance(myPosition,playerPos) > MIN_ZOMBIE_DISTANCE )
			goodPos=true;
	} while ( !goodPos );

	sq->sqIcon=ZOMBIE_ICON;
	sq->BGcolor=ZOMBIE_COLOR;
	sq->FGcolor=BKG_COLOR;

	previousSquare.sqIcon=EMPTY_ICON;
	previousSquare.BGcolor=black;
	previousSquare.FGcolor=BKG_COLOR;	
}

// zombie destructor (I thought that was the player's job)
zombie::~zombie()
{
	square *sq=gridSquare(myPosition);
	sq->sqIcon=EMPTY_ICON;
	sq->BGcolor=black;
	sq->FGcolor=BKG_COLOR;	
}

// returns true if the move resulted in killing the player
bool zombie::move(position goal, int maxDelay, bool realTime)
{	
	//clock_t thisTick=clock();
	//if ( thisTick-lastMoveTick < moveDelay ) 
	//{
	//	return false;
	//}
	//lastMoveTick=clock();

	square *sqOrig=gridSquare(myPosition);
	
	moveDelay--;

	if ( realTime )
	{
		clock_t thisTick=clock();
		if ( (thisTick-lastMoveTick) < maxDelay ) return false;
		lastMoveTick=thisTick;
	} else	{
		if ( moveDelay <= 0 ) 
			moveDelay=maxDelay;
		else
			return false;
	}

	// see which way I could step that would get me closer to the goal
	position newPos=myPosition;
	if ( abs( (myPosition.row+1)-goal.row) <  abs( myPosition.row-goal.row ) )
		newPos.row++;
	else if ( abs((myPosition.row-1)-goal.row) <  abs(myPosition.row-goal.row) )
		newPos.row--;
	if ( abs( (myPosition.col+1)-goal.col) <  abs( myPosition.col-goal.col ) )
		newPos.col++;
	else if ( abs((myPosition.col-1)-goal.col) <  abs(myPosition.col-goal.col) ) 
		newPos.col--;

	// can I move that way? (is it on the grid)
	if ( newPos.row < 0 ) 
		newPos.row=0;
	else if ( newPos.row >= GRID_ROWS ) 
		newPos.row=GRID_ROWS-1;
	if ( newPos.col < 0 ) 
		newPos.col=0;
	else if ( newPos.col >= GRID_COLS ) 
		newPos.col=GRID_COLS-1;

	square *sq=gridSquare(newPos);

	// can I move that way? (is there another zombie in my way)
	if ( sq->sqIcon == ZOMBIE_ICON )
	{
		return false;
	} else if ( sq->sqIcon == MINE_ICON )
	{	// zombies aren't smart enough to notice mines, they just step on them and die
		sqOrig->sqIcon=EMPTY_ICON;
		sqOrig->BGcolor=black;
		sqOrig->FGcolor=BKG_COLOR;	
		updateGridSquare(myPosition);
		myPosition=newPos;
		explosion(myPosition);
		//die();
		return false;
	} else if ( sq->sqIcon == EXIT_ICON )
	{	// zombies aren't allowed to walk into the edit
		return false; 
	}

	// empty the current spot, and move to the next
	sqOrig->sqIcon=previousSquare.sqIcon;
	sqOrig->BGcolor=previousSquare.BGcolor;
	sqOrig->FGcolor=previousSquare.FGcolor;

	//sqOrig->sqIcon=EMPTY_ICON;
	//sqOrig->BGcolor=black;
	//sqOrig->FGcolor=BKG_COLOR;	
	updateGridSquare(myPosition);
	myPosition=newPos;
	
	previousSquare.sqIcon=sq->sqIcon;
	previousSquare.BGcolor=sq->BGcolor;
	previousSquare.FGcolor=sq->FGcolor;

	sq->sqIcon=ZOMBIE_ICON;
	sq->BGcolor=ZOMBIE_COLOR;
	sq->FGcolor=BKG_COLOR;
	updateGridSquare(myPosition);

	// did I just kill the player? 
	if ( myPosition.row == goal.row && myPosition.col == goal.col ) 
		return true;
	else
		return false;
}

void zombie::checkStatus()
{
	square *sq=gridSquare(myPosition);
	// I may have been killed by a weapon and don't know it. check...
	if ( sq->sqIcon != ZOMBIE_ICON )	die();
}

void zombie::die()
{
	square *sq=gridSquare(myPosition);
	sq->sqIcon=CORPSE_ICON;
	sq->BGcolor=CORPSE_COLOR;
	sq->FGcolor=BKG_COLOR;
	alive=false;
	updateGridSquare(myPosition);
}