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.IO.Ports;

namespace VTK_RELAY_01_Utility
{
    public partial class Form1 : Form
    {
        private uint m_nStep = 0;
        private uint nSystemCount = 0;

        public Form1()
        {
            InitializeComponent();

            m_nStep = 0;
            nSystemCount = 0;

            string[] ports = SerialPort.GetPortNames();
            List<string> listPorts = new List<string>(ports);
            Comparison<string> comparer = delegate(string name1, string name2)
            {
                int port1 = Convert.ToInt32(name1.Remove(0, 3));
                int port2 = Convert.ToInt32(name2.Remove(0, 3));
                return port1 - port2;
            };
            listPorts.Sort(comparer);
            comboBox_PortNum.Items.Clear();
            comboBox_PortNum.Items.AddRange(listPorts.ToArray());
            if (comboBox_PortNum.Items.Count > 0)
                comboBox_PortNum.SelectedIndex = 0;

            comboBox_GPI12Level.Items.Clear();
            comboBox_GPI12Level.Items.Add("GPI Active Low");
            comboBox_GPI12Level.Items.Add("GPI Active High");
            comboBox_GPI12Level.SelectedIndex = 0;

            comboBox_GPI34Level.Items.Clear();
            comboBox_GPI34Level.Items.Add("GPI Active Low");
            comboBox_GPI34Level.Items.Add("GPI Active High");
            comboBox_GPI34Level.SelectedIndex = 0;

            comboBox_GPO12PullUp.Items.Clear();
            comboBox_GPO12PullUp.Items.Add("Internal");
            comboBox_GPO12PullUp.Items.Add("External");
            comboBox_GPO12PullUp.SelectedIndex = 0;

            comboBox_GPO34PullUp.Items.Clear();
            comboBox_GPO34PullUp.Items.Add("Internal");
            comboBox_GPO34PullUp.Items.Add("External");
            comboBox_GPO34PullUp.SelectedIndex = 0;

            comboBox_GPO1.Items.Clear();
            comboBox_GPO1.Items.Add("Low");
            comboBox_GPO1.Items.Add("High");
            comboBox_GPO1.SelectedIndex = 1;

            comboBox_GPO2.Items.Clear();
            comboBox_GPO2.Items.Add("Low");
            comboBox_GPO2.Items.Add("High");
            comboBox_GPO2.SelectedIndex = 1;

            comboBox_GPO3.Items.Clear();
            comboBox_GPO3.Items.Add("Low");
            comboBox_GPO3.Items.Add("High");
            comboBox_GPO3.SelectedIndex = 1;

            comboBox_GPO4.Items.Clear();
            comboBox_GPO4.Items.Add("Low");
            comboBox_GPO4.Items.Add("High");
            comboBox_GPO4.SelectedIndex = 1;

            comboBox_Relay1.Items.Clear();
            comboBox_Relay1.Items.Add("OFF");
            comboBox_Relay1.Items.Add("ON");
            comboBox_Relay1.SelectedIndex = 0;

            comboBox_Relay2.Items.Clear();
            comboBox_Relay2.Items.Add("OFF");
            comboBox_Relay2.Items.Add("ON");
            comboBox_Relay2.SelectedIndex = 0;

            comboBox_Relay3.Items.Clear();
            comboBox_Relay3.Items.Add("OFF");
            comboBox_Relay3.Items.Add("ON");
            comboBox_Relay3.SelectedIndex = 0;

            comboBox_Relay4.Items.Clear();
            comboBox_Relay4.Items.Add("OFF");
            comboBox_Relay4.Items.Add("ON");
            comboBox_Relay4.SelectedIndex = 0;

            int nMajorVersion = 0;
            int nMinorVersion = 0;
            VTK_RELAY_01.ExIO_Get_DLL_Version(ref nMajorVersion, ref nMinorVersion);
            textBox_Message.Text = "DLL ver : " + nMajorVersion + "." + nMinorVersion;

            DisableButtonWhenClose();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            button_Close_Click(this, e);
        }

        private void fnGetMCUVersion()
        {
            int nMCUVersion = 0;
            int nResult = VTK_RELAY_01.ExIO_GetMCUVersion(ref nMCUVersion);
            if (nResult == 1)
            {
                textBox_MCU_Version.Text = "VK50_R" + nMCUVersion.ToString("D2");
            }
            else
            {
                textBox_MCU_Version.Text = "?";
            }
        }

