using System.Collections.Generic;
using System;
using System.Drawing;
using System.Diagnostics;
using System.Data;
using System.Collections;
using System.Windows.Forms;
using AR;
using System.Linq;
using System.Net.Security;
using COMM;
using OpenTK.Audio.OpenAL;
using System.ComponentModel;

namespace vmsnet
{

    public partial class Frm_Cell
    {
        public HMI.CITEM cellidx = null;
        readonly DataTable DT = new DataTable();

        //  SpPerfChart.PerfChart runChart1;
        ScottPlot.Plottables.Scatter Logger1;
        ScottPlot.Plottables.Crosshair CrossHair;
        //ScottPlot.Plottables.VerticalLine[] CursorLine;
        ScottPlot.WinForms.FormsPlot formsPlot1;
        private int currentDataCount = 10;
        private const int maxDataCount = 600;

        short voltlimit = 0;
        short timelimit = 1;

        List<float> dataVolt = null;
        List<double> dataTime = null;

        public Frm_Cell()
        {

            // 이 호출은 디자이너에 필요합니다.
            InitializeComponent();
            // InitializeComponent() 호출 뒤에 초기화 코드를 추가하십시오.

            InitControl();
        }
        public Frm_Cell(HMI.CITEM pidx)
        {

            // 이 호출은 디자이너에 필요합니다.
            InitializeComponent();
            cellidx = pidx;
            cellidx.OnAlamStausChanged += cellidx_OnChangeStatus;
            cellidx.OnChangeData += cellidx_OnChangeData;
            cellidx.OnChangeValueData += cellidx_OnChangeValueData;
            // InitializeComponent() 호출 뒤에 초기화 코드를 추가하십시오.
            InitControl();
        }

        public void InitControl()
        {
            dataVolt = new List<float>(0);
            dataTime = new List<double>(0);

            formsPlot1 = new ScottPlot.WinForms.FormsPlot() { Dock = DockStyle.Fill };
            formsPlot1.MouseDown += FormsPlot1_MouseDown;
            formsPlot1.MouseUp += FormsPlot1_MouseUp;
            formsPlot1.MouseMove += FormsPlot1_MouseMove;

            CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0);
            CrossHair.TextColor = ScottPlot.Colors.White;
            CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color;

            formsPlot1.Plot.YLabel("VOLTAGE");
            formsPlot1.Plot.XLabel("COUNT");
            formsPlot1.Plot.Axes.SetLimitsX(0, currentDataCount);

            this.formsPlot1.Plot.ShowLegend();

            formsPlot1.Plot.Axes.DateTimeTicksBottom();
            this.formsPlot1.Plot.Axes.ContinuouslyAutoscale = true;
            this.formsPlot1.Plot.RenderManager.RenderStarting += (s1, e1) =>
            {
                ScottPlot.Tick[] ticks = formsPlot1.Plot.Axes.Bottom.TickGenerator.Ticks;
                for (int i = 0; i < ticks.Length; i++)
                {
                    DateTime dt = DateTime.FromOADate(ticks[i].Position);
                    string label = $"{dt:yy-MM-dd\nHH:mm:ss}";
                    ticks[i] = new ScottPlot.Tick(ticks[i].Position, label);
                }
            };

            this.TabPage1.Controls.Clear();
            this.TabPage1.Controls.Add(this.formsPlot1); //runChart1
            this.TabPage1.Controls.Add(this.DV_VALUE);
            this.TabPage1.Controls.Add(this.ToolStrip2);
        }



        public void Frm_Cell_Load(object sender, System.EventArgs e)
        {

            DT.Columns.Add("VOLT");
            DT.Columns.Add("TIME");
            this.BS_DATA.DataSource = DT;
            this.Text = cellidx.이름 + "셀 속성";
            this.PropertyGrid1.SelectedObject = cellidx;

            loadviewSetting();

            System.Windows.Forms.Binding bd = new System.Windows.Forms.Binding("text", cellidx, "column");

            refreshalama();
        }
        public void Frm_Cell_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            cellidx.OnAlamStausChanged -= cellidx_OnChangeStatus;
            cellidx.OnChangeData -= cellidx_OnChangeData;
            cellidx.OnChangeValueData -= cellidx_OnChangeValueData;

            formsPlot1.MouseDown -= FormsPlot1_MouseDown;
            formsPlot1.MouseUp -= FormsPlot1_MouseUp;
            formsPlot1.MouseMove -= FormsPlot1_MouseMove;

