using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotNettyFrom.common;
using DotNettyFrom.config;
using DotNettyFrom.db;
using DotNettyFrom.dialog;
using DotNettyFrom.form;
using DotNettyFrom.generatecmd;
using DotNettyFrom.netty;
using DotNettyFrom.util;

namespace DotNettyFrom
{
    public partial class MainForm : Form
    {
        #region 属性

        private NettyClient _nettyClient;
        private string host;
        private int port;

        #endregion


        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            if (!CheckUtil.CheckDbFileIsExits())
            {
                MessageBox.Show("Access数据库文件不存在! 强制退出程序!");
                Application.Exit();
            }

            DbHelper.Init();

            UpdateUiComponent();

            ChangeDtu();

            TbDeviceId.Text = SystemConfig.DefaultNo;


            var consumer = Task.Factory.StartNew(() =>
            {
                foreach (UIInfoModel value in DataModel.ReceCollection.GetConsumingEnumerable())
                {
                    Invoke(new ThreadStart(delegate { CallUI(value); }));
                }
            });
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            DbHelper.GetInstance().CloseAccessDb();
        }


        private void CallUI(UIInfoModel value)
        {
            if (value.cmdId != SystemConfig.HeartbeatDownCmdCode)
            {
                LBLogShow.Items.Add(value);
            }
            else
            {
                if (SystemConfig.IsLogHeartBeatInfo)
                {
                    LBLogShow.Items.Add(value);
                }
            }
            LBLogShow.TopIndex = LBLogShow.Items.Count - 1;
            if (LBLogShow.Items.Count > SystemConfig.LBLogShowClearCount)
            {
                LBLogShow.Items.RemoveAt(0);
            }
            switch (value.action)
            {
                case -1: //连接不上,服务器没开启
                    break;
                case 1: //连接成功.ChannelActive
                    ConnectionActive();
                    break;
                case 2: //连接断开 ChannelInactive
                    ConnectionInActive();
                    break;
                case 3: //异常. ExceptionCaught
                    break;
            }
        }

        private void ConnectionActive()
        {
            TbHost.ReadOnly = true;
            TbPort.ReadOnly = true;
            TbDeviceId.ReadOnly = true;
            TbCCID.ReadOnly = true;

            BtnConnection.Enabled = false;
            BtnLogin.Enabled = false;

            BtnDisConn.Enabled = true;
            BtnSendData.Enabled = true;

            water2ToolStripMenuItem.Enabled = false;
            dtuToolStripMenuItem.Enabled = false;
        }


        private void ConnectionInActive()
        {
            TbHost.ReadOnly = false;
            TbPort.ReadOnly = false;
            TbDeviceId.ReadOnly = false;
            TbCCID.ReadOnly = false;

            BtnConnection.Enabled = true;
            BtnLogin.Enabled = true;

            BtnDisConn.Enabled = false;
            BtnSendData.Enabled = false;


            water2ToolStripMenuItem.Enabled = true;
            dtuToolStripMenuItem.Enabled = true;
        }

        private void BeforeConnection()
        {
            try
            {
                IPAddress[] hostAddresses = Dns.GetHostAddresses(TbHost.Text.Trim());
                IPAddress hostAddress = hostAddresses[0];
                this.host = hostAddress.ToString();
                this.port = int.Parse(TbPort.Text.Trim());

                //设置地址
                CmdGenetor.Genetor.DeviceId = TbDeviceId.Text.Trim();

                UpdateUiComponent();
            }
            catch (SocketException exception)
            {
                MessageBox.Show(exception.Message);
            }
        }

        private void UpdateUiComponent()
        {
            StatusItemHbTime.Text = "R:" + SystemConfig.ReaderIdleTimeSeconds + "/s,W:" +
                                    SystemConfig.WriterIdleTimeSeconds + "/s,A:" + SystemConfig.AllIdleTimeSeconds +
                                    "/s";
        }


