/*------------------------------------------------------------------------------*
 * File Name: Settigns.h														*
 * Creation: YuI 12/20/2002														*
 * Purpose: Origin C OriginSettings Class Header								*
 * Copyright (c) OriginLab Corp.2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007	*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/
#ifndef _SETTINGS_H
#define _SETTINGS_H

/** >Internal Origin Objects
 		The OriginSettings class provides methods and properties to access different 
 		customizable settings of Origin.
	Example:
		// get types of file that can be imported into the active page
		// and bring up "Open File" dialog box
		void test()
		{
			StringArray saTypes;
			PageBase pg = Project.Pages();
			Project.Settings.GetUserTypes(saTypes, pg.GetType());
			string strPath = GetOpenBox(saTypes);
			printf("File name is \"%s\"", strPath);
		}
		
*/
class	OriginSettings
{
public:
	OriginSettings();
	
public:
	void	GetUserTypes(StringArray& saTypes, int nGroup);
};


/** >System
		The INIFile class provides methods to access data stored in initialization file
*/
class INIFile
{
public:
	/**
		Constructor to determine what INI file to use
	Parameters:
		lpcszFilename - File name (can specify full path and file name)
		bUseIniPath - Set to TRUE for INI path, false for program path
	Returns:
	Example:
		// This function will output an ini file's section and key names.
		void output_ini(LPCSTR lpcszIniFile)
		{
			INIFile ini1("Origin.ini", FALSE);
			INIFile ini2("Origin.ini");
			int nNumLevels1 = ini1.ReadInt("Config", "NumLevels", 0);
			int nNumLevels2 = ini2.ReadInt("Config", "NumLevels", 0);
			printf("NumLevels in Program folder ini = %d", nNumLevels1);
			printf("NumLevels in ini folder ini = %d", nNumLevels2);
		}			
		
	*/

	INIFile(LPCSTR lpcszFilename = NULL, BOOL bUseIniPath = TRUE);

public:
	/**
		Get all the section names into a string array.
		Parameters:
			saSections - string array to receive the section names
		Returns:
			number of section names in the array
		Example:
			// This function will output an ini file's section and key names.
			void output_ini(LPCSTR lpcszIniFile)
			{
				string str;
				INIFile ini(lpcszIniFile);
				StringArray saSections, saKeys;
				ini.GetSectionNames(saSections);
				for( int iSection = 0; iSection < saSections.GetSize(); iSection++ )
				{
					printf("%s\n", saSections[iSection]);
					ini.GetKeyNames(saKeys, saSections[iSection]);
					for( int iKey = 0; iKey < saKeys.GetSize(); iKey++ )
					{
						str = ini.ReadString(saSections[iSection], saKeys[iKey]);
						printf("    %s = %s\n", saKeys[iKey], str);
					}
				}
			}			
	*/
	int GetSectionNames(StringArray &saSections);
	
	/**
		Get all the key names in a section into a string array.
		Parameters:
			saKeys - string array to receive the key names
			lpcszSection - pointer to the section name to get the key names from
		Returns:
			number of key names in the array
		Example:
			// This function will output an ini file's section and key names.
			void output_ini(LPCSTR lpcszIniFile)
			{
				string str;
				INIFile ini(lpcszIniFile);
				StringArray saSections, saKeys;
				ini.GetSectionNames(saSections);
				for( int iSection = 0; iSection < saSections.GetSize(); iSection++ )
				{
					printf("%s\n", saSections[iSection]);
					ini.GetKeyNames(saKeys, saSections[iSection]);
					for( int iKey = 0; iKey < saKeys.GetSize(); iKey++ )
					{
						str = ini.ReadString(saSections[iSection], saKeys[iKey]);
						printf("    %s = %s\n", saKeys[iKey], str);
					}
				}
			}			
	*/
	int GetKeyNames(StringArray &saKeys, LPCSTR lpcszSection);

