#ifndef _SETTINGS_H
#define _SETTINGS_H


extern "C"
{
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
}


#include <SDL/SDL.h>
#include <vector>
#include <string>
#include <iostream>
#include <stdlib.h>

#ifdef __APPLE__
       #include "config_mac.h"
#endif

#include "configfile.h"

using namespace std;

class VIDEOMODES
{
private:
	vector<SDL_Rect> modes;
	int sel;
	bool bpp32;
	bool fullscreen;

public:
	VIDEOMODES()
	{
		modes.clear();
		sel = 0;
		bpp32 = fullscreen = false;
	}
	~VIDEOMODES() {}

	vector<SDL_Rect> GetModes() { return modes; }
	int GetSel() { return sel; }
	bool GetBpp32() { return bpp32; }
	bool GetFullscreen() { return fullscreen; }

	void SetModes( vector<SDL_Rect> new_modes ) { modes = new_modes; }
	void SetSel( int new_sel ) { sel = new_sel; }
	void SetBpp32( int new_bpp32 ) { bpp32 = new_bpp32; }
	void SetFullscreen( int new_fullscreen ) { fullscreen = new_fullscreen; }
};


template<class option_t>
class OPTION
{
private:
	vector<string> option_list;
	vector<option_t> value_list;
	string name;
	string title;
	string desc;
	string cat;
	string true_value;
	string false_value;
	string accepts;
	float min_value;
	float max_value;
	option_t default_value;

public:
	OPTION()
	{
		name = title = desc = cat = true_value = false_value = accepts = "";
		min_value = 0.0;
		max_value = 1.0;
		option_list.clear();
		value_list.clear();
	}

	~OPTION() {}

	vector<string> GetOptionList() { return option_list; }
	vector<option_t> GetValueList() { return value_list; }
	string GetName() { return name; }
	string GetTitle() { return title; }
	string GetDesc() { return desc; }
	string GetCat() { return cat; }
	string GetTrueValue() { return true_value; }
	string GetFalseValue() { return false_value; }
	string GetAccepts() { return accepts; }
	float GetMinValue() { return min_value; }
	float GetMaxValue() { return max_value; }
	option_t GetDefaultValue() { return default_value; }
	void SetOptionList( vector<string> new_option_list ) { option_list = new_option_list; }
	void SetValueList( vector<option_t> new_value_list ) { value_list = new_value_list; }
	void SetName( string new_name ) { name = new_name; }
	void SetTitle( string new_title ) { title = new_title; }
	void SetDesc( string new_desc ) { desc = new_desc; }
	void SetCat( string new_cat ) { cat = new_cat; }
	void SetTrueValue( string new_true_value ) { true_value = new_true_value; }
	void SetFalseValue( string new_false_value ) { false_value = new_false_value; }
	void SetAccepts( string new_accepts ) { accepts = new_accepts; }
	void SetMinValue( float new_min_value ) { min_value = new_min_value; }
	void SetMaxValue( float new_max_value ) { max_value = new_max_value; }
	void SetDefaultValue( option_t new_default_value ) { default_value = new_default_value; }
};


class SETTINGS
{
public:
	SETTINGS();
	~SETTINGS();

	void SaveSettings(CONFIGFILE &c);
	void Init();
	void ParseOptionFile();
	void ParseDynamicOptions();

	bool Get( string var_name, float & out_var );
//	bool Get( string var_name, float * out_var );
	bool Get( string var_name, int & out_var );
	bool Get( string var_name, string & out_var );
	bool Get( string var_name, bool & out_var );

	bool Set( string var_name, float in_var );
//	bool Set( string var_name, float * in_var );
	bool Set( string var_name, int in_var );
	bool Set( string var_name, string in_var );
	bool Set( string var_name, bool in_var );

	OPTION<float> GetFloatOption( string cat, string name );
	OPTION<int> GetIntOption( string cat, string name );
	OPTION<bool> GetBoolOption( string cat, string name );
	OPTION<string> GetStringOption( string cat, string name );

	string GetSettingsDir();
	string GetHomeDir();
	string GetDataDir();
	string GetDataDir( string filename );
	string GetLocaleDir ();
	string GetGameVersion() { return VERSION; }
	string GetConfigFileVersion();
	string GetFullDataPath( string filename );
	void SetDataDir( string new_data_dir );
	void SetDefaultDataDir( string new_data_dir );
	vector<string> LoadCarPartsSettings();
	void SaveCarPartsSettings( vector<string> &p_list );
	string GetCarPartName( string part_path );
	string GetSkinPath();

private:
	void ParseSettings(CONFIGFILE &c);
	bool FileExists(string path);
	//bool DirExists(string path);
	void CreateDir(string path);
	void FindHomeDir();
	void GetValidVideoModes();

	CONFIGFILE configfile;
	CONFIGFILE default_configfile;
	CONFIGFILE options_configfile;
	CONFIGFILE car_parts;

	VIDEOMODES valid_display_modes;

	vector<string> parts_list;
/*
	vector<string> float_settings;
	vector<string> vec_settings;
	vector<string> int_settings;
	vector<string> bool_settings;
	vector<string> string_settings;
*/	vector< OPTION<float> > float_options;
	vector< OPTION<int> > int_options;
	vector< OPTION<bool> > bool_options;
	vector< OPTION<string> > string_options;


	string settings_path;
	string data_directory;
	string locale_directory;
	string settings_directory;
	string home_directory;
	string config_version;

	bool spew;
};

#endif /* _SETTINGS_H */
