// PreparedCommands.cpp: implementation of the PreparedCommands class.
//
//////////////////////////////////////////////////////////////////////

#include "Player/World/PreparedCommands.h"
#include "Common/World/Circle.h"
#include "Common/Support/Debug.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/// \brief Implicitny konstruktor 
/// Ciel nie je nastaveny, presnost je nastavena na -1
PreparedCommands::PreparedCommands()
{
	ResetAll();
}

/// \brief Destruktor 
PreparedCommands::~PreparedCommands()
{
}

/// \brief Zrusi vsetky plany
void PreparedCommands::ResetAll()
{
	activeTarget = false;
	targetPrecision = -1.0;
	waitTime = -1;
	bKickTo = false;
	bMoveTo = false;
	bKickTo = false;
	bTurnTo =false;			
	haveFindpassableFriend = false;
	
	/* SS old
	notRunToBall = false;
	forceRunToBall = false;
	*/

	// SS:
	sPustiBehaviorStatus = DEFAULT;	
	sPustiBallDistance = -1;
	sPustiBallVector = Vector();
	//ticksToCancelNotRun = -1;
}

/// \brief Kopirovaci konstruktor
/// \param other Druhy PreparedCommands z ktoreho sa vytvara tato instancia
PreparedCommands::PreparedCommands(const PreparedCommands &other)
{
	activeTarget = other.activeTarget;
    targetPos = other.targetPos;
    targetPrecision = other.targetPrecision;
}

/// \brief Operator priradenia
/// \param other Druhy PreparedCommands z ktoreho sa kopiruju informacie
PreparedCommands& PreparedCommands::operator =(const PreparedCommands &other)
{
	if(&other == this) return *this;
	targetPos = other.targetPos;
	activeTarget = other.activeTarget;
	targetPrecision = other.targetPrecision;
	return *this;
}

/// \brief Nastavic ciel
/// \param pos pozicia ciela
/// \param precision vzdialenost, v ktorej je uz ciel spolneny
void PreparedCommands::SetTarget(Point pos, float precision)
{
	activeTarget =true;
	targetPos = pos;
	targetPrecision = precision;
}

/// \brief Zrusi ciel.
void PreparedCommands::ResetTarget()
{
	activeTarget =false;
}

/// \brief Debugovaci vypis
void PreparedCommands::Debug()
{
	if (!activeTarget){
		TXTN("\nTarget nie je aktivny");
		return;
	}
	TXTN("\nTarget: (%f,%f) :%f", targetPos.GetX(), targetPos.GetY(), targetPrecision);
}

/// \brief urci, ci dosiahol ciel, 
/// \param pos Moja aktualna pozicia
/// \return \li true ak som v okoli ciela, a zrusim nastavenie ciela
///			\li false ak som ciel este nedosiahol
bool PreparedCommands::ReachTarget(Point pos)
{
	Circle c(targetPos, targetPrecision);
	if (c.IsInside(pos)){
		activeTarget = false;
		return true;
	}
	return false;
}

void PreparedCommands::SetKickTo(Point &p)
{
	kickPosTo = p;
	bKickTo = true;
}

void PreparedCommands::resetKickTo()
{
	bKickTo = false;
}

bool PreparedCommands::HaveKick(Point &pos)
{
	pos = kickPosTo;
	return bKickTo;
}

void PreparedCommands::SetTurnTo(Point pos)
{
	turnToPos = pos;
	bTurnTo = true;
}	

void PreparedCommands::ResetTurnTo()
{
	bTurnTo = false;
}

bool PreparedCommands::HaveTurnTo(Point &pos)
{
	pos = turnToPos;
	return bTurnTo;
}

void PreparedCommands::SetMoveTo(Point pos)
{
	moveToPos = pos;
	bMoveTo  = true;
}

void PreparedCommands::ResetMoveTo()
{
	bMoveTo  = false;
}

bool PreparedCommands::HaveMoveTo(Point &pos)
{
	pos = moveToPos;
	return bMoveTo;
}

void PreparedCommands::SetWaitTime(int time)
{
	if (time>=0)
		waitTime = time;
	else
		waitTime = -1;
}

bool PreparedCommands::HaveWaitTo(int cycle)
{
	bool result = false;
	if (waitTime != -1)
	{
		result =  (waitTime<=cycle)?false:true;		// ak uz cas uplynul
		if (result == false)
			ResetWaitTime();
	}
	return result;
}

void PreparedCommands::ResetWaitTime()
{
	waitTime = -1;
}

// SS: checks if player should run to ball
bool PreparedCommands::ShouldRunToBall()
{
	return (sPustiBehaviorStatus != NOTRUNTOBALL);
}

// checks if player sended SPusti message before
bool PreparedCommands::ForceRunToBall()
{
	return (sPustiBehaviorStatus == FORCERUNTOBALL);
}

// check if default behavior is set
bool PreparedCommands::DefaultRunToBall()
{
	return (sPustiBehaviorStatus == DEFAULT);
}


// sets sPustiBehaviorStatus to FORCERUNTOBALL
void PreparedCommands::SetForceRunToBall(float meBallDist, Vector* ballVector)
{
	sPustiBehaviorStatus = FORCERUNTOBALL;
	sPustiBallDistance = meBallDist;
	sPustiBallVector = Vector(*ballVector);
}

// sets sPustiBehaviorStatus to DEFAULT
void PreparedCommands::SetDefaultRunToBall()
{
	sPustiBehaviorStatus = DEFAULT;
}

// sets sPustiBehaviorStatus to NOTRUNTOBALL
void PreparedCommands::SetNotRunToBall(Vector* ballVector)
{
	sPustiBehaviorStatus = NOTRUNTOBALL;
	sPustiBallVector = Vector(*ballVector);
}

// gets distance to ball when player sended last SPusti
float PreparedCommands::GetSPustiDistToBall()
{
	if (sPustiBehaviorStatus != FORCERUNTOBALL)
		DBG("Fatal SPusti error! Something has been wrong!");

	return sPustiBallDistance;
}

// gets vector of ball when player sended last SPusti
Vector PreparedCommands::GetSpustiBallVect()
{
	if (sPustiBehaviorStatus == DEFAULT)
		DBG("Fatal SPusti error! Something has been wrong!");

	return sPustiBallVector;
}