///////////////////////////////////////////////////////////////////////////////
/// @file deRegisry.cpp
///
/// @brief Simple Win32 Registry Class
///
/// @author Hootie
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Oct 2001
/// @author Hootie
/// @remarks Rearchitecture II
///
///////////////////////////////////////////////////////////////////////////////


//=================================================================================
// Includes
//=================================================================================

#include "deShared.hpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>



//=================================================================================
// deRegistry::deRegistry()
//
// Constructor 
//=================================================================================
deRegistry::deRegistry()
{
   CurrentRootKey = HKEY_LOCAL_MACHINE;
   CurrentOpenKey = NULL;
   LastReturnCode = ERROR_SUCCESS;
}



//=================================================================================
// deRegistry::SetRoot()
//
// Set a new root key
//=================================================================================
deBoolean deRegistry::SetRoot(const deRegistryRootKey RootKey)
{
   switch (RootKey)
   {
      case DEREGISTRY_CLASSES_ROOT:
         CurrentRootKey = HKEY_CLASSES_ROOT;
         return deTRUE;
         break;

      case DEREGISTRY_CURRENT_USER:
         CurrentRootKey = HKEY_CURRENT_USER;
         return deTRUE;
         break;

      case DEREGISTRY_LOCAL_MACHINE:
         CurrentRootKey = HKEY_LOCAL_MACHINE;
         return deTRUE;
         break;

      case DEREGISTRY_USERS:
         CurrentRootKey = HKEY_USERS;
         return deTRUE;
         break;

      default:
         return deFALSE;
         break;
   }
}



//=================================================================================
// deRegistry::ReadString()
//
// Read a string value from registry.
//=================================================================================
deBoolean deRegistry::ReadString(const char *Key, const char *ValueName, char *Buffer, int *BufferSize)
{
   LONG DummyReturnCode;
   DWORD DataType = 0;
   DWORD ReturnSize;


   if (Key == NULL || strlen(Key) == 0 ||
       ValueName == NULL || strlen(ValueName) == 0 ||
       Buffer == NULL || 
       BufferSize == NULL || 0 == *BufferSize)
      return deFALSE;

   ReturnSize = *BufferSize;

   LastReturnCode = RegOpenKeyEx(CurrentRootKey,
                                 Key,
                                 0,
                                 KEY_ALL_ACCESS,
                                 &CurrentOpenKey);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   LastReturnCode = RegQueryValueEx(CurrentOpenKey,
                                    ValueName,
                                    NULL,
                                    &DataType,
                                    (PBYTE)Buffer,
                                    &ReturnSize);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      DummyReturnCode = RegCloseKey(CurrentOpenKey);
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   *BufferSize = ReturnSize;

   LastReturnCode = RegCloseKey(CurrentOpenKey);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   CurrentOpenKey = NULL;
   return deTRUE;
}



//=================================================================================
// deRegistry::WriteString()
//
// Write a string value to registry.
//=================================================================================
deBoolean deRegistry::WriteString(const char *Key, const char *ValueName, const char *Buffer, const int BufferSize)
{
   LONG DummyReturnCode;
   DWORD Disposition = 0;


   if (Key == NULL || strlen(Key) == 0 ||
       ValueName == NULL || strlen(ValueName) == 0 ||
       Buffer == NULL || strlen(Buffer) == 0 ||
       BufferSize == 0)
      return deFALSE;

   LastReturnCode = RegCreateKeyEx(CurrentRootKey,
                                   Key,
                                   0,
                                   "",
                                   REG_OPTION_NON_VOLATILE,
                                   KEY_ALL_ACCESS,
                                   NULL,
                                   &CurrentOpenKey,
                                   &Disposition);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   LastReturnCode = RegSetValueEx(CurrentOpenKey,
                                  ValueName,
                                  NULL,
                                  REG_SZ,
                                  (PBYTE)Buffer,
                                  BufferSize + 1);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      DummyReturnCode = RegCloseKey(CurrentOpenKey);
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   LastReturnCode = RegCloseKey(CurrentOpenKey);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   CurrentOpenKey = NULL;
   return deTRUE;
}



//=================================================================================
// deRegistry::ReadInt()
//
// Read a integer value from registry.
//=================================================================================
deBoolean deRegistry::ReadInt(const char *Key, const char *ValueName, int *IntValue)
{
   LONG DummyReturnCode;
   DWORD DataType = 0;
   DWORD ReturnValue = 0;
   DWORD ReturnSize = sizeof(DWORD);


   if (Key == NULL || strlen(Key) == 0 ||
       ValueName == NULL || strlen(ValueName) == 0 ||
       IntValue == NULL)
      return deFALSE;

   LastReturnCode = RegOpenKeyEx(CurrentRootKey,
                                 Key,
                                 0,
                                 KEY_ALL_ACCESS,
                                 &CurrentOpenKey);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   LastReturnCode = RegQueryValueEx(CurrentOpenKey,
                                    ValueName,
                                    NULL,
                                    &DataType,
                                    (PBYTE)&ReturnValue,
                                    &ReturnSize);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      DummyReturnCode = RegCloseKey(CurrentOpenKey);
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   *IntValue = ReturnValue;

   LastReturnCode = RegCloseKey(CurrentOpenKey);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   CurrentOpenKey = NULL;
   return deTRUE;
}



//=================================================================================
// deRegistry::WriteInt()
//
// Write a integer value to registry.
//=================================================================================
deBoolean deRegistry::WriteInt(const char *Key, const char *ValueName, const int IntValue)
{
   LONG DummyReturnCode;
   DWORD ReturnValue = 0;
   DWORD Disposition = 0;


   if (Key == NULL || strlen(Key) == 0 ||
       ValueName == NULL || strlen(ValueName) == 0)
      return deFALSE;

   ReturnValue = IntValue;

   LastReturnCode = RegCreateKeyEx(CurrentRootKey,
                                   Key,
                                   0,
                                   "",
                                   REG_OPTION_NON_VOLATILE,
                                   KEY_ALL_ACCESS,
                                   NULL,
                                   &CurrentOpenKey,
                                   &Disposition);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   LastReturnCode = RegSetValueEx(CurrentOpenKey,
                                  ValueName,
                                  NULL,
                                  REG_DWORD,
                                  (PBYTE)&ReturnValue,
                                  sizeof(DWORD));

   if (LastReturnCode != ERROR_SUCCESS)
   {
      DummyReturnCode = RegCloseKey(CurrentOpenKey);
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   LastReturnCode = RegCloseKey(CurrentOpenKey);

   if (LastReturnCode != ERROR_SUCCESS)
   {
      CurrentOpenKey = NULL;
      return deFALSE;
   }

   CurrentOpenKey = NULL;
   return deTRUE;
}