	/**
		Retrieves an integer value from the specified section in an initialization file
		Parameters:
			lpcszSection - section name
			lpcszKey - key name
			nDefault - return value if section or key is not found in initialization file
		Returns:
			integer value specified by section and key from initialization file
		
		Example:
			//gets current value for Initial Origin window state from Origin.ini file
			//see "Config" section og Origin.ini for more details
			void test()
			{
				string strFileName = GetAppPath(1)+ "Origin.ini";
				INIFile ini(strFileName);
				printf("Initial Origin window state is %d", ini.ReadInt("Config", "ShowState", -1));
			}
	*/
	int		ReadInt(LPCSTR lpcszSection, LPCSTR lpcszKey, int nDefault);
	
	/**
		Writes integer value into the specified section of an initialization file
		Parameters:
			lpcszSection - section name
			lpcszKey - key name
			nValue - value to be written
		Example:
			This example writes integer value into the Config section of MyOrigin.ini.
			For this example to run, a file with the name MyOrigin.ini should exist under C:\ folder.
			In addition, MyOrigin.ini should contain a section named Config and a key named ShowState.

			void test_INIFile_WriteInt()
			{
					int iState = 3;
					INIFile iniMyF("C:\\MyOrigin.ini");
					
					iniMyF.WriteInt("Config", "ShowState", iState);
					printf("Set initial Origin window state to %d\n", iState);
					
					if (iState == iniMyF.ReadInt("Config", "ShowState", -1))
						printf("Success!\ninitial Origin window state is %d\n",iState);
					else 
						out_str("Error!");
			}
	*/
	void	WriteInt(LPCSTR lpcszSection, LPCSTR lpcszKey, int nValue);
		
	/**
			Reads the value of a key in a given section into a string.
			Parameters:
				lpcszSection = section name
				lpcszKey = key name
				lpcszDefault = NULL 
			Returns:
				the value of a key in a given section in the form of a string
			Example:
				    // reads and prints all the key values in all sections
					string str;
					INIFile ini("filename.ini");
					StringArray saSections, saKeys;
					ini.GetSectionNames(saSections);
					for( int iSection = 0; iSection < saSections.GetSize(); iSection++ )
					{
						printf("%s\n", saSections[iSection]);
						ini.GetKeyNames(saKeys, saSections[iSection]);
						for( int iKey = 0; iKey < saKeys.GetSize(); iKey++ )
						{
							str = ini.ReadString(saSections[iSection], saKeys[iKey]);
							printf("    %s = %s\n", saKeys[iKey], str);
						}
					}
					
	*/
	string	ReadString(LPCSTR lpcszSection, LPCSTR lpcszKey, LPCSTR lpcszDefault = NULL);
	
	
	/**
				Writes a string value for a given keyname in a given section
			Parameters:
				lpcszSection = section name
				lpcszKey = key name
				lpcszValue = the string that needs to be written  
			Returns:
			Example:
					// writes "***" into all the key values in all sections
					string str = "***";
					INIFile ini("EBGIF2.ini");
					StringArray saSections, saKeys;
					ini.GetSectionNames(saSections);
					for( int iSection = 0; iSection < saSections.GetSize(); iSection++ )
					{
						printf("%s\n", saSections[iSection]);
						ini.GetKeyNames(saKeys, saSections[iSection]);
						for( int iKey = 0; iKey < saKeys.GetSize(); iKey++ )
						{
							ini.WriteString(saSections[iSection], saKeys[iKey], str);
							string str1 = ini.ReadString(saSections[iSection], saKeys[iKey], str);
							printf("    %s = %s\n", saKeys[iKey], str1);
						}
					}
					
	*/
	void	WriteString(LPCSTR lpcszSection, LPCSTR lpcszKey, LPCSTR lpcszValue);
	
	/**
				Sets the file name to the given string.
			Parameters:
				lpcszSection = new file name
				
			Returns:
			Example:
				
					INIFile ini("Origin.ini");
					int nNumLevels = ini.ReadInt("Config", "NumLevels", 0);
					printf("NumLevels = %d", nNumLevels);
					
	*/
	void	SetFileName(LPCSTR lpcszSection);
	
	/**
				Gets the name of the INI file.
			Parameters:				
			Returns:
					the file name of the INI file in the form of a string. 
			Example:
					INIFile ini("Origin.ini");;
					int nNumLevels = ini.ReadInt("Config", "NumLevels", 0);
					printf("NumLevels = %d", nNumLevels);
					out_str(ini.GetFileName());
	
	*/
	string	GetFileName();
	
