using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;

namespace Foo.Platform.Utilities
{
    public enum HKEYRoot
    {
        ClassesRoot,
        CurrentUser,
        LocalMachine,
    }

    public enum KeySub
    {
        Software,
        Custom
    }

    public class RegM
    {
        
        private RegistryKey _RegKey;

        /// <summary>
        /// Use this to Open/Automatically Create a Registry Key
        /// </summary>
        /// <param name="root">specify registry root</param>
        /// <param name="sub">specify a sub or custom</param>
        /// <param name="Key">key you want to open / create </param>
        /// <param name="bWrite">true if you plan on writing to it</param>
        public RegM(HKEYRoot root, KeySub sub, string Key, bool bWrite)
        {
            string KeyToOpen = String.Empty;
            if (sub == KeySub.Custom)
                KeyToOpen = Key;
            else
                KeyToOpen = sub.ToString() + "\\" + Key;

            RegistryKeyPermissionCheck permission = RegistryKeyPermissionCheck.ReadSubTree;
            if (bWrite)
                permission = RegistryKeyPermissionCheck.ReadWriteSubTree;

            // Open/Create if it doesn't exist, the Proper Key
            switch (root)
            {
                case HKEYRoot.ClassesRoot:
                    _RegKey = Registry.ClassesRoot.CreateSubKey(KeyToOpen, permission);
                    break;

                case HKEYRoot.CurrentUser:
                    _RegKey = Registry.CurrentUser.CreateSubKey(KeyToOpen, permission);
                    break;

                case HKEYRoot.LocalMachine:
                    _RegKey = Registry.LocalMachine.CreateSubKey(KeyToOpen, permission);
                    break;
            }
        }

        #region GetValue Registry Functions

        public bool GetVal_String(string strValKey, out string StringValue)
        {
            StringValue = String.Empty;
            try
            {                
                object keyvalue = null;
                keyvalue = _RegKey.GetValue(strValKey);
                if (isValidStr(keyvalue))
                    StringValue = keyvalue.ToString();
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        public bool GetVal_Bool(string strValKey, out bool BoolValue)
        {
            BoolValue = false;
            try
            {
                string StringValue;
                if (GetVal_String(strValKey, out StringValue) &&
                    !String.IsNullOrEmpty(StringValue))
                    BoolValue = Boolean.Parse(StringValue);
                return true;                
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        public bool GetVal_Int(string strValKey, out int IntValue)
        {
            IntValue = 0;
            try
            {
                string StringValue;
                if (GetVal_String(strValKey, out StringValue) &&
                    !String.IsNullOrEmpty(StringValue))
                    IntValue = int.Parse(StringValue);
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        public bool GetVal_Binary(string strValKey, out byte[] ByteValue)
        {
            ByteValue = null;
            try
            {
                string StringValue;
                if (GetVal_String(strValKey, out StringValue) &&
                    !String.IsNullOrEmpty(StringValue))
                {
                    ByteValue = new Byte[StringValue.Length];
                    for (int i = 0; i < ByteValue.Length; ++i)
                    {
                        string strByte = Convert.ToString(StringValue[i]);                                                
                        ByteValue[i] = byte.Parse(strByte);
                    }
                }
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        #endregion

        #region SetValue Registry Functions

        public bool SetVal_String(string strValKey, string StringValue)
        {
            try
            {
                _RegKey.SetValue(strValKey, StringValue, RegistryValueKind.String);
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        public bool SetVal_Bool(string strValKey, bool BoolValue)
        {
            try
            {
                _RegKey.SetValue(strValKey, BoolValue.ToString(), RegistryValueKind.String);
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        public bool SetVal_Int(string strValKey, int DwordValue)
        {
            try
            {
                _RegKey.SetValue(strValKey, DwordValue, RegistryValueKind.DWord);
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        public bool SetVal_Binary(string strValKey, byte[] ByteValue)
        {
            try
            {
                _RegKey.SetValue(strValKey, ByteValue, RegistryValueKind.Binary);
                return true;
            }
            catch (Exception) { /* ignore */ }
            return false;
        }

        #endregion

        /// <returns>Returns true if passed in object is valid and not ""</returns>
        private bool isValidStr(object oToValidate)
        {
            if ((oToValidate != null) && (oToValidate.ToString() != ""))
                return true;
            else
                return false;
        }       
    }    

}