        private void fnGetIgnitionStatus()
        {
            int nIgnitionStatus = 0;
            int nResult = VTK_RELAY_01.ExIO_GetIgnitionStatus(ref nIgnitionStatus);
            if (nResult == 1)
            {
                switch (nIgnitionStatus)
                {
                    case 0: textBox_Ignition.Text = "OFF"; break;
                    case 1: textBox_Ignition.Text = "ON"; break;
                    default: textBox_Ignition.Text = "Undefined"; break;
                }
            }
            else
            {
                textBox_Ignition.Text = "?";
            }
        }

        private void fnGetSupplyVoltage()
        {
            int nSupplyVoltage = 0;
            int nResult = VTK_RELAY_01.ExIO_GetSupplyVoltage(ref nSupplyVoltage);
            if (nResult == 1)
            {
                double fVoltage = (double)nSupplyVoltage / 1000;
                textBox_SupplyVoltage.Text = fVoltage.ToString("F01") + " V";
            }
            else
            {
                textBox_SupplyVoltage.Text = "?";
            }
        }

        private void fnGetExtGPILevel()
        {
            int nGPI12 = 0;
            int nGPI34 = 0;

            int nResult = VTK_RELAY_01.ExIO_GetExtGPILevel(ref nGPI12, ref nGPI34);
            if (nResult == 1)
            {
                switch (nGPI12)
                {
                    case 0: textBox_GPI12Level.Text = "GPI Active Low"; break;
                    case 1: textBox_GPI12Level.Text = "GPI Active High"; break;
                    default: textBox_GPI12Level.Text = "Undefined"; break;
                }

                switch (nGPI34)
                {
                    case 0: textBox_GPI34Level.Text = "GPI Active Low"; break;
                    case 1: textBox_GPI34Level.Text = "GPI Active High"; break;
                    default: textBox_GPI34Level.Text = "Undefined"; break;
                }
            }
            else
            {
                textBox_GPI12Level.Text = "?";
                textBox_GPI34Level.Text = "?";
            }
        }

        private void fnGetExtGPOPullUp()
        {
            int nGPO12 = 0;
            int nGPO34 = 0;

            int nResult = VTK_RELAY_01.ExIO_GetExtGPOPullUp(ref nGPO12, ref nGPO34);
            if (nResult == 1)
            {
                switch (nGPO12)
                {
                    case 0: textBox_GPO12PullUp.Text = "Internal"; break;
                    case 1: textBox_GPO12PullUp.Text = "External"; break;
                    default: textBox_GPO12PullUp.Text = "Undefined"; break;
                }

                switch (nGPO34)
                {
                    case 0: textBox_GPO34PullUp.Text = "Internal"; break;
                    case 1: textBox_GPO34PullUp.Text = "External"; break;
                    default: textBox_GPO34PullUp.Text = "Undefined"; break;
                }
            }
            else
            {
                textBox_GPO12PullUp.Text = "?";
                textBox_GPO34PullUp.Text = "?";
            }
        }

        private void fnGetExtGPIStatus()
        {
	        int nGPI1 = 0;
	        int nGPI2 = 0;
	        int nGPI3 = 0;
	        int nGPI4 = 0;

            int nResult = VTK_RELAY_01.ExIO_GetExtGPIStatus(ref nGPI1, ref nGPI2, ref nGPI3, ref nGPI4);
	        if( nResult == 1 )
	        {
		        switch(nGPI1)
		        {
		        case 0: textBox_GPI1.Text = "Low"; break;
		        case 1: textBox_GPI1.Text = "High"; break;
		        default: textBox_GPI1.Text = "Undefined"; break;
		        }

		        switch(nGPI2)
		        {
		        case 0: textBox_GPI2.Text = "Low"; break;
		        case 1: textBox_GPI2.Text = "High"; break;
		        default: textBox_GPI2.Text = "Undefined"; break;
		        }

		        switch(nGPI3)
		        {
		        case 0: textBox_GPI3.Text = "Low"; break;
		        case 1: textBox_GPI3.Text = "High"; break;
		        default: textBox_GPI3.Text = "Undefined"; break;
		        }

		        switch(nGPI4)
		        {
		        case 0: textBox_GPI4.Text = "Low"; break;
		        case 1: textBox_GPI4.Text = "High"; break;
		        default: textBox_GPI4.Text = "Undefined"; break;
		        }
	        }
	        else
	        {
                textBox_GPI1.Text = "?";
                textBox_GPI2.Text = "?";
                textBox_GPI3.Text = "?";
                textBox_GPI4.Text = "?";
	        }
        }