        private void ChangeWater2()
        {
            this.Text = "模拟器-Water2";
            dtuToolStripMenuItem.Checked = false;
            toolStripMenuItemDefault.Checked = false;
            water2ToolStripMenuItem.Checked = true;
            CmdGenetor.Genetor = null;
            CmdGenetor.Genetor = new Water2CmdGenetor();
            ConfigChange.ChangeDevice(SystemConfig.Water2);
            TbDeviceId.Text = SystemConfig.DefaultNo;
            TbPort.Text = "" + SystemConfig.DefaultPort;
        }

        private void ChangeDefault()
        {
            this.Text = "模拟器";
            dtuToolStripMenuItem.Checked = false;
            water2ToolStripMenuItem.Checked = false;
            toolStripMenuItemDefault.Checked = true;
            CmdGenetor.Genetor = null;

        }

        /// <summary>
        /// 记得Reload数据库
        /// </summary>
        private void ChangeDtu()
        {
            this.Text = "模拟器-DTU";
            water2ToolStripMenuItem.Checked = false;
            toolStripMenuItemDefault.Checked = false;
            dtuToolStripMenuItem.Checked = true;

            CmdGenetor.Genetor = null;
            CmdGenetor.Genetor = new DtuCmdGenetor();
            ConfigChange.ChangeDevice(SystemConfig.Dtu);
            TbDeviceId.Text = SystemConfig.DefaultNo;
            TbPort.Text = "" + SystemConfig.DefaultPort;
        }

        #region Component Event

        private void BtnConnection_Click(object sender, EventArgs e)
        {
            BeforeConnection();

            Task startNew = Task.Factory.StartNew(() =>
            {
                _nettyClient = new NettyClient();
                _nettyClient.StartNetty(host, port, null);
            });
        }

        private void BtnLogin_Click(object sender, EventArgs e)
        {
            BeforeConnection();

            Task startNew = Task.Factory.StartNew(() =>
            {
                string loginCmd = CmdGenetor.Genetor.GetLoginCmd(TbCCID.Text.Trim());
                _nettyClient = new NettyClient();
                _nettyClient.StartNetty(host, port, loginCmd);
            });
        }

        private void BtnDisConn_Click(object sender, EventArgs e)
        {
            _nettyClient?.StopNetty();
            //t?.Abort();
        }

        private void BtnSendData_Click(object sender, EventArgs e)
        {
            string cmd = TbSendData.Text.Trim();
            _nettyClient?.SendData(cmd);
        }


        private void RT_HB_Time_Click(object sender, EventArgs e)
        {
            HeartBeatTime hbt = new HeartBeatTime();
            hbt.ShowDialog();
        }

        private void RT_HB_Enable_Click(object sender, EventArgs e)
        {
            SystemConfig.OpenHeartBeat = RT_HB_Enable.Checked;
        }

