
#pragma once
#ifndef AI_USERCONSTANTS_HPP
#define AI_USERCONSTANTS_HPP

#include <Stuff\Scalar.hpp>
#include <Stuff\Auto_Ptr.hpp>
#pragma warning(push)
#include <stlport\string>
#pragma warning(pop)
#include <Adept\Resource.hpp>
#include <Stuff\NotationFile.hpp>
#include <Stuff\Matrix.hpp>


namespace Stuff
{
	class Page;
};


namespace MW4AI
{
	class UserConstants
	{
	  public:
		enum ID
		{
			entropy_regeneration_at_0		= 0,	// change ID_FIRST if you change this
			entropy_regeneration_at_100,
			building_ff_multiplier,
			shutdown,
			internal_armor_breached,
			fall_down,
			first_arm_hit,
			second_arm_hit,
			first_leg_hit,
			mood_squad_dead_unit_multiplier,
			interval_multiplier_desperate,
			interval_multiplier_defensive,
			interval_multiplier_neutral,
			interval_multiplier_aggressive,
			interval_multiplier_brutal,
			skew_at_0,
			skew_at_100,
			skew_inc_at_0,
			skew_inc_at_100,
			speed_stopped,
			speed_slow,
			speed_medium,
			speed_fast,
			speed_maximum,
			mech_tiny,
			mech_small,
			mech_medium,
			mech_large,
			mech_huge,
			distance_adjacent,
			distance_near,
			distance_medium,
			distance_far,
			distance_very_far,
			if_crouched,
			if_tiny,
			if_small,
			if_medium_size,
			if_large,
			if_huge,
			if_stopped,
			if_slow,
			if_medium_speed,
			if_fast,
			if_maximum,
			if_shooter_stopped,
			if_shooter_slow,
			if_shooter_medium,
			if_shooter_fast,
			if_shooter_maximum,
			if_adjacent,
			if_near,
			if_medium_range,
			if_far,
			if_very_far,
			if_firing_with_one_arm,
			if_turning,
			if_bearing_90,
			min_evade_when_missiles_shot_at_me,
			max_evade_when_missiles_shot_at_me,
			min_evade_when_targeted,
			max_evade_when_targeted,
			min_evade_by_jumping,
			max_evade_by_jumping,
			min_evade_by_throttle_override,
			max_evade_by_throttle_override,
			min_evade_by_crouching,
			max_evade_by_crouching,
			min_jump_if_rushed,
			max_jump_if_rushed,
			min_opportunity_fire,
			max_opportunity_fire,
			min_look_left_or_right,
			max_look_left_or_right,
			min_look_time_at_0,
			min_look_time_at_100,
			min_dont_use_limited_ammo_vs_non_mechs,
			max_dont_use_limited_ammo_vs_non_mechs,
			min_vulnerable_leg_hiding,
			max_vulnerable_leg_hiding,
			min_mood_vulnerable_leg_hiding,
			max_mood_vulnerable_leg_hiding,
			min_throttle_override,
			torso_twist_multiplier_at_0,
			torso_twist_use_full_multiplier,
			switch_to_random_component_picking,
			switch_to_most_damaged_component_picking,
			min_prefer_water,
			max_prefer_water,
			jump_wait_time_at_0,
			jump_wait_time_at_100,
			evade_focus_time_at_0,
			evade_focus_time_at_100,
			lancemate_can_attack_radius,
			max_lancemate_distance_from_leader,
			max_defend_distance_from_target,
			jump_and_shoot_hover_height_min,
			jump_and_shoot_hover_height_max,
			max_fire_cheat_angle,
			max_airplane_fire_cheat_angle,
			max_turret_fire_cheat_angle,
			min_tactic_time,
			min_elite_joust,
			max_elite_joust,
			min_mood_joust,
			max_mood_joust,
			min_elite_rush,
			max_elite_rush,
			min_mood_rush,
			max_mood_rush,
			min_elite_hitandrun,
			max_elite_hitandrun,
			min_mood_hitandrun,
			max_mood_hitandrun,
			min_elite_rear,
			max_elite_rear,
			min_mood_rear,
			max_mood_rear,
			min_elite_circle,
			max_elite_circle,
			min_mood_circle,
			max_mood_circle,
			min_elite_retreat,
			max_elite_retreat,
			min_mood_retreat,
			max_mood_retreat,
			min_elite_dfa,
			max_elite_dfa,
			min_mood_dfa,
			max_mood_dfa,
			leg_up_slope,
			leg_down_slope,
			track_up_slope,
			track_down_slope,
			wheel_up_slope,
			wheel_down_slope,
			hover_up_slope,
			hover_down_slope,
			leg_dirt_cost,
			leg_rock_cost,
			leg_steel_cost,
			leg_blacktop_cost,
			leg_glass_cost,
			leg_brick_cost,
			leg_grass_cost,
			leg_wood_cost,
			leg_tree_cost,
			leg_swamp_cost,
			leg_concrete_cost,
			leg_rough_cost,
			leg_snow_cost,
			leg_underbrush_cost,
			leg_shallowwater_cost,
			leg_midwater_cost,
			leg_oceanicwater_cost,
			leg_desert_cost,
			leg_flatswamp_cost,
			leg_thickswamp_cost,
// MSL 5.03 Lava
			leg_crackedlava_cost,
			leg_openlava_cost,
			track_dirt_cost,
			track_rock_cost,
			track_steel_cost,
			track_blacktop_cost,
			track_glass_cost,
			track_brick_cost,
			track_grass_cost,
			track_wood_cost,
			track_tree_cost,
			track_swamp_cost,
			track_concrete_cost,
			track_rough_cost,
			track_snow_cost,
			track_underbrush_cost,
			track_shallowwater_cost,
			track_midwater_cost,
			track_oceanicwater_cost,
			track_desert_cost,
			track_flatswamp_cost,
			track_thickswamp_cost,
// MSL 5.03 Lava
			track_crackedlava_cost,
			track_openlava_cost,
			wheel_dirt_cost,
			wheel_rock_cost,
			wheel_steel_cost,
			wheel_blacktop_cost,
			wheel_glass_cost,
			wheel_brick_cost,
			wheel_grass_cost,
			wheel_wood_cost,
			wheel_tree_cost,
			wheel_swamp_cost,
			wheel_concrete_cost,
			wheel_rough_cost,
			wheel_snow_cost,
			wheel_underbrush_cost,
			wheel_shallowwater_cost,
			wheel_midwater_cost,
			wheel_oceanicwater_cost,
			wheel_desert_cost,
			wheel_flatswamp_cost,
			wheel_thickswamp_cost,
// MSL 5.03 Lava
			wheel_crackedlava_cost,
			wheel_openlava_cost,
			hover_dirt_cost,
			hover_rock_cost,
			hover_steel_cost,
			hover_blacktop_cost,
			hover_glass_cost,
			hover_brick_cost,
			hover_grass_cost,
			hover_wood_cost,
			hover_tree_cost,
			hover_swamp_cost,
			hover_concrete_cost,
			hover_rough_cost,
			hover_snow_cost,
			hover_underbrush_cost,
			hover_shallowwater_cost,
			hover_midwater_cost,
			hover_oceanicwater_cost,
			hover_desert_cost,
			hover_flatswamp_cost,
			hover_thickswamp_cost,
// MSL 5.03 Lava
			hover_crackedlava_cost,
			hover_openlava_cost,
			objective_display_time,
			default_pilot,
			default_gunnery,
			default_elite,
			default_minheat,
			default_maxheat,
			default_sensor,
			default_blind,
			default_longrange,
			default_shortrange,
			default_addpilot,
			default_addgunnery,
			default_addelite,
			max_skill_add,
			max_fog_dist_to_use_blind_skill,
			damage_amount,
			damage_mod,
			fall_damage_minus,
			fall_splash_multiplier,
			min_fall_timer,
			low_water_mod,
			mid_water_mod,
			concrete_mod,
			gimped_mod,
			double_damage_mod,
			moving_fast_mod,
			jump_recover_mod,
			max_water_jump,
			eject_chance_for_non_lancemate,
			eject_chance_for_lancemate,
			eject_chance_ok_when_ejected,
			eject_chance_injured_when_ejected,
			friend_easy_gunnery_mod,
			friend_medium_gunnery_mod,
			friend_hard_gunnery_mod,
			friend_impossible_gunnery_mod,
			enemy_easy_gunnery_mod,
			enemy_medium_gunnery_mod,
			enemy_hard_gunnery_mod,
			enemy_impossible_gunnery_mod,
			neutral_easy_gunnery_mod,
			neutral_medium_gunnery_mod,
			neutral_hard_gunnery_mod,
			neutral_impossible_gunnery_mod,
			collision_mech_light_damage,
			collision_mech_light_slowdown,
			collision_mech_light_building_speed,
			collision_mech_light_mech_speed,
			collision_mech_medium_tonage,
			collision_mech_medium_damage,
			collision_mech_medium_slowdown,
			collision_mech_medium_building_speed,
			collision_mech_medium_mech_speed,
			collision_mech_heavy_tonage,
			collision_mech_heavy_damage,
			collision_mech_heavy_slowdown,
			collision_mech_heavy_building_speed,
			collision_mech_heavy_mech_speed,
			collision_dfa_speed,
			collision_dfa_damage_given,
			collision_dfa_damage_taken,
			collision_tank_slowdown,

