#pragma once
#include "Defines.h"

//#include <VersionHelpers.h> //нужен windows kit 8.1 в нём функция IsWindowsVistaOrGreater
#include "Ini.h"
#include "MSF.h"

enum CONFIG_BKMODEL_NUMBER
{
	CONFIG_BKMODEL_NUMBER_BK_0010_01 = 0,
	CONFIG_BKMODEL_NUMBER_BK_0010_01_MSTD,
	CONFIG_BKMODEL_NUMBER_BK_0010_01_EXT32RAM,
	CONFIG_BKMODEL_NUMBER_BK_0010_01_FDD,
	CONFIG_BKMODEL_NUMBER_BK_0010_01_A16M,
	CONFIG_BKMODEL_NUMBER_BK_0010_01_SMK512,
	CONFIG_BKMODEL_NUMBER_BK_0010_01_SAMARA,
	CONFIG_BKMODEL_NUMBER_BK_0011,
	CONFIG_BKMODEL_NUMBER_BK_0011_FDD,
	CONFIG_BKMODEL_NUMBER_BK_0011_A16M, //заглушка
	CONFIG_BKMODEL_NUMBER_BK_0011_SMK512, //заглушка
	CONFIG_BKMODEL_NUMBER_BK_0011_SAMARA,
	CONFIG_BKMODEL_NUMBER_BK_0011M,
	CONFIG_BKMODEL_NUMBER_BK_0011M_FDD,
	CONFIG_BKMODEL_NUMBER_BK_0011M_A16M,
	CONFIG_BKMODEL_NUMBER_BK_0011M_SMK512,
	CONFIG_BKMODEL_NUMBER_BK_0011M_SAMARA,
	CONFIG_BKMODEL_NUMBERS_NUMBER
};

//струкутра строковых параметров
struct confStringParam
{
	int nID; //ид ресурса
	CString *pstrValue; //указатель на переменную
	CString defValue; //значение по умолчанию
};


struct SoundChipModelList
{
	int nModelNum;
	CString strModel;
};
#define SSR_LIST_SIZE 4
#define SCHM_LIST_SIZE 2
//список допустимых частот, чтобы что попало вручную не вводили.
static const int g_EnabledSSR[] =
{
	DEFAULT_SOUND_SAMPLE_RATE,
	48000,
	96000,
	192000
};

//список допустимых моделей звукового проуессора, чтобы что попало вручную не вводили.
static const SoundChipModelList g_EnabledSoundChipModels[] =
{
	{ MODEL_AY_3_8910, _T("AY-3-8910") },
	{ MODEL_YM2149, _T("YM2149F") }
};


class CConfig
{
	public:
		//Rom модули
		static CString m_strBK10_017_Monitor,
		       m_strBK10_018_Focal,
		       m_strBK10_019_MSTD,
		       m_strBK10_106_basic1,
		       m_strBK10_107_basic2,
		       m_strBK10_108_basic3,
		       m_strBK11_201_bos,
		       m_strBK11_202_ext,
		       m_strBK11_203_mstd,
		       m_strBK11_198_basic1,
		       m_strBK11_199_basic2,
		       m_strBK11_200_basic3,
		       m_strBK11m_324_bos,
		       m_strBK11m_325_ext,
		       m_strBK11m_330_mstd,
		       m_strBK11m_327_basic1,
		       m_strBK11m_328_basic2,
		       m_strBK11m_329_basic3,
		       m_strFDD_Std,
		       m_strFDD_Std253,
		       m_strFDD_A16M,
		       m_strFDD_SMK512,
		       m_strFDD_Samara,
		       m_strBK11Pg121,
		       m_strBK11Pg122,
		       m_strBK11Pg131,
		       m_strBK11Pg132;
		//Директории
		static CString m_strBinPath,
		       m_strToolsPath,
		       m_strMemPath,
		       m_strSavesPath,
		       m_strTapePath,
		       m_strScriptsPath,
		       m_strROMPath,
		       m_strIMGPath,
		       m_strScreenShotsPath;