        private void TbPort_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        private void dtuToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeDtu();
        }

        private void water2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeWater2();
        }


        private void BtnClearAll_Click(object sender, EventArgs e) => LBLogShow.Items.Clear();

        private void BtnCmdManager_Click(object sender, EventArgs e)
        {
            ItemManagerForm imf = new ItemManagerForm();
            imf.ShowDialog();
        }


        private void RT_HI_Host_Click(object sender, EventArgs e)
        {
            HistoryDialog hd = new HistoryDialog(SystemConfig.IpHisType);
            hd.HistoryHandler += Hd_HistoryHandler;
            hd.ShowDialog();
        }

        private void HalfPkgToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            TcpPkgConfigDialog tcpDialog = new TcpPkgConfigDialog();
            tcpDialog.ShowDialog();
        }

        private void RT_HI_DeviceId_Click(object sender, EventArgs e)
        {
            HistoryDialog hd = new HistoryDialog(SystemConfig.AddrHisType);
            hd.HistoryHandler += Hd_HistoryHandler;
            hd.ShowDialog();
        }

        private void RT_HI_CCID_Click(object sender, EventArgs e)
        {
            HistoryDialog hd = new HistoryDialog(SystemConfig.CcidHisType);
            hd.HistoryHandler += Hd_HistoryHandler;
            hd.ShowDialog();
        }

        private void RT_HI_SendData_Click(object sender, EventArgs e)
        {
            HistoryDialog hd = new HistoryDialog(SystemConfig.SendHisType);
            hd.HistoryHandler += Hd_HistoryHandler;
            hd.ShowDialog();
        }

        private void TSMI_ClearAll_Click(object sender, EventArgs e)
        {
            BtnClearAll_Click(null, null);
        }


        private void Hd_HistoryHandler(string type, string result)
        {
        }

        #endregion

        #region ListBox

        private void LBLogShow_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index >= 0 && e.Index < LBLogShow.Items.Count)
            {
                e.DrawBackground();
                UIInfoModel res = LBLogShow.Items[e.Index] as UIInfoModel;

                if (res.SendType == SystemConfig.SendType)
                {
                    Font f = new Font("微软雅黑", e.Font.Size);
                    e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), f,
                        new SolidBrush(Color.Crimson),
                        e.Bounds);
                }
                else if (res.SendType == SystemConfig.RecType)
                {
                    Font f = new Font("微软雅黑", e.Font.Size);
                    e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), f, new SolidBrush(Color.Blue),
                        e.Bounds);
                }
                else if (res.SendType == SystemConfig.ReplyType)
                {
                    Font f = new Font("微软雅黑", e.Font.Size);
                    e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), f,
                        new SolidBrush(Color.BlueViolet),
                        e.Bounds);
                }
                else
                {
                    e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), e.Font,
                        new SolidBrush(e.ForeColor),
                        e.Bounds);
                }
            }
        }

        private void LBLogShow_DoubleClick(object sender, EventArgs e)
        {
            int index = LBLogShow.SelectedIndex;
            if (index >= 0 && index < LBLogShow.Items.Count)
            {
                UIInfoModel uiInfoModel = LBLogShow.SelectedItem as UIInfoModel;
            }
        }


        private void LB_Context_CpCmd_Click(object sender, EventArgs e)
        {
            int index = LBLogShow.SelectedIndex;
            if (index >= 0 && index < LBLogShow.Items.Count)
            {
                UIInfoModel uiInfoModel = LBLogShow.SelectedItem as UIInfoModel;
                string line = CmdUtil.FilterCmd(uiInfoModel.ToString());
                if (!line.Trim().Equals(""))
                    Clipboard.SetDataObject(line);
            }
        }

        private void LB_Context_CpLine_Click(object sender, EventArgs e)
        {
            int index = LBLogShow.SelectedIndex;
            if (index >= 0 && index < LBLogShow.Items.Count)
            {
                UIInfoModel uiInfoModel = LBLogShow.SelectedItem as UIInfoModel;
                string line = uiInfoModel?.ToString();
                if (!line.Trim().Equals(""))
                    Clipboard.SetDataObject(line);
            }
        }

        private void LB_Context_GJson_Click(object sender, EventArgs e)
        {
            int index = LBLogShow.SelectedIndex;
            if (index >= 0 && index < LBLogShow.Items.Count)
            {
                UIInfoModel uiInfoModel = LBLogShow.SelectedItem as UIInfoModel;
                string line = CmdUtil.FilterCmd(uiInfoModel?.ToString());
                if (!line.Trim().Equals(""))
                {
                }
            }
        }

        private void LB_Context_AnaCmd_Click(object sender, EventArgs e)
        {
            int index = LBLogShow.SelectedIndex;
            if (index >= 0 && index < LBLogShow.Items.Count)
            {
                UIInfoModel uiInfoModel = LBLogShow.SelectedItem as UIInfoModel;
                string line = CmdUtil.FilterCmd(uiInfoModel?.ToString());
                if (!line.Trim().Equals(""))
                {
                }
            }
        }

        private void LB_Context_ClearAll_Click(object sender, EventArgs e) => LBLogShow.Items.Clear();

        #endregion

        private void LogHbtoolStripMenuItem_Click(object sender, EventArgs e)
        {
            SystemConfig.IsLogHeartBeatInfo = LogHbtoolStripMenuItem.Checked;
        }

        private void BtnTest_Click(object sender, EventArgs e)
        {
            Water2CmdGenetor w = new Water2CmdGenetor();
            string reply = w.GetReplyCmd(TbSendData.Text.Trim());
            if (reply != null)
                Console.WriteLine("回复------:" + reply);
            else
                Console.WriteLine("resp is null");
        }
    }
}