/**
 * \file PlayerTactics.h
 * \date 08.05.2002
 *
 * Interface for the PlayerTactics class
 */

#ifndef MODULES_PLAYERTACTICS_H
#define MODULES_PLAYERTACTICS_H

#include <float.h>
#include "Player/PlayerSkills.h"
#include "Common/Main.h"
#include "Formation.h"
#include "Player/Interfaces/Tactics.h"

#define KICKIN_DBGN DBGN
//#define KICKIN_DBGN DO_NOTHING

/**
 * \class PlayerTactics
 * \author Daniel Novomesky
 * \author Martin Zuzcak
 * \author Marek Lehuta
 * \brief PlayerTactics module
 */
class PlayerTactics : public PlayerSkills, public TacticsInterface 
{
public:
	bool CanStopBall();
	bool AmDependForKickoff();
	
	void FastDribble();
	bool CanFastDribble();

	bool LookAround();
	void PlanedFreeKick();
	bool DoPlan();
	void GetKickPos(Point &pos);
	void DoFreeKick();
	bool IsFreeKick();
	void Dribble();
	bool CanDribble();
	void GetGoalPosition(Point &pos);
	void MidfiledWithoutBall(Side who, int idx);
	void MidfiledWithBall();
	int GetPassableFriendFreeKick2();
	int GetPassableFriend2();
	void FindBestFreeKickPosition(Point &pos);
	void DefenderWithoutBall(Side who, int idx);
	void DefenderWithBall();
// Construction and destruction
	PlayerTactics();
	virtual ~PlayerTactics() {}

// GP
	void OnInit(RealSide realSide, unsigned uniform, PlayMode iMode);
	virtual Interface* GetInterface(int task) const;

// Operations
	/// \return player that is most suitable for a pass; -1 -> no player is
	int GetPassAbleFriend() const; 

	/// \return is player offside?
	bool InOffsidePos(float) const;
	bool HeInOffsidePos(int index,float off_l) const;
	/// \return offside line location
	float GetOffsideLine() const;

	/// \return is player responsible for the ball?
	//bool DependentForBall() const;

protected:
	void AttackerWithoutBall(Side who, int idx);
	void AttackerWithBall();
	void BehaveWithoutBallDefault();
	virtual void BehaveWithBall();
	virtual void BehaveWithoutBall();
	virtual void BehaveWithBallGoalie();
	virtual void BehaveWithoutBallGoalie();

	virtual Point GetHomePos();

	void ExitOffside(bool fast=true);

	bool ShouldKickOnGoal();
	float DistanceToGoal(const Point&) const;

	/// No enemies are around, so dribble
	bool NoEnemiesAround() const;
    int FindEnemyToBlock(const Point& refPos, float treshold = FLT_MAX) const;
	bool SmartDribleTo(const Point&);
	bool ShortKick(const Point&);
	float GetKickPower(const Point& ciel, int steps);
	
	/// \return does an enemy block our pass to given place?
	bool IsBlockingEnemy(const Point& target);
	
	/// \return distance to nearest opponent
	float GetNearestEnemyDistance(const Point& target);
	/// Get nearest friend player index
	int GetNearestFriend(const Point& target);
	/// \return distance to nearest friend
	float GetNearestFriendDistance(const Point& target);
	/// \return distance to ball
	float GetPlayerBallDistance(int who);
	
	/// Pass to running player
	bool PassIntoRun();
	/// Run to a tactical position or watch the ball if already there
	void Patrol();
	/// \return is given place offside?
	bool IsOffsidePosition(Point target);

	/// \return is our player nearest to the ball?
	bool IsOurBall();
	/// Go to the best place where someone could pass the ball to you
	bool GotoPositionToPass(bool fast=true);

	/// Should we kick the ball in when it is not PlayOn?
	virtual bool ShouldKickIn();

	/// Change play mode handler
	virtual void OnChangeMode(int time, PlayMode mode);

    // GP
    void ChangeFormation(const char* formation);

    // SG 2004/03/02
    Point GetStaticPos();

private:
	Formation m_cFormation;

    int GetFormation(const char* formation);
    int GetUnit(int PlayerCount, char type);

	/// Current angle for scanning before kick off
	float scanBeforeKickOffAngle;
	int m_nNeckPos;
	/// pocet krokov odkedy som urobil vykop aby som sa nerozbehol po lopte
	int m_nStepsFromMyFreeKick; 
	int m_nStepsFromIHaveBall;
};

#endif // MODULES_PLAYERTACTICS_H