	/**# CP
	
	*/
	//void	SetUseIniPath(BOOL bOn = TRUE);
	
	/**# CP
	
	*/
	//BOOL	GetUseIniPath();
};

/**
		The Registry class provides methods to access data stored in registry
*/
typedef byte* LPBYTE;
typedef uint* LPDWORD;
//
// Reserved Key Handles.
//
#define HKEY_CLASSES_ROOT           ( 0x80000000 )
#define HKEY_CURRENT_USER           ( 0x80000001 )
#define HKEY_LOCAL_MACHINE          ( 0x80000002 )
#define HKEY_USERS                  ( 0x80000003 )
#define HKEY_PERFORMANCE_DATA       ( 0x80000004 )
#define HKEY_CURRENT_CONFIG         ( 0x80000005 )
#define HKEY_DYN_DATA               ( 0x80000006 )

//
// Predefined Value Types.
//
#define REG_NONE                    ( 0 )   // No value type
#define REG_SZ                      ( 1 )   // Unicode nul terminated string
#define REG_EXPAND_SZ               ( 2 )   // Unicode nul terminated string
                                            // (with environment variable references)
#define REG_BINARY                  ( 3 )   // Free form binary
#define REG_DWORD                   ( 4 )   // 32-bit number
#define REG_DWORD_LITTLE_ENDIAN     ( 4 )   // 32-bit number (same as REG_DWORD)
#define REG_DWORD_BIG_ENDIAN        ( 5 )   // 32-bit number
#define REG_LINK                    ( 6 )   // Symbolic Link (unicode)
#define REG_MULTI_SZ                ( 7 )   // Multiple Unicode strings
#define REG_RESOURCE_LIST           ( 8 )   // Resource list in the resource map
#define REG_FULL_RESOURCE_DESCRIPTOR ( 9 )  // Resource list in the hardware description
#define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )

/** >System
*/
class Registry
{
public:
	Registry(DWORD hParentKey);

public:
	/**
		Has the specified registry key or not.
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey to test. 

	Return:
		TRUE or FALSE.
	Example:
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			return TRUE;
	SeeAlso:
	*/
	BOOL HasKey(LPCSTR lpSubKey);

	/**
		Removes a named value from the specified registry key.
	Parameters:
		lpSubKey = Pointer to a null-terminated string specifying the name of the key to delete. This parameter cannot be NULL. 
		lpValueName = Pointer to a null-terminated string that names the value to remove. 
					  If this parameter is NULL or points to an empty string, the value set by the SetValue function is removed. 

	Return:
	Example:
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.DelValue("a\\b\\c", "MyLabel");
	SeeAlso:
	*/
	BOOL DelValue(LPCSTR lpSubKey, LPCSTR lpValueName = NULL);

	/**
		Deletes a subkey.
	Parameters:
		lpSubKey = Pointer to a null-terminated string specifying the name of the key to delete. This parameter cannot be NULL. 

	Return:
		FALSE if the key does not exist or it fails to remove it.  
	Example:
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.DelKey("a\\b\\c");
	SeeAlso:
	*/
	BOOL DelKey(LPCSTR lpSubKey);

	/**
		Retrieves the data for a specified value name associated with a subkey.
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey to open. 
		lpValueName = Pointer to a string containing the name of the value to query. 
					  If this parameter is NULL or an empty string, "", the function retrieves 
					  the type and data for the key's unnamed or default value, if any.
	Return:
		TRUE if key value pair is in registry, FALSE if not
	Example:
		DWORD dwCntrl;
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.GetValue("a\\b\\c", "Control", dwCntrl);
	SeeAlso:
	*/
	BOOL GetValue(LPCSTR lpSubKey, LPCSTR lpValueName, DWORD &dwValue);

