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

namespace TesteLeitura
{
    public partial class Form1 : Form
    {
        SerialPort portaSerial = new SerialPort("COM5", 9600);
        byte tensaoAtual = 0;
        Color corTensao = Color.Lime;
        byte[] byteRequisicao = { 0x00 };
        List<byte> tensoesPlotagem = new List<byte>();
        int qtd = 75;
        float dis = 0;
        int total = 0;
        int eventos = 1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!portaSerial.IsOpen)
                portaSerial.Open();

            timerLeitura.Start();
            timerRelogio.Start();

            dis = (pictureBoxPlotagem.Width / qtd);
            total = (int)(pictureBoxPlotagem.Width / dis);
        }

        private void timerLeitura_Tick(object sender, EventArgs e)
        {
            if (portaSerial.IsOpen)
            {
                portaSerial.Write(byteRequisicao, 0, byteRequisicao.Length);
                if (portaSerial.BytesToRead > 0)
                {
                    byte lido = (byte)portaSerial.ReadByte();
                    tensaoAtual = lido;

                    tensoesPlotagem.Add(tensaoAtual);
                    if (tensoesPlotagem.Count == total)
                        tensoesPlotagem.Clear();

                    bool evento = false;

                    textBoxTensao.Text = tensaoAtual.ToString() + "V";
                    if ((tensaoAtual > 110 && tensaoAtual < 120) || (tensaoAtual > 127 && tensaoAtual <= 135))
                    {
                        corTensao = Color.Yellow;
                    }
                    else if (tensaoAtual <= 110 || tensaoAtual > 135)
                    {
                        corTensao = Color.Red;
                        evento = true;
                    }
                    else
                        corTensao = Color.Lime;

                    if (evento)
                    {
                        ListViewItem item = new ListViewItem(eventos.ToString());
                        item.SubItems.Add(new ListViewItem.ListViewSubItem(item, tensaoAtual.ToString()));
                        item.SubItems.Add(new ListViewItem.ListViewSubItem(item, DateTime.Now.ToString()));
                        listViewEventos.Items.Add(item);

                        eventos++;
                    }

                    pictureBoxTensao.Invalidate();
                    pictureBoxPlotagem.Invalidate();
                }
            }
        }

        private void timerRelogio_Tick(object sender, EventArgs e)
        {
            labelHorario.Text = DateTime.Now.ToString();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (portaSerial.IsOpen)
                portaSerial.Close();
            timerLeitura.Stop();
        }

        private void pictureBoxTensao_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

            desenharNivelTensao(g);
        }

        private void pictureBoxPlotagem_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

            desenharTensoes(g);
        }

        private void desenharNivelTensao(Graphics g)
        {
            Rectangle rectTensao = new Rectangle(new Point(0, pictureBoxTensao.Height - tensaoAtual), new Size(pictureBoxTensao.Width, pictureBoxTensao.Height));
            g.FillRectangle(new SolidBrush(Color.FromArgb(185, corTensao)), rectTensao);

            g.DrawLine(new Pen(Color.Black, 4), new Point(0, pictureBoxTensao.Height - tensaoAtual), new Point(pictureBoxTensao.Width, pictureBoxTensao.Height - tensaoAtual));

            g.DrawString("Nvel de Tenso", new Font("Verdana", 12, FontStyle.Bold), Brushes.Black, new PointF((pictureBoxTensao.Width / 2) - 75, pictureBoxTensao.Height / 2));
        }

        private void desenharTensoes(Graphics g)
        {
            float inc = 0;
            List<PointF> pts = new List<PointF>();

            for (int i = 0; i < tensoesPlotagem.Count; i++)
            {
                PointF pTensao = new PointF(inc, pictureBoxPlotagem.Height - tensoesPlotagem[i]);
                pts.Add(pTensao);
                inc += dis;
            }

            inc = 0;

            if (pts.Count >= 1)
            {
                g.DrawLine(Pens.LightGray, new PointF(0, pictureBoxPlotagem.Height - tensaoAtual), new PointF(pictureBoxPlotagem.Width, pictureBoxPlotagem.Height - tensaoAtual));
                g.DrawLine(Pens.LightGray, new PointF(pts[pts.Count - 1].X, 0), new PointF(pts[pts.Count - 1].X, pictureBoxPlotagem.Height));
            }

            if(pts.Count >= 2)
                g.DrawCurve(Pens.Black, pts.ToArray());

            for (int i = 0; i < tensoesPlotagem.Count; i++)
            {
                PointF pTensao = new PointF(inc, pictureBoxPlotagem.Height - tensoesPlotagem[i]);
                Pen penTensao = new Pen(Color.Lime);

                if ((tensoesPlotagem[i] > 110 && tensoesPlotagem[i] < 120) || (tensoesPlotagem[i] > 127 && tensoesPlotagem[i] <= 135))
                    penTensao.Color = Color.Yellow;
                else if (tensoesPlotagem[i] <= 110 || tensoesPlotagem[i] > 135)
                    penTensao.Color = Color.Red;

                g.FillEllipse(penTensao.Brush, new RectangleF(new PointF(pTensao.X - 3, pTensao.Y - 3), new SizeF(6, 6)));

                inc += dis;
            }

            g.DrawString("Oscilografia", new Font("Verdana", 12, FontStyle.Bold), Brushes.Black, new PointF(5, 5));
        }
    }
}