using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using SamsungMobileSdk;     //api pro telefony Samsung

namespace WiFi_klient_for_WM
{
    public partial class Form1 : Form
    {
        static int ROZSAH_JOYSTICKU = 255;
        static UdpClient odchoziKlient,prichoziKlient;
        Graphics platno;
        bool bRizeniPovoleno = false;
        bool bPrstNaObrazovce = false;  //indikuje, zda ma uzivatel polozeny prst na obrazovce

        static byte[] prijataData = null;              //data priajta pres UDP
        int JoyX = 127, JoyY = 127, JoyZ = 255;    //temp pro pozice dotyku prstu
        Accelerometer.Vector avVektor = new Accelerometer.Vector();     //vektor dat z g-senzoru
        Thread thPrijemDat = new Thread(new ThreadStart(PrijmiData));  //inicializace threadu pro prijem dat

        enum Klavesa { None, U, UR, R, DR, D, DL, L, UL };          //enumerataor pro stisknutou virtualni klavesu
        byte stisknutaKlavesa=0;                                    //temp pro stisknutou klavesu

        Byte FLVzdalenost = 255, FRVzdalenost = 255, RLVzdalenost = 255, RRVzdalenost = 255;
        Int32 Uhel = 0;        //uhel natoceni voziku

        enum smeryJoysticku : byte { LN = 1, N, PN, L, STOP, P, LD, D, PD };       //enum - smer vychyleni joysticku
        byte smerJoysticku = (byte)smeryJoysticku.STOP;     //smer vychyleni
        
        public Form1()
        {
            InitializeComponent();

            odchoziKlient = new UdpClient();        //inicializace klienta UDP
            platno = pictureBoxJoystick.CreateGraphics();   //inicializace platna
            comboBoxVstup.SelectedIndex = 0;         //vyber vstupu
            comboBoxIdleTimerResetInterval.SelectedIndex = 1;   //reset idle timeru jednou za 10s
            textBoxPrichoziIP.Text = ZjistiLokalniIP(); //zjisti lokalni IP a vypise do textboxu
        }

        static void PrijmiData()
        {
            while (true)
            {
                prichoziKlient = null;

                try
                {
                    prichoziKlient = new UdpClient(3001);     //prijem dat na portu 3001
                    IPEndPoint ipEp = new IPEndPoint(IPAddress.Any, 0);

                    prijataData = prichoziKlient.Receive(ref ipEp);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message.ToString(), "Došlo k vyjímce!");
                }
                finally
                {
                    if (prichoziKlient != null)
                        prichoziKlient.Close();
                }
            }
        }