        private void fnGetExtGPOStatus()
        {
	        int nGPO1 = 0;
            int nGPO2 = 0;
            int nGPO3 = 0;
            int nGPO4 = 0;

            int nResult = VTK_RELAY_01.ExIO_GetExtGPOStatus(ref nGPO1, ref nGPO2, ref nGPO3, ref nGPO4);
	        if( nResult == 1 )
	        {
		        switch(nGPO1)
		        {
		        case 0: textBox_GPO1.Text = "Low"; break;
		        case 1: textBox_GPO1.Text = "High"; break;
		        default: textBox_GPO1.Text = "Undefined"; break;
		        }

		        switch(nGPO2)
		        {
		        case 0: textBox_GPO2.Text = "Low"; break;
		        case 1: textBox_GPO2.Text = "High"; break;
		        default: textBox_GPO2.Text = "Undefined"; break;
		        }

		        switch(nGPO3)
		        {
		        case 0: textBox_GPO3.Text = "Low"; break;
		        case 1: textBox_GPO3.Text = "High"; break;
		        default: textBox_GPO3.Text = "Undefined"; break;
		        }

		        switch(nGPO4)
		        {
		        case 0: textBox_GPO4.Text = "Low"; break;
		        case 1: textBox_GPO4.Text = "High"; break;
		        default: textBox_GPO4.Text = "Undefined"; break;
		        }
	        }
	        else
	        {
                textBox_GPO1.Text = "?";
                textBox_GPO2.Text = "?";
                textBox_GPO3.Text = "?";
                textBox_GPO4.Text = "?";
	        }
        }

        private void fnGetRelayStatus()
        {
            int nRelay1 = 0;
            int nRelay2 = 0;
            int nRelay3 = 0;
            int nRelay4 = 0;

            int nResult = VTK_RELAY_01.ExIO_GetRelayStatus(ref nRelay1, ref nRelay2, ref nRelay3, ref nRelay4);
	        if( nResult == 1 )
	        {
		        switch(nRelay1)
		        {
		        case 0: textBox_Relay1.Text = "OFF"; break;
		        case 1: textBox_Relay1.Text = "ON"; break;
		        default: textBox_Relay1.Text = "Undefined"; break;
		        }

		        switch(nRelay2)
		        {
		        case 0: textBox_Relay2.Text = "OFF"; break;
		        case 1: textBox_Relay2.Text = "ON"; break;
		        default: textBox_Relay2.Text = "Undefined"; break;
		        }

		        switch(nRelay3)
		        {
		        case 0: textBox_Relay3.Text = "OFF"; break;
		        case 1: textBox_Relay3.Text = "ON"; break;
		        default: textBox_Relay3.Text = "Undefined"; break;
		        }

		        switch(nRelay4)
		        {
		        case 0: textBox_Relay4.Text = "OFF"; break;
		        case 1: textBox_Relay4.Text = "ON"; break;
		        default: textBox_Relay4.Text = "Undefined"; break;
		        }
	        }
	        else
	        {
                textBox_Relay1.Text = "?";
                textBox_Relay2.Text = "?";
                textBox_Relay3.Text = "?";
                textBox_Relay4.Text = "?";
	        }
        }

        private void fnGetInputCurrent()
        {
	        int nInputCurrent = 0;
            int nResult = VTK_RELAY_01.ExIO_GetInputCurrent(ref nInputCurrent);
	        if( nResult == 1 )
	        {
                textBox_InputCurrent.Text = nInputCurrent.ToString() + " mA";
	        }
	        else
	        {
                textBox_InputCurrent.Text = "? mA";
	        }
        }

        private void fnGetInputVoltage()
        {
            int nInputVoltage = 0;
            int nResult = VTK_RELAY_01.ExIO_GetInputVoltage(ref nInputVoltage);
            if (nResult == 1)
            {
                double fVoltage = (double)nInputVoltage / 1000;
                textBox_InputVoltage.Text = fVoltage.ToString("F01") + " V";
            }
            else
            {
                textBox_InputVoltage.Text = "?";
            }
        }