	/**
		Retrieves the data for a specified value name associated with a subkey.
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey to open. 
		lpValueName = Pointer to a string containing the name of the value to query. 
					  If this parameter is NULL or an empty string, "", the function retrieves 
					  the type and data for the key's unnamed or default value, if any.
	Return:
		TRUE if key value pair is in registry, FALSE if not
	Example:
		string strLabel;
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.GetValue("a\\b\\c", "Label", strLabel);
	SeeAlso:
	*/
	BOOL GetValue(LPCSTR lpSubKey, LPCSTR lpValueName, string &strValue);

	/**
		Retrieves the data for a specified value name associated with a subkey.
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey to open. 
		lpValueName = Pointer to a string containing the name of the value to query. 
					  If this parameter is NULL or an empty string, "", the function retrieves 
					  the type and data for the key's unnamed or default value, if any.
		lpData = Pointer to a buffer that receives the value’s data. This parameter can be NULL if the data is not required.
		lpcbData = Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the lpData parameter. 
				   When the function returns, this variable contains the size of the data copied to lpData. 
		lpType = Pointer to a variable that receives the type of data associated with the specified value,
				 The lpType parameter can be NULL if the type is not required.
	Return:
	Example:
		byte szValue[MY_BUFSIZE];
		DWORD dwBufLen = MY_BUFSIZE;
		string strSubKey = "Classes\\CLSID\\{B0F21977-8AAB-4632-A73D-528B909C5663}\\InProcServer32";

		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.GetValue("a\\b\\c", strSubKey, (LPBYTE)szValue, &dwBufLen);
	SeeAlso:
	*/
	BOOL GetValue(LPCSTR lpSubKey, LPCSTR lpValueName, LPBYTE lpData, LPDWORD lpcbData, LPDWORD lpType = NULL);

	/**
		Sets the data for the default or unnamed value of a specified registry key. 
		The data must be a text string.
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey.
				   If the lpSubKey does not exist, it will be created there
		lpValue = Pointer to a null-terminated string containing the data to set for the default value of the specified key.
		lpValueName = Pointer to a string containing the name of the value, 
					  If lpszValueName is supplied, the name value pair lpszValueName = lpszValue will be created for the key. 
					  If lpszValueName is NULL, the default value of the lpSubKey will be set to lpszValue.
	Return:
	Example:
		string strLabel = "Test";
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.SetValue("a\\b\\c", "Label", strLabel);
	SeeAlso:
	*/
	void SetValue(LPCSTR lpSubKey, LPCSTR lpValueName, LPCSTR lpValue);

	/**
		Sets the data for a specified value name associated with a subkey.
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey to open. 
		lpValueName = Pointer to a string containing the name of the value to set. 
		dwValue = a unsigned int value
	Return:
	Example:
		Registry myRegAccess(HKEY_CLASSES_ROOT);
		if( myRegAccess.HasKey("a\\b\\c") )
			myRegAccess.SetValue("a\\b\\c", "Control", 12345);
	SeeAlso:
	*/
	void SetValue(LPCSTR lpSubKey, LPCSTR lpValueName, DWORD dwValue);
	/**
		Sets the data for the default or unnamed value of a specified registry key. 
	Parameters:
		lpSubKey = Pointer to a null-terminated string containing the name of the subkey.
				   If the lpSubKey does not exist, it will be created there
		lpValueName = Pointer to a string containing the name of the value, 
					  If lpszValueName is NULL, the default value of the lpSubKey will be set to lpszValue.
		lpData = Pointer to a buffer containing the data to be stored with the specified value name. 
		dwType = Specifies a code indicating the type of data pointed to by the lpData parameter.
		dwcbData = Specifies the size of the information pointed to by the lpData parameter, in bytes.
	Return:
	Example:
		Registry myRegAccess(HKEY_CURRENT_USER);
   		vector<byte> vb = {43, 44, 45, 46, 47, 48, 49, 0};
   		DWORD dwType = REG_BINARY;
  		DWORD dwNumBytes = 8;
   
   		if( myRegAccess.HasKey("a\\b\\c") )
      		myRegAccess.SetValue("a\\b\\c", "Place1", vb, dwType, dwNumBytes);
	SeeAlso:
	*/
	void SetValue(LPCSTR lpSubKey, LPCSTR lpValueName, LPBYTE lpData, DWORD dwType, DWORD dwcbData);
};
#endif // _SETTINGS_H