        private string ZjistiLokalniIP()
        {
            string strHostName = Dns.GetHostName();
            IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
            IPAddress[] ipAdd = ipEntry.AddressList;
            
            return ipAdd[0].ToString();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (buttonStart.Text == "Start")
            {
                buttonStart.Text = "Stop";
                bRizeniPovoleno = true;
            }
            else
            {
                buttonStart.Text = "Start";
                bRizeniPovoleno = false;
                VykresliPozicniKriz();
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if(comboBoxVstup.SelectedIndex==0)      //pouze pokud je jako vstup zvolen touchscreen
                VykresliPoziciPrstu();
        }

        private void pictureBoxJoystick_MouseDown(object sender, MouseEventArgs e)
        {
            if (comboBoxVstup.SelectedIndex == 0)   //pouze pokud je jako vstup zvolen touchscreen
                VykresliPoziciPrstu();
        }

        private void VykresliPoziciPrstu()
        {
            pictureBoxJoystick.Refresh();
            
            platno.DrawLine(new Pen(Color.Red,3), //horizontalni linka
                0,
                MousePosition.Y - pictureBoxJoystick.Top - this.Top,
                this.Width,
                MousePosition.Y - pictureBoxJoystick.Top - this.Top);

            platno.DrawLine(new Pen(Color.Red,3), //vertikalni linka
               MousePosition.X - pictureBoxJoystick.Left - this.Left,
               0,
               MousePosition.X - pictureBoxJoystick.Left - this.Left,
               this.Height);

            JoyX = MousePosition.X - pictureBoxJoystick.Left - this.Left;   //prirazeni do docasnych promennych
            JoyY = MousePosition.Y - pictureBoxJoystick.Top - this.Top;
            JoyZ = (byte)(255-trackBarGain.Value);

            if (JoyX > 255)     //saturace
                JoyX = 255;

            if (JoyX <0)
                JoyX = 0;

            if (JoyY > 255)
                JoyY = 255;

            if (JoyY < 0)
                JoyY = 0;
        }

        private void VyhodnotStisknutouKlavesu()
        {
            switch (stisknutaKlavesa)
            {
                default: JoyX = 127; JoyY = 127; break;
                case (byte)Klavesa.U: JoyX = 127; JoyY = 0; break;
                case (byte)Klavesa.UR: JoyX = 255; JoyY = 0; break;
                case (byte)Klavesa.R: JoyX = 255; JoyY = 127; break;
                case (byte)Klavesa.DR: JoyX = 255; JoyY = 255; break;
                case (byte)Klavesa.D: JoyX = 127; JoyY = 255; break;
                case (byte)Klavesa.DL: JoyX = 0; JoyY = 255; break;
                case (byte)Klavesa.L: JoyX = 0; JoyY = 127; break;
                case (byte)Klavesa.UL: JoyX = 0; JoyY = 0; break;
            }
        }

        private void VykresliPoziciAkcelerometru()
        {
            int X = 127, Y = 127;       //souradnice joysticku, prepocitane z dat ziskanych z akcelerometru

            if (Accelerometer.GetVector(ref avVektor) != SmiResultCode.Success) //pokud se nepodari ziskat data ze senzoru, konec
                return;

            X = (int)((avVektor.x + 1) * 128);     //meri se zrychleni v jednotkach g, od -1 do +1, timto prepocitame na rozsah 0-255
            Y = (int)((avVektor.y + 1) * 128);     //meri se zrychleni v jednotkach g, od -1 do +1, timto prepocitame na rozsah 0-255

            pictureBoxJoystick.Refresh();

            platno.DrawLine(new Pen(Color.Red, 3), //horizontalni linka
                0,
                Y,
                this.Width,
                Y);

            platno.DrawLine(new Pen(Color.Red, 3), //vertikalni linka
               X,
               0,
               X,
               this.Height);

            JoyX = X;   //prirazeni do docasnych promennych
            JoyY = Y;
            JoyZ = (byte)(255 - trackBarGain.Value);

            if (JoyX > 255)     //saturace
                JoyX = 255;

            if (JoyX < 0)
                JoyX = 0;

            if (JoyY > 255)
                JoyY = 255;

            if (JoyY < 0)
                JoyY = 0;
        }

        private void pictureBoxJoystick_MouseUp(object sender, MouseEventArgs e)
        {
            if (comboBoxVstup.SelectedIndex == 0)       //pouze pokud je jako vstup zvolen touchscreen
            {
            VykresliPozicniKriz();

            JoyX = 127;     //reset docasnych promennych
            JoyY = 127;
            JoyZ = (byte)(255-trackBarGain.Value);
                }
        }

        private void VykresliPozicniKriz()      //vzkresli kriz v pictureboxu na zakladni pozici
        {
            pictureBoxJoystick.Refresh();

            platno.DrawLine(new Pen(Color.Red, 3), //horizontalni linka
                0,
                pictureBoxJoystick.Height / 2,
                this.Width,
                pictureBoxJoystick.Height / 2);

            platno.DrawLine(new Pen(Color.Red, 3), //vertikalni linka
               pictureBoxJoystick.Width / 2,
               0,
               pictureBoxJoystick.Width / 2,
               this.Height);        
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            VykresliPozicniKriz();                   //vykresli kriz v pictureboxu na zakladni pozici
        }

        private void buttonVymazat_Click(object sender, EventArgs e)
        {
            textBoxLog.Text = "";
        }

        private void timerOdchozi_Tick(object sender, EventArgs e)
        {
            string Temp = textBoxLog.Text.ToString();

            if (comboBoxVstup.SelectedIndex == 1)   //pokud je jako vstup vybran akcelerometr
            {
                if (bPrstNaObrazovce == true)       //pokud ma uzivatel polozeny prst na obrazovce
                    VykresliPoziciAkcelerometru();
                else
                {
                    VykresliPozicniKriz();

                    JoyX = 127;     //reset docasnych promennych
                    JoyY = 127;
                    JoyZ = (byte)(255 - trackBarGain.Value);
                }
            }

            if (comboBoxVstup.SelectedIndex == 2)      //pokud je vybrana virtualni klavesnice
                VyhodnotStisknutouKlavesu();

            if (JoystickXUvnitrThreshold(JoyX) == true)       //kontrolka thresholdu osy X
                pictureBoxThresholdXAktivni.BackColor = Color.LimeGreen;
            else
                pictureBoxThresholdXAktivni.BackColor = Color.White;

            if (JoystickYUvnitrThreshold(JoyY) == true)       //kontrolka thresholdu osy Y
                pictureBoxThresholdYAktivni.BackColor = Color.LimeGreen;
            else
                pictureBoxThresholdYAktivni.BackColor = Color.White;

            #region Smer
            //urcuje zamysleny smer voziku dle polohy joysticku

            if ((JoystickXUvnitrThreshold(JoyX) || JoystickYUvnitrThreshold(JoyY)) == false)
            {
                if (JoyX < 127)
                {
                    if (JoyY < 127)
                        smerJoysticku = (byte)smeryJoysticku.LN;
                    else
                        smerJoysticku = (byte)smeryJoysticku.LD;
                }
                else
                {
                    if (JoyY < 127)
                        smerJoysticku = (byte)smeryJoysticku.PN;
                    else
                        smerJoysticku = (byte)smeryJoysticku.PD;
                }
            }
            else
            {
                if (JoystickXUvnitrThreshold(JoyX))
                {
                    if (JoyY < 127)
                        smerJoysticku = (byte)smeryJoysticku.N;
                    else
                        smerJoysticku = (byte)smeryJoysticku.D;

                    if (JoystickYUvnitrThreshold(JoyY))
                        smerJoysticku = (byte)smeryJoysticku.STOP;
                }
                else
                {
                    if (JoyX < 127)
                        smerJoysticku = (byte)smeryJoysticku.L;
                    else
                        smerJoysticku = (byte)smeryJoysticku.P;
                }
            }

            switch (smerJoysticku)
            {
                case 1: labelSmer.Text = "Směr:\nLN"; break;
                case 2: labelSmer.Text = "Směr:\nN"; break;
                case 3: labelSmer.Text = "Směr:\nPN"; break;
                case 4: labelSmer.Text = "Směr:\nL"; break;
                default: labelSmer.Text = "Směr:\nN/A"; break;
                case 6: labelSmer.Text = "Směr:\nP"; break;
                case 7: labelSmer.Text = "Směr:\nLD"; break;
                case 8: labelSmer.Text = "Směr:\nD"; break;
                case 9: labelSmer.Text = "Směr:\nPD"; break;
            }

            #endregion

            #region UpravaGainu
            //snizuje gain podle dat z UZ senzoru

            byte tempFL, tempFR, tempRR, tempRL, tempGainRed;

            tempFL = (FLVzdalenost <= Convert.ToByte(textBoxSledovanaVzdalenost.Text)) ? (byte)(255 * ((float)(FLVzdalenost - Convert.ToByte(textBoxKritickaVzdalenost.Text)) / (float)(Convert.ToByte(textBoxSledovanaVzdalenost.Text) - Convert.ToByte(textBoxKritickaVzdalenost.Text)))) : (byte)255;    //plynule snizovani gainu, pokud je detekovan objekt ve sledovane vzdalenosti
            tempFR = (FRVzdalenost <= Convert.ToByte(textBoxSledovanaVzdalenost.Text)) ? (byte)(255 * ((float)(FRVzdalenost - Convert.ToByte(textBoxKritickaVzdalenost.Text)) / (float)(Convert.ToByte(textBoxSledovanaVzdalenost.Text) - Convert.ToByte(textBoxKritickaVzdalenost.Text)))) : (byte)255;
            tempRL = (RLVzdalenost <= Convert.ToByte(textBoxSledovanaVzdalenost.Text)) ? (byte)(255 * ((float)(RLVzdalenost - Convert.ToByte(textBoxKritickaVzdalenost.Text)) / (float)(Convert.ToByte(textBoxSledovanaVzdalenost.Text) - Convert.ToByte(textBoxKritickaVzdalenost.Text)))) : (byte)255;
            tempRR = (RRVzdalenost <= Convert.ToByte(textBoxSledovanaVzdalenost.Text)) ? (byte)(255 * ((float)(RRVzdalenost - Convert.ToByte(textBoxKritickaVzdalenost.Text)) / (float)(Convert.ToByte(textBoxSledovanaVzdalenost.Text) - Convert.ToByte(textBoxKritickaVzdalenost.Text)))) : (byte)255;

            if (FLVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))  //pokud je objekt blize, nez kriticka vzdalenost, stahne gain na 0
                tempFL = 0;
            if (FRVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))
                tempFR = 0;
            if (RRVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))
                tempRR = 0;
            if (RLVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))
                tempRL = 0;


            switch (smerJoysticku)
            {
                case 1: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * (tempFL / 255.0)); break;
                case 2: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * ((tempFL < tempFR ? tempFL : tempFR) / 255.0)); break;
                case 3: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * (tempFR / 255.0)); break;
                case 4: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * ((tempFL < tempRL ? tempFL : tempRL) / 255.0)); break;
                default: tempGainRed = (byte)(ROZSAH_JOYSTICKU - JoyZ); break;
                case 6: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * ((tempFR < tempRR ? tempFR : tempRR) / 255.0)); break;
                case 9: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * (tempRL / 255.0)); break;      //pokud je zvolen smer LD, staci se vozik do PD
                case 8: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * ((tempRL < tempRR ? tempRL : tempRR) / 255.0)); break;
                case 7: tempGainRed = (byte)((ROZSAH_JOYSTICKU - JoyZ) * (tempRR / 255.0)); break;      //vymena s LD, viz vyse
            }

            progressBarGainRed.Value = tempGainRed;
            labelGainRed.Text = tempGainRed.ToString();
            #endregion

            if (bRizeniPovoleno == true)
            {
                byte[] data = { (byte)JoyX, (byte)JoyY, (byte)JoyZ }; //pole dat X,Y,Z k odeslani pres wifi
                odchoziKlient.Send(data, data.Length, textBoxIP.Text, Convert.ToInt32(textBoxPort.Text));   //odesle data po wifi

                textBoxLog.Text = JoyX.ToString() + " " + JoyY.ToString() + " " + JoyZ.ToString() + Environment.NewLine + Temp;   //tiskne do logu
            }
        }

        private void trackBarGain_ValueChanged(object sender, EventArgs e)
        {
            JoyZ = (byte)(255-trackBarGain.Value);

            progressBarGain.Value = trackBarGain.Value;
            labelGain.Text = trackBarGain.Value.ToString();
        }

        private void timerPrichozi_Tick(object sender, EventArgs e)
        {
            if (prijataData != null)
            {
                IPEndPoint ipEP = new IPEndPoint(0, 0);                  //ip endpoint
                Graphics grafika = pictureBoxObraz.CreateGraphics();    //grafika pro vykresleni obrazku
                Object oKlic = new Object();                            //klic

                lock (oKlic)        //zamkne data pro ostatni thready
                {
                    try
                    {
                        if (prijataData[0] == 2 || prijataData[0] == 3) //pokud jsou platna data z UZ senzoru
                        {
                            FLVzdalenost = Convert.ToByte(textBoxFLVzdalenost.Text = prijataData[1].ToString());
                            FRVzdalenost = Convert.ToByte(textBoxFRVzdalenost.Text = prijataData[2].ToString());
                            RRVzdalenost = Convert.ToByte(textBoxRRVzdalenost.Text = prijataData[3].ToString());
                            RLVzdalenost = Convert.ToByte(textBoxRLVzdalenost.Text = prijataData[4].ToString());

                            Uhel = prijataData[5] + (prijataData[6] << 8);

                            textBoxSledovanaVzdalenost.Text = prijataData[8].ToString();    //nastaveni kriticke a sledovane vzdalenosti
                            textBoxKritickaVzdalenost.Text = prijataData[9].ToString();

                            VykresliOrientaciVoziku(Uhel);
                            VykresliUZkuzely(true);
                        }
                        else
                        {
                            FLVzdalenost = Convert.ToByte(textBoxFLVzdalenost.Text = "255");
                            FRVzdalenost = Convert.ToByte(textBoxFRVzdalenost.Text = "255");
                            RRVzdalenost = Convert.ToByte(textBoxRRVzdalenost.Text = "255");
                            RLVzdalenost = Convert.ToByte(textBoxRLVzdalenost.Text = "255");

                            pictureBoxOrientaceVoziku.Refresh();
                            VykresliUZkuzely(false);

                            Graphics platno2 = pictureBoxOrientaceVoziku.CreateGraphics();
                            platno2.DrawString("N/A", new Font(FontFamily.GenericSerif, 10f, FontStyle.Regular), new SolidBrush(Color.Red), new RectangleF(8, 15, 44, 40));
                        }

                        textBoxThreshold.Text = prijataData[7].ToString();     //velikost pasma necitlivosti

                        if (prijataData[0] == 1 || prijataData[0] == 3) //pokud se prijima obraz
                        {
                            MemoryStream ms = new MemoryStream(prijataData, 10, prijataData.Length - 10);

                            Image frame = new Bitmap(ms);

                            grafika.DrawImage(frame,
                                new Rectangle(0, 0, pictureBoxObraz.Width, pictureBoxObraz.Height),    //prizpusobit pictureboxu
                                new Rectangle(0, 0, frame.Width, frame.Height),                         //cely frame, neorezavat
                                GraphicsUnit.Pixel);
                        }
                        else
                        {
                            grafika.Clear(Color.White);
                            grafika.DrawString("Obraz není k dispozici", new Font(FontFamily.GenericSerif, 16f, FontStyle.Regular), new SolidBrush(Color.Red), new Rectangle(0, 0, pictureBoxObraz.Width, pictureBoxObraz.Height));
                        }
                    }
                    catch (Exception exc)
                    {
                        grafika.DrawString("Chyba při přenosu obrazu!\n" + exc.Message.ToString(), new Font(FontFamily.GenericSerif, 6, FontStyle.Regular), new SolidBrush(Color.Red), 0, 0);
                    }
                    finally
                    {
                        prijataData = null;
                    }
                }
            }
        }

        private void buttonZacitPrijem_Click(object sender, EventArgs e)
        {
            if (buttonZacitPrijem.Text == "Začít přijímat")
            {
                timerPrichozi.Enabled = true;
                buttonZacitPrijem.Text = "Ukončit příjem";
            }
            else
            {
                timerPrichozi.Enabled = false;
                buttonZacitPrijem.Text = "Začít přijímat";
            }
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 0 && comboBoxVstup.SelectedIndex != 2)
                VykresliPozicniKriz();
        }

        private void comboBoxVstup_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (comboBoxVstup.SelectedIndex)
            {
                default:
                    {
                        pictureBoxJoystick.Visible = true;
                        buttonD.Visible = false;
                        buttonDL.Visible = false;
                        buttonDR.Visible = false;
                        buttonL.Visible = false;
                        buttonR.Visible = false;
                        buttonU.Visible = false;
                        buttonUL.Visible = false;
                        buttonUR.Visible = false;
                        buttonStop.Visible = false;
                        break;
                    }
                case 1:
                    {
                        pictureBoxJoystick.Visible = true;
                        buttonD.Visible = false;
                        buttonDL.Visible = false;
                        buttonDR.Visible = false;
                        buttonL.Visible = false;
                        buttonR.Visible = false;
                        buttonU.Visible = false;
                        buttonUL.Visible = false;
                        buttonUR.Visible = false;
                        buttonStop.Visible = false;
                        break;
                    }
                case 2:
                    {
                        pictureBoxJoystick.Visible = false;
                        buttonD.Visible = true;
                        buttonDL.Visible = true;
                        buttonDR.Visible = true;
                        buttonL.Visible = true;
                        buttonR.Visible = true;
                        buttonU.Visible = true;
                        buttonUL.Visible = true;
                        buttonStop.Visible = true;
                        buttonUR.Visible = true;
                        break;
                    
                    }
            }
        }

        private void buttonUL_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.UL;
        }

        private void buttonU_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.U;
        }

        private void buttonUR_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.UR;
        }

        private void buttonL_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.L;
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.None;
        }

        private void buttonR_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.R;
        }

        private void buttonDL_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.DL;
        }

        private void buttonD_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.D;
        }

        private void buttonDR_Click(object sender, EventArgs e)
        {
            stisknutaKlavesa = (byte)Klavesa.DR;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            thPrijemDat.IsBackground = true;                        //vlakno pro prijem dat bezi v pozadi
            thPrijemDat.Start();                                    //start asynchronniho prijmu dat
        }

        private void timerIdleReset_Tick(object sender, EventArgs e)
        {
            cNapajeni.ResetujTimer();
        }

        private void checkBoxResetidleTimer_CheckStateChanged(object sender, EventArgs e)
        {
            timerIdleReset.Enabled = checkBoxResetidleTimer.Checked;
        }

        private void comboBoxIdleTimerResetInterval_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (comboBoxIdleTimerResetInterval.SelectedIndex)
            {
                case 0: timerIdleReset.Interval = 5000; break;
                case 1: timerIdleReset.Interval = 10000; break;
                case 2: timerIdleReset.Interval = 20000; break;
                case 3: timerIdleReset.Interval = 30000; break;
                case 4: timerIdleReset.Interval = 45000; break;
                default: timerIdleReset.Interval = 60000; break;
            }
        }

        private void VykresliUZkuzely(bool bDataKDispozici)   //vykresli kuzely podle prijatych dat z ultrazvuku
        {
            Color barvaFL, barvaFR, barvaRR, barvaRL;
            byte pocetKruznicFL, pocetKruznicFR, pocetKruznicRR, pocetKruznicRL;    //podle vzdalenosti ubyvaji ctvrtkruznice na prislusnem indikatoru
            Image tempImage;
            Graphics gMain, gTemp;

            if (bDataKDispozici == true)
            {
                byte sledovanyInterval = (byte)(Convert.ToByte(textBoxSledovanaVzdalenost.Text) - Convert.ToByte(textBoxKritickaVzdalenost.Text));

                if (FLVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))     //pocet kruznic FL
                {
                    pocetKruznicFL = 3;
                    barvaFL = Color.Red;
                }
                else
                {
                    if (FLVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3))
                    {
                        pocetKruznicFL = 3;
                        barvaFL = Color.FromArgb(0, 255, 0);
                    }
                    else
                    {
                        if (FLVzdalenost < (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3) && FLVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - 2 * sledovanyInterval / 3))
                        {
                            pocetKruznicFL = 2;
                            barvaFL = Color.FromArgb(0, 255, 0);
                        }
                        else
                        {
                            pocetKruznicFL = 1;
                            barvaFL = Color.FromArgb(0, 255, 0);
                        }
                    }
                }

                if (FRVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))     //pocet kruznic FR
                {
                    pocetKruznicFR = 3;
                    barvaFR = Color.Red;
                }
                else
                {
                    if (FRVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3))
                    {
                        pocetKruznicFR = 3;
                        barvaFR = Color.FromArgb(0, 255, 0);
                    }
                    else
                    {
                        if (FRVzdalenost < (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3) && FRVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - 2 * sledovanyInterval / 3))
                        {
                            pocetKruznicFR = 2;
                            barvaFR = Color.FromArgb(0, 255, 0);
                        }
                        else
                        {
                            pocetKruznicFR = 1;
                            barvaFR = Color.FromArgb(0, 255, 0);
                        }
                    }
                }

                if (RRVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))     //pocet kruznic RR
                {
                    pocetKruznicRR = 3;
                    barvaRR = Color.Red;
                }
                else
                {
                    if (RRVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3))
                    {
                        pocetKruznicRR = 3;
                        barvaRR = Color.FromArgb(0, 255, 0);
                    }
                    else
                    {
                        if (RRVzdalenost < (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3) && RRVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - 2 * sledovanyInterval / 3))
                        {
                            pocetKruznicRR = 2;
                            barvaRR = Color.FromArgb(0, 255, 0);
                        }
                        else
                        {
                            pocetKruznicRR = 1;
                            barvaRR = Color.FromArgb(0, 255, 0);
                        }
                    }
                }

                if (RLVzdalenost <= Convert.ToByte(textBoxKritickaVzdalenost.Text))     //pocet kruznic RL
                {
                    pocetKruznicRL = 3;
                    barvaRL = Color.Red;
                }
                else
                {
                    if (RLVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3))
                    {
                        pocetKruznicRL = 3;
                        barvaRL = Color.FromArgb(0, 255, 0);
                    }
                    else
                    {
                        if (RLVzdalenost < (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - sledovanyInterval / 3) && RLVzdalenost >= (Convert.ToByte(textBoxSledovanaVzdalenost.Text) - 2 * sledovanyInterval / 3))
                        {
                            pocetKruznicRL = 2;
                            barvaRL = Color.FromArgb(0, 255, 0);
                        }
                        else
                        {
                            pocetKruznicRL = 1;
                            barvaRL = Color.FromArgb(0, 255, 0);
                        }
                    }
                }
            }
            else
            {
                pocetKruznicFL = pocetKruznicFR = pocetKruznicRL = pocetKruznicRR = 3;
                barvaFL = barvaFR = barvaRL = barvaRR = Color.Black;
            }

            //LEVY PREDNI
            tempImage = new Bitmap(pictureBoxFLKuzel.Width, pictureBoxFLKuzel.Height);
            gTemp = Graphics.FromImage(tempImage);
            gMain = pictureBoxFLKuzel.CreateGraphics();

            gTemp.Clear(tabPage1.BackColor);

            if (pocetKruznicFL > 1)
            {
                gTemp.DrawEllipse(new Pen(barvaFL, 4f), pictureBoxFLKuzel.Width / 3, pictureBoxFLKuzel.Height / 3, 4 * pictureBoxFLKuzel.Width / 3, 4 * pictureBoxFLKuzel.Height / 3);

                if (pocetKruznicFL > 2)
                    gTemp.DrawEllipse(new Pen(barvaFL, 4f), 0, 0, pictureBoxFLKuzel.Width * 2, pictureBoxFLKuzel.Height * 2);
            }
            gTemp.DrawEllipse(new Pen(barvaFL, 4f), 2 * pictureBoxFLKuzel.Width / 3, 2 * pictureBoxFLKuzel.Height / 3, 2 * pictureBoxFLKuzel.Width / 3, 2 * pictureBoxFLKuzel.Height / 3);

            gMain.DrawImage(tempImage, 0, 0);

            //PRAVY PREDNI
            tempImage = new Bitmap(pictureBoxFRKuzel.Width, pictureBoxFRKuzel.Height);
            gTemp = Graphics.FromImage(tempImage);
            gMain = pictureBoxFRKuzel.CreateGraphics();

            gTemp.Clear(tabPage1.BackColor);

            if (pocetKruznicFR > 1)
            {
                gTemp.DrawEllipse(new Pen(barvaFR, 4f), -2 * pictureBoxFRKuzel.Width / 3, pictureBoxFRKuzel.Height / 3, 4 * pictureBoxFRKuzel.Width / 3, 4 * pictureBoxFRKuzel.Height / 3);

                if (pocetKruznicFR > 2)
                    gTemp.DrawEllipse(new Pen(barvaFR, 4f), -pictureBoxFRKuzel.Width, 0, pictureBoxFRKuzel.Width * 2, pictureBoxFRKuzel.Height * 2);
            }
            gTemp.DrawEllipse(new Pen(barvaFR, 4f), -pictureBoxFRKuzel.Width / 3, 2 * pictureBoxFRKuzel.Height / 3, 2 * pictureBoxFRKuzel.Width / 3, 2 * pictureBoxFRKuzel.Height / 3);

            gMain.DrawImage(tempImage, 0, 0);

            //PRAVY ZADNI
            tempImage = new Bitmap(pictureBoxRRKuzel.Width, pictureBoxRRKuzel.Height);
            gTemp = Graphics.FromImage(tempImage);
            gMain = pictureBoxRRKuzel.CreateGraphics();

            gTemp.Clear(tabPage1.BackColor);

            if (pocetKruznicRR > 1)
            {
                gTemp.DrawEllipse(new Pen(barvaRR, 4f), -2 * pictureBoxRRKuzel.Width / 3, -2 * pictureBoxRRKuzel.Height / 3, 4 * pictureBoxRRKuzel.Width / 3, 4 * pictureBoxRRKuzel.Height / 3);

                if (pocetKruznicRR > 2)
                    gTemp.DrawEllipse(new Pen(barvaRR, 4f), -pictureBoxRRKuzel.Width, -pictureBoxRRKuzel.Height, pictureBoxRRKuzel.Width * 2, pictureBoxRRKuzel.Height * 2);
            }
            gTemp.DrawEllipse(new Pen(barvaRR, 4f), -pictureBoxRRKuzel.Width / 3, -pictureBoxRRKuzel.Height / 3, 2 * pictureBoxRRKuzel.Width / 3, 2 * pictureBoxRRKuzel.Height / 3);

            gMain.DrawImage(tempImage, 0, 0);

            //LEVY ZADNI
            tempImage = new Bitmap(pictureBoxRLKuzel.Width, pictureBoxRLKuzel.Height);
            gTemp = Graphics.FromImage(tempImage);
            gMain = pictureBoxRLKuzel.CreateGraphics();

            gTemp.Clear(tabPage1.BackColor);

            if (pocetKruznicRL > 1)
            {
                gTemp.DrawEllipse(new Pen(barvaRL, 4f), pictureBoxRLKuzel.Width / 3, -2 * pictureBoxRLKuzel.Height / 3, 4 * pictureBoxRLKuzel.Width / 3, 4 * pictureBoxRLKuzel.Height / 3);

                if (pocetKruznicRL > 2)
                    gTemp.DrawEllipse(new Pen(barvaRL, 4f), 0, -pictureBoxRLKuzel.Height, pictureBoxRLKuzel.Width * 2, pictureBoxRLKuzel.Height * 2);
            }
            gTemp.DrawEllipse(new Pen(barvaRL, 4f), 2 * pictureBoxRLKuzel.Width / 3, -pictureBoxRLKuzel.Height / 3, 2 * pictureBoxRLKuzel.Width / 3, 2 * pictureBoxRLKuzel.Height / 3);

            gMain.DrawImage(tempImage, 0, 0);
        }

        private void VykresliOrientaciVoziku(Int32 Uhel)    //vykresli sipku predstavujici natoceni voziku
        {
            int hPul=pictureBoxOrientaceVoziku.Height/2,wPul=pictureBoxOrientaceVoziku.Width/2;
            Image tempImage = new Bitmap(pictureBoxOrientaceVoziku.Width, pictureBoxOrientaceVoziku.Height);
            Graphics gMain = pictureBoxOrientaceVoziku.CreateGraphics(), gTemp = Graphics.FromImage(tempImage);

            gTemp.Clear(tabPage1.BackColor);
            gTemp.FillEllipse(new SolidBrush(Color.White), 0, 0, pictureBoxOrientaceVoziku.Width, pictureBoxOrientaceVoziku.Height);

            Point[] sipka = { new Point((int)(wPul + Math.Sin(Uhel / 1000.0) * wPul), (int)(hPul - Math.Cos(Uhel / 1000.0) * hPul)), new Point((int)(wPul + Math.Sin((Uhel / 1000.0 + 2 * Math.PI / 3.0)) * wPul), (int)(hPul - Math.Cos(Uhel / 1000.0 + 2 * Math.PI / 3.0) * hPul)), new Point(wPul, hPul), new Point((int)(wPul + Math.Sin((Uhel / 1000.0 + 4 * Math.PI / 3.0)) * wPul), (int)(hPul - Math.Cos(Uhel / 1000.0 + 4 * Math.PI / 3.0) * hPul)) };
            gTemp.FillPolygon(new SolidBrush(Color.Black), sipka);
            
            gMain.DrawImage(tempImage, 0, 0);
        }

        private bool JoystickXUvnitrThreshold(int X)     //zjisti, zda je osa X joysticku uvnitr pasma necitlivosti
        {
            int threshold = (int)((ROZSAH_JOYSTICKU / 2) * (Convert.ToInt32(textBoxThreshold.Text) / 100.0));

            if ((ROZSAH_JOYSTICKU / 2 - threshold) > X || (ROZSAH_JOYSTICKU / 2 + threshold) < X)
                return false;

            return true;
        }

        private bool JoystickYUvnitrThreshold(int Y)     //zjisti, zda je osa Y joysticku uvnitr pasma necitlivosti
        {
            int threshold = (int)((ROZSAH_JOYSTICKU / 2) * (Convert.ToInt32(textBoxThreshold.Text) / 100.0));
            if ((ROZSAH_JOYSTICKU / 2 - threshold) > Y || (ROZSAH_JOYSTICKU / 2 + threshold) < Y)
                return false;

            return true;
        }

        private void pictureBoxOrientaceVoziku_Paint(object sender, PaintEventArgs e)
        {
            Graphics platno2 = e.Graphics;

            platno2.Clear(this.BackColor);
            platno2.FillEllipse(new SolidBrush(Color.White), 0, 0, pictureBoxOrientaceVoziku.Width, pictureBoxOrientaceVoziku.Height);       //vnejsi kruznice
        
        }

        private void pictureBoxFLKuzel_Paint(object sender, PaintEventArgs e)
        {
            Graphics gTemp = e.Graphics;

            gTemp.Clear(tabPage1.BackColor);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), pictureBoxFLKuzel.Width / 3, pictureBoxFLKuzel.Height / 3, 4 * pictureBoxFLKuzel.Width / 3, 4 * pictureBoxFLKuzel.Height / 3);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), 0, 0, pictureBoxFLKuzel.Width * 2, pictureBoxFLKuzel.Height * 2);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), 2 * pictureBoxFLKuzel.Width / 3, 2 * pictureBoxFLKuzel.Height / 3, 2 * pictureBoxFLKuzel.Width / 3, 2 * pictureBoxFLKuzel.Height / 3);

        }

        private void pictureBoxFRKuzel_Paint(object sender, PaintEventArgs e)
        {
            Graphics gTemp = e.Graphics;

            gTemp.Clear(tabPage1.BackColor);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), -2 * pictureBoxFRKuzel.Width / 3, pictureBoxFRKuzel.Height / 3, 4 * pictureBoxFRKuzel.Width / 3, 4 * pictureBoxFRKuzel.Height / 3);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), -pictureBoxFRKuzel.Width, 0, pictureBoxFRKuzel.Width * 2, pictureBoxFRKuzel.Height * 2);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), -pictureBoxFRKuzel.Width / 3, 2 * pictureBoxFRKuzel.Height / 3, 2 * pictureBoxFRKuzel.Width / 3, 2 * pictureBoxFRKuzel.Height / 3);
        }

        private void pictureBoxRRKuzel_Paint(object sender, PaintEventArgs e)
        {
            Graphics gTemp = e.Graphics;

            gTemp.Clear(tabPage1.BackColor);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), -2 * pictureBoxRRKuzel.Width / 3, -2 * pictureBoxRRKuzel.Height / 3, 4 * pictureBoxRRKuzel.Width / 3, 4 * pictureBoxRRKuzel.Height / 3);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), -pictureBoxRRKuzel.Width, -pictureBoxRRKuzel.Height, pictureBoxRRKuzel.Width * 2, pictureBoxRRKuzel.Height * 2);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), -pictureBoxRRKuzel.Width / 3, -pictureBoxRRKuzel.Height / 3, 2 * pictureBoxRRKuzel.Width / 3, 2 * pictureBoxRRKuzel.Height / 3);
        }

        private void pictureBoxRLKuzel_Paint(object sender, PaintEventArgs e)
        {
            Graphics gTemp = e.Graphics;

            gTemp.Clear(tabPage1.BackColor);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), pictureBoxRLKuzel.Width / 3, -2 * pictureBoxRLKuzel.Height / 3, 4 * pictureBoxRLKuzel.Width / 3, 4 * pictureBoxRLKuzel.Height / 3);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), 0, -pictureBoxRLKuzel.Height, pictureBoxRLKuzel.Width * 2, pictureBoxRLKuzel.Height * 2);
            gTemp.DrawEllipse(new Pen(Color.Black, 4f), 2 * pictureBoxRLKuzel.Width / 3, -pictureBoxRLKuzel.Height / 3, 2 * pictureBoxRLKuzel.Width / 3, 2 * pictureBoxRLKuzel.Height / 3);
        }

        private void tabPage1_MouseDown(object sender, MouseEventArgs e)
        {
            bPrstNaObrazovce = true;
        }

        private void tabPage1_MouseUp(object sender, MouseEventArgs e)
        {
            bPrstNaObrazovce = false;
        }

        private void tabPage1_Click(object sender, EventArgs e)
        {
            bPrstNaObrazovce = true;
        }
    }

    public static class cNapajeni           //PInvoke knihoven, zajistujicich power management
    {
        [DllImport("coredll.dll")]
        private static extern void SystemIdleTimerReset();

        [DllImport("coredll.dll")]
        private static extern int SetSystemPowerState(string pwrState,
                       int pwrStateFlags, int options);

        enum powerState : int
        { 
            POWER_STATE_ON = 0x10000,
            POWER_STATE_OFF = 0x20000,
            POWER_STATE_SUSPEND = 0x200000,
            POWER_FORCE = 4096
        }

        public static void ResetujTimer()
        {
            SetSystemPowerState(null, (int)powerState.POWER_STATE_ON, (int)powerState.POWER_FORCE);
            SystemIdleTimerReset();
        }
    }
}