using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Runtime.InteropServices;
using System.IO;

using LFP_Manager.DataStructure;

namespace LFP_Manager.Function
{
    class csIniControlFunction
    {
        #region [Function] INI File Read Function(Section Setting)
        public static string[] GetIniValue(string Section, string path)
        {
            byte[] ba = new byte[5000];
            uint Flag = GetPrivateProfileSection(Section, ba, 5000, path);
            return Encoding.Default.GetString(ba).Split(new char[1] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
        }
        #endregion

        #region [Function] INI File Read Function(Section and Key Setting)
        public static string GetIniValue(string Section, string key, string path)
        {
            StringBuilder sb = new StringBuilder(500);
            int Flag = GetPrivateProfileString(Section, key, "", sb, 500, path);
            return sb.ToString();
        }
        #endregion

        #region [Function] INI File Read Function(Section, Key, Value, Address Setting)
        public bool SetIniValue(string Section, string Key, string Value, string path)
        {
            return (WritePrivateProfileString(Section, Key, Value, path));
        }
        #endregion

        #region [DLL Function] INI DLL Load
        [DllImport("kernel32")]
        public static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
        [DllImport("kernel32")]
        public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
        [DllImport("kernel32")]
        public static extern uint GetPrivateProfileInt(string lpAppName, string lpKeName, int nDefault, string lpFileName);
        [DllImport("kernel32")]
        public static extern uint GetPrivateProfileSection(string lpAppName, byte[] lpPairValues, uint nSize, string lpFileName);
        [DllImport("kernel32")]
        public static extern uint GetPrivateProfileSectionNames(byte[] lpSections, uint nSize, string lpFileName);
        #endregion

        public static DateTime Delay(int MS)
        {
            DateTime thisMoment = DateTime.Now;
            TimeSpan duration = new TimeSpan(0, 0, 0, 0, MS);
            DateTime afterMoment = thisMoment.Add(duration);

            while (afterMoment >= thisMoment)
            {
                System.Windows.Forms.Application.DoEvents();

                thisMoment = DateTime.Now;
            }

            return DateTime.Now;
        }

        public static void IniLoad(string AppPath, ref CommConfig rConfig)
        {
            string path;

            path = System.IO.Path.GetDirectoryName(AppPath);

            if (File.Exists(String.Format("{0}\\CommSet.ini", path)))
            {
                StringBuilder ret = new StringBuilder();
                string InIPath = String.Format("{0}\\CommSet.ini", path);

                // CommType = 0: RS-485, 1: SNMP
                rConfig.CommType = (int)csIniControlFunction.GetPrivateProfileInt("COMM TYPE", "TYPE", 0, InIPath);

                // SNMP Config
                // IP
                ret.Clear();
                csIniControlFunction.GetPrivateProfileString("SNMP", "IP", "(NONE)", ret, 32, InIPath);
                rConfig.SnmpIP = ret.ToString();
                // Model
                rConfig.SnmpModelIndex = (int)csIniControlFunction.GetPrivateProfileInt("SNMP", "MODEL", 2, InIPath);

                // Serial Port Config
                // PORT
                ret.Clear();
                csIniControlFunction.GetPrivateProfileString("UART", "PORT", "(NONE)", ret, 32, InIPath);
                rConfig.UartPort = ret.ToString();
                // MODEL
                rConfig.UartModelIndex = (int)csIniControlFunction.GetPrivateProfileInt("UART", "MODEL", 0, InIPath);

                // Module Qunatity = 1 - 16
                rConfig.ModuleQty = (int)csIniControlFunction.GetPrivateProfileInt("UART", "MODULE_QTY", 1, InIPath);

                // PROTOCOL
                rConfig.UartProtocol = (int)csIniControlFunction.GetPrivateProfileInt("UART", "PROTOCOL", 0, InIPath);

                // PROTOCOL
                rConfig.RecvWaitTime = (int)csIniControlFunction.GetPrivateProfileInt("UART", "RECV_WAIT_TIME", 1500, InIPath);

                // Etc. Config
                rConfig.DbLogPeriod = (int)csIniControlFunction.GetPrivateProfileInt("DATABASE", "LOG_PERIOD", 1, InIPath);

                // Gyro. Config
                rConfig.GyroSensitive = (int)csIniControlFunction.GetPrivateProfileInt("GYRO", "SENSITIVITY", 120, InIPath);

                try
                {
                    // ENABLE PASSWORD
                    ret.Clear();
                    csIniControlFunction.GetPrivateProfileString("PW", "MASTER", CsCryptoHelper.Encrypt("8003"), ret, 32, InIPath);
                    rConfig.MasterPw = CsCryptoHelper.Decrypt(ret.ToString());
                    // DISABLE PASSWORD
                    ret.Clear();
                    csIniControlFunction.GetPrivateProfileString("PW", "ENGINEER", CsCryptoHelper.Encrypt("7003"), ret, 32, InIPath);
                    rConfig.EngineerPw = CsCryptoHelper.Decrypt(ret.ToString());
                    // LEVEL PASSWORD
                    ret.Clear();
                    csIniControlFunction.GetPrivateProfileString("PW", "TECHNICIAN", CsCryptoHelper.Encrypt("6003"), ret, 32, InIPath);
                    rConfig.TechnicianPw = CsCryptoHelper.Decrypt(ret.ToString());
                }
                catch (Exception)
                {
                    rConfig.MasterPw = "8003";
                    rConfig.EngineerPw = "7003";
                    rConfig.TechnicianPw = "6003";
                }
            }
            else
            {
                rConfig.CommType = 0;

                rConfig.SnmpIP = "192.168.0.200";
                rConfig.SnmpModelIndex = 0;

                rConfig.UartPort = "";
                rConfig.UartProtocol= 0;
                rConfig.RecvWaitTime = 1500;

                rConfig.DbLogPeriod = 5;

                rConfig.GyroSensitive = 120;

                rConfig.MasterPw = "8003";
                rConfig.EngineerPw = "7003";
                rConfig.TechnicianPw = "6003";
            }
        }

        public static void IniSave(string AppPath, CommConfig aConfig)
        {
            string path = Path.GetDirectoryName(AppPath);
            string InIPath = String.Format("{0}\\CommSet.ini", path);

            // write ini

            // CommType = 0: SNMP, 1: RS-485
            WritePrivateProfileString("COMM TYPE", "TYPE", aConfig.CommType.ToString(), InIPath);

            // SNMP Config
            // IP
            WritePrivateProfileString("SNMP", "IP", aConfig.SnmpIP, InIPath);
            // Model
            WritePrivateProfileString("SNMP", "MODEL", aConfig.SnmpModelIndex.ToString(), InIPath);

            // Serial Port Config
            // PORT
            WritePrivateProfileString("UART", "PORT", aConfig.UartPort, InIPath);
            // MODEL
            WritePrivateProfileString("UART", "MODEL", aConfig.UartModelIndex.ToString(), InIPath);
            // MODULE QTY = 1 - 16
            WritePrivateProfileString("UART", "MODULE_QTY", aConfig.ModuleQty.ToString(), InIPath);
            // PROTOCOL
            WritePrivateProfileString("UART", "PROTOCOL", aConfig.UartProtocol.ToString(), InIPath);
            // RECV_WAIT_TIME
            WritePrivateProfileString("UART", "RECV_WAIT_TIME", aConfig.RecvWaitTime.ToString(), InIPath);

            // Etc Config
            WritePrivateProfileString("DATABASE", "LOG_PERIOD", aConfig.DbLogPeriod.ToString(), InIPath);

            // Gyro Config
            WritePrivateProfileString("GYRO", "SENSITIVITY", aConfig.GyroSensitive.ToString(), InIPath);

            // MASTER PASSWORD
            WritePrivateProfileString("PW", "MASTER", CsCryptoHelper.Encrypt(aConfig.MasterPw), InIPath);
            // ENGINEER PASSWORD
            WritePrivateProfileString("PW", "ENGINEER", CsCryptoHelper.Encrypt(aConfig.EngineerPw), InIPath);
            // TECHNICIAN PASSWORD
            WritePrivateProfileString("PW", "TECHNICIAN", CsCryptoHelper.Encrypt(aConfig.TechnicianPw), InIPath);
        }
    }
}
