using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace FleetPC_11_RTX3000_1_0
{
    public partial class Form1 : Form
    {
        private bool check_32 = false;
        private bool check_64 = false;

        #region InOut資料庫

        [DllImport("inpout32.dll")]
        private static extern UInt32 IsInpOutDriverOpen();

        [DllImport("inpout32.dll")]
        private static extern void Out32(UInt16 PortAddress, UInt32 Data);

        [DllImport("inpout32.dll")]
        //private static extern char Inp32(UInt16 PortAddress);
        private static extern UInt32 Inp32(UInt16 PortAddress);

        [DllImport("inpout32.dll")]
        private static extern void DlPortWritePortUshort(short PortAddress, ushort Data);

        [DllImport("inpout32.dll")]
        private static extern ushort DlPortReadPortUshort(short PortAddress);

        [DllImport("inpout32.dll")]
        private static extern void DlPortWritePortUlong(int PortAddress, uint Data);

        [DllImport("inpout32.dll")]
        private static extern uint DlPortReadPortUlong(int PortAddress);

        [DllImport("inpout32.dll")]
        private static extern bool IsXP64Bit();

        [DllImport("inpout32.dll")]
        private static extern int Opendriver(bool bX64);

        [DllImport("inpout32.dll")]
        private static extern void Closedriver();

        [DllImport("inpoutx64.dll")]
        private static extern bool GetPhysLong(ref int PortAddress, ref uint Data);

        [DllImport("inpoutx64.dll")]
        private static extern bool SetPhysLong(ref int PortAddress, ref uint Data);

        [DllImport("inpoutx64.dll", EntryPoint = "IsInpOutDriverOpen")]
        private static extern UInt32 IsInpOutDriverOpen_x64();

        [DllImport("inpoutx64.dll", EntryPoint = "Out32")]
        private static extern void Out32_x64(UInt16 PortAddress, UInt32 Data);

        [DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
        //private static extern char Inp32_x64(UInt16 PortAddress);
        private static extern UInt32 Inp32_x64(UInt16 PortAddress);

        [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUshort")]
        private static extern void DlPortWritePortUshort_x64(short PortAddress, ushort Data);

        [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUshort")]
        private static extern ushort DlPortReadPortUshort_x64(short PortAddress);

        [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUlong")]
        private static extern void DlPortWritePortUlong_x64(int PortAddress, uint Data);

        [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUlong")]
        private static extern uint DlPortReadPortUlong_x64(int PortAddress);

        [DllImport("inpoutx64.dll", EntryPoint = "GetPhysLong")]
        private static extern bool GetPhysLong_x64(ref int PortAddress, ref uint Data);

        [DllImport("inpoutx64.dll", EntryPoint = "SetPhysLong")]
        private static extern bool SetPhysLong_x64(ref int PortAddress, ref uint Data);

        [DllImport("inpoutx64.dll", EntryPoint = "IsXP64Bit")]
        private static extern bool IsXP64Bit_x64();

        [DllImport("inpoutx64.dll", EntryPoint = "Opendriver")]
        private static extern int Opendriver_x64(bool bX64);

        [DllImport("inpoutx64.dll", EntryPoint = "Closedriver")]
        private static extern void Closedriver_x64();

        #endregion InOut資料庫

        #region Check資料庫x64

        private void Driver_Check_x64()
        {
            uint nResult = 0;

            nResult = IsInpOutDriverOpen_x64();
            check_64 = IsXP64Bit_x64();
            if (nResult == 0)
            {
                Opendriver(check_64);
                Closedriver_x64();
            }
        }

        #endregion Check資料庫x64

        #region Check資料庫x86

        private void Driver_Check_x86()
        {
            uint nResult = 0;

            nResult = IsInpOutDriverOpen();
            check_32 = IsXP64Bit();
            if (nResult == 0)
            {
                Opendriver(check_32);
                Closedriver();
            }
        }

        #endregion Check資料庫x86

        public Form1()
        {
            InitializeComponent();
            Driver_Check_x86();
            RenderUps();
            upsTimer.Start();
        }

        private UInt16 SMBus_Base = 0xF040;
        private UInt16 SMBus_SlaveAddress = 0x94;
        private int POE_Current;
        private int POE_Voltage;
        private UInt32 UpsPerCent; //讀取SMBus上的upspercent,A6,A7
        private string UpsVoltage; //讀取SMBus上的upsvoltage,A2,A3

        #region SMBus讀取與寫入(功能)

        private void SMB_Write(UInt16 SMB_Addr, UInt16 DEV_Address, UInt16 DEV_Reg, UInt16 Value) //SMBus寫入
        {
            Out32(SMB_Addr, 0xFF);                                              // Clear SMBUS Status
            Thread.Sleep(10);                                                  // Delay 10 ms (1000 is 1 Sec)
            Out32((ushort)(SMB_Addr + 0x04), DEV_Address);                      // EEPROM Address AE -Write / AF -Read
            Thread.Sleep(10);
            Out32((ushort)(SMB_Addr + 0x03), DEV_Reg);                          // EEPROM Reg Address
            Thread.Sleep(10);
            Out32((ushort)(SMB_Addr + 0x05), Value);                            // Write Data in EEPROM
            Thread.Sleep(10);
            Out32((ushort)(SMB_Addr + 0x02), 0x48);                             // Start to Send
            Thread.Sleep(10);
        }

        private UInt32 SMB_Read(UInt16 SMB_Addr, UInt16 DEV_Address, UInt16 DEV_Reg) //SMBus讀取
        {
            UInt32 Value;
            Out32(SMB_Addr, 0xFF);                                              // Clear SMBUS Status
            Thread.Sleep(10);                                                  // Delay 10 ms (1000 is 1 Sec)
            Out32((ushort)(SMB_Addr + 0x04), (ushort)(DEV_Address + 1));         // EEPROM Address AE -Write / AF -Read
            Thread.Sleep(10);
            Out32((ushort)(SMB_Addr + 0x03), DEV_Reg);                          // EEPROM Reg Address
            Thread.Sleep(10);
            Out32((ushort)(SMB_Addr + 0x02), 0x48);                             // Start to Send
            Thread.Sleep(50);
            Value = Inp32((ushort)(SMB_Addr + 0x05));                           // Read Data in EEPROM
            Thread.Sleep(10);
            return Value;
        }

        #endregion SMBus讀取與寫入(功能)

        #region POE讀取電壓與電流(功能)

        private void Get_POE_Current(UInt16 POE_address, UInt16 iplsb, UInt16 ipmsb)
        {
            UInt32 Current_Value, Value_LSB, Value_MSB;
            int X_value;

            Value_LSB = SMB_Read(SMBus_Base, POE_address, iplsb);
            Thread.Sleep(10);
            Value_MSB = SMB_Read(SMBus_Base, POE_address, ipmsb);
            Thread.Sleep(10);
            Current_Value = (Value_MSB << 8) + Value_LSB;
            X_value = Convert.ToInt32(Current_Value);
            X_value = (X_value * 122070) / 1000000;                             // 1 LSB = 122.07μA when RSENSE = 0.25Ω
            POE_Current = X_value;
        }

        private void Get_POE_Voltage(UInt16 POE_address, UInt16 vplsb, UInt16 vpmsb)
        {
            UInt32 Voltage_Value, Value_LSB, Value_MSB;
            int X_value;

            Value_LSB = SMB_Read(SMBus_Base, POE_address, vplsb);
            Thread.Sleep(10);
            Value_MSB = SMB_Read(SMBus_Base, POE_address, vpmsb);
            Thread.Sleep(10);
            Voltage_Value = (Value_MSB << 8) + Value_LSB;
            X_value = Convert.ToInt32(Voltage_Value);
            X_value = (X_value * 5835) / 1000000;                               // 1 LSB = 5.835mV
            POE_Voltage = X_value;
        }

        #endregion POE讀取電壓與電流(功能)

        #region 取得POE 電壓與電流

        private void Get_POE1_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x40, 0x30, 0x31);
            POE1_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE1_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x40, 0x32, 0x33);
            POE1_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE2_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x40, 0x34, 0x35);
            POE2_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE2_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x40, 0x36, 0x37);
            POE2_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE3_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x40, 0x38, 0x39);
            POE3_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE3_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x40, 0x3A, 0x3B);
            POE3_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE4_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x40, 0x3C, 0x3D);
            POE4_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE4_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x40, 0x3E, 0x3F);
            POE4_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE5_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x42, 0x30, 0x31);
            POE5_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE5_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x42, 0x32, 0x33);
            POE5_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE6_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x42, 0x34, 0x35);
            POE6_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE6_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x42, 0x36, 0x37);
            POE6_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE7_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x42, 0x38, 0x39);
            POE7_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE7_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x42, 0x3A, 0x3B);
            POE7_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        private void Get_POE8_Current_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Current(0x42, 0x3C, 0x3D);
            POE8_Current_TextBox.Text = POE_Current.ToString();
        }

        private void Get_POE8_Voltage_Button_Click(object sender, EventArgs e)
        {
            Get_POE_Voltage(0x42, 0x3E, 0x3F);
            POE8_Voltage_TextBox.Text = POE_Voltage.ToString();
        }

        #endregion 取得POE 電壓與電流

        #region 關閉POE Port1~8

        private void POE1_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xEE) | 0x10;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE2_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xDD) | 0x20;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE3_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xBB) | 0x40;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE4_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0x77) | 0x80;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE5_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xEE) | 0x10;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE6_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xDD) | 0x20;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE7_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xBB) | 0x40;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE8_OFF_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value;
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0x77) | 0x80;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        #endregion 關閉POE Port1~8

        #region 開啟POE Port1~8

        private void POE1_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x40, 0x14);
            Detect_Value = (Detect_Value & 0xFE) | 0x01;
            SMB_Write(SMBus_Base, 0x40, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xEE) | 0x01;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE2_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x40, 0x14);
            Detect_Value = (Detect_Value & 0xFD) | 0x02;
            SMB_Write(SMBus_Base, 0x40, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xDD) | 0x02;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE3_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x40, 0x14);
            Detect_Value = (Detect_Value & 0xFB) | 0x04;
            SMB_Write(SMBus_Base, 0x40, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xBB) | 0x04;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE4_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x40, 0x14);
            Detect_Value = (Detect_Value & 0xF7) | 0x08;
            SMB_Write(SMBus_Base, 0x40, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x40, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0x77) | 0x08;
            SMB_Write(SMBus_Base, 0x40, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE5_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x42, 0x14);
            Detect_Value = (Detect_Value & 0xFE) | 0x01;
            SMB_Write(SMBus_Base, 0x42, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xEE) | 0x01;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE6_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x42, 0x14);
            Detect_Value = (Detect_Value & 0xFD) | 0x02;
            SMB_Write(SMBus_Base, 0x42, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xDD) | 0x02;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE7_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x42, 0x14);
            Detect_Value = (Detect_Value & 0xFB) | 0x04;
            SMB_Write(SMBus_Base, 0x42, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0xBB) | 0x04;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        private void POE8_ON_Button_Click(object sender, EventArgs e)
        {
            UInt32 ON_OFF_Value, Detect_Value;
            Detect_Value = SMB_Read(SMBus_Base, 0x42, 0x14);
            Detect_Value = (Detect_Value & 0xF7) | 0x08;
            SMB_Write(SMBus_Base, 0x42, 0x14, (UInt16)Detect_Value);
            ON_OFF_Value = SMB_Read(SMBus_Base, 0x42, 0x19);
            ON_OFF_Value = (ON_OFF_Value & 0x77) | 0x08;
            SMB_Write(SMBus_Base, 0x42, 0x19, (UInt16)ON_OFF_Value);
        }

        #endregion 開啟POE Port1~8

        private void WDT_Initial()
        {
            Out32(0x4E, 0x87);
            Out32(0x4E, 0x87);
            Out32(0x4E, 0x07);
            Out32(0x4F, 0x07);
            Out32(0x4E, 0xFA);
            Out32(0x4F, 0x01);
            Out32(0x4E, 0x30);
            Out32(0x4F, 0x01);
            Out32(0x4E, 0xaa);
        }

        #region UpsImage

        private Image UpsImage()
        {
            if (UpsPerCent <= 100 && UpsPerCent >= 91)
            {
                return global::FleetPC_11_RTX3000_1_0.Properties.Resources._1;//五格電量
            }
            else if (UpsPerCent <= 90 && UpsPerCent >= 71)
            {
                return global::FleetPC_11_RTX3000_1_0.Properties.Resources._2;//四格電量
            }
            else if (UpsPerCent <= 70 && UpsPerCent >= 56)
            {
                return global::FleetPC_11_RTX3000_1_0.Properties.Resources._3;//三格電量
            }
            else if (UpsPerCent <= 55 && UpsPerCent >= 41)
            {
                return global::FleetPC_11_RTX3000_1_0.Properties.Resources._4;//兩格電量
            }
            else if (UpsPerCent <= 40 && UpsPerCent >= 1)
            {
                return global::FleetPC_11_RTX3000_1_0.Properties.Resources._5;//一格電量
            }
            else
            {
                return global::FleetPC_11_RTX3000_1_0.Properties.Resources._6;
            }
        }

        #endregion UpsImage

        #region UPS

        private void RenderUps() //更新UPS資料
        {
            GetUps(); //取得UPS資料
            upsPictureBox.Image = UpsImage(); //更換UPS圖片
            upsPerCentLabel.Text = UpsPerCent.ToString() + " %"; //UPS容量顯示
            upsVoltageLabel.Text = UpsVoltage; //UPS電壓顯示;
        }

        private void GetUps() //讀取UPS相關數值
        {
            UInt32 upspercent1, upspercent2;
            UInt32 upsvoltage1, upsvoltage2;
            upspercent1 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0xA6); //%
            upspercent2 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0xA7); //%
            upsvoltage1 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0xA3); //v High
            upsvoltage2 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0xA2); //v Low
            UpsPerCent = upspercent1 + upspercent2;
            UpsVoltage = upsvoltage1 + "." + upsvoltage2 + " V";
        }

        #endregion UPS

        private void Get_IGN_Delay_Time_Button_Click(object sender, EventArgs e)
        {
            UInt32 IGN_Hour, IGN_Min, IGN_Sec;
            IGN_Sec = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x66);
            IGN_Min = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x67);
            IGN_Hour = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x68);
            IGN_Delay_Hour_TextBox.Text = IGN_Hour.ToString();
            IGN_Delay_Min_TextBox.Text = IGN_Min.ToString();
            IGN_Delay_Sec_TextBox.Text = IGN_Sec.ToString();
        }

        private void Set_IGN_Delay_Time_Button_Click(object sender, EventArgs e)
        {
            if (int.Parse(IGN_Delay_Hour_TextBox.Text) < 0 || int.Parse(IGN_Delay_Hour_TextBox.Text) > 23)
            {
                MessageBox.Show("Hour enter:'0~23'");
                IGN_Delay_Hour_TextBox.Text = "0";
            }
            else if (int.Parse(IGN_Delay_Min_TextBox.Text) < 0 || int.Parse(IGN_Delay_Min_TextBox.Text) > 59)
            {
                MessageBox.Show("Min enter:'0~59'");
                IGN_Delay_Min_TextBox.Text = "0";
            }
            else if (int.Parse(IGN_Delay_Sec_TextBox.Text) < 0 || int.Parse(IGN_Delay_Sec_TextBox.Text) > 59)
            {
                MessageBox.Show("Sec enter:'0~59'");
                IGN_Delay_Sec_TextBox.Text = "0";
            }
            else
            {
                UInt16 IGN_Hour, IGN_Min, IGN_Sec;
                IGN_Hour = UInt16.Parse(IGN_Delay_Hour_TextBox.Text, System.Globalization.NumberStyles.Number);
                IGN_Min = UInt16.Parse(IGN_Delay_Min_TextBox.Text, System.Globalization.NumberStyles.Number);
                IGN_Sec = UInt16.Parse(IGN_Delay_Sec_TextBox.Text, System.Globalization.NumberStyles.Number);
                SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x66, IGN_Sec);
                SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x67, IGN_Min);
                SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x68, IGN_Hour);
            }
        }

        private void Ignition_Status_Button_Click(object sender, EventArgs e)
        {
            UInt32 Ignition_Status;
            Ignition_Status = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x12);                             // SMB address:0xF040; Device address: 0x94; System Status Reg:0x12

            if (Ignition_Status == 0x01)                                                 // Ignition is On
            {
                IGN_ON_RadioButton.Checked = true;
            }
            else if (Ignition_Status == 0x00)                                            // If bit3 = 0 --> Ignition is Off
            {
                IGN_OFF_RadioButton.Checked = true;
            }
        }

        private void Input_Voltage_Button_Click(object sender, EventArgs e)
        {
            UInt32 Voltage, Voltage1;
            Voltage = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x46);                             // SMB address:0xF040; Device address: 0x94; Input Voltage Low Reg:0x46
            Voltage1 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x47);                            // SMB address:0xF040; Device address: 0x94; Input Voltage High Reg:0x47
            Input_Voltage_TextBox.Text = Voltage1.ToString() + "." + Voltage.ToString() + "V";
        }

        private void Firmware_Check_Button_Click(object sender, EventArgs e)
        {
            UInt32 Firmware_version1, Firmware_version2, Firmware_version3, Firmware_version4, Firmware_version5;
            Firmware_version5 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x05);
            Firmware_version4 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x04);
            Firmware_version3 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x03);
            Firmware_version2 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x02);
            Firmware_version1 = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x01);
            Firmware_Check_TextBox.Text = "V" + string.Format("{0:X}", Firmware_version1) + "." + string.Format("{0:X}", Firmware_version2) + "." + string.Format("{0:X}", Firmware_version3) + "." + string.Format("{0:X2}", Firmware_version4) + "." + string.Format("{0:X}", Firmware_version5);
        }

        private void Set_DIO_Button_Click(object sender, EventArgs e)
        {
            UInt32 GPO, GPI;

            GPO = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x31);

            if (DO0_H_RadioButton.Checked == true)
            {
                GPO = GPO | 0x01;
            }

            if (DO0_L_RadioButton.Checked == true)
            {
                GPO = GPO & 0xFE;
            }

            if (DO1_H_RadioButton.Checked == true)
            {
                GPO = GPO | 0x02;
            }

            if (DO1_L_RadioButton.Checked == true)
            {
                GPO = GPO & 0xFD;
            }

            if (DO2_H_RadioButton.Checked == true)
            {
                GPO = GPO | 0x04;
            }

            if (DO2_L_RadioButton.Checked == true)
            {
                GPO = GPO & 0xFB;
            }

            if (DO3_H_RadioButton.Checked == true)
            {
                GPO = GPO | 0x08;
            }

            if (DO3_L_RadioButton.Checked == true)
            {
                GPO = GPO & 0xF7;
            }

            SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x31, (UInt16)GPO);
            //Data = (GPO << 8) + GPI;
            GPI = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x30);
            DO_TextBox.Text = GPO.ToString("X");
            DI_TextBox.Text = GPI.ToString("X");
        }

        private void Get_DIO_Button_Click(object sender, EventArgs e)
        {
            UInt32 GPO, GPI;
            GPI = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x30);
            GPO = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x31);

            if ((GPO & 0x01) == 1)
            {
                DO0_H_RadioButton.Checked = true;
            }
            else
            {
                DO0_L_RadioButton.Checked = true;
            }

            if (((GPO >> 1) & 0x01) == 1)
            {
                DO1_H_RadioButton.Checked = true;
            }
            else
            {
                DO1_L_RadioButton.Checked = true;
            }

            if (((GPO >> 2) & 0x01) == 1)
            {
                DO2_H_RadioButton.Checked = true;
            }
            else
            {
                DO2_L_RadioButton.Checked = true;
            }

            if (((GPO >> 3) & 0x01) == 1)
            {
                DO3_H_RadioButton.Checked = true;
            }
            else
            {
                DO3_L_RadioButton.Checked = true;
            }

            DO_TextBox.Text = GPO.ToString("X");
            DI_TextBox.Text = GPI.ToString("X");
        }

        private int SystemTemperature()
        {
            UInt32 TempVal;
            int temp2;
            Out32(0xA05, 0x74);
            TempVal = Inp32(0xA06);
            temp2 = Convert.ToInt32(TempVal);
            return temp2;
        }

        private void Get_System_Temp_Button_Click(object sender, EventArgs e)
        {
            UInt32 TempVal;
            int temp2;

            Out32(0xA05, 0x74);
            TempVal = Inp32(0xA06);
            temp2 = Convert.ToInt32(TempVal);
            System_Temp_TextBox.Text = temp2.ToString();
        }

        private void Select_SIM1_Button_Click(object sender, EventArgs e)
        {
            UInt32 SIM;
            SIM = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x39);
            SIM = (SIM & 0xFE) | 0x01;
            SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x39, (UInt16)SIM);
        }

        private void Select_SIM2_Button_Click(object sender, EventArgs e)
        {
            UInt32 SIM;
            SIM = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x39);
            SIM = SIM & 0xFE;
            SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x39, (UInt16)SIM);
        }

        private void Reset_3G_Button_Click(object sender, EventArgs e)
        {
            UInt32 Reset_3G;
            Reset_3G = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x39);
            Reset_3G = Reset_3G & 0xFD;
            SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x39, (UInt16)Reset_3G);
            Thread.Sleep(2000);
            Reset_3G = Reset_3G | 0x02;
            SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x39, (UInt16)Reset_3G);
        }

        private void Save_MCU_Button_Click(object sender, EventArgs e)
        {
            SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x28, 0x02);
        }

        private void Exit_Button_Click(object sender, EventArgs e)
        {
            upsTimer.Stop();
            this.Close();
        }

        private void WDT_Start_Button_Click(object sender, EventArgs e)
        {
            UInt16 WDT_Timer;
            UInt32 WDT_Value;
            WDT_Initial();

            WDT_Value = Inp32(0xA15);

            WDT_Timer = UInt16.Parse(WDT_Timer_TextBox.Text, System.Globalization.NumberStyles.HexNumber);
            Out32(0xA16, WDT_Timer);     // Set watchdog timer value

            WDT_Value = WDT_Value | 0x32;

            if (WDT_Min_RadioButton.Checked == true)
            {
                WDT_Value = WDT_Value | 0x08;
            }
            if (WDT_Sec_RadioButton.Checked == true)
            {
                WDT_Value = WDT_Value & 0xF7;
            }

            Out32(0xA15, WDT_Value);
            WDT_Start_Button.Enabled = false;
        }

        private void WDT_Stop_Button_Click(object sender, EventArgs e)
        {
            UInt32 WDT_Value;
            WDT_Initial();

            WDT_Value = Inp32(0xA15);
            WDT_Value = WDT_Value & 0xDF;
            WDT_Start_Button.Enabled = true;
            Out32(0xA15, WDT_Value);
        }

        private void upsTimer_Tick(object sender, EventArgs e)
        {
            RenderUps();
            System_Temp_TextBox.Text = SystemTemperature().ToString();
        }

        private void getCurrentPerCentButton_Click(object sender, EventArgs e)
        {
            setPerCentTextBox.Text = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x54).ToString();
        }

        private void setCurrentPerCentButton_Click(object sender, EventArgs e)
        {
            UInt16 percent;
            if (int.Parse(setPerCentTextBox.Text) > 100)
            {
                MessageBox.Show("Maximum % <= 100 %");
                setPerCentTextBox.Text = "0";
            }
            else if (int.Parse(setPerCentTextBox.Text) < 40)
            {
                MessageBox.Show("Minimum % >= 40 %");
                setPerCentTextBox.Text = "0";
            }
            else
            {
                percent = UInt16.Parse(setPerCentTextBox.Text);
                SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x54, percent);
            }
        }

        private void getUpsDelayOffButton_Click(object sender, EventArgs e)
        {
            UInt32 UPS_Min, UPS_Sec;
            UPS_Sec = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x72);
            UPS_Min = SMB_Read(SMBus_Base, SMBus_SlaveAddress, 0x73);
            upsDelayOffMinTextBox.Text = UPS_Min.ToString();
            upsDelayOffSecTextBox.Text = UPS_Sec.ToString();
        }

        private void setUpsDelayOffButton_Click(object sender, EventArgs e)
        {
            if (int.Parse(upsDelayOffMinTextBox.Text) < 0 || int.Parse(upsDelayOffMinTextBox.Text) > 25)
            {
                MessageBox.Show("Min enter:'0~25'");
                upsDelayOffMinTextBox.Text = "0";
            }
            else if (int.Parse(upsDelayOffSecTextBox.Text) < 0 || int.Parse(upsDelayOffSecTextBox.Text) > 59)
            {
                MessageBox.Show("Sec enter:'0~59'");
                upsDelayOffSecTextBox.Text = "0";
            }
            else
            {
                UInt16 UPS_Min, UPS_Sec;
                UPS_Min = UInt16.Parse(upsDelayOffMinTextBox.Text, System.Globalization.NumberStyles.Number);
                UPS_Sec = UInt16.Parse(upsDelayOffSecTextBox.Text, System.Globalization.NumberStyles.Number);
                SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x72, UPS_Sec);
                SMB_Write(SMBus_Base, SMBus_SlaveAddress, 0x73, UPS_Min);
            }
        }
    }
}