		//Параметры
		CString m_strBKBoardType;
		WORD    m_nCPURunAddr;
		int     m_nCPUFrequency,
				m_nRegistersDumpInterval,
				m_nScreenshotNumber,
				m_nSoundVolume,
				m_nScreenRenderType,
				m_nOscRenderType,
				m_nSoundSampleRate, //чтобы можно было менять частоту дискретизации звука на ходу.
				m_nSoundChipFrequency,
				m_nSoundChipModel;

		//Опции
		bool    m_bSavesDefault,
		        m_bSpeaker,
		        m_bSpeakerFilter,
		        m_bCovox,
		        m_bCovoxFilter,
		        m_bStereoCovox,
		        m_bAY8910,
		        m_bAY8910Filter,
		        m_bBKKeyboard,
		        m_bJoystick,
		        m_bICLBlock,

		        m_bColorMode,
		        m_bAdaptBWMode,
		        m_bLuminoforeEmulMode,
		        m_bFullscreenMode,

		        m_bPauseCPUAfterStart,
		        m_bAskForBreak, /*при чтении/записи из несуществующего адреса не прерываться.
                                    (полезно для отладки и не полезно для работы эмулятора)
                                    */
		        m_bEmulateLoadTape,
		        m_bEmulateSaveTape,
		        m_bTapeAutoBeginDetection,
		        m_bTapeAutoEnsDetection,

		        m_bShowPerformance,
		        m_bEmulateFDDIO;

		WORD    m_nAdrDump,
		        m_nAdrAsm;

		int     m_nVKBDType;

		//Приводы
		CString m_strDrives[4];
		CString m_strHDDrives[2];

//остальные параметры, которые желательно должны быть доступны глобально.
		OSVERSIONINFOEX m_osvi; //структура с версией винды
		CONFIG_BKMODEL_NUMBER m_BKConfigurationModelNumber; //номер конфигурации
		MSF_CONF        m_BKBoardModel;     //тип эмулируемой модели БК (для конструктора конфигураций)
		BKFDD_MODEL     m_BKFDDModel;       //переменная-посредник, сюда помещается номер модели дисковода перед созданием
		// конфигурации и используется во время создания конфигурации, в остальное время - не нужно.
	protected:
		static confStringParam m_romModules[];
		static confStringParam m_Directories[];

		CIni            iniFile; //наш распарсенный ини файл
		CString         m_strCurrentPath; //путь к проге
		CString         m_strIniFilePath; //полное имя ини файла, с путём

		CString         _GetCurrentPath();
		void            DefaultConfig();
		void            _intLoadConfig(bool bLoadMain);

	public:
		CConfig();
		virtual ~CConfig();
		void            InitConfig(const CString &strIniName);
		void            UnInitConfig();
		inline BOOL     IsWindowsVistaOrGreater()
		{
			return m_osvi.dwMajorVersion >= 6;
		}

		inline CIni    *GetIniObj()
		{
			return &iniFile;
		}

		CString         GetDriveImgName(int nDrive);
		void            SetDriveImgName(int nDrive, const CString &strPathName);
		CString         GetHDDriveImgName(int nDrive);
		void            SetHDDriveImgName(int nDrive, const CString &strPathName);
		const CString   &GetCurrentPath();
		CString         &NormalizePath(CString &strPath);
		CString         GetFilePath(const CString &strPath);
		CString         GetFileTitle(const CString &strPath);
		CString         GetFileName(const CString &strPath);
		CString         GetFileExt(const CString &strPath);
		void            LoadConfig(bool bLoadMain = true);
		void            LoadConfig_FromMemory(BYTE *pBuff = nullptr, UINT nSize = 0);
		void            SaveConfig();
		ULONGLONG       SaveConfig_ToMemory(BYTE *pBuff = nullptr, UINT nSize = 0);
		bool            VerifyRoms();
		CONFIG_BKMODEL_NUMBER GetBKModelNumber();
		void            SetBKModelNumber(CONFIG_BKMODEL_NUMBER n);
};

