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

namespace zapisovac
{
    
    public partial class Form1 : Form
    {   
       
        
        bool hore = false, dole = false, levo = false, pravo = false, vypnoutKom = true, startPress = false, stopPress = false;
        UInt16 xPos = 0x0f, yPos = 0x0f;// LHprev = 0, LDprev = 0, PHprev = 0, PDprev = 0; 
        int nasobPrev = 1; 

        public Form1()
        { 
            
            InitializeComponent();
            
        }

        private void NahoruB_Click(object sender, EventArgs e)
        {
            if (KomBut.Text == "Vypnout komunikaci")
            hore = true;
            //if (!komunikace.IsAlive) komunikace.Start();
        }

        private void DoluB_Click(object sender, EventArgs e)
        {
            if (KomBut.Text == "Vypnout komunikaci")
            dole = true;
            //if (!komunikace.IsAlive) komunikace.Start();
        }

        private void LevoB_Click(object sender, EventArgs e)
        {
            if (KomBut.Text == "Vypnout komunikaci")
            levo = true;
            //if (!komunikace.IsAlive) komunikace.Start();
        }

        private void PravoB_Click(object sender, EventArgs e)
        {
            if (KomBut.Text == "Vypnout komunikaci")
            pravo = true;
           // if (!komunikace.IsAlive) komunikace.Start();
        }

        private void KomunBut_Click(object sender, EventArgs e)
        {
            if (KomBut.Text == "Spustit komunikaci")
            {
                
                vypnoutKom = false;
                serialPort1.PortName = portVyb.Text;
                serialPort1.BaudRate = 250000;
                
                Thread komunikace = new Thread(spustse);
                komunikace.Start();
            }

            if (KomBut.Text == "Vypnout komunikaci")
            {
                vypnoutKom = true;
            }
        }

        private void StartB_Click(object sender, EventArgs e)
        {
            if (KomBut.Text == "Vypnout komunikaci")
            startPress = true;
        }

        private void StopB_Click(object sender, EventArgs e)
        {
            stopPress = true;
        }



        // funkce na pozadi
        void spustse()
        {    
            //char testByte = 0;

            EnabForm(false);
            

            try
            {
                
                if (!serialPort1.IsOpen)
                    serialPort1.Open();
                serialPort1.Write("p");
                StavRadek2W("Komunikační rychlost: 2500 kBaud", false);

                Tlkomun(false);

                while (true)
                {
                    if (levo)
                    {
                        levo = false;
                        serialPort1.Write("<");
                        Thread.Sleep(20);
                    }

                    if (pravo)
                    {
                        pravo = false;
                        serialPort1.Write(">");
                        Thread.Sleep(20);
                    }

                    if (hore)
                    {
                        hore = false;
                        serialPort1.Write("n");
                        Thread.Sleep(20);
                    }

                    if (dole)
                    {
                        dole = false;
                        serialPort1.Write("d");
                        Thread.Sleep(20);
                    }
                    
                    if (stopPress)
                    {
                        EnabStart(true);
                        EnabStop(false);
                        stopPress = false;
                        serialPort1.Write("p");
                        Thread.Sleep(1);
                    }

                    if (startPress)
                    {
                        EnabStart(false);
                        EnabStop(true);
                        startPress = false;
                        serialPort1.Write("s");
                        Thread.Sleep(1);
                    }

                    if (serialPort1.BytesToRead > 0)    // cekani na znackovy bit
                    {

                        switch (serialPort1.ReadByte())
                        {
                            case 'Z':
                                while (serialPort1.BytesToRead < 13)
                                    Thread.Sleep(1);

                                xPos = cti();                           //cteni pozice
                                yPos = cti();
                                nasobPrev = serialPort1.ReadByte();     //cteni nasobicky
                                LHbarW(cti() * nasobPrev);               //cteni bargrafu
                                PHbarW(cti() * nasobPrev);
                                LDbarW(cti() * nasobPrev);
                                PDbarW(cti() * nasobPrev);
                                                                
                                serialPort1.DiscardInBuffer();
                                break;

                            case 'N':                                   //paprsek nenalezen

                                StavRadek2W("Nenalezen paprsek", true);
                                serialPort1.Write("p");
                                break;

                            case 'U':                                   //paprsek moc nahore

                                StavRadek2W("Paprsek je prilis vysoko", true);
                                serialPort1.Write("p");
                                break;

                            case 'D':                                   //paprsek moc dole

                                StavRadek2W("Paprsek je prilis nizko", true);
                                serialPort1.Write("p");
                                break;

                            case 'R':                                   //paprsek moc vpravo

                                StavRadek2W("paprsek je prilis vpravo", true);
                                serialPort1.Write("p");
                                break;

                            case 'L':                                   //paprsek moc vlevo

                                StavRadek2W("Paprsek je prilis vlevo", true);
                                serialPort1.Write("p");
                                break;

                            case 'P':
                                EnabStart(true);
                                EnabStop(false);
                                StavRadek1W("Sledovani zastaveno", true);


                                break;

                            case 'S':
                                StavRadek1W("Spusteno sledovani", false);
                                break;

                            default:

                                break;
                        }
                    }
                    if (vypnoutKom == true)
                    {
                        serialPort1.Close();
                        EnabStart(true);
                        EnabStop(false);
                        Tlkomun(true);
                        EnabForm(true);
                        StavRadek1W("Komunikace ukoncena", false);
                        break;
                    }
                }

            }

            catch
            {
               // serialPort1.Write("p");
                serialPort1.Close();
                EnabStart(true);
                EnabStop(false);
                Tlkomun(true);
                EnabForm(true);
                StavRadek1W("No device detected on this port",true);
                StavRadek2W("Komunikace uzavřena chybou přenosu či dat", true);
                
            }
        }

