#pragma warning disable IDE1006 // 명명 스타일

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 arDev.DIO;
using arDev.AjinEXTEK;
using AR;
using AR;

namespace Project.Dialog
{
    public partial class fIOMonitor : Form
    {
        arCtl.GridView.GridView[] gvIlog;
        Label[] lbILog;

        public fIOMonitor()
        {
            InitializeComponent();
            this.FormClosed += fIOMonitor_FormClosed;

            this.Opacity = 1.0;

            gvIlog = new arCtl.GridView.GridView[] {
                gbi00,gbi01,gbi02,gbi03,gbi04,gbi05,
                gbi06,gbi07,gbi08,gbi09,gbi10,gbi11,
                gbi12,gbi13,gbi14,gbi15,gbi16,gbi17,
            };
            lbILog = new Label[] {
                lbi00,lbi01,lbi02,lbi03,lbi04,lbi05,
                lbi06,lbi07,lbi08,lbi09,lbi10,lbi11,
                lbi12,lbi13,lbi14,lbi15,lbi16,lbi17,
            };

            //DI,DO,
            var dinames = DIO.Pin.GetDIName;
            var donames = DIO.Pin.GetDOName;
            tblDI.setTitle(dinames);
            tblDO.setTitle(donames);
            //tblFG.setTitle(PUB.flag.Name);
            var pinNameI = DIO.Pin.GetDIPinName;// new string[dinames.Length];
            var pinNameO = DIO.Pin.GetDOPinName;// new string[donames.Length];
            //for (int i = 0; i < pinNameI.Length; i++) pinNameI[i] = Enum.GetName(typeof(eDIPin), i);
            //for (int i = 0; i < pinNameO.Length; i++) pinNameO[i] = Enum.GetName(typeof(eDOPin), i);
            tblDI.setNames(pinNameI);
            tblDO.setNames(pinNameO);

            tblDI.setItemTextAlign(ContentAlignment.MiddleLeft);
            tblDO.setItemTextAlign(ContentAlignment.MiddleLeft);

            // tblFG.setItemTextAlign(ContentAlignment.BottomLeft);
            tblDI.ColorList = new arDev.AjinEXTEK.UI.ColorListItem[] {
                new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.DimGray, BackColor2 = Color.FromArgb(30,30,30), Remark="False" },
                new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.Lime, BackColor2 = Color.Green, Remark="True" },
            };
            tblDO.ColorList = new arDev.AjinEXTEK.UI.ColorListItem[] {
                new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.DimGray, BackColor2 = Color.FromArgb(30,30,30), Remark="False" },
                new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.Tomato, BackColor2 = Color.Red, Remark="True" },
            };

            //인터락이름
            //var ILNameEV = new string[Pub.iLock.Length];
            for (int i = 0; i < PUB.iLock.Length; i++)
            {
                var axisname = ((eAxis)i).ToString();
                var nonaxis = false;
                if (i >= 7)   //이름이없는경우
                {
                    axisname = PUB.iLock[i].Tag.ToString();
                    nonaxis = true;
                }
                string[] ILNameEV;

                //if (axisname.StartsWith("X")) ILNameEV = Enum.GetNames(typeof(eILockPKX));
                //else if (axisname.StartsWith("Y")) ILNameEV = Enum.GetNames(typeof(eILockPKY));
                //else if (axisname.StartsWith("Z")) ILNameEV = Enum.GetNames(typeof(eILockPKZ));
                //else if (axisname.StartsWith("U")) ILNameEV = Enum.GetNames(typeof(eILockEV));
                //else if (axisname.StartsWith("L")) ILNameEV = Enum.GetNames(typeof(eILockEV));
                //else
                if (i == 7) ILNameEV = Enum.GetNames(typeof(eILockPRL));
                else if (i == 8) ILNameEV = Enum.GetNames(typeof(eILockPRR));
                else if (i == 9) ILNameEV = Enum.GetNames(typeof(eILockVS0));
                else if (i == 10) ILNameEV = Enum.GetNames(typeof(eILockVS1));
                else if (i == 11) ILNameEV = Enum.GetNames(typeof(eILockVS2));
                else if (i == 12) ILNameEV = Enum.GetNames(typeof(eILockCV));
                else if (i == 13) ILNameEV = Enum.GetNames(typeof(eILockCV));
                else ILNameEV = Enum.GetNames(typeof(eILock));

                this.lbILog[i].Text = axisname;
                this.gvIlog[i].setTitle(ILNameEV);
                this.gvIlog[i].setItemTextAlign(ContentAlignment.MiddleCenter);
                this.gvIlog[i].ColorList[1].BackColor1 = Color.IndianRed;
                this.gvIlog[i].ColorList[1].BackColor2 = Color.LightCoral;

                if (nonaxis)
                {
                    lbILog[i].ForeColor = Color.Gold;
                }
                else
                {
                    if (axisname.StartsWith("PX")) this.lbILog[i].ForeColor = Color.Gold;
                    else if (axisname.StartsWith("PY")) this.lbILog[i].ForeColor = Color.Tomato;
                    else if (axisname.StartsWith("PZ")) this.lbILog[i].ForeColor = Color.Lime;
                    else if (axisname.StartsWith("PU")) this.lbILog[i].ForeColor = Color.SkyBlue;
                    else if (axisname.StartsWith("PL")) this.lbILog[i].ForeColor = Color.Magenta;
                    else this.lbILog[i].ForeColor = Color.DimGray;
                }

            }



            //값확인
            List<Boolean> diValue = new List<bool>();
            for (int i = 0; i < PUB.dio.GetDICount; i++)
                diValue.Add(PUB.dio.GetDIValue(i));

            List<Boolean> doValue = new List<bool>();
            for (int i = 0; i < PUB.dio.GetDOCount; i++)
                doValue.Add(PUB.dio.GetDOValue(i));
            //List<Boolean> fgValue = new List<bool>();
            //for (int i = 0; i < PUB.flag.Length; i++)
            //    fgValue.Add(PUB.flag.get(i));

            tblDI.setValue(diValue.ToArray());
            tblDO.setValue(doValue.ToArray());
            // tblFG.setValue(fgValue.ToArray());

            PUB.dio.IOValueChanged += dio_IOValueChanged;
            //PUB.flag.ValueChanged += flag_ValueChanged;

            //interlock
            var axislist = Enum.GetNames(typeof(eAxis));



            for (int i = 0; i < PUB.iLock.Length; i++)
            {
                List<Boolean> PKValues = new List<bool>();

                //인터락에는 값이 몇개 있지?
                for (int j = 0; j < 64; j++)
                {
                    PKValues.Add(PUB.iLock[i].get(j));
                }

                gvIlog[i].setValue(PKValues.ToArray());
                gvIlog[i].Tag = i;

                PUB.iLock[i].ValueChanged += LockXF_ValueChanged;

                if (PUB.sm.isRunning == false)
                {
                    gvIlog[i].ItemClick += gvILXF_ItemClick;
                }
                gvIlog[i].Invalidate();
            }


            if (PUB.sm.isRunning == false)
            {
                this.tblDI.ItemClick += tblDI_ItemClick;
                this.tblDO.ItemClick += tblDO_ItemClick;
                //this.tblFG.ItemClick += tblFG_ItemClick;
            }

            this.tblDI.Invalidate();
            this.tblDO.Invalidate();
            // this.tblFG.Invalidate();

            this.KeyDown += fIOMonitor_KeyDown;
            this.WindowState = FormWindowState.Maximized;
        }


        void fIOMonitor_FormClosed(object sender, FormClosedEventArgs e)
        {
            PUB.dio.IOValueChanged -= dio_IOValueChanged;
            // PUB.flag.ValueChanged -= flag_ValueChanged;

            for (int i = 0; i < PUB.iLock.Length; i++)
            {
                PUB.iLock[i].ValueChanged -= LockXF_ValueChanged;
            }


            if (PUB.sm.isRunning == false)
            {
                this.tblDI.ItemClick -= tblDI_ItemClick;
                this.tblDO.ItemClick -= tblDO_ItemClick;
                //  this.tblFG.ItemClick -= tblFG_ItemClick;

                for (int i = 0; i < PUB.iLock.Length; i++)
                {
                    gvIlog[i].ItemClick -= gvILXF_ItemClick;
                }

            }

            this.KeyDown -= fIOMonitor_KeyDown;
        }

        void LockXF_ValueChanged(object sender, AR.InterfaceValueEventArgs e)
        {
            var item = sender as CInterLock;
            //var tagStr = item.Tag.ToString();
            //var axis = (eAxis)Enum.Parse(typeof(eAxis), tagStr);
            var axisno = item.idx;// (int)axis;

            if (this.gvIlog[axisno].setValue((int)e.ArrIDX, e.NewValue))
                this.gvIlog[axisno].Invalidate();

        }

        void gvILXF_ItemClick(object sender, arCtl.GridView.GridView.ItemClickEventArgs e)
        {
            var gv = sender as arCtl.GridView.GridView;
            var tagStr = gv.Tag.ToString();

            var axis = (eAxis)Enum.Parse(typeof(eAxis), tagStr);
            var axisno = (int)axis;

            var curValue = PUB.iLock[axisno].get((int)e.idx);
            PUB.iLock[axisno].set((int)e.idx, !curValue, "IOMONITOR");
        }

        void fIOMonitor_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape) this.Close();
            else if (e.KeyCode == Keys.D && e.Control)
            {
                this.tblDO.showDebugInfo = !this.tblDO.showDebugInfo;
                this.tblDI.showDebugInfo = this.tblDO.showDebugInfo;
                // this.tblFG.showDebugInfo = this.tblDO.showDebugInfo;
            }
        }

        private void fIOMonitor_Load(object sender, EventArgs e)
        {
            this.Text = "I/O Monitor";
            this.Show();
            //'Application.DoEvents();



            Dialog.Quick_Control fctl = new Quick_Control
            {
                TopLevel = false,
                Visible = true
            };
            this.panel3.Controls.Add(fctl);
            fctl.Dock = DockStyle.Top;
            fctl.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            fctl.panBG.BackColor = this.BackColor;
            fctl.panBG.BorderStyle = BorderStyle.None;
            fctl.Show();
            fctl.Dock = DockStyle.Fill;

            this.tmDisplay.Start();
        }





        //void tblFG_ItemClick(object sender, arCtl.GridView.GridView.ItemClickEventArgs e)
        //{
        //    var curValue = PUB.flag.get((int)e.idx);
        //    PUB.flag.set((int)e.idx, !curValue, "IOMONITOR");
        //}

        void tblDO_ItemClick(object sender, arDev.AjinEXTEK.UI.IOPanel.ItemClickEventArgs e)
        {
            var newValue = !PUB.dio.GetDOValue(e.idx);
            if (PUB.dio.IsInit == false)
            {
                //임시시그널
                var dlg = UTIL.MsgQ("Do you want to create a virtual signal?");
                if (dlg == System.Windows.Forms.DialogResult.Yes)
                {
                    PUB.dio.RaiseEvent(eIOPINDIR.OUTPUT, e.idx, newValue);
                    PUB.log.Add("fake do : " + e.idx.ToString() + ",val=" + newValue.ToString());
                }
            }
            else
            {
                PUB.dio.SetOutput(e.idx, newValue);
                PUB.log.Add(string.Format("set output(iomonitor-userclick) idx={0},val={1}", e.idx, newValue));
            }
        }

        void tblDI_ItemClick(object sender, arDev.AjinEXTEK.UI.IOPanel.ItemClickEventArgs e)
        {
            var newValue = !PUB.dio.GetDIValue(e.idx);
            if (PUB.dio.IsInit == false || PUB.flag.get(eVarBool.FG_DEBUG) == true)
            {
                //임시시그널
                var dlg = UTIL.MsgQ("Do you want to create a virtual signal?");
                if (dlg == System.Windows.Forms.DialogResult.Yes)
                {
                    PUB.dio.RaiseEvent(eIOPINDIR.INPUT, e.idx, newValue);
                    PUB.log.Add("fake di : " + e.idx.ToString() + ",val=" + newValue.ToString());
                }
            }
        }

        //void flag_ValueChanged(object sender, AR.InterfaceValueEventArgs e)
        //{
        //    //var butIndex = getControlIndex(e.ArrIDX);
        //    //if (butIndex >= this.tblFG.Controls.Count) return;

        //    //해당 아이템의 값을 변경하고 다시 그린다.
        //    if (tblFG.setValue((int)e.ArrIDX, e.NewValue))
        //        tblFG.Invalidate();//.drawItem(e.ArrIDX);
        //}


        void dio_IOValueChanged(object sender, arDev.DIO.IOValueEventArgs e)
        {
            //var butIndex = getControlIndex(e.ArrIDX);
            if (e.Direction == eIOPINDIR.INPUT)
            {
                //해당 아이템의 값을 변경하고 다시 그린다.
                if (tblDI.setValue(e.ArrIDX, e.NewValue))
                    tblDI.Invalidate();//.drawItem(e.ArrIDX);
            }
            else
            {
                //해당 아이템의 값을 변경하고 다시 그린다.
                if (tblDO.setValue(e.ArrIDX, e.NewValue))
                    tblDO.Invalidate();//.drawItem(e.ArrIDX);
            }
        }


        private void tmDisplay_Tick(object sender, EventArgs e)
        {
            if (this.tabControl1.SelectedIndex == 2)
            {
                //flag
                //var fvalue = PUB.flag.Value();
                //lbTitle3.Text = "FLAG(" + fvalue.HexString() + ")";
                //for (int i = 0; i < 128; i++)
                //    tblFG.setValue((int)i, PUB.flag.get(i));
                //tblFG.Invalidate();
            }
            else if (this.tabControl1.SelectedIndex == 3)
            {
                //inter lock
                for (uint i = 0; i < PUB.iLock.Length; i++)
                {
                    var axis = (eAxis)i;
                    var axisname = axis.ToString();
                    if (axisname.Equals(i.ToString()))
                    {
                        axisname = PUB.iLock[i].Tag.ToString();
                    }
                    this.lbILog[i].Text = string.Format("{0}({1})", axisname, PUB.iLock[i].Value().HexString());
                }
            }
        }

        private void lbTitle1_Click(object sender, EventArgs e)
        {
            //input list
            var fn = "descin.txt";
            var sb = new System.Text.StringBuilder();
            sb.AppendLine("No\tTitle\tDesc");
            foreach (var item in Enum.GetValues(typeof(eDIName)))
            {
                var em = (eDIName)item;
                var dr = PUB.mdm.dataSet.InputDescription.Where(t => t.Idx == (int)em).FirstOrDefault();
                var pinNo = $"X{(int)em:X2}";
                var pinTitle = item.ToString();
                var Desc = dr == null ? "" : dr.Description;
                sb.Append(pinNo);
                sb.Append("\t");
                sb.Append(pinTitle);
                sb.Append("\t");
                sb.Append(Desc);
                sb.AppendLine();
            }
            System.IO.File.WriteAllText(fn, sb.ToString(), System.Text.Encoding.Default);
            UTIL.RunExplorer(fn);
        }

        private void arLabel2_Click(object sender, EventArgs e)
        {
            //oputput list
            var fn = "descout.txt";
            var sb = new System.Text.StringBuilder();
            sb.AppendLine("No\tTitle\tDesc");
            foreach (var item in Enum.GetValues(typeof(eDOName)))
            {
                var em = (eDOName)item;
                var itemidx = (int)em;
                var dr = PUB.mdm.dataSet.OutputDescription.Where(t => t.Idx == itemidx).FirstOrDefault();
                var pinNo = $"Y{(int)em:X2}";
                var pinTitle = item.ToString();
                var Desc = dr == null ? "" : dr.Description;
                sb.Append(pinNo);
                sb.Append("\t");
                sb.Append(pinTitle);
                sb.Append("\t");
                sb.Append(Desc);
                sb.AppendLine();
            }
            System.IO.File.WriteAllText(fn, sb.ToString(), System.Text.Encoding.Default);
            UTIL.RunExplorer(fn);
        }

        private void pinDefineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var f = new fSetting_IOMessage();
            f.ShowDialog();

        
            tblDI.setTitle(DIO.Pin.GetDIName);
            tblDO.setTitle(DIO.Pin.GetDOName);
            tblDI.setNames(DIO.Pin.GetDIPinName);
            tblDO.setNames(DIO.Pin.GetDOPinName);
            tblDI.Invalidate();
            tblDO.Invalidate();
        }
    }
}
