#ifndef	__WIZ_HELPER_H__
#define	__WIZ_HELPER_H__

#include <shlwapi.h>
#include <atlsafe.h>
#include <vector>
#include <atlstr.h>

inline BOOL WizRegReadString(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName,  LPTSTR pszValue, DWORD dwLen)
{
	BOOL bRet = FALSE;
	HKEY hKey = NULL;

	if (ERROR_SUCCESS == RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_READ, &hKey))
	{
		DWORD dwType = REG_SZ;
		if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpszValueName, 0, &dwType, (BYTE *)(pszValue), &dwLen))
		{
			bRet = TRUE;
		}
		RegCloseKey(hKey);
	}
	return bRet;
}
inline BOOL WizRegReadInt32(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName,  int& nValue)
{
	BOOL bRet = FALSE;
	HKEY hKey = NULL;

	if (ERROR_SUCCESS == RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_READ, &hKey))
	{
		//
		DWORD dwValue = 0;
		DWORD dwType = REG_DWORD;
		DWORD dwSize = sizeof(DWORD);
		if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpszValueName, 0, &dwType, (BYTE *)(&dwValue), &dwSize))
		{
			nValue = int(dwValue);
			bRet = TRUE;
		}
		RegCloseKey(hKey);
	}
	return bRet;
}
inline BOOL WizRegReadBool(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName,  BOOL& bValue)
{
	int nRet = 0;
	if (!WizRegReadInt32(hRootKey, lpszKey, lpszValueName, nRet))
		return FALSE;
	bValue = nRet ? TRUE : FALSE;
	return TRUE;
} 
inline BOOL WizRegWriteString(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName, LPCTSTR lpszValue)
{
	BOOL bRet = FALSE;
	HKEY hKey = NULL;

	if (ERROR_SUCCESS != RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_ALL_ACCESS, &hKey))
	{
		RegCreateKeyEx(hRootKey, lpszKey, 0, NULL, 0, KEY_ALL_ACCESS, 0, &hKey, 0);
	}
	//
	if (hKey)
	{
		if (ERROR_SUCCESS == RegSetValueEx(hKey, lpszValueName, 0, REG_SZ, (BYTE *)lpszValue, (DWORD)((_tcslen(lpszValue) + 1) * sizeof(TCHAR))))
		{
			bRet = TRUE;
		}
		RegCloseKey(hKey);
	}
	return bRet;
}

inline BOOL WizRegWriteInt32(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName, int nValue)
{
	BOOL bRet = FALSE;
	HKEY hKey = NULL;

	if (ERROR_SUCCESS != RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_ALL_ACCESS, &hKey))
	{
		RegCreateKeyEx(hRootKey, lpszKey, 0, NULL, 0, KEY_ALL_ACCESS, 0, &hKey, 0);
	}
	if (hKey)
	{
		DWORD dwValue = nValue;
		//
		if (ERROR_SUCCESS == RegSetValueEx(hKey, lpszValueName, 0, REG_DWORD, (BYTE *)(&dwValue), sizeof(DWORD)))
		{
			bRet = TRUE;
		}
		RegCloseKey(hKey);
	}
	return bRet;
}
inline BOOL WizRegWriteBool(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName,  BOOL bVal)
{
	return WizRegWriteInt32(hRootKey, lpszKey, lpszValueName, bVal ? 1 : 0);
}

inline BOOL WizRegDeleteValue(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName)
{
	BOOL bRet = FALSE;
	HKEY hKey = NULL;

	if (ERROR_SUCCESS == RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_ALL_ACCESS, &hKey) && hKey)
	{
		if (ERROR_SUCCESS == RegDeleteValue(hKey, lpszValueName))
		{
			bRet = TRUE;
		}
		RegCloseKey(hKey);
	}
	return bRet;
}


inline CString WizRegReadStringDef(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName, LPCTSTR lpszDefault)
{
	const int nBufferLen = 1024;
	TCHAR szBuffer[nBufferLen] = {0};
	ZeroMemory(szBuffer, nBufferLen * sizeof(TCHAR));
	//
	if (!WizRegReadString(hRootKey, lpszKey, lpszValueName, szBuffer, nBufferLen))
	{
		if (lpszDefault)
		{
			_tcscpy_s(szBuffer, 1024, lpszDefault);
		}
	}
	//
	return CString(szBuffer);
}

inline int WizRegReadInt32Def(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName, int nDefault)
{
	int nRet = 0;
	if (!WizRegReadInt32(hRootKey, lpszKey, lpszValueName, nRet))
	{
		nRet = nDefault;
	}
	return nRet;
}

inline BOOL WizRegReadBoolDef(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName,  BOOL bDefault)
{
	BOOL bRet = FALSE;
	if (!WizRegReadBool(hRootKey, lpszKey, lpszValueName, bRet))
	{
		return bRet = bDefault;
	}
	return bRet;
} 

inline BOOL WizRegKeyExists(HKEY hRootKey, LPCTSTR lpszKey)
{
	HKEY hKey = NULL;
	if (ERROR_SUCCESS == RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_READ, &hKey))
	{
		RegCloseKey(hKey);
	}
	return hKey ? TRUE : FALSE;
}
inline BOOL WizRegCreateKey(HKEY hRootKey, LPCTSTR lpszKey)
{
	BOOL bRet = FALSE;
	HKEY hKey = NULL;

	if (ERROR_SUCCESS != RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_ALL_ACCESS, &hKey))
	{
		RegCreateKeyEx(hRootKey, lpszKey, 0, NULL, 0, KEY_ALL_ACCESS, 0, &hKey, 0);
	}
	//
	if (hKey)
	{
		bRet = TRUE;
		RegCloseKey(hKey);
	}
	//
	return bRet;
}

inline BOOL WizRegValueExists(HKEY hRootKey, LPCTSTR lpszKey, LPCTSTR lpszValueName)
{
	BOOL bRet = FALSE;
	//
	HKEY hKey = NULL;
	if (ERROR_SUCCESS == RegOpenKeyEx(hRootKey, lpszKey, 0, KEY_READ, &hKey))
	{
		DWORD dwType = REG_DWORD;
		if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpszValueName, 0, &dwType, NULL, 0))
		{
			bRet = TRUE;
		}
		RegCloseKey(hKey);
	}
	//
	return bRet;
}
inline BOOL WizRegDeleteKey(HKEY hRootKey, LPCTSTR lpszKey)
{
	return ERROR_SUCCESS == SHDeleteKey(hRootKey, lpszKey);
}



typedef std::vector<CString> CWizStdStringArray;

inline BOOL WizStringArrayToVariant(const CWizStdStringArray& arrayText, VARIANT& v)
{
	ULONG nCount = ULONG(arrayText.size());
	CComSafeArray<VARIANT> varray(nCount);
	for (ULONG i = 0; i < nCount; i++)
	{
		varray.SetAt(i, CComVariant(CComBSTR(arrayText[i])));
	}
	CComVariant vTemp(varray.m_psa);
	//
	VariantCopy(&v, &vTemp);
	//
	return TRUE;
}

#endif	//__WIZ_HELPER_H__
