using GatewayTool.Businesses;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WjwLib.API.Configuration;
using GatewayTool.Models;
using System.Reflection;

namespace GatewayTool
{
    public partial class FormConfig : FormBase
    {
        private const string NAME = "Name";
        private const string VALUE = "Value";

        private SoftwareConfigs _softwareConfigs;
        private static IConfig config = new ConfigServer(ConfigType.CT_INI);

        public event EventHandler ExecConfigSaved;

        public FormConfig(ref SoftwareConfigs softwareConfigs)
        {
            InitializeComponent();
            this.IsMaximizable = false;
            this.IsMinimizable = false;
            this.Icon = Resource.favicon;
            this.ShowInTaskbar = false;
            _softwareConfigs = softwareConfigs;
        }

        private void InitStrings()
        {
            this.Title = StrMsg.Settings;
            tabPage1.Text = StrMsg.Net;
            lbServicePort.Text = StrMsg.ServicePort;

            tabPage2.Text = StrMsg.Log;
            lbShowMaxLine.Text = StrMsg.ShowMaxLine;
            lbFolderPath.Text = StrMsg.FolderPath;

            tabPage3.Text = StrMsg.DeviceSniff;
            lbRemotePort.Text = StrMsg.RemotePort;
            lbBaudRate.Text = StrMsg.Baudrate;
            lbDataBits.Text = StrMsg.Databits;
            lbStopBits.Text = StrMsg.Stopbits;
            lbParity.Text = StrMsg.Parity;
            btnDefault.Text = StrMsg.DefaultValue;
            btnOK.Text = StrMsg.MessageBoxButtonOK;
            btnCancel.Text = StrMsg.MessageBoxButtonCancel;
        }

        private void FormConfig_Load(object sender, EventArgs e)
        {
            InitComboxes();
            InitStrings();
            ModelToView();
        }

        private void InitComboxes()
        {
            InitCombox<EnumBaudrate>(cmbBaudRate, VALUE, VALUE);
            InitCombox<EnumDataBits>(cmbDataBits, VALUE, VALUE);
            InitCombox<EnumStopBits>(cmbStopBits, VALUE, VALUE);
            InitCombox<EnumCheckBit>(cmbParity, NAME, VALUE);
        }

        private void InitCombox<T>(ComboBox cmb, string displayMember, string valueMember)
        {
            cmb.Items.Clear();
            cmb.DataSource = GetDataTable<T>();
            cmb.DisplayMember = displayMember;
            cmb.ValueMember = valueMember;
        }

        private DataTable GetDataTable<T>()
        {
            Type t = typeof(T);  //创建类型
            FieldInfo[] fieldinfo = t.GetFields(); //获取字段信息对象集合

            DataTable table = new DataTable();
            table.Columns.Add("Name", typeof(String));
            table.Columns.Add("Value", typeof(Int32));

            foreach (FieldInfo field in fieldinfo)
            {
                if (!field.IsSpecialName)
                {
                    DataRow row = table.NewRow();
                    row[0] = field.Name;   //获取文本字段
                    row[1] = (int)field.GetRawConstantValue();  //获取int数值
                    table.Rows.Add(row);
                }
            }
            return table;
        }

        private void ModelToView()
        {
            numServicePort.Value = _softwareConfigs.ServicePortNum;
            numShowMaxLine.Value = _softwareConfigs.ShowLogMaxLine;
            txtFolderPath.Text = _softwareConfigs.LogFolderPath;
            numRemotePort.Value = _softwareConfigs.SniffRemotePortNum;
            cmbBaudRate.Text = Convert.ToInt32(Enum.Parse(typeof(EnumBaudrate), _softwareConfigs.SniffBaudRate.ToString())).ToString();
            cmbDataBits.Text = Convert.ToInt32(Enum.Parse(typeof(EnumDataBits), _softwareConfigs.SniffDataBits.ToString())).ToString();
            cmbStopBits.Text = Convert.ToInt32(Enum.Parse(typeof(EnumStopBits), _softwareConfigs.SniffStopBits.ToString())).ToString();
            cmbParity.Text = Enum.Parse(typeof(EnumCheckBit), _softwareConfigs.SniffParity.ToString()).ToString();
        }

        private void ViewToModel()
        {
            _softwareConfigs.ServicePortNum = Convert.ToInt32(numServicePort.Value);
            _softwareConfigs.ShowLogMaxLine = Convert.ToInt32(numShowMaxLine.Value);
            _softwareConfigs.LogFolderPath = txtFolderPath.Text.Trim();
            _softwareConfigs.SniffRemotePortNum = Convert.ToInt32(numRemotePort.Value);
            _softwareConfigs.SniffBaudRate = (EnumBaudrate)cmbBaudRate.SelectedValue;
            _softwareConfigs.SniffDataBits = (EnumDataBits)cmbDataBits.SelectedValue;
            _softwareConfigs.SniffStopBits = (EnumStopBits)cmbStopBits.SelectedValue;
            _softwareConfigs.SniffParity = (EnumCheckBit)cmbParity.SelectedValue;
        }

