﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using Ivi.Visa.Interop;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using pidcon;

namespace WindowsFormsApplication1
{
    /* read-only properties */
    /// <summary>
    /// frmInterface
    /// </summary>
    /// 

    public partial class frmInterface : Form
    {

        //private int resistorVoltage;
        //private int sampleVoltage;
        //private int resistorCurrent;
        //private int sampleCurrent;
        //private int temperature=10;
        //private int time;
        //private int flag = 0;

        // This delegate enables asynchronous calls for setting
        // the text property on a Text(label,textbox,etc...) control.
        delegate void SetTextCallback(string text);

        private ConductivityExperiment exp;
       // private pidcon.consoleshow mostra;
        private ConductivityExperiment.Measurement chartp;
        private pidcon.ConductivityExperiment.Parameters prmt;
        private PID.Controller pidd;
        private Limits lm;


        /// <summary>
        /// frmInterface
        /// </summary>
        public frmInterface()
        {
            InitializeComponent();

           // mostra = new consoleshow();
           // mostra.MostraConsole();
            
        }

        /// <summary>
        /// Elapsed time during the experiment.
        /// </summary>
        /// 

        private ParserClass ParserClass_ =  new ParserClass();

        public Label time_
        {
          get { return lblTime; }
          set { lblTime = value; }
        }

        public TextBox tbkp
        {
            get { return txtbox_proportional; }
            set { txtbox_proportional = value; }
        }

        public TextBox tbki
        {
            get { return txtbox_integral; }
            set { txtbox_integral = value; }
        }

        public TextBox tbkd
        {
            get { return txtbox_derivative; }
            set { txtbox_derivative = value; }
        }

        public void setStrValue(string customText, Label obj)
        {
            if (InvokeRequired)
            {
                MethodInvoker invoker = delegate { setStrValue(customText, obj); };
                Invoke(invoker);
            }
            else
            {
                obj.Text = customText;
            }
        }

        public void getStrValue(string customText, TextBox obj)
        {
            if (InvokeRequired)
            {
                MethodInvoker invoker = delegate { getStrValue(customText, obj); };
                Invoke(invoker);
            }
            else
            {
                customText = obj.Text;
            }
        }

        public void SetChartValues(float[] measures, Chart obj, int i)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (InvokeRequired)
            {
                MethodInvoker invoker = delegate { SetChartValues(measures, obj, i); };
                Invoke(invoker);
            }
            else
            {
                chart_Progress(measures,obj,i);
            }
        }

        public void Settime_(string customText)
        {
           // this.lblTime.Text = customText;

            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (lblTime.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(Settime_);
                this.Invoke(d, new object[] { customText });
            }
            else
            {
                lblTime.Text = customText;
            }
        }

      /*  public void setInstrumentValue(FormattedIO488 dmm, InstrumentInfo cmd, float val, bool VF)
        {
            if (InvokeRequired)
            {
                MethodInvoker invoker = delegate { setInstrumentValue(dmm, cmd, val, VF); };
                Invoke(invoker);
            }
            else
            {
               // dmm.WriteString(instrInfo.sendCmd + val + "\n", true);
                dmm.WriteString(cmd.sendCmd + val + "\n", VF);
            }
        }*/

        /// <summary>
        /// Resistance = U / i
        /// </summary>
        public Label R_
        {             
            get { return lblSampleCurrent; }
            set { lblSampleCurrent = value; }
        }

        /// <summary>
        /// Temperature measured.
        /// </summary>
        public Label T_
        {             
            get { return lblTemperature; }
            set { lblTemperature = value; }
        }

        /// <summary>
        /// Measured temperature rate (temperature/time)
        /// </summary>
        public Label rate_
        {             
            get { return lblResistorCurrent; }
            set { lblResistorCurrent = value; }
        }


        private void btnParar_Click(object sender, EventArgs e)
        {
            if (threadExperiment.WorkerSupportsCancellation == true)
            {
                exp.StopExperiment();
                threadExperiment.CancelAsync();
            }
        }