        private void fnGetInputFrequency()
        {
	        int nInputFrequency = 0;
            int nResult = VTK_RELAY_01.ExIO_GetInputFrequency(ref nInputFrequency);
	        if( nResult == 1 )
	        {
                textBox_InputFrequency.Text = nInputFrequency.ToString() + " Hz";
	        }
	        else
	        {
                textBox_InputFrequency.Text = "? Hz";
	        }
        }

        private void button_Open_Click(object sender, EventArgs e)
        {
            if (comboBox_PortNum.Items.Count == 0)
            {
                System.Windows.Forms.MessageBox.Show("No items found!!!");
                return;
            }

            if (comboBox_PortNum.SelectedItem == null)
            {
                System.Windows.Forms.MessageBox.Show("Please select an item!!!");
                return;
            }

            string strPortName = comboBox_PortNum.GetItemText(comboBox_PortNum.SelectedItem);

            int nSerialPortNum = Convert.ToInt32(strPortName.Remove(0, 3));

            if (1 != VTK_RELAY_01.ExIO_Connect(nSerialPortNum))
            {
                System.Windows.Forms.MessageBox.Show("Connect to device failed!!!");
            }
            else
            {
#if DEBUG
                string strDLLVersion;
                int nMajorVersion = 0;
                int nMinorVersion = 0;
                VTK_RELAY_01.ExIO_Get_DLL_Version(ref nMajorVersion, ref nMinorVersion);
                strDLLVersion = "DLL ver : " + nMajorVersion + "." + nMinorVersion;

                string strDTPVersion;
                int nDTPVersion = 0;
                int nResult = VTK_RELAY_01.ExIO_GetDTPVersion(ref nDTPVersion);
                if (nResult == 1)
                {
                    strDTPVersion = "MCU DTP : " + nDTPVersion;
                }
                else
                {
                    strDTPVersion = "MCU DTP : ?";
                }

                string strBLVersion;
                int nBLVersion = 0;
                nResult = VTK_RELAY_01.ExIO_GetBLVersion(ref nBLVersion);
                if (nResult == 1)
                {
                    strBLVersion = "MCU BL : " + nBLVersion;
                }
                else
                {
                    strBLVersion = "MCU BL : ?";
                }

                string strDTPType;
                int nDTPType = 0;
                nResult = VTK_RELAY_01.ExIO_GetDTPType(ref nDTPType);
                if (nResult == 1)
                {
                    strDTPType = "MCU DTP type : " + nDTPType;
                }
                else
                {
                    strDTPType = "MCU DTP type : ?";
                }

                textBox_Message.Text = strDLLVersion + ", " + strDTPVersion + ", " + strBLVersion + ", " + strDTPType;
#endif

                m_nStep = 0;
                timer1.Interval = 100;
                timer1.Start();
                EnableButtonWhenOpen();
            }
        }

        private void button_Close_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            timer2.Stop();

            VTK_RELAY_01.ExIO_Disconnect();

            DisableButtonWhenClose();
        }

        private void button_GPOPullUp_Click(object sender, EventArgs e)
        {
            int nGPO12 = comboBox_GPO12PullUp.SelectedIndex;
            int nGPO34 = comboBox_GPO34PullUp.SelectedIndex;

            int nResult = VTK_RELAY_01.ExIO_SetExtGPOPullUpControl(nGPO12, nGPO34);
            if (nResult == 1)
            {
                textBox_Message.Text = "Set GPO Pull-Up Success.";

                fnGetExtGPOPullUp();
            }
            else
            {
                textBox_Message.Text = "Set GPO Pull-Up Failed!!!";
            }
        }

        private void button_GPILevel_Click(object sender, EventArgs e)
        {
            int nGPI12 = comboBox_GPI12Level.SelectedIndex;
            int nGPI34 = comboBox_GPI34Level.SelectedIndex;

            int nResult = VTK_RELAY_01.ExIO_SetExtGPILevelControl(nGPI12, nGPI34);
            if (nResult == 1)
            {
                textBox_Message.Text = "Set GPI Level Success.";

                fnGetExtGPILevel();
            }
            else
            {
                textBox_Message.Text = "Set GPI Level Failed!!!";
            }
        }

        private void button_GPO_Click(object sender, EventArgs e)
        {
            int nGPO1 = comboBox_GPO1.SelectedIndex;
            int nGPO2 = comboBox_GPO2.SelectedIndex;
            int nGPO3 = comboBox_GPO3.SelectedIndex;
            int nGPO4 = comboBox_GPO4.SelectedIndex;

            int nResult = VTK_RELAY_01.ExIO_SetExtGPOControl(nGPO1, nGPO2, nGPO3, nGPO4);
            if (nResult == 1)
            {
                textBox_Message.Text = "Set Ext GPO Success.";

                fnGetExtGPOStatus();
            }
            else
            {
                textBox_Message.Text = "Set Ext GPO Failed!!!";
            }
        }

