/**
 * \file PlayerKernel.h
 * \date 30.03.2002
 *
 * Interface for the PlayerKernel class
 */

#ifndef PLAYER_PLAYERKERNEL_H
#define PLAYER_PLAYERKERNEL_H

#include "Player/Interfaces/Synchronization.h"
#include "Player/Interfaces/Memory.h"
#include "Player/World/World.h"
#include "Common/Module.h"
#include "Common/Main.h"

struct FEEDBACK_DATA;

/**
 * \class PlayerKernel
 * \author Daniel Novomesky
 * \author Marek Lehuta
 * \brief PlayerKernel module
 *
 * Player kernel with synchronization and acting
 */
class PlayerKernel : public Module, public SynchronizationInterface, public MemoryInterface
{
public:
// Construction and destruction
	PlayerKernel(
		const char* name = "PlayerKernel",
		const char* desc = "PlayerKernel module");
	virtual ~PlayerKernel();

// Interface implementation
	virtual Interface* GetInterface(int iTask) const;

	// Perceptions and world model
	virtual void OnInit(RealSide realSide, int uniform, PlayMode mode);
	virtual void OnChangeMode(int time, PlayMode mode);
	virtual void OnHear(int time, float direction, bool ourTeam, int uniform, const char* msg);
	virtual void OnScore(int time, int our, int their);
	virtual void OnSenseBody(const SENSE_BODY*);
	virtual void OnSee(const VISUAL_INFO*);
	virtual void OnChangePlayerType(int uniform, int type);
	virtual void OnServerParam(const SERVER_PARAMS* params);
	virtual void OnPlayerParam(const PLAYER_PARAMS* params);
	virtual void OnPlayerType(int id, const PLAYER_TYPE* type);
	// GP
    virtual void OnFreeform(const char* msg);
//    virtual void OnSetParameterUseNN(const char* msg);

	/// Handlers for sending commands to server
	virtual void OnExecKick(float power, float direction);
	virtual void OnExecTurn(float moment);
	virtual void OnExecDash(float power);
	virtual void OnExecNeck(int angle);
	
	/// Get/set synchronization mode
	virtual SynchroMode GetCurrentSynchMode() const { return synchMode; }
	virtual SynchroMode GetNextSynchMode() const { return nextSynchMode; }
	virtual void SetNextSynchMode(SynchroMode mode) { nextSynchMode = mode; }

	// Get pointer to world model
	virtual World* GetWorld() const { return world; }
	RealSide	myside;

protected:
	/// Making decisions
	virtual void Act() {}

	// Last sense body and last visual info data
	const SENSE_BODY* lastSb;
	const VISUAL_INFO* lastVi;

	int lastSbTime;
	int lastViTime;
	int lastActTime;

	// World model
	World* world; 
	
private:
	// We store all executed commands here. Then we apply the commands
	// to the world model, so that is reflects what we have done.
	FEEDBACK_DATA* feedback;

	// Number of processed commands
	COMMAND_COUNTS* counts;

	// Synchronization
	SynchroMode synchMode;
	SynchroMode nextSynchMode;
	bool decisionWasMade;

};


// Structure for saving executed commands
struct FEEDBACK_DATA
{
	float lastPower;
	float lastTurn;
	int lastNeck;
	float lastKickPower;
	float lastKickDir;
};

#endif // PLAYER_PLAYERKERNEL_H