        private void btnIniciar_Click(object sender, EventArgs e)
        {
            if (threadExperiment.IsBusy != true)
            {
                threadExperiment.RunWorkerAsync();
            }
        }


        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (threadExperiment.WorkerSupportsCancellation == true)
            {
                threadExperiment.CancelAsync();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            chart_setting(this.chart1);
            chart_setting(this.chart2);
            if (threadExperiment.IsBusy != true)
            {
                //backgroundWorker1.RunWorkerAsync();
            }
        }


        private void btn_run_monitor_Click(object sender, EventArgs e)
        {
            if (threadMonitor.IsBusy != true)
            {
                threadMonitor.RunWorkerAsync();
            }
        }

        private void btn_stop_monitor_Click(object sender, EventArgs e)
        {
            if (threadMonitor.WorkerSupportsCancellation == true)
            {
                exp.StopMonitor();
                threadMonitor.CancelAsync();
            }

        }

        private void threadMonitor_DoWork(object sender, DoWorkEventArgs e)
        {
            Random random = new Random();
            BackgroundWorker worker = sender as BackgroundWorker;

            exp = new ConductivityExperiment();

            /* temperature limits in the experiment */
            /* Minimum temperature, Maximum temperature */
            lm = new Limits(ParserClass_.ParseNumberFloat(this.txtbox_min_temp.Text), ParserClass_.ParseNumberFloat(this.txtbox_max_temp.Text));

            //Tlim,aV,envT,desiR
            /* Amperimeter voltage, Temperature rate, Environment temperature */
            prmt = new pidcon.ConductivityExperiment.Parameters(lm, int.Parse(this.txtbox_delta_time.Text), ParserClass_.ParseNumberFloat(this.txtbox_sample_V.Text), ParserClass_.ParseNumberFloat(this.txtbox_env.Text), ParserClass_.ParseNumberFloat(this.txtbox_set_point.Text), this.txtbox_comment.Text);

            //lmt = new pidcon.Limits();
            //exp.Init(10);

            pidd = new PID.Controller();

            exp._mainForm = this;

            exp.RunMonitor(prmt);
        }

        private void threadExperiment_DoWork(object sender, DoWorkEventArgs e)
        {
            
            Random random = new Random();
            BackgroundWorker worker = sender as BackgroundWorker;

            exp = new ConductivityExperiment();

            /* temperature limits in the experiment */
            /* Minimum temperature, Maximum temperature */
            lm = new Limits(ParserClass_.ParseNumberFloat(this.txtbox_min_temp.Text), ParserClass_.ParseNumberFloat(this.txtbox_max_temp.Text));

            //Tlim,aV,envT,desiR
            /* Amperimeter voltage, Temperature rate, Environment temperature */
            prmt = new pidcon.ConductivityExperiment.Parameters(lm, int.Parse(this.txtbox_delta_time.Text), ParserClass_.ParseNumberFloat(this.txtbox_sample_V.Text), ParserClass_.ParseNumberFloat(this.txtbox_env.Text), ParserClass_.ParseNumberFloat(this.txtbox_set_point.Text), this.txtbox_comment.Text);

            //lmt = new pidcon.Limits();
            //exp.Init(10);

            pidd = new PID.Controller();

            //TestEvents.EventListener evl = new TestEvents.EventListener();
            exp._mainForm = this;
             
            exp.RunExperiment(prmt, pidd.parms);

            /*
            while ( true )
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    resistorVoltage = random.Next(0, 100);
                    sampleVoltage = random.Next(0, 100);
                    resistorCurrent = random.Next(0, 100);
                    sampleCurrent = random.Next(0, 100);

                    if (flag == 0)
                    {
                        temperature = temperature + 1;
                        if (temperature > 50)
                            flag = 1;
                    }
                    else
                    {
                        temperature = temperature - 1;
                        if (temperature < 5)
                            flag = 0;
                    }
                    

                    // Perform a time consuming operation and report progress.
                    System.Threading.Thread.Sleep(40);
                    worker.ReportProgress(1);
                }
            }
            */

        }

        private void threadExperiment_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lblTime.Text = DateTime.Now.ToLongTimeString();

            //this.chart1.Series[0].Points.AddXY(DateTime.Now, temperature);

