using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

using System.Windows.Forms.DataVisualization.Charting;

namespace ComPort
{
    public partial class Form1 : Form
    {
        string dataOUT;
        string dataIN;
        string sendWith;
        int bufferSize;
        int counter;

        //array for storing history of data for chart
        int[] old_array = new int[1000];
        int[] new_array = new int[1000];

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //getting avaible COM port names
            string[] ports = SerialPort.GetPortNames();
            cBoxCOMPORT.Items.AddRange(ports);

            //making sure, we cant at start press close
            btnOpen.Enabled = true;
            btnClose.Enabled = false;

            //DTR - data terminal ready
            chBoxDtrEnable.Checked = false;
            serialPort1.DtrEnable = false;

            //RTS - request to send
            chBoxDtrEnable.Checked = false;
            serialPort1.DtrEnable = false;

            //send button initial state
            btnSendData.Enabled = true;
            
            //write and writeLine initial states

            sendWith = "Write";

            //Enable always update mode at start
            chBoxAddToOldData.Checked = false;
            chBoxAlwaysUpdate.Checked = false;


            //disabling check boxes, before COM PORT is opened
            chBoxDtrEnable.Enabled = false;
            chBoxRtsEnable.Enabled = false;

            chBoxAlwaysUpdate.Enabled = false;
            chBoxAddToOldData.Enabled = false;

            btnClearDataOut.Enabled = false;
            btnClearDataIn.Enabled = false;

            //Chart inicialization
            chart1.Series.Add("Serie 1");
        }

        //////////////////////////////////////////////////////////////////////////////// 
        //                   OPEN CLOSE