        UInt16 cti()
        {
            byte[] mala = new byte[2];                  // alokace pameti
            if (serialPort1.BytesToRead >= 2)           //podminka dvou zbyvajiich bytu
            {
                serialPort1.Read(mala, 0, 2);           //precteni dvou bytu
                return (BitConverter.ToUInt16(mala, 0));//spojeni dvou bytu do cisla
            }
            else return (0xffff);
        }

     
        void Tlkomun (bool start)       //prepisovani spojovaciho tlacitka
        {
            if (KomBut.InvokeRequired)
            {
                KomBut.Invoke(new MethodInvoker(delegate()
                {
                    Tlkomun (start);
                }));
                return;
            }

            if (start) KomBut.Text = "Spustit komunikaci";
            else KomBut.Text = "Vypnout komunikaci";

        }

        void EnabForm (bool enableB)       // schovavani tlacitka s vyberem portu
        {
            if (portVyb.InvokeRequired)
            {
                portVyb.Invoke(new MethodInvoker(delegate()
                {
                    EnabForm(enableB);
                }));
                return;
            }
            portVyb.Enabled = enableB;
        }

        void LDbarW(Int32 hodnota)         // zapis na bar LD
        {
            if (BarLD.InvokeRequired)
            {
                BarLD.Invoke(new MethodInvoker(delegate()
                {
                    LDbarW(hodnota);
                }));
                return;
            }
            BarLD.Value = hodnota;
        }

        void LHbarW(Int32 hodnota)         // zapis na bar LH
        {
            if (BarLH.InvokeRequired)
            {
                BarLH.Invoke(new MethodInvoker(delegate()
                {
                    LHbarW(hodnota);
                }));
                return;
            }
            BarLH.Value = hodnota;
        }
        
        void PDbarW(Int32 hodnota)         // zapis na bar PD
        {
            if (BarPD.InvokeRequired)
            {
                BarPD.Invoke(new MethodInvoker(delegate()
                {
                    PDbarW(hodnota);
                }));
                return;
            }
            BarPD.Value = hodnota;
        }

        void PHbarW(Int32 hodnota)         // zapis na bar PH
        {
            if (BarPH.InvokeRequired)
            {
                BarPH.Invoke(new MethodInvoker(delegate()
                {
                    PHbarW(hodnota);
                }));
                return;
            }
            BarPH.Value = hodnota;
        }

        void EnabStart(bool enableB)       // schovavani tlacitka start
        {
            if ( StartB.InvokeRequired)
            {
                StartB.Invoke(new MethodInvoker(delegate()
                {
                    EnabStart(enableB);
                }));
                return;
            }
            StartB.Enabled = enableB;
        }

        void EnabStop(bool enableB)       // schovavani tlacitka stop
        {
            if (StopB.InvokeRequired)
            {
                StopB.Invoke(new MethodInvoker(delegate()
                {
                    EnabStop(enableB);
                }));
                return;
            }
            StopB.Enabled = enableB;
        }

               
        void StavRadek1W(string textW, bool zvyraznit)       // zapis do prvniho prvku ve stav radku
        {
            if (StatRad.InvokeRequired)
            {
                StatRad.Invoke(new MethodInvoker(delegate()
                {
                    StavRadek1W (textW, zvyraznit);
                }));
                return;
            }
            spodlab1.Text = textW;
            if (zvyraznit) spodlab1.ForeColor = Color.Red;
            else spodlab1.ForeColor = Color.Black;
        }

        void StavRadek2W(string textW, bool zvyraznit)       // zapis do prvniho prvku ve stav radku
        {
            if (StatRad.InvokeRequired)
            {
                StatRad.Invoke(new MethodInvoker(delegate()
                {
                    StavRadek2W(textW, zvyraznit);
                }));
                return;
            }
            spodlab2.Text = textW;
            if (zvyraznit) spodlab2.ForeColor = Color.Red;
            else spodlab1.ForeColor = Color.Black;
        }
    } 
}
