#pragma once
#include <hash_map>
#include "GameData.h"
#include "AI_StateInspector.h"

class AI_StateInspector_Impl :	public AI_StateInspector
{
public:
	AI_StateInspector_Impl(GameData* _data, int _pnum);
	~AI_StateInspector_Impl() {}

	STATE_VAR_ID get_state_id(const std::string& name);
	std::string get_state_name(STATE_VAR_ID sid);
	state_var_info& get_state_info(const std::string& name);
	state_var_info& get_state_info(STATE_VAR_ID sid);
	STATE_VALUE get_state_value(const std::string& name, bool constrain=true);
	STATE_VALUE get_state_value(STATE_VAR_ID sid, bool constrain=true);
	void get_state(AI_State& state, bool constrain=true);

	void reset() { prev_player_score = prev_opponent_score = 0; }
	void load(PLAYER_ID pid);
	void end_ai_step();

	STATE_VALUE get_distance();
	STATE_VALUE get_current_move();
	STATE_VALUE get_opp_current_move();
	STATE_VALUE get_obj_delta();
	STATE_VALUE get_user_move_choice();
	STATE_VALUE get_user_reinforcement();
	STATE_VALUE get_angle();
	STATE_VALUE get_speed();
	STATE_VALUE get_opp_approach_speed();
	STATE_VALUE get_opp_extension();
	STATE_VALUE get_opp_attacking();
	STATE_VALUE get_opp_attack_section();
	STATE_VALUE get_end() { return -1; }
	
private:
	void state_var_init();
	STATE_VALUE constrain_to_limits(STATE_VAR_ID sid, STATE_VALUE sv);

	GameData* game;
	int pnum;
	int opnum;

	class LogicPlayer* player;
	class LogicPlayer* opponent;

	STATE_VALUE prev_player_score;
	STATE_VALUE prev_opponent_score;
	STATE_VALUE prev_speed;
	STATE_VALUE prev_angle;
	STATE_VALUE prev_distance;

	typedef stdext::hash_map<STATE_VAR_ID, state_var_info> info_map;
	typedef info_map::iterator info_iter;
	typedef stdext::hash_map<STATE_VAR_ID, STATE_VALUE (AI_StateInspector_Impl::*)() > val_map;
	typedef val_map::iterator val_iter;
	typedef stdext::hash_map<std::string, STATE_VAR_ID> id_map;
	typedef id_map::iterator name_iter;
	typedef stdext::hash_map<std::string, int> att_sect_map;
	
	info_map map_to_info;
	id_map map_to_id;
	val_map map_to_value;
	att_sect_map attack_sections;
};