        private void button_GPI_Click(object sender, EventArgs e)
        {
            fnGetExtGPIStatus();
        }

        private void button_Relay_Click(object sender, EventArgs e)
        {
            int nRelay1 = comboBox_Relay1.SelectedIndex;
            int nRelay2 = comboBox_Relay2.SelectedIndex;
            int nRelay3 = comboBox_Relay3.SelectedIndex;
            int nRelay4 = comboBox_Relay4.SelectedIndex;

            int nResult = VTK_RELAY_01.ExIO_SetRelayControl(nRelay1, nRelay2, nRelay3, nRelay4);
            if (nResult == 1)
            {
                textBox_Message.Text = "Set Relay Success.";

                fnGetRelayStatus();
            }
            else
            {
                textBox_Message.Text = "Set Relay Failed!!!";
            }
        }

        private void button_InputCurrent_Click(object sender, EventArgs e)
        {
            fnGetInputCurrent();
        }

        private void button_InputVoltage_Click(object sender, EventArgs e)
        {
            fnGetInputVoltage();
        }

        private void button_InputFrequency_Click(object sender, EventArgs e)
        {
            fnGetInputFrequency();
        }

        private void button_Save_Click(object sender, EventArgs e)
        {
            int nResult = VTK_RELAY_01.ExIO_SetFlashUpdate();
            if (nResult == 1)
            {
                System.Windows.Forms.MessageBox.Show("Settings saved successfully.");
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Save settings failed!!!");
            }
        }

        // ================================================================================================================================================
        // Enable or disable all buttons
        // ================================================================================================================================================
        private void DisableButtonWhenClose()
        {
            button_GPOPullUp.Enabled = false;
            button_GPILevel.Enabled = false;
            button_GPO.Enabled = false;
            button_GPI.Enabled = false;
            button_Relay.Enabled = false;
            button_InputCurrent.Enabled = false;
            button_InputVoltage.Enabled = false;
            button_InputFrequency.Enabled = false;
            button_Save.Enabled = false;
            button_Close.Enabled = false;

            // Open Button
            button_Open.Enabled = true;
        }

        private void EnableButtonWhenOpen()
        {
            button_GPOPullUp.Enabled = true;
            button_GPILevel.Enabled = true;
            button_GPO.Enabled = true;
            button_GPI.Enabled = true;
            button_Relay.Enabled = true;
            button_InputCurrent.Enabled = true;
            button_InputVoltage.Enabled = true;
            button_InputFrequency.Enabled = true;
            button_Save.Enabled = true;
            button_Close.Enabled = true;

            // Open Button
            button_Open.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();

            switch (m_nStep)
            {
                case 0: fnGetMCUVersion(); m_nStep++; break;
                case 1: fnGetIgnitionStatus(); m_nStep++; break;
                case 2: fnGetSupplyVoltage(); m_nStep++; break;
                case 3: fnGetExtGPILevel(); m_nStep++; break;
                case 4: fnGetExtGPOPullUp(); m_nStep++; break;
                case 5: fnGetExtGPIStatus(); m_nStep++; break;
                case 6: fnGetExtGPOStatus(); m_nStep++; break;
                case 7: fnGetRelayStatus(); m_nStep++; break;
                case 8: fnGetInputCurrent(); m_nStep++; break;
                case 9: fnGetInputVoltage(); m_nStep++; break;
                case 10: fnGetInputFrequency(); m_nStep++; break;
                default: break;
            }

            if (m_nStep < 11)
            {
                timer1.Interval = 100;
                timer1.Start();
            }
            else
            {
                timer2.Interval = 100;
                timer2.Start();
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            timer2.Stop();

            switch (nSystemCount % 6)
            {
                case 0: fnGetIgnitionStatus(); break;
                case 1: fnGetSupplyVoltage(); break;
                case 2: fnGetExtGPIStatus(); break;
                case 3: fnGetInputCurrent(); break;
                case 4: fnGetInputVoltage(); break;
                case 5: fnGetInputFrequency(); break;
            }

            nSystemCount++;

            timer2.Interval = 200;
            timer2.Start();
        }
    }
}