        private void btnOpen_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.PortName = cBoxCOMPORT.Text;
                serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
                serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
                serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBits.Text);
                serialPort1.Parity   = (Parity)Enum.Parse(typeof(Parity), cBoxParityBits.Text);

                serialPort1.Open();
                //turning ON indicators
                progressBar1.Value = 100;
                lblStatusCom.Text = "ON";
                //enable a disable of open and close buttons
                btnOpen.Enabled = false;
                btnClose.Enabled = true;

                //DTR - data terminal ready
                chBoxDtrEnable.Checked = false;
                serialPort1.DtrEnable = false;

                //RTS - request to send
                chBoxDtrEnable.Checked = false;
                serialPort1.DtrEnable = false;

                //send button initial state
                btnSendData.Enabled = true;
                
                sendWith = "Write";

                //Enable always update mode at start
                chBoxAddToOldData.Checked = true;
                chBoxAlwaysUpdate.Checked = false;

                //enabling check boxes, because port was opened COM PORT is opened
                chBoxDtrEnable.Enabled = true;
                chBoxRtsEnable.Enabled = true;
                chBoxAlwaysUpdate.Enabled = true;
                chBoxAddToOldData.Enabled = true;

                btnClearDataOut.Enabled = true;
                btnClearDataIn.Enabled = true;

            }

            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //turning OFF indicators
                progressBar1.Value = 100;
                lblStatusCom.Text = "ON";
                //COM port couldnt be open, therefore user has next chance to press OPEN button
                btnOpen.Enabled = true;
                btnClose.Enabled = false;

                //disabling check boxes, because COM PORT was not opened
                chBoxDtrEnable.Enabled = false;
                chBoxRtsEnable.Enabled = false;
                chBoxAlwaysUpdate.Enabled = false;
                chBoxAddToOldData.Enabled = false;

                btnClearDataOut.Enabled = false;
                btnClearDataIn.Enabled = false;
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            if(serialPort1.IsOpen)
            {
                serialPort1.Close();
                //turning OFF indicators
                progressBar1.Value = 0;
                lblStatusCom.Text = "OFF";
                //enable a disable of open and close buttons
                btnOpen.Enabled = true;
                btnClose.Enabled = false;

            }
        }

        //////////////////////////////////////////////////////////////////////////////// 
        //                   SEND

        private void btnSendData_Click(object sender, EventArgs e)
        {
            if(serialPort1.IsOpen)
            {
                dataOUT = tBoxDataOut.Text;

                if (sendWith == "WriteLine")
                    serialPort1.WriteLine(dataOUT);
                else if (sendWith == "Write")
                    serialPort1.Write(dataOUT);
            }
        }

        //////////////////////////////////////////////////////////////////////////////// 
        //       DTR - data terminal ready           RTS - request to send

        private void chBoxDtrEnable_CheckedChanged(object sender, EventArgs e)
        {
            if (chBoxDtrEnable.Checked)
            {
                serialPort1.DtrEnable = true;
                MessageBox.Show("DTR Enabled", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                serialPort1.DtrEnable = false;
                MessageBox.Show("DTR Disabled", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (chBoxRtsEnable.Checked)
            {
                serialPort1.RtsEnable = true;
                MessageBox.Show("RTS Enabled", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                serialPort1.RtsEnable = false;
                MessageBox.Show("RTS Disabled", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        //////////////////////////////////////////////////////////////////////////////// 
        //                   TEXT BOXES CLEAR

        private void btnClearDataOut_Click(object sender, EventArgs e)
        {
            if (tBoxDataOut.Text != "")
            {
                tBoxDataOut.Text = "";
            }
        }

        private void btnClearDataIn_Click(object sender, EventArgs e)
        {
            if (tBoxDataIn.Text != "")
                tBoxDataIn.Text = "";

        }

        //////////////////////////////////////////////////////////////////////////////// 
        //                       TEXT LENGTH


        private void tBoxDataOut_TextChanged(object sender, EventArgs e)
        {
            int dataOUTLength = tBoxDataOut.TextLength;
            lblDataOutLength.Text = string.Format("{0:00}", dataOUTLength);

        }

        //////////////////////////////////////////////////////////////////////////////// 

        private void tBoxDataOut_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Enter)
                if (serialPort1.IsOpen)
                {
                    dataOUT = tBoxDataOut.Text;
                    serialPort1.WriteLine(dataOUT);
                }
        }

        //***********************************************************************************
        //                     Transmitter - Write vs Write line                            *
        //***********************************************************************************

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            //dataIN = serialPort1.ReadExisting();
            string last_character = "@";
            dataIN = serialPort1.ReadTo(last_character);
            bufferSize = serialPort1.ReadBufferSize;

            if(true)
            {
                Console.WriteLine("bufferSize:");
                Console.WriteLine(bufferSize);
                Console.WriteLine(dataIN);
                Console.WriteLine("");
            }

            counter++;
            if (counter == 10)
            {
                this.Invoke(new EventHandler(ShowData));
                counter = 0;
            }

        }

        //////////////////////////////////////////////////////////////////////////////// 
        //                 HANDLES RECIEVING OF DATA

        private void ShowData(object sender, EventArgs e)
        {
            //***********************************************************************************
            //            SHOWING INFORMATION ABOUT MESSAGE LENGTH                              *
            //***********************************************************************************
            int dataINLength = dataIN.Length;                                           //obtaining size of input data - used for printing into message box
            lblDataInLength.Text = string.Format("{0:00}", dataINLength);               //putting input text to box

            //determines whether box keeps data stored
            if (chBoxAlwaysUpdate.Checked)
                tBoxDataIn.Text = dataIN;
            else if (chBoxAddToOldData.Checked)
                tBoxDataIn.Text += dataIN;

            //***********************************************************************************
            //                              CREATING CHART                                      *
            //***********************************************************************************

            Array.Copy(new_array, 1, new_array, 0, new_array.Length - 1);

            //***********************************************************************************
            //                              FORMATING CHART                                     *
            //***********************************************************************************
            bool success_parsing_string = int.TryParse(dataIN, out new_array[999]);    //we need to convert input string to integer to put it into array
            //-----------------------------------
            if(true)
            {
                Console.WriteLine("NewArrayValue");
                Console.WriteLine(new_array[999]);
                Console.WriteLine("");
            }
            //-----------------------------------
            var chart = chart1.ChartAreas[0];                                          //obtaining chart handle
            chart.AxisX.IntervalType = DateTimeIntervalType.Number;
                        //Chart labels
                        //chart.AxisX.LabelStyle.Format = "Time";
                        //chart.AxisY.LabelStyle.Format = "Number";
                        //chart.AxisY.LabelStyle.IsEndLabelVisible = true;

            //Chart axis dimensions
            chart.AxisX.Minimum = 1;
            chart.AxisX.Maximum = 1000;  //we log last 1000 values
            chart.AxisY.Minimum = 0;
            chart.AxisY.Maximum = 100000;

            //Axis scale precision
            chart.AxisX.Interval = 100;
            chart.AxisY.Interval = 5000;

            //Chart series type
            //chart1.Series["Serie 1"].ChartType = SeriesChartType.Line;
            //chart1.Series["Serie 1"].ChartType = SeriesChartType.Spline;

            //Setting color
            chart1.Series["Serie 1"].Color = Color.Red;
            chart1.Series[0].IsVisibleInLegend = false;

            chart1.Series["Serie 1"].Points.Clear();
            for (int i = 0; i < 1000; i++)
            {
                
                chart1.Series["Serie 1"].Points.AddXY(i, new_array[i]);
            }
            
        }

        //////////////////////////////////////////////////////////////////////////////// 
        //         UPDATING INPUT TEXT - ALWAYS OR KEEP ADDING TEXT TO TEXT BOX

        private void chBoxAlwaysUpdate_CheckedChanged(object sender, EventArgs e)
        {
            if (chBoxAlwaysUpdate.Checked)
            {
                chBoxAlwaysUpdate.Checked = true;
                chBoxAddToOldData.Checked = false;
            }
            else
                chBoxAddToOldData.Checked = true;
        }

        private void chBoxAddToOldData_CheckedChanged(object sender, EventArgs e)
        {
            if (chBoxAddToOldData.Checked)
            {
                chBoxAlwaysUpdate.Checked = false;
                chBoxAddToOldData.Checked = true;
            }
            else
                chBoxAlwaysUpdate.Checked = true;
        }

        private void tBoxDataIn_TextChanged(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void progressBar1_Click(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void lblStatusCom_Click(object sender, EventArgs e)
        {

        }

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }


        //////////////////////////////////////////////////////////////////////////////// 


    }
}