            //lblResistorVoltage.Text = resistorVoltage.ToString();
            //lblSampleVoltage.Text = sampleVoltage.ToString();
            //lblResistorCurrent.Text = resistorCurrent.ToString();
            //lblSampleCurrent.Text = sampleCurrent.ToString();
            //lblTemperature.Text = temperature.ToString();
        }

        public void chart_setting(Chart planilha)
        {
            if (planilha == this.chart1)
            {
                // setting chart
                // string[] seriesArray = { "LastT", "time" };
                // Set palette.
                planilha.Palette = ChartColorPalette.SeaGreen;

                // Set title.
                planilha.Titles.Add("Title1");
                planilha.Titles["Title1"].Text = "Measurement Monitor";
                planilha.Titles["Title1"].Docking = Docking.Top;
                planilha.Titles["Title1"].TextOrientation = TextOrientation.Horizontal;

                planilha.Titles.Add("Title2");
                planilha.Titles["Title2"].Text = "Temperature";
                planilha.Titles["Title2"].Docking = Docking.Left;
                planilha.Titles["Title2"].TextOrientation = TextOrientation.Rotated270;

                planilha.Titles.Add("Title3");
                planilha.Titles["Title3"].Text = "Time";
                planilha.Titles["Title3"].Docking = Docking.Bottom;
                planilha.Titles["Title3"].TextOrientation = TextOrientation.Horizontal;
            }
            else
            {
                // Set palette.
                planilha.Palette = ChartColorPalette.SeaGreen;

                // Set title.
                planilha.Titles.Add("Title1");
                planilha.Titles["Title1"].Text = " Proportional-Integral-Derivative controller (PID controller)";
                planilha.Titles["Title1"].Docking = Docking.Top;
                planilha.Titles["Title1"].TextOrientation = TextOrientation.Horizontal;

                planilha.Titles.Add("Title2");
                planilha.Titles["Title2"].Text = "Delta T / Delta t";
                planilha.Titles["Title2"].Docking = Docking.Left;
                planilha.Titles["Title2"].TextOrientation = TextOrientation.Rotated270;

                planilha.Titles.Add("Title3");
                planilha.Titles["Title3"].Text = "Time";
                planilha.Titles["Title3"].Docking = Docking.Bottom;
                planilha.Titles["Title3"].TextOrientation = TextOrientation.Horizontal;
            }
           /* planilha.ChartAreas.Add("planilha");
            planilha.ChartAreas["planilha"].AxisY.Title = "Times(s)";
            planilha.ChartAreas["planilha"].AxisX.Title = "Speed (m/s)";
            * /
             
           /* // Add series.
            for (int i = 0; i < seriesArray.Length; i++)
            {
            // Add series.
                Series series = planilha.Series.Add(seriesArray[i]);
            }*/
        }

        public void chart_Progress(float[] measures, Chart obj, int i)
        {
            if (obj == chart1)
            {
                //chart1.Series["Series1"].XValueType = String();
                //chart1.Series["Series1"].IsValueShownAsLabel = true; /*mostra os valore no gráfico*/
                chart1.Series["Series1"].YValuesPerPoint = 1;

                // Data arrays.
                float[] pointsArray = { measures[0], measures[2] };

                // Add point.

                chart1.Series["Series1"].ChartType = SeriesChartType.Line;
                //chart1.Series["Series1"].Points.AddY(20);
                chart1.Series["Series1"].Points.AddXY(pointsArray[0], pointsArray[1]);
                chart1.ResetAutoValues();
            }
            else if (obj == chart2){
                //chart1.Series["Series1"].XValueType = String();
                //chart2.Series["Series1"].IsValueShownAsLabel = true; /*mostra os valore no gráfico*/
                chart2.Series["Series1"].YValuesPerPoint = 1;

                // Data arrays.
                float[] pointsArray = { measures[0], measures[1] };

                // Add point.

                chart2.Series["Series1"].ChartType = SeriesChartType.Line;
                //chart1.Series["Series1"].Points.AddY(20);
                chart2.Series["Series1"].Points.AddXY(pointsArray[0], pointsArray[1]);
                chart2.ResetAutoValues();
            }
                   
        }



    }
}
