/**
 * \file World.h
 * \date 14.04.2003
 *
 * World model interface
 */

#ifndef COMMON_WORLD_WORLD_H
#define COMMON_WORLD_WORLD_H

// For debugging SB and VI recalculation
//#define WORLD_RECALC_DBG DBGN
#define WORLD_RECALC_DBG DO_NOTHING

// For debugging the World contents
//#define WORLD_STATS_DBG DBGN
#define WORLD_STATS_DBG DO_NOTHING

class Ball;
class Player;
class SimPlayer;
class Myself;
class State;
class Params;
class Variables;

struct FEEDBACK_DATA;

#include "Player/Interfaces/Synchronization.h"
#include "Common/Protocol/ParseStructs.h"
#include "Common/World/ParamStructs.h"
#include "Common/World/Types.h"
//#include "Common/Support/DynArray.h"
#include "Common/Support/Debug.h"
#include "Player/World/PlayerArray.h"
#include "Common/Support/Log.h"
#include "Common/World/Types.h"	// Added by ClassView
#include "Common/World/Circle.h"
#include <vector>

using namespace std;


struct PASSABLE_FRIEND
{
	int age;
	int index;
	int Uniform;
};

#define NUM_ZONES 15
const struct ZONE {
  float from, to, fromy, toy;
} zones[NUM_ZONES] = {
  {-52.5f, -36.0f,  34.0f,  25.0f},
  {-52.5f, -36.0f,  25.0f, -25.0f},
  {-52.5f, -36.0f, -25.0f, -34.0f},
  {-36.0f, -18.0f,  34.0f,  25.0f},
  {-36.0f, -18.0f,  25.0f, -25.0f},
  {-36.0f, -18.0f, -25.0f, -34.0f},
  {-18.0f,  18.0f,  34.0f,  25.0f},
  {-18.0f,  18.0f,  25.0f, -25.0f},
  {-18.0f,  18.0f, -25.0f, -34.0f},
  {18.0f,  36.0f,  34.0f,  25.0f},
  {18.0f,  36.0f,  25.0f, -25.0f},
  {18.0f,  36.0f, -25.0f, -34.0f},
  {36.0f,  52.5f,  34.0f,  25.0f},
  {36.0f,  52.5f,  25.0f, -25.0f},
  {36.0f,  52.5f, -25.0f, -34.0f},
};

/**
 * \class World
 * \author Matus Horvath
 * \author Marek Lehuta
 * \brief World model
 * 
 * All information about player surroundings is in this world model.
 */

class World
{
public:
// Construction and destruction
	World();
	World(const World& world);
	virtual ~World();
	
// Operations on the world
	int FindFriendIndex(int uniform) const;
	int FindEnemyIndex(int uniform) const;

// Internal operations
	// Set up world from server information
	void ProcessInfo(const SENSE_BODY* sb, const VISUAL_INFO* vi);
	// Use stored feedback data to update world
	void ApplyFeedback(FEEDBACK_DATA* fd);
	// Step all objects
	void Step();

	// Re-read player type information and link them to players
	void RelinkPlayerTypes();

// Initialize the synchro variable
	static void BindInterfaces();
	/// Set player type for player with uniform, Side == OUR for fiends  | Side == THEIR for enemies
	void SetPlayerType(Side side, int uniform, int type);	

private:
	void UpdatePassAbleIndexAfterDelete(int nFrom);
public:
	int GetNumberOfEnemisInQuadrant(Circle c, QUADRANT q, vector<Point> &idx);
	int GetNumberOfEnemisInQuadrant(Circle c, QUADRANT q, vector<int> &idx);
	int GetNumberOfEnemisInQuadrant(Circle c, QUADRANT q);
	int NumberOfEnemiesToRadius(float radius);
	void Debug();
	int FindFreeEnemy(Point formPos, float radius);
	int FindNearestFreeEnemy(Point formPos, float radius);
	int FindNearestFreeFriend(Point formPos, float radius);
	void LogWorld();
	void WhoHasBall(Side &who, int &playerIndex);
	
	// Objects world consists of
	Ball* ball;
	Myself* me;

	PlayerArray friends;
	PlayerArray enemies;
	
	// pole spoluhracov, ktorym mozem prihrat zo zvukovej spravy
	DynArray<PASSABLE_FRIEND, 32> passableFriends;

	State* state;
	Params* params;
	Variables* variables;
	
	PLAYER_TYPE* friendTypes[12];
	PLAYER_TYPE* enemieTypes[12];

	Log *log;
	
protected:
	void RecalculateFriends(const SENSE_BODY* sb, const VISUAL_INFO* vi);
	void RecalculateEnemies(const SENSE_BODY* sb, const VISUAL_INFO* vi);

private:
	static SynchronizationInterface* synchro;
	
};

#include "Player/World/State.h"
#include "Player/World/Params.h"
#include "Player/World/Variables.h"
#include "Player/World/Ball.h"
#include "Player/World/Player.h"
#include "Player/World/SimPlayer.h"
#include "Player/World/Myself.h"

#endif // COMMON_WORLD_WORLD_H