            saveviewSetting();
        }
        private void loadviewSetting()
        {
            cmb_volt.SelectedIndex = (PUB.CONFIG.cell_voltindex); // Xml.Data("rtlview", "voltindex", "1")
            cmb_time.SelectedIndex = (PUB.CONFIG.cell_timeindex); // XMl.Data("rtlview", "timeindex", "0")
        }
        private void saveviewSetting()
        {
            PUB.CONFIG.cell_voltindex = (cmb_volt.SelectedIndex);
            PUB.CONFIG.cell_timeindex = (cmb_time.SelectedIndex);
            PUB.CONFIG.Save();
        }
        #region "scott plot mouse event"

        private ScottPlot.Plottables.AxisLine GetLineUnderMouse(float x, float y)
        {
            ScottPlot.CoordinateRect rect = formsPlot1.Plot.GetCoordinateRect(x, y, radius: 10);

            foreach (var axLine in formsPlot1.Plot.GetPlottables<ScottPlot.Plottables.AxisLine>().Reverse())
            {
                if (axLine.IsUnderMouse(rect))
                    return axLine;
            }

            return null;
        }



        private void FormsPlot1_MouseDown(object sender, MouseEventArgs e)
        {
            var lineUnderMouse = GetLineUnderMouse(e.X, e.Y);
            if (lineUnderMouse != null)
            {
                PlottableBeingDragged = lineUnderMouse;
                formsPlot1.Interaction.Disable(); // disable panning while dragging
            }
        }

        private void FormsPlot1_MouseUp(object sender, MouseEventArgs e)
        {
            PlottableBeingDragged = null;
            formsPlot1.Interaction.Enable(); // enable panning again
            formsPlot1.Refresh();
        }
        ScottPlot.Plottables.AxisLine PlottableBeingDragged = null;
        private void FormsPlot1_MouseMove(object sender, MouseEventArgs e)
        {

            //update cross line
            ScottPlot.Pixel mousePixel = new ScottPlot.Pixel(e.X, e.Y);
            ScottPlot.Coordinates mouseCoordinates = formsPlot1.Plot.GetCoordinates(mousePixel);

            if (mouseCoordinates.X is double.NaN || mouseCoordinates.Y is double.NaN ||
                mouseCoordinates.X is double.PositiveInfinity || mouseCoordinates.Y is double.PositiveInfinity ||
                mouseCoordinates.X is double.NegativeInfinity || mouseCoordinates.Y is double.NegativeInfinity)
            {
                return;
            }

            if (CrossHair != null)
            {
                CrossHair.Position = mouseCoordinates;
                var time = DateTime.FromOADate(mouseCoordinates.X);

                CrossHair.VerticalLine.Text = $"{time:yy-MM-dd\nHH:mm:ss}";

                CrossHair.HorizontalLine.Text = $"{mouseCoordinates.Y:N2}v";
                formsPlot1.Refresh();
            }




            // this rectangle is the area around the mouse in coordinate units
            ScottPlot.CoordinateRect rect = formsPlot1.Plot.GetCoordinateRect(e.X, e.Y, radius: 10);

            if (PlottableBeingDragged is null)
            {
                // set cursor based on what's beneath the plottable
                var lineUnderMouse = GetLineUnderMouse(e.X, e.Y);
                if (lineUnderMouse is null) Cursor = Cursors.Default;
                else if (lineUnderMouse.IsDraggable && lineUnderMouse is ScottPlot.Plottables.VerticalLine) Cursor = Cursors.SizeWE;
                else if (lineUnderMouse.IsDraggable && lineUnderMouse is ScottPlot.Plottables.HorizontalLine) Cursor = Cursors.SizeNS;
            }
            else
            {
                // update the position of the plottable being dragged
                if (PlottableBeingDragged is ScottPlot.Plottables.HorizontalLine hl)
                {
                    hl.Y = rect.VerticalCenter;
                    hl.Text = $"{hl.Y:0.00}v";
                }
                else if (PlottableBeingDragged is ScottPlot.Plottables.VerticalLine vl)
                {
                    vl.X = rect.HorizontalCenter;
                    var time = DateTime.FromOADate(vl.X);
                    //vl.Text = $"{vl.X:0.00}";
                    vl.Text = $"{time:yy-MM-dd\nHH:mm:ss}";
                }
                formsPlot1.Refresh();
            }
        }
        #endregion



        public void Frm_Grp_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
            }
        }

        private void refreshalama()
        {
            if (cellidx.상위알람발생)
            {
                this.ToolStripButton2.Image = global::vmsnet.Properties.Resources.Red_Ball;
            }
            else
            {
                this.ToolStripButton2.Image = global::vmsnet.Properties.Resources.Green_Ball;
            }
            if (cellidx.하위알람발생)
            {
                this.ToolStripButton1.Image = global::vmsnet.Properties.Resources.Red_Ball;
            }
            else
            {
                this.ToolStripButton1.Image = global::vmsnet.Properties.Resources.Green_Ball;
            }
        }

         public void TabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
        {

            switch (this.TabControl1.SelectedIndex)
            {
                case 1: ////알림목록 tab

                    var Dt =  PUB.Alarm.GetAlarmData(cellidx.인덱스_번호);
                    foreach (var Dr in Dt.Item2)
                    {
                        Dr.RTYPESTR = ((COMM.EALAMRAISETYPE)Dr.RTYPE).ToString();
                        Dr.ATYPESTR = ((COMM.EALAMTYPE)Dr.ATYPE).ToString();
                    }
                    Dt.Item2.AcceptChanges();
                    this.BS_ALAM.DataSource = Dt;
                    this.DataGridView1.AutoGenerateColumns = false;
                    this.DataGridView1.DataSource = this.BS_ALAM;
                    this.DataGridView1.AutoResizeColumns();
                    break;
            }
        }

        public void DataGridView1_CellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
        {
            var row = this.DataGridView1.Rows[e.RowIndex];
            var CV = row.Cells["RTYPESTR"].Value;
            if (CV == null)
            {
                row.DefaultCellStyle.BackColor = Color.Empty;
                return;
            }

            switch (this.DataGridView1.Rows[e.RowIndex].Cells["RTYPESTR"].Value.ToString().ToUpper())
            {
                case "HIGH-OFF":
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Empty;
                    break;
                case "HIGH-ON":
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Orange;
                    break;
                case "LOW-OFF":
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Empty;
                    break;
                case "LOW-ON":
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Blue;
                    break;
                case "OVER-ON":
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Magenta;
                    break;
                case "OVER-OFF":
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Empty;
                    break;
                default:
                    DataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Empty;
                    break;
            }

        }

        private void cellidx_OnChangeStatus()
        {
            refreshalama();
        }

        private void cellidx_OnChangeData()
        {

            bool ok = PUBC.UpdateChannel(cellidx.idx, cellidx.이름, (int)cellidx.알람형태, (cellidx.사용 ? 1 : 0), cellidx.HIGH, cellidx.LOW, cellidx.H, cellidx.L);
            if (!ok)
            {
                UTIL.MsgE("셀 정보가 업데이트되지 않았습니다");
                PUB.log.Add("Cell update error idx=" + cellidx.ToString());
            }

        }

        private void cellidx_OnChangeValueData()
        {
            ////값이 바뀌엇다.

            float value = 0.0F;
            float.TryParse(cellidx.Value.Replace("V", "").Replace("v", ""), out value);
            this.tb_val.Text = value.ToString();
            this.tb_time.Text = cellidx.mtime;

            try
            {
                //datetime = CDate(cellidx.측정시간)
                var dt = DateTime.Parse(cellidx.측정시간);

                formsPlot1.Plot.Clear<ScottPlot.Plottables.Scatter>();
                dataVolt.Add(value);
                dataTime.Add(dt.ToOADate());
                Logger1 = formsPlot1.Plot.Add.Scatter(dataTime.ToArray(), dataVolt.ToArray());
                Logger1.Color = ScottPlot.Colors.Blue;

                var mintime = DateTime.FromOADate(dataTime.First());
                var maxtime = DateTime.FromOADate(dataTime.Last());
                var ts = (maxtime - mintime);
                if (ts.TotalMinutes >= this.timelimit)
                {
                    //10개지운다
                    if (dataTime.Count > 10)
                    {
                        dataVolt.RemoveRange(0, 10);
                        dataTime.RemoveRange(0, 10);
                    }
                }


                this.BeginInvoke(new Action(() =>
                {
                    this.DT.Rows.Add(value, dt.ToString("yy-MM-dd HH:mm:ss"));
                    this.DT.AcceptChanges();
                    if (voltlimit != 0) formsPlot1.Plot.Axes.AutoScaleX();
                    this.formsPlot1.Refresh();
                }));

            }
            catch (Exception)
            {

            }
        }

        public void ToolStripComboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
        {

        }


        public void cmb_time_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (cmb_time.SelectedIndex < 0) return;

            timelimit = short.Parse(this.cmb_time.Text.Replace("분", ""));
        }

        private void runChart1_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            this.DV_VALUE.Visible = !this.DV_VALUE.Visible;
        }

        private void TabPage1_Click(object sender, EventArgs e)
        {
            DV_VALUE.Visible = !DV_VALUE.Visible;
        }
    }
}