			throttle_center,
			throttle_dead_low,
			throttle_dead_high,

			chance_salvage,

			mouse_min_change,
			mouse_interia_mult,
			mouse_max_mouse,

			flying_turn_rate,

			dont_use_this_id	// Insert all user constants BEFORE this one
		};

		enum
		{
			ID_FIRST = entropy_regeneration_at_0,
			ID_LAST = dont_use_this_id-1,
			ID_MOVE_COST_START = leg_dirt_cost,
// MSL 5.03 Lava
//			ID_MOVE_COST_LAST = hover_thickswamp_cost
			ID_MOVE_COST_LAST = hover_openlava_cost
		};

		UserConstants();
		~UserConstants();

		Stuff::Scalar Get(ID id) const;

		static void IncrementRefCount();
		static void DecrementRefCount();

		static UserConstants* Instance();

		Stuff::Scalar GetMultiplier_Tonnage(Stuff::Scalar tonnage) const;
		Stuff::Scalar GetMultiplier_CrouchState(bool fCrouched) const;
		Stuff::Scalar GetMultiplier_Speed(Stuff::Scalar kph) const;
		Stuff::Scalar GetMultiplier_ShooterSpeed(Stuff::Scalar kph) const;
		Stuff::Scalar GetMultiplier_Distance(Stuff::Scalar distance) const;
		Stuff::Scalar GetMultiplier_Bearing(const Stuff::Point3D& self, const Stuff::LinearMatrix4D& shooting_at, Stuff::Scalar target_speed) const;
		Stuff::Scalar GetMultiplier_TurnRate(Stuff::Scalar yaw_demand) const;

		UserConstants::ID FindCategory(Stuff::Scalar user_value, MW4AI::UserConstants::ID first, MW4AI::UserConstants::ID last) const;

	  private:
		Stuff::Scalar m_Value[ID_LAST - ID_FIRST + 1];
		int m_RefCount;

		void LookUpValue(const std::string& header_name, const std::string& item_name, int value_index);

		static UserConstants* m_Instance;

		Stuff::Scalar FindCategorizedValue(Stuff::Scalar user_value, ID first, ID last, ID first_lookup) const;

	  private:
		Adept::Resource m_Resource;
		Stuff::Auto_Ptr<Stuff::NotationFile> m_NotationFile;
		Stuff::Page* m_LastPage;
	};
};



#endif // AI_USERCONSTANTS_HPP