        private void DefaultToModel()
        {
            SoftwareConfigs defaultConfig = new SoftwareConfigs();
            _softwareConfigs.ServicePortNum = defaultConfig.ServicePortNum;
            _softwareConfigs.ShowLogMaxLine = defaultConfig.ShowLogMaxLine;
            _softwareConfigs.LogFolderPath = defaultConfig.LogFolderPath;
            _softwareConfigs.SniffRemotePortNum = defaultConfig.SniffRemotePortNum;
            _softwareConfigs.SniffBaudRate = defaultConfig.SniffBaudRate;
            _softwareConfigs.SniffDataBits = defaultConfig.SniffDataBits;
            _softwareConfigs.SniffStopBits = defaultConfig.SniffStopBits;
            _softwareConfigs.SniffParity = defaultConfig.SniffParity;
        }

        public static void ConfigToModel(ref SoftwareConfigs softwareConfigs)
        {
            try
            {
                softwareConfigs.ServicePortNum = Convert.ToInt32(config.ReadConfig("Net", "ServicePortNum", softwareConfigs.ConfigFilePath));
                softwareConfigs.ShowLogMaxLine = Convert.ToInt32(config.ReadConfig("Log", "ShowLogMaxLine", softwareConfigs.ConfigFilePath));
                softwareConfigs.LogFolderPath = config.ReadConfig("Log", "LogFolderPath", softwareConfigs.ConfigFilePath);
                softwareConfigs.SniffRemotePortNum = Convert.ToInt32(config.ReadConfig("Sniff", "SniffRemotePortNum", softwareConfigs.ConfigFilePath));
                softwareConfigs.SniffBaudRate = (EnumBaudrate)Enum.Parse(typeof(EnumBaudrate), config.ReadConfig("Sniff", "SniffBaudRate", softwareConfigs.ConfigFilePath));
                softwareConfigs.SniffDataBits = (EnumDataBits)Enum.Parse(typeof(EnumDataBits), config.ReadConfig("Sniff", "SniffDataBits", softwareConfigs.ConfigFilePath));
                softwareConfigs.SniffStopBits = (EnumStopBits)Enum.Parse(typeof(EnumStopBits), config.ReadConfig("Sniff", "SniffStopBits", softwareConfigs.ConfigFilePath));
                softwareConfigs.SniffParity = (EnumCheckBit)Enum.Parse(typeof(EnumCheckBit), config.ReadConfig("Sniff", "SniffParity", softwareConfigs.ConfigFilePath));
            }
            catch { }
        }

        private bool SaveConfigs()
        {
            if (_softwareConfigs == null) return false;
            try
            {
                ViewToModel();
                bool res = config.WriteConfig("Net", "ServicePortNum", _softwareConfigs.ServicePortNum.ToString(), _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Log", "ShowLogMaxLine", _softwareConfigs.ShowLogMaxLine.ToString(), _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Log", "LogFolderPath", _softwareConfigs.LogFolderPath, _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Sniff", "SniffRemotePortNum", _softwareConfigs.SniffRemotePortNum.ToString(), _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Sniff", "SniffBaudRate", _softwareConfigs.SniffBaudRate.ToString(), _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Sniff", "SniffDataBits", _softwareConfigs.SniffDataBits.ToString(), _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Sniff", "SniffStopBits", _softwareConfigs.SniffStopBits.ToString(), _softwareConfigs.ConfigFilePath);
                if (res) res = config.WriteConfig("Sniff", "SniffParity", _softwareConfigs.SniffParity.ToString(), _softwareConfigs.ConfigFilePath);
                return res;
            }
            catch
            {
                return false;
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (SaveConfigs())
            {
                ExecConfigSaved?.Invoke(sender, e);
                MessageBox.Show(StrMsg.SaveConfigOK, StrMsg.Prompt, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show(StrMsg.SaveConfigFail, StrMsg.Attention, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderDlg = new FolderBrowserDialog();
            if (folderDlg.ShowDialog() == DialogResult.OK)
            {
                txtFolderPath.Text = folderDlg.SelectedPath;
            }
        }

        private void btnDefault_Click(object sender, EventArgs e)
        {
            DefaultToModel();
            ModelToView();
        }
    }
}