using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;

namespace Application_Monitor
{
    public partial class frmPulseOximetryOnlineSigned : Form
    {
        float pxOld = 0,pyOld=0;
        int intSamplingRate = 0;
        Pen gridPen = new Pen(Color.DimGray);
        float intYConfigure = 0;
        int intSPo2Time = 0;
        string m_HR = "XXX";
        string m_Spo2 = "128";
        float m_PPIX = 0;
        float m_PPIY = 0;
        Pen redPen = new Pen(Color.Red);
        Graphics objSpo2Graphics;
        Graphics objSpo2RedGraphics;
        RS_232_Communication objRS232;
        bool blnHeader = false;
        byte[] bttemp = null;
        //create variables for storing current and previous points        
        float px, py = 0,pxRed=0,pyRed=0;
        Queue _queue = new Queue();
        //create colored pens for drawing 
        Pen yelgpen = new Pen(Color.YellowGreen);        
        Pen blackpen = new Pen(Color.Black);        
        int intDisplayBuffer = 0;
        bool blnXScale = false;
        int intXScaling = 0;
        Bitmap bmpPulseOximetry = null;
        Bitmap bmpRed = null;
        int intAcquireBuffer = 0;
        bool blnInitial = false;
        int intDataCount = 0;
        int int25DisplayBuffer = 0;
        int int50DisplayBuffer = 0;
        SpO2Data[] objSpO2Data = null;
        bool blnRecord = false;
        int intStringLength = 5000;
        StringBuilder strData = null;
        DateTime dtStart = DateTime.Now;
        bool blnYScale = false;
        float ftYScale = 1;
        int intClearBuffer = 0;
        int intClearBufferCount = 0;
        Pen objPenGraph1 = null;
        public RS_232_Communication RS232Communication
        {
            get
            {
                return objRS232;
            }
            set
            {
                objRS232 = value;
            }
        }
        public frmPulseOximetryOnlineSigned()
        {
            InitializeComponent();
            
            intSamplingRate = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["Spo2SamplingRate"]);
            intYConfigure = (float)Convert.ToSingle(System.Configuration.ConfigurationSettings.AppSettings["Spo2YConfigure"]);
            intXScaling = (int)Constants.XScale.XSCale_25mm;
            intSPo2Time = (int)Constants.TimeForScaling.Time_25mmXScale;
            objSpO2Data = new SpO2Data[intSamplingRate * (int)Constants.TimeForScaling.Time_25mmXScale];
            intClearBuffer = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["ClearBuffer"]);
            for (int i = 0; i < intSamplingRate * (int)Constants.TimeForScaling.Time_25mmXScale; i++)
            {
                SpO2Data objSpO2 = new SpO2Data();
                objSpO2Data[i] = objSpO2;
            }
            strData = new StringBuilder();
          //  DrawSpO2PieChart();
        }

        /// <summary>
        /// Used to store the recorded ECG data
        /// </summary>
        /// <param name="strInfo">ECG Information</param>
        public void SaveRecordedData(string strInfo)
        {
            if (strData != null && strData.Length == intStringLength)
            {
                WriteFile(strData.ToString());
                strData = null;
                strData = new StringBuilder();
            }
            strData.Append(strInfo);
        }

        /// <summary>
        /// This function is used to draw the grid lines on the graphs
        /// </summary>
        private void DrawGrid()
        {
          //  float flt5mmYAxis = (10 * m_PPIY) / 25.4F;
            int intHorLines = pbxPulseOximetry.Height / 10;
            //Draw horizontal lines  
            for (int i = 0; i < intHorLines; i++)
            {
                objSpo2Graphics.DrawLine(gridPen, 0, i *25, pbxPulseOximetry.Width, i * 25);
              //  objSpo2RedGraphics.DrawLine(gridPen, 0, i * flt5mmYAxis, pbxRed.Width, i * flt5mmYAxis);
               
            }

            //Draw Vertical lines
            float flt5mmXAxis = (10 * m_PPIX) / 25.4F;
            int intVertLines = (intSPo2Time * intXScaling) / 10;
            for (int i = 0; i < intVertLines; i++)
            {
                objSpo2Graphics.DrawLine(gridPen, i * flt5mmXAxis, 0, i * flt5mmXAxis, pbxPulseOximetry.Height);
                //objSpo2RedGraphics.DrawLine(gridPen, i * flt5mmXAxis, 0, i * flt5mmXAxis, pbxRed.Height);
             
            }
            pbxPulseOximetry.Image = bmpPulseOximetry;
            pbxRed.Image = bmpRed;
            
        }

        //private void DrawSpO2PieChart()
            
        //{
        //    Bitmap myImagepie = new Bitmap(pbxPie.Width, pbxPie.Height);
        //    pbxPie.Image = myImagepie;

        //    // Get the graphics handler reference
        //    Graphics objGraphics = Graphics.FromImage(myImagepie);
        //    //objGraphics.DrawEllipse(new Pen(Color.Blue), 0, 0, 100, 100);
        //    objGraphics.FillEllipse(new SolidBrush(Color.Tomato), 1, 1, 100, 100);
        //    objGraphics.FillPie(new SolidBrush(Color.Blue),1,1,100,100,0,72);
        //    //objGraphics.DrawPie(new Pen(Color.PowderBlue), 0, 0, pbxPie.Width, pbxPie.Height, 324, 36);
        //}

        private void frmPulseOximetryOnline_Load(object sender, EventArgs e)
        {
            this.CancelButton = btnCancel;
            SetControls();
           
                SetSerialPortSettings();
         
            _timerPulseOximetry.Start();
            _timerDraw.Interval = 60;
            _timerDraw.Start();
        }

        private void SetControls()
        {
            // Set the width and height of the picture boxes
            Graphics objGraphics = CreateGraphics();
            //Calculate the pixels per inch
            PixelsPerInch objPPI = new PixelsPerInch(objGraphics);
            m_PPIX = objPPI.PPIX;
            m_PPIY = objPPI.PPIY;
            int intWidth = (int)((intXScaling * intSPo2Time * m_PPIX) / 25.4);
            pbxPulseOximetry.Width = intWidth;
            bmpPulseOximetry = new Bitmap(pbxPulseOximetry.Width, pbxPulseOximetry.Height);
            pbxPulseOximetry.Image = bmpPulseOximetry;   


            pbxRed.Width = intWidth;
            bmpRed = new Bitmap(pbxRed.Width, pbxRed.Height);
            pbxRed.Image = bmpRed;

            // Get the graphics handler reference
            objSpo2RedGraphics = Graphics.FromImage(bmpRed);

            // Get the graphics handler reference
            objSpo2Graphics = Graphics.FromImage(bmpPulseOximetry);
            lblScaleXtext.Text = intXScaling.ToString() + " " + Constants.XSCALE_MEASURE;
            lblScaleYText.Text = "100" + " %";
            DrawGrid();
            this.Width = pbxPulseOximetry.Width + 200;
            gpScale.Left = pbxPulseOximetry.Right - gpScale.Width;
            saveFileDialog.DefaultExt = Constants.SPO2_FILE_EXTENSION;
            saveFileDialog.AddExtension = true;
            saveFileDialog.Filter = "SpO2 Files (*.spo2)|*.spo2|All files (*.*)|*.*";
            saveFileDialog.OverwritePrompt = true;


        }

        /// <summary>
        /// This is used to set the Com port settings and open the Com port.
        /// </summary>
        private void SetSerialPortSettings()
        {
            objRS232.OpenCOMPort();
           
        }   
   
     

        private void _timerPulseOximetry_Tick(object sender, EventArgs e)
        {
            //Check whether serial port is opened or not
            if (objRS232.objSerialPort != null && objRS232.objSerialPort.IsOpen)
            {
                try
                {
                    // Obtain the number of bytes waiting in the port's buffer 
                    int bytes = objRS232.objSerialPort.BytesToRead;

                    // Create a byte array buffer to hold the incoming data 
                    byte[] buffer = new byte[bytes];

                    // Read the data from the port and store it in our buffer 
                    objRS232.objSerialPort.Read(buffer, 0, bytes);
                    if (buffer != null && buffer.Length > 0)
                    {
                        toolStripStatusSP.Image = global::Application_Monitor.Properties.Resources.SerialPortConnected; ;
                        toolStripStatusSP.Text = "     Serial Port Connected";
                        StoreData(buffer);                       
                    }                   
                }
                catch (Exception objException)
                {
                    string str = objException.Message;
                }
            }
           
        }

        ///// <summary>
        ///// This function used to parse and save the ECG data that recieved from RS 232
        ///// </summary>
        ///// <param name="bytSPDataOld">Bytes recieved from Com Poert</param>
        //private void StoreData(byte[] bytSPDataOld)
        //{
        //    byte[] bytSPData = null;
        //    try
        //    {
        //        if (bytSPDataOld != null && bytSPDataOld.Length > 0)
        //        {
        //            try
        //            {
        //                //Verfify whether temp buffer is having any data or not
        //                //If temp is having data then merge the bytes from temp to the RS 232 recieved bytes
        //                if (bttemp != null && bttemp.Length >= 1)
        //                {
        //                    bytSPData = new byte[bytSPDataOld.Length + bttemp.Length];
        //                    Buffer.BlockCopy(bttemp, 0, bytSPData, 0, bttemp.Length);
        //                    Buffer.BlockCopy(bytSPDataOld, 0, bytSPData, bttemp.Length, bytSPDataOld.Length);
        //                }
        //                else
        //                {
        //                    bytSPData = bytSPDataOld;
        //                }
        //            }
        //            catch (Exception objException)
        //            {
        //                string str = objException.Message;
        //            }

        //            int intCount = 0;
        //            //Check whether Header has recieved or not
        //            if (!blnHeader)
        //            {
        //                while (intCount < bytSPData.Length)
        //                {
        //                    try
        //                    {
        //                        if (bytSPData.Length - intCount >= 6)
        //                        {
        //                            byte[] bytHeader = new byte[7];
        //                            Buffer.BlockCopy(bytSPData, intCount, bytHeader, 0, 6);
        //                            //If header has recieved set the header flag
        //                            if (bytHeader[0].ToString("X2") == Constants.SPO2_HEADER_BYTE1.ToString()
        //                            && bytHeader[1].ToString("X2") == Constants.SPO2_HEADER_BYTE2.ToString()
        //                           && bytHeader[2].ToString("X2") == Constants.SPO2_HEADER_BYTE3.ToString()
        //                                 && bytHeader[3].ToString("X2") == Constants.SPO2_HEADER_BYTE4.ToString()
        //                           && bytHeader[4].ToString("X2") == Constants.SPO2_HEADER_BYTE5.ToString())
        //                            {
        //                                blnHeader = true;                                       
        //                                break;
        //                            }
        //                            else
        //                            {
        //                                intCount++;
        //                            }
        //                        }
        //                        else
        //                        {
        //                            break;
        //                        }
        //                    }
        //                    catch (Exception objException)
        //                    {
        //                        string str = objException.Message;
        //                    }
        //                }
        //            }
        //            //Starts reading the data once it recieves the initial header
        //            if (blnHeader)
        //            {
        //                while (intCount < bytSPData.Length)
        //                {
        //                    if (bytSPData.Length - intCount >= 5)
        //                    {
        //                        byte[] bytHeader = new byte[5];
        //                        Buffer.BlockCopy(bytSPData, intCount, bytHeader, 0, 5);
        //                        //Check whether Header has recieved or not. If store the heart rate, Lead off and 
        //                        //Leads samples
        //                        if (bytHeader[0].ToString("X2") == Constants.SPO2_HEADER_BYTE1.ToString()
        //                            && bytHeader[1].ToString("X2") == Constants.SPO2_HEADER_BYTE2.ToString()
        //                           && bytHeader[2].ToString("X2") == Constants.SPO2_HEADER_BYTE3.ToString()
        //                                 && bytHeader[3].ToString("X2") == Constants.SPO2_HEADER_BYTE4.ToString()
        //                           && bytHeader[4].ToString("X2") == Constants.SPO2_HEADER_BYTE5.ToString())
        //                        {
        //                            if (bytSPData.Length - intCount >= 7)
        //                            {


        //                              ushort ussampleData=  BitConverter.ToUInt16(bytSPData, intCount+ 5);
        //                              _queue.Enqueue(ussampleData);
        //                                intCount = intCount + 7;
        //                            }
        //                            else
        //                            {
        //                                break;
        //                            }
        //                        }
        //                        if (bytSPData.Length - intCount >= 2)
        //                        {
        //                            ushort ussampleData = BitConverter.ToUInt16(bytSPData, intCount);
        //                            _queue.Enqueue(ussampleData);
                                    
        //                            intCount = intCount + 2;
        //                        }
        //                        else
        //                        {
        //                            break;
        //                        }
        //                    }
        //                    else
        //                    {
        //                        break;
        //                    }

        //                }

        //            }
        //            bttemp = null;
        //            bttemp = new byte[bytSPData.Length - intCount];
        //            if (bttemp != null && bttemp.Length > 0)
        //            {
        //                Buffer.BlockCopy(bytSPData, intCount, bttemp, 0, bytSPData.Length - intCount);
        //            }
        //        }

        //    }
        //    catch (Exception objException)
        //    {
        //        string str = objException.Message;
        //    }
        //}

        ///// <summary>
        ///// This function used to parse and save the ECG data that recieved from RS 232
        ///// </summary>
        ///// <param name="bytSPDataOld">Bytes recieved from Com Poert</param>
        //private void StoreData(byte[] bytSPDataOld)
        //{
        //    byte[] bytSPData = null;
        //    try
        //    {
        //        if (bytSPDataOld != null && bytSPDataOld.Length > 0)
        //        {
        //            try
        //            {
        //                //Verfify whether temp buffer is having any data or not
        //                //If temp is having data then merge the bytes from temp to the RS 232 recieved bytes
        //                if (bttemp != null && bttemp.Length >= 1)
        //                {
        //                    bytSPData = new byte[bytSPDataOld.Length + bttemp.Length];
        //                    Buffer.BlockCopy(bttemp, 0, bytSPData, 0, bttemp.Length);
        //                    Buffer.BlockCopy(bytSPDataOld, 0, bytSPData, bttemp.Length, bytSPDataOld.Length);
        //                }
        //                else
        //                {
        //                    bytSPData = bytSPDataOld;
        //                }
        //            }
        //            catch (Exception objException)
        //            {
        //                string str = objException.Message;
        //            }

        //            int intCount = 0;
        //            //Check whether Header has recieved or not
        //            if (!blnHeader)
        //            {
        //                while (intCount < bytSPData.Length)
        //                {
        //                    try
        //                    {
        //                        if (bytSPData.Length - intCount >= 6)
        //                        {
        //                            byte[] bytHeader = new byte[7];
        //                            Buffer.BlockCopy(bytSPData, intCount, bytHeader, 0, 6);
        //                            //If header has recieved set the header flag
        //                            if (bytHeader[0].ToString("X2") == Constants.SPO2_HEADER_BYTE1.ToString()
        //                            && bytHeader[1].ToString("X2") == Constants.SPO2_HEADER_BYTE2.ToString()
        //                           && bytHeader[2].ToString("X2") == Constants.SPO2_HEADER_BYTE3.ToString()
        //                                 && bytHeader[3].ToString("X2") == Constants.SPO2_HEADER_BYTE4.ToString()
        //                           && bytHeader[4].ToString("X2") == Constants.SPO2_HEADER_BYTE5.ToString())
        //                            {
        //                                blnHeader = true;
        //                                break;
        //                            }
        //                            else
        //                            {
        //                                intCount++;
        //                            }
        //                        }
        //                        else
        //                        {
        //                            break;
        //                        }
        //                    }
        //                    catch (Exception objException)
        //                    {
        //                        string str = objException.Message;
        //                    }
        //                }
        //            }
        //            //Starts reading the data once it recieves the initial header
        //            if (blnHeader)
        //            {
        //                while (intCount < bytSPData.Length)
        //                {
        //                    if (bytSPData.Length - intCount >= 5)
        //                    {
        //                        byte[] bytHeader = new byte[5];
        //                        Buffer.BlockCopy(bytSPData, intCount, bytHeader, 0, 5);
        //                        //Check whether Header has recieved or not. If store the heart rate, Lead off and 
        //                        //Leads samples
        //                        if (bytHeader[0].ToString("X2") == Constants.SPO2_HEADER_BYTE1.ToString()
        //                            && bytHeader[1].ToString("X2") == Constants.SPO2_HEADER_BYTE2.ToString()
        //                           && bytHeader[2].ToString("X2") == Constants.SPO2_HEADER_BYTE3.ToString()
        //                                 && bytHeader[3].ToString("X2") == Constants.SPO2_HEADER_BYTE4.ToString()
        //                           && bytHeader[4].ToString("X2") == Constants.SPO2_HEADER_BYTE5.ToString())
        //                        {
        //                            if (bytSPData.Length - intCount >= 5)
        //                            {                                       
                                        
                                       
        //                                intCount = intCount + 5;
        //                            }
        //                            else
        //                            {
        //                                break;
        //                            }
        //                        }
        //                        if (bytSPData.Length - intCount >= 4)
        //                        {
        //                            SpO2Data objData = new SpO2Data();
                                    
        //                            short usIRsampleData = BitConverter.ToInt16(bytSPData, intCount);
        //                            objData.SpO2Sample = usIRsampleData;
        //                            short usRsampleData = BitConverter.ToInt16(bytSPData, intCount+2);
        //                            objData.SpO2RedSample = usRsampleData;
        //                            _queue.Enqueue(objData);                                    
        //                            if (!blnInitial && (intAcquireBuffer + 1) == 10)
        //                            {
        //                                blnInitial = true;
        //                            }
        //                            if (intAcquireBuffer == intSamplingRate * (int)Constants.TimeForScaling.Time_25mmXScale - 1)
        //                            {
        //                                intAcquireBuffer = 0;
        //                            }
        //                            else
        //                            {
        //                                intAcquireBuffer++;
        //                            }
                                   
        //                            intCount = intCount + 4;
        //                        }
        //                        else
        //                        {
        //                            break;
        //                        }
        //                    }
        //                    else
        //                    {
        //                        break;
        //                    }

        //                }

        //            }
        //            bttemp = null;
        //            bttemp = new byte[bytSPData.Length - intCount];
        //            if (bttemp != null && bttemp.Length > 0)
        //            {
        //                Buffer.BlockCopy(bytSPData, intCount, bttemp, 0, bytSPData.Length - intCount);
        //            }
        //        }

        //    }
        //    catch (Exception objException)
        //    {
        //        string str = objException.Message;
        //    }
        //}


        /// <summary>
        /// This function used to parse and save the ECG data that recieved from RS 232
        /// </summary>
        /// <param name="bytSPDataOld">Bytes recieved from Com Poert</param>
        private void StoreData(byte[] bytSPDataOld)
        {
            byte[] bytSPData = null;
            try
            {
                if (bytSPDataOld != null && bytSPDataOld.Length > 0)
                {
                    try
                    {
                        //Verfify whether temp buffer is having any data or not
                        //If temp is having data then merge the bytes from temp to the RS 232 recieved bytes
                        if (bttemp != null && bttemp.Length >= 1)
                        {
                            bytSPData = new byte[bytSPDataOld.Length + bttemp.Length];
                            Buffer.BlockCopy(bttemp, 0, bytSPData, 0, bttemp.Length);
                            Buffer.BlockCopy(bytSPDataOld, 0, bytSPData, bttemp.Length, bytSPDataOld.Length);
                        }
                        else
                        {
                            bytSPData = bytSPDataOld;
                        }
                    }
                    catch (Exception objException)
                    {
                        string str = objException.Message;
                    }

                    int intCount = 0;
                    //Check whether Header has recieved or not
                    if (!blnHeader)
                    {
                        while (intCount < bytSPData.Length)
                        {
                            try
                            {
                                if (bytSPData.Length - intCount >= 6)
                                {
                                    byte[] bytHeader = new byte[7];
                                    Buffer.BlockCopy(bytSPData, intCount, bytHeader, 0, 6);
                                    //If header has recieved set the header flag
                                    if (bytHeader[0].ToString("X2") == Constants.SPO2_HEADER_BYTE1.ToString()
                                    && bytHeader[1].ToString("X2") == Constants.SPO2_HEADER_BYTE2.ToString()
                                   && bytHeader[2].ToString("X2") == Constants.SPO2_HEADER_BYTE3.ToString()
                                         && bytHeader[3].ToString("X2") == Constants.SPO2_HEADER_BYTE4.ToString()
                                   && bytHeader[4].ToString("X2") == Constants.SPO2_HEADER_BYTE5.ToString())
                                    {
                                        blnHeader = true;
                                        break;
                                    }
                                    else
                                    {
                                        intCount++;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            catch (Exception objException)
                            {
                                string str = objException.Message;
                            }
                        }
                    }
                    //Starts reading the data once it recieves the initial header
                    if (blnHeader)
                    {
                        while (intCount < bytSPData.Length)
                        {
                            if (bytSPData.Length - intCount >= 5)
                            {
                                byte[] bytHeader = new byte[5];
                                Buffer.BlockCopy(bytSPData, intCount, bytHeader, 0, 5);
                                //Check whether Header has recieved or not. If store the heart rate, Lead off and 
                                //Leads samples
                                if (bytHeader[0].ToString("X2") == Constants.SPO2_HEADER_BYTE1.ToString()
                                    && bytHeader[1].ToString("X2") == Constants.SPO2_HEADER_BYTE2.ToString()
                                   && bytHeader[2].ToString("X2") == Constants.SPO2_HEADER_BYTE3.ToString()
                                         && bytHeader[3].ToString("X2") == Constants.SPO2_HEADER_BYTE4.ToString()
                                   && bytHeader[4].ToString("X2") == Constants.SPO2_HEADER_BYTE5.ToString())
                                {
                                    if (bytSPData.Length - intCount >= 7)
                                    {
                                        // Store the lead Off status info
                                        byte sbytSpo2 = Convert.ToByte(bytSPData[intCount + 5]);                                        
                                        m_Spo2 = sbytSpo2.ToString();
                                       // lblSpO2Text.Text = m_Spo2 + "%";
                                        byte sbytHR = Convert.ToByte(bytSPData[intCount + 6]);
                                        //Store the heart rate
                                        m_HR = sbytHR.ToString();
                                        lblHRText.Text = m_HR;                                      
                                        if (blnRecord)
                                        {
                                            SaveRecordedData(System.Environment.NewLine);
                                            SaveRecordedData(Constants.SPO2.Trim().ToUpper());
                                            SaveRecordedData('\t'.ToString());
                                            SaveRecordedData(m_Spo2);    
                                            SaveRecordedData(System.Environment.NewLine);
                                            SaveRecordedData(Constants.HEART_RATE.Trim().ToUpper());
                                            SaveRecordedData('\t'.ToString());
                                            SaveRecordedData(m_HR);
                                                                                 
                                        }
                                        intCount = intCount + 7;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                if (bytSPData.Length - intCount >= 4)
                                {
                                    SpO2Data objData = new SpO2Data();
                                    objData.SpO2 = m_Spo2;
                                    objData.HeartRate = m_HR;
                                    short usIRsampleData = BitConverter.ToInt16(bytSPData, intCount);
                                    objData.SpO2Sample = usIRsampleData;

                                    short usRsampleData = BitConverter.ToInt16(bytSPData, intCount + 2);
                                    objData.SpO2RedSample = usRsampleData;
                                    _queue.Enqueue(objData);

                                    if (blnRecord)
                                    {
                                        SaveRecordedData(System.Environment.NewLine);
                                        SaveRecordedData(usIRsampleData.ToString());
                                        SaveRecordedData('\t'.ToString());
                                        SaveRecordedData(usRsampleData.ToString());
                                    }

                                    
                                    if (!blnInitial && (intAcquireBuffer + 1) == 10)
                                    {
                                        blnInitial = true;
                                    }
                                    if (intAcquireBuffer == intSamplingRate * (int)Constants.TimeForScaling.Time_25mmXScale - 1)
                                    {
                                        intAcquireBuffer = 0;
                                    }
                                    else
                                    {
                                        intAcquireBuffer++;
                                    }

                                    intCount = intCount + 4;
                                   
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }

                        }

                    }
                    bttemp = null;
                    bttemp = new byte[bytSPData.Length - intCount];
                    if (bttemp != null && bttemp.Length > 0)
                    {
                        Buffer.BlockCopy(bytSPData, intCount, bttemp, 0, bytSPData.Length - intCount);
                    }
                }

            }
            catch (Exception objException)
            {
                string str = objException.Message;
            }
        }
        /// <summary>
        /// This is used to draw the grid lines for erased path
        /// </summary>
        /// <param name="xValue">X value</param>
        /// <param name="intWidth">Width of the Erased rectangle</param>
        /// <param name="objGraphics">Graphics object</param>
        /// <param name="pbxLead">Picture box</param>
        private void FillGrid(float xValue, float intWidth, Graphics objGraphics, PictureBox pbxLead)
        {
            float flt5mmXAxis = (10 * m_PPIX) / 25.4F;
            float fltFillRectangle = 0.03125f;
            //Draw Vertical lines
            int intVertLines = (intSPo2Time * intXScaling) / 10;
            for (int i = 1; i < intVertLines; i++)
            {
                float fltmm = i * flt5mmXAxis;
                //if ((fltmm >=(int) xValue && fltmm <=(int)( xValue + intWidth)))// || (fltmm >= 0 && fltmm <= pbxLead.Height))
                if ((fltmm >= xValue && fltmm <= xValue + intWidth)
                    || ((int)xValue == (int)fltmm) && (xValue - Math.Floor(xValue) < fltFillRectangle))
                // || (fltmm >= 0 && fltmm <= pbxLead.Height))
                {
                    objGraphics.DrawLine(gridPen, fltmm, 0, fltmm, pbxLead.Height);
                    //  break;
                }
            }
            //float flt5mmYAxis = (10 * m_PPIY) / 25.4F;
            int intHorLines = pbxPulseOximetry.Height / 25;
            //Draw horizontal lines  
            for (int i = 1; i < intHorLines; i++)
            {
                float fltmm = i * 25;
                //if ((fltmm >= xValue && fltmm <= xValue + intWidth) || (fltmm >= 0 && fltmm <= pbxLead.Height))
                //{
                objGraphics.DrawLine(gridPen, xValue, fltmm, xValue + intWidth, fltmm);
                //}
            }
        }

        /// <summary>
        /// This method is used to display the selected Y - Scale 5, 10 0r 20 mm/mV
        /// </summary>
        private void ScalingOnTime()
        {
            blnXScale = true;
            
            switch (intXScaling)
            {
                case (int)Constants.XScale.XSCale_25mm:
                    {
                        intXScaling = (int)Constants.XScale.XSCale_50mm;
                        intSPo2Time = (int)Constants.TimeForScaling.Time_50mmXScale;
                        lblScaleXtext.Text = intXScaling.ToString() + " " + Constants.XSCALE_MEASURE;
                        break;


                    }
                case (int)Constants.XScale.XSCale_50mm:
                    {

                        intXScaling = (int)Constants.XScale.XSCale_25mm;
                        intSPo2Time = (int)Constants.TimeForScaling.Time_25mmXScale;
                        lblScaleXtext.Text = intXScaling.ToString() + " " + Constants.XSCALE_MEASURE;
                        break;
                    }

                default:
                    break;
            }
           
        }

        /// <summary>
        /// This method is used to display the selected Y - Scale 5, 10 0r 20 mm/mV
        /// </summary>
        private void ScalingOnYAxis()
        {
            blnYScale = true;

            if (ftYScale == 1)
            {
                ftYScale = 2;
                lblScaleYText.Text = "200" + " %";
            }
            else if (ftYScale == 2)
            {
                ftYScale = 3f;
                lblScaleYText.Text = "300" + " %";
            }
            else if (ftYScale == 3)
            {
                ftYScale = 0.5f;
                lblScaleYText.Text = "50" + " %";
            }
            else if (ftYScale == 0.5F)
            {
                ftYScale = 0.75f;
                lblScaleYText.Text = "75" + " %";
            }
            else if (ftYScale == 0.75F)
            {
                ftYScale = 1;
                lblScaleYText.Text = "100" + " %";
            }

        }

        /// <summary>
        /// This functio is used to record the ECG data
        /// </summary>
        private void Recording()
        {
            string strTitle = toolTip.GetToolTip(btnRecord);

            // string strtspTitle = toolStrip.Items[5].ToolTipText;
            //Start Recording Option
            // if (btnRecord.Text.ToLower().Trim() == "Start Recording".ToLower().Trim())
            if (strTitle.ToLower().Trim() == "Start Recording".ToLower().Trim())
            // || strtspTitle.ToLower().Trim() == "Start Recording".ToLower().Trim())
            {
                //Create a new temporary file       
                string srcfilename = Application.StartupPath + "\\SPO2\\" + Constants.SPO2_TEMP_FILENAME + Constants.SPO2_FILE_EXTENSION;
                try
                {
                    if (File.Exists(srcfilename))
                    {
                        File.Delete(srcfilename);
                    }
                }
                catch (Exception objExc)
                {
                    string str = objExc.Message;
                }

                blnRecord = true;
                btnRecord.Text = "Stop &Recording";
                toolTip.SetToolTip(btnRecord, "Stop Recording");
                //  toolStrip.Items[5].ToolTipText = "Stop Recording";
                // tspbtnRecord.Text = "Stop &Recording";
                SaveRecordedData(System.Environment.NewLine);
                SaveRecordedData(Constants.SPO2.Trim().ToUpper());
                SaveRecordedData('\t'.ToString());
                SaveRecordedData(m_Spo2);
                SaveRecordedData(System.Environment.NewLine);
                SaveRecordedData(Constants.HEART_RATE.Trim().ToUpper());
                SaveRecordedData('\t'.ToString());
                SaveRecordedData(m_HR);
            }
            //Stop Recording Option
            // else if (btnRecord.Text.ToLower().Trim() == "Stop Recording".ToLower().Trim())
            else if (strTitle.ToLower().Trim() == "Stop Recording".ToLower().Trim())
            // || strtspTitle.ToLower().Trim() == "Stop Recording".ToLower().Trim())
            {
                blnRecord = false;
                btnRecord.Text = "Start &Recording";
                toolTip.SetToolTip(btnRecord, "Start Recording");
                //  toolStrip.Items[5].ToolTipText = "Start Recording";
                // tspbtnRecord.Text = "Start &Recording";
                //Save the ECG information in the temporary file     
                if (strData != null && strData.Length >= 1)
                {
                    WriteFile(strData.ToString());
                }
                RecordData();

            }
        }

        /// <summary>
        /// This function is used to open the SaveFileDialog to store the recorded ECG file
        /// </summary>
        private void RecordData()
        {
            string strPath = Application.StartupPath + "\\SPO2\\";
            try
            {
                if (!Directory.Exists(strPath))
                {
                    Directory.CreateDirectory(strPath);

                }
            }
            catch (Exception objException)
            {
                string str = objException.Message;
            } saveFileDialog.InitialDirectory = strPath;

            int intFileNo = 1;

            while (File.Exists(strPath + Constants.SPO2_FILE_NAME.Trim() + intFileNo.ToString() + Constants.SPO2_FILE_EXTENSION))
            {
                intFileNo++;
            }

            saveFileDialog.FileName = strPath + Constants.SPO2_FILE_NAME.Trim().ToUpper() + intFileNo.ToString() + Constants.SPO2_FILE_EXTENSION;
            Showdialog();
            string srcfilename = Application.StartupPath + "\\SPO2\\" + Constants.SPO2_TEMP_FILENAME + Constants.SPO2_FILE_EXTENSION;
            try
            {
                if (File.Exists(srcfilename))
                {

                    File.Delete(srcfilename);
                }
            }
            catch (Exception objExc)
            {
                string str = objExc.Message;
            }
        }

        /// <summary>
        /// This function is used to save the SPO2 file in a particlular path
        /// </summary>
        private void Showdialog()
        {
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string srcfilename = Application.StartupPath + "\\SPO2\\" + Constants.SPO2_TEMP_FILENAME + Constants.SPO2_FILE_EXTENSION;
                try
                {
                    if (File.Exists(srcfilename))
                    {

                        File.Copy(srcfilename, saveFileDialog.FileName);
                    }
                }
                catch (Exception objExc)
                {
                    string str = objExc.Message;
                }
            }
            else
            {
                if (MessageBox.Show("The Recoreded SPO2 data is not saved and will be lost. Press Cancel to go back and save SPO2 or OK to continue."
              , "", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
                {
                    Showdialog();
                }
            }
        }

        /// <summary>
        /// Used to save the recorded data in a text file
        /// </summary>
        /// <param name="stringData">SPO2 Data</param>
        private void WriteFile(String stringData)
        {
            StreamWriter lswException = null;
            try
            {
                if (strData != null && strData.Length >= 1)
                {
                    //Check whether SPO2 folder exists or not. If not create the folder
                    if (!Directory.Exists(Application.StartupPath + "\\SPO2\\"))
                    {
                        Directory.CreateDirectory(Application.StartupPath + "\\SPO2\\");
                    }
                    string filename = Application.StartupPath + "\\SPO2\\" + Constants.SPO2_TEMP_FILENAME + Constants.SPO2_FILE_EXTENSION;
                    //Check whether file exists or not.
                    if (File.Exists(filename))
                    {
                        lswException = File.AppendText(filename);
                    }
                    else
                    {
                        lswException = File.CreateText(filename);
                    }
                    lswException.Write(stringData);
                    strData = null;
                    strData = new StringBuilder();
                }
                lswException.Close();
            }
            catch (Exception objException)
            {
                string str = objException.Message;
            }
            finally
            {
                if (lswException != null)
                {
                    lswException.Close();
                }
            }
        }

        private void btnXScaling_Click(object sender, EventArgs e)
        {
            ScalingOnTime();
        }

        private void btnScale_Click(object sender, EventArgs e)
        {
            ScalingOnYAxis();
        }

        private void btnRecord_Click(object sender, EventArgs e)
        {
            Recording();

        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            objRS232.CloseCOMPort();
            this.Close();
        }

        private void DrawStaticSpo2Graph()
        {
            objSpo2RedGraphics.Clear(Color.Black);
            objSpo2Graphics.Clear(Color.Black);

           int intDisplayStaticBuffer = 0;
           float pxStatic=0, x2Static=0;
           float pyStatic=0 , y2Graph1Static=0;
           float pyRedStatic = 0, y2RedGraph1Static = 0;
            SpO2Data[] objSpO2 = null;
            if (intSPo2Time == (int)Constants.TimeForScaling.Time_25mmXScale)
            {
                objSpO2 = objSpO2Data;
            }
            else
            {
                objSpO2 = new SpO2Data[intSamplingRate * (int)Constants.TimeForScaling.Time_50mmXScale];
                for (int i = 0; i < intSamplingRate * (int)Constants.TimeForScaling.Time_50mmXScale; i++)
                {
                    SpO2Data obj = new SpO2Data();
                    objSpO2[i] = obj;
                }
                int i50 = 0;
                for (int intCount = 0; intCount < objSpO2Data.Length; intCount++)
                {
                    if (objSpO2Data[intCount].IsDraw)
                    {
                        objSpO2[i50].IsDraw = objSpO2Data[intCount].IsDraw;
                        objSpO2[i50].HeartRate = objSpO2Data[intCount].HeartRate;
                        objSpO2[i50].SpO2Sample = objSpO2Data[intCount].SpO2Sample;
                        objSpO2[i50].SpO2RedSample = objSpO2Data[intCount].SpO2RedSample;
                        objSpO2[i50].SpO2 = objSpO2Data[intCount].SpO2;
                        if (i50 == intSamplingRate * (int)Constants.TimeForScaling.Time_50mmXScale - 1)
                        {
                            i50 = 0;
                        }
                        else
                        {
                            i50++;
                        }
                    }
                   
                }
            }
            DrawGrid();
            //Traverse through the points one by one to draw the ECG graphs
            for (int intCount = 0; intCount < objSpO2.Length; intCount = intCount + 1)
            {
                if (objSpO2[intCount].IsDraw)
                {
                    byte[] bytSpo2 = new byte[1];
                    bytSpo2[0] = Convert.ToByte(objSpO2[intCount].SpO2);
                    BitArray bitarr = new BitArray(bytSpo2);
                    objPenGraph1 = yelgpen;
                    if (bitarr != null && bitarr.Length == 8 && bitarr[7])
                    {
                        objPenGraph1 = redPen;
                    }
                    x2Static = (intDisplayStaticBuffer + 1) * (float)(((intXScaling * m_PPIX) / 25.4) / intSamplingRate);
                    //Convert the digital value to mV
                    y2Graph1Static = (pbxPulseOximetry.Height /2) - (objSpO2[intCount].SpO2Sample*ftYScale / intYConfigure);

                    //Convert the digital value to mV
                    y2RedGraph1Static = (pbxPulseOximetry.Height / 2) - (objSpO2[intCount].SpO2RedSample * ftYScale / intYConfigure);

                    ////Draw Red wave form 
                    //objSpo2RedGraphics.DrawLine(objPenGraph1, pxStatic, pyRedStatic, x2Static, y2RedGraph1Static);
                    //pbxRed.Image = bmpRed;
                    //pyRedStatic = y2RedGraph1Static;
                    if (intDisplayStaticBuffer == 0)
                    {
                        pyStatic = y2Graph1Static;
                    }
                    //Draw Infrared wave form
                    objSpo2Graphics.DrawLine(objPenGraph1, pxStatic, pyStatic, x2Static, y2Graph1Static);
                    pbxPulseOximetry.Image = bmpPulseOximetry;
                    pxStatic = x2Static;
                    pyStatic = y2Graph1Static;
                    intDisplayStaticBuffer++;
                }
            }
            pbxPulseOximetry.Image = bmpPulseOximetry;           
        }

        private void _timerDraw_Tick(object sender, EventArgs e)
        {
           
            
            float x2 = 0;
            float y2Graph1 = 0;
            float y2Graph2 = 0;
            
            int intTotalCount = 0;
            
            

            try
            {
                if (blnInitial)
                {
                    if (_queue != null && _queue.Count > 0)
                    {
                        while (_queue != null && _queue.Count > 0)
                        {
                            //short ushDigital = (short)_queue.Dequeue();
                            SpO2Data objData = (SpO2Data)_queue.Dequeue();
                            byte[] bytSpo2=new byte[1];
                            bytSpo2[0] = Convert.ToByte(objData.SpO2);
                            BitArray bitarr = new BitArray(bytSpo2);
                            objPenGraph1 = yelgpen;
                            if (bitarr!=null && bitarr.Length==8 && bitarr[7])
                            {
                                objPenGraph1 = redPen;
                            }
                            bitarr.Set(7, false);
                            byte[] byt=new byte[1];
                            bitarr.CopyTo(byt,0);
                            lblSpO2Text.Text = byt[0].ToString() + "%";
                            
                            


                            //Assign all the points to zero
                            if (intDisplayBuffer == 0)
                            {
                                px = 0;
                                x2 = 0;
                                dtStart = DateTime.Now;
                            }
                            //Store old data
                            objSpO2Data[intDataCount].HeartRate = m_HR;
                            objSpO2Data[intDataCount].SpO2 = m_Spo2;
                            objSpO2Data[intDataCount].SpO2Sample = objData.SpO2Sample;
                            objSpO2Data[intDataCount].SpO2RedSample = objData.SpO2RedSample;
                            objSpO2Data[intDataCount].IsDraw = false;
                            if (blnXScale || blnYScale)
                            {
                                DrawStaticSpo2Graph();
                                py = (pbxPulseOximetry.Height / 2) - (objData.SpO2Sample * ftYScale / intYConfigure);
                                pyRed = (pbxPulseOximetry.Height / 2) - (objData.SpO2RedSample * ftYScale / intYConfigure);
                                if (blnYScale)
                                {
                                    blnYScale = false;
                                }
                                if (blnXScale)
                                {
                                    blnXScale = false;

                                    if (intXScaling == (int)Constants.XScale.XSCale_50mm)
                                    {
                                        intDisplayBuffer = int50DisplayBuffer;
                                    }
                                    else
                                    {
                                        intDisplayBuffer = int25DisplayBuffer;
                                    }
                                    float x2Old = (intDisplayBuffer) * (float)(((intXScaling * m_PPIX) / 25.4) / (intSamplingRate));
                                    px = x2Old;

                                }
                            }

                            x2 = (intDisplayBuffer + 1) * (float)(((intXScaling * m_PPIX) / 25.4) / intSamplingRate);
                            float y0 = pbxPulseOximetry.Height / 2;
                            //Convert the digital value to mV
                            y2Graph1 = y0 - ((objData.SpO2Sample / intYConfigure) * ftYScale);
                            y2Graph2 = y0 - ((objData.SpO2RedSample / intYConfigure) * ftYScale);
                            float xValue = 3;
                            if (x2 - px > 3)
                            {
                                xValue = x2 - px;
                            }
                            if (intDisplayBuffer == 0)
                            {
                                py = y2Graph1;
                            }

                            //Draw Red Graph
                            //objSpo2RedGraphics.FillRectangle(new SolidBrush(Color.Black), px + 0.5f, 0, xValue, pbxRed.Height);
                            //// objSpo2Graphics.DrawLine(yelgpen, pxOld, pyOld, px, py);
                            //FillGrid(x2, xValue, objSpo2RedGraphics, pbxRed);
                            //objSpo2RedGraphics.DrawLine(objPenGraph1, px, pyRed, x2, y2Graph2);
                            //pbxRed.Image = bmpRed;
                            //pyRed = y2Graph2;

                            //Draw Infrared Graph
                            objSpo2Graphics.FillRectangle(new SolidBrush(Color.Black), px + 0.5f, 0, xValue, pbxPulseOximetry.Height);
                            // objSpo2Graphics.DrawLine(yelgpen, pxOld, pyOld, px, py);
                            FillGrid(x2, xValue, objSpo2Graphics, pbxPulseOximetry);
                            objSpo2Graphics.DrawLine(objPenGraph1, px, py, x2, y2Graph1);
                            pbxPulseOximetry.Image = bmpPulseOximetry;
                            px = x2;
                            py = y2Graph1;
                            //pxOld = px;
                            //pyOld = py;
                            objSpO2Data[intDataCount].IsDraw = true;
                            if (int25DisplayBuffer == intSamplingRate * (int)Constants.TimeForScaling.Time_25mmXScale - 1)
                            {
                                int25DisplayBuffer = 0;

                            }
                            else
                            {
                                int25DisplayBuffer++;
                            }

                            if (int50DisplayBuffer == intSamplingRate * (int)Constants.TimeForScaling.Time_50mmXScale - 1)
                            {
                                int50DisplayBuffer = 0;

                            }
                            else
                            {
                                int50DisplayBuffer++;
                            }
                            if (intDisplayBuffer == intSamplingRate * intSPo2Time - 1)
                            {
                                intDisplayBuffer = 0;
                                px = 0;
                                pxOld = 0;
                                DateTime dtEnd = DateTime.Now;
                                TimeSpan t = dtEnd - dtStart;

                                if (intClearBufferCount == intClearBuffer - 1)
                                {
                                    intClearBufferCount = 0;
                                    if (_queue != null && _queue.Count > 0)
                                    {
                                        _queue.Clear();
                                    }

                                }
                                else
                                {
                                    intClearBufferCount++;
                                }
                              //  MessageBox.Show(t.TotalSeconds.ToString());
                            }
                            else
                            {
                                intDisplayBuffer++;
                            }
                            if (intDataCount == intSamplingRate * ((int)Constants.TimeForScaling.Time_25mmXScale) - 1)
                            {
                                intDataCount = 0;
                            }
                            else
                                intDataCount = intDataCount + 1;


                            intTotalCount++;
                            if (intTotalCount >= 16)
                            {
                                break;
                            }
                        }
                    }
                }

            }
            catch (Exception objException)
            {
                string str = objException.Message;
             
            }

            
        }

        private void frmPulseOximetryOnline_FormClosing(object sender, FormClosingEventArgs e)
        {
            objRS232.CloseCOMPort();
        }
    }
}