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 System.Windows.Forms.DataVisualization.Charting;
using System.Threading;
using N_Series_SDK;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace N_Series_SDK
{
    public partial class Graph : Form
    {
        public delegate void getDataDelegate();
        public delegate void RefreshDelegate();
        private getDataDelegate dataDelegate;
        private RefreshDelegate refreshdelegate;
        public NSeries pParent;
        private Series s1;
        public double[] dWL;
        public int[] DataArray;
        public int[] YPlotDataArray;
        bool FormRefreshStatus = false;

        public BackgroundWorker _worker = null;

        public Graph()
        {
            InitializeComponent();
            dataDelegate = new getDataDelegate(Plotchart);
            refreshdelegate = new RefreshDelegate(ReFreshForm);
            s1 = new Series("Intensity");
            s1.IsValueShownAsLabel = true;
            s1.ChartType = SeriesChartType.FastLine;
            s1.IsVisibleInLegend = false;
            chart1.Series.Add(s1);
        }
        public void ReFreshForm()
        {
            if(FormRefreshStatus == false)
            {
                Refresh();
                FormRefreshStatus = true;
            }
               

        }
        public int GetData()
        {
            int rRtn;
            int[] iDataArray = new int[pParent.m_stDeviceInfo[pParent.selDev].iTotPixel];
            YPlotDataArray = new Int32[pParent.m_stDeviceInfo[pParent.selDev].iRealPixel];
            if (pParent.m_stDeviceInfo[pParent.selDev].sTrgMode == (short)KSPLIB_NSeries.emTriggerMode.SP_TRIGGER_EXTERNAL)
            {
                do
                {
                    rRtn = pParent.m_KSPLIB_NSeries.NReadDataEx(iDataArray, pParent.m_stDeviceInfo[pParent.selDev].sChannel);
                } while (rRtn == -99);
            }
            else
            {
                rRtn = pParent.m_KSPLIB_NSeries.NReadDataEx(iDataArray, pParent.m_stDeviceInfo[pParent.selDev].sChannel);
            }
            System.Buffer.BlockCopy(iDataArray, sizeof(int) * pParent.m_stDeviceInfo[pParent.selDev].iDummyPixel, YPlotDataArray, 0, sizeof(int) * pParent.m_stDeviceInfo[pParent.selDev].iRealPixel);

            if (rRtn < 0)
            {
                Thread.Sleep(100);
                Trace.WriteLine("\t\t\tTime Out \n");
            }

            return rRtn;
        }


        public void Woker(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (_worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }

                int iRtn = GetData();
                bool bChkConnect = pParent.m_KSPLIB_NSeries.NCheckConnection(0);

                if (iRtn > 0)
                {
                    if (this.InvokeRequired)
                    {
                        if (FormRefreshStatus == false)
                        {
                            this.Invoke(dataDelegate);
                            this.Invoke(refreshdelegate);                            
                        }
                        else
                            this.Invoke(dataDelegate);

                        this.Invoke((new MethodInvoker(delegate { txtDevStatus.ForeColor = Color.Blue; txtDevStatus.Text = "Complete ReadData...!"; })));
                    }
                    else
                    {
                        Plotchart();
                        txtDevStatus.ForeColor = Color.Blue; 
                        txtDevStatus.Text = "Complete ReadData...!"; 
                    }
                }
                else
                {
                    if(bChkConnect)
                        this.Invoke((new MethodInvoker(delegate { txtDevStatus.ForeColor = Color.Red; txtDevStatus.Text = "Time Out...!"; })));
                    else
                        this.Invoke((new MethodInvoker(delegate { txtDevStatus.ForeColor = Color.Red; txtDevStatus.Text = "Disconnected...! Check connection cable."; })));
                }
            }
        }

        private void btnChartStart_Click(object sender, EventArgs e)
        {
            if (_worker == null)
            {
                _worker = new BackgroundWorker();
                _worker.DoWork += new DoWorkEventHandler(Woker);
                _worker.WorkerSupportsCancellation = true;
                _worker.RunWorkerAsync();
            }
            else if (_worker.IsBusy == false)
            {
                _worker = new BackgroundWorker();
                _worker.DoWork += new DoWorkEventHandler(Woker);
                _worker.WorkerSupportsCancellation = true;
                _worker.RunWorkerAsync();
            }
        }

        private void btnChartStop_Click(object sender, EventArgs e)
        {
            _worker.CancelAsync();
        }

        private void Graph_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_worker != null && _worker.IsBusy == true)
                _worker.CancelAsync();
        }

        public void Plotchart()
        {
            if (s1.Points != null)
            {
                s1.Points.Clear();

                for (int i = 0; i < pParent.m_stDeviceInfo[pParent.selDev].iRealPixel; i++)
                {
                    s1.Points.AddXY(pParent.m_stDeviceInfo[pParent.selDev].dWLTable[i], YPlotDataArray[i]);
                }
            }
        }
    }
}
