using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using System.Globalization;


namespace SnimaceStisku
{
    
    

    public partial class Hlavni : Form
    {
        Thread Cyclic = null;//vlakno pro zasilani pozadavku k vyslani hodnot z merici karty
        const char IDw = 'S';//hlavicka odchozi zpravy
        const char IDr = 'U';//hlavicka prichozi zpravy
        const Int32 MaxValue = 500;//maximalni hodnota sily v Newtonech
        const String ComPort = "COM3";//komunikacni port
        Int32 OffsetLeft = 0;
        Int32 OffsetRight = 0;
        Byte[] buff = new Byte[4];
        bool blik = false;
        bool blik2 = false;

        bool start = false;

        int memlen = 15;
        Int32[] mem1 = new int[15];//pamet pro ulozeni poslednich x vzorku
        Int32[] mem2 = new int[15];//pamet pro ulozeni poslednich x vzorku

        int hodnota1_prumer = 0;
        int hodnota2_prumer = 0;
        bool stisk1 = false;
        bool stisk2 = false;
        int kompenzace1 = 0;
        int kompenzace2 = 0;
        int kompenzovana1 = 0;
        int kompenzovana2 = 0;
        bool fall1 = false;
        bool fall2 = false;
        int fall1_counter = 0;
        int fall2_counter = 0;

        int min_hodnota1 = 100;
        int min_hodnota2 = 100;
        int max_hodnota1 = 0;
        int max_hodnota2 = 0;

        bool connected = false;
        //POMOCNA//
        int usart_counter_1 = 0;
        //
        Int32[] hodnota = new int[2];
        Int32 hodnota1 = 0;
        Int32 copy_hodnota1 = 0;
        Int32 copy_hodnota1_minula = 0;
        Int32 hodnota2 = 0;
        Int32 copy_hodnota2 = 0;
        Int32 copy_hodnota2_minula = 0;
        Int32 max1 = 0, max2 = 0;
        bool zap = false;
        int[] arrscore = null;
        string[] arrdatum = null;

        string score = "", datum = "";
        int score_max = 0, score_min = 0;
        int  score_win = 0;


        
        //Variables used for PONG GAME
        bool PONG_GAME = false;
        int l_ball_pos_x = 0;
        int l_ball_pos_y = 0;
        int SIZE_X = 0;
        int SIZE_Y = 0;
        int pong_ball = 0;
        int course = 0;
        int[] pong_start = { 0, 0 };
        int pong_out, pong_outt = 0;
        int[] pong_score = { 0, 0 };
        int plate_width = 0;
        int plate1, plate2 = 0;
        int plate_height = 0;
        int ball_pos_x = 0;
        int ball_pos_y = 0;
        int pong_step = 5;//5 ideal
        int pong_size_y = 0;
        int plate_start = 0;
        int l_plate1 = 0;
        int l_plate2 = 0;
        int stop_plate = 0;
        bool stop_plate_now = false;
        bool SPEED_UP_PONG = true;
        bool plate1_drift = false;
        bool plate2_drift = false;
        //int pong_game_start = 1;
        Int32 menu_press = 50;
        //int press_counter = 0;
        //int pong_game_mode = 0;
        //ool NO_FORCE = false;
        int PROGRAM_STATE= 0;
        int LAST_PROGRAM_STATE= 20;

        //POMOCNE PROMENNE NA ODPOCITAVANI PRI STARTU NOVE HRY PONG
        bool PONG_GAME_START = false;
        static int second_counter_ticks = 10;
        int second_counter = second_counter_ticks - 1;
        int seconds_to_display = 5;

        public Hlavni()
        {
            InitializeComponent();
        }
 
        private void Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            // funkce je volana pri prijmu dat na komunikacnim portu
            // pokud souhlasi identifikacni byte prijate zpravy, zavola se funkce pro updatovani hodnot
            try
            {
                Int32 wid = (Int32)Port.ReadByte();
                buff[0] = (Byte)Port.ReadByte();
                buff[1] = (Byte)Port.ReadByte();
                buff[2] = (Byte)Port.ReadByte();
                buff[3] = (Byte)Port.ReadByte();
                if (wid == IDr)
                {
                    connected = true;
                    hodnota = UpdateValues(buff, hodnota);
                    Port.DiscardInBuffer();
                }
                
            }
            catch (Exception ex)
            {
                this.BeginInvoke((MethodInvoker)delegate { ssWarning.Text = ex.Message/*"Sending problem."*/; });
            }
        }

        private void CyclicRoutine()
        {
            // vlakno periodicky posila pozadavek o zaslani hodnot ze zarizeni s tenzometry

            while (1 == 1)
            {
                Port.Write(IDw.ToString());
                Thread.Sleep(100);
                usart_counter_1++;
                connected = false;
            }
            
        }


        private int[] UpdateValues(Byte[] message, int[] policko)
        {
            /*
             * funkce pro zpracovani odpovedi ze zarizeni
             * zprava obsahuje 4 znaky :
             *      prvni 2 znaky reprezentuji hodnotu z prvniho tenzometru
             *      druhe 2 znaky reprezentuji hodnotuz druheho tenzometru
             * 2 znaky odpovidajici hodnote z AD prevodniku z tenzometrickeho mustku jsou 10 bit, pricemz
             * prvni znak je horni byte a druhy znak je spodni byte
            */
            UInt16 ADvalue1 = (UInt16)((message[0] << 8) | (message[1] & 0xFF));
            UInt16 ADvalue2 = (UInt16)((message[2] << 8) | (message[3] & 0xFF));
            Int32 hodnota1 = (Int32)Math.Round((MaxValue / (Double)1023) * ADvalue1) - OffsetLeft;
            Int32 hodnota2 = (Int32)Math.Round((MaxValue / (Double)1023) * ADvalue2) - OffsetRight;

            
            //spusti se po prvnim spusteni a nastavi se offset, aby byl meric vynulovan
            if (start == false)
            {
                start = true;
                OffsetLeft = hodnota1 + 12;
                OffsetRight = hodnota2 + 12;
                hodnota1 = 0;   //hodnota1 pro levy snimac
                hodnota2 = 0;   //hodnota2 pro pravy snimac
            }

            if (PONG_GAME) 
            { 
                hodnota2 = hodnota2 * 2 * 3;//puvodne * 2
                hodnota1 = hodnota1 * 2 * 2;//puvodne * 2
            }
            else 
            {
                hodnota2 = hodnota2 * 2;//puvodne * 2
                hodnota1 = hodnota1 * 2;//puvodne * 2 
            }
               
            if (hodnota1 < 0)
            {
                hodnota1 = 0;
            }          

            if (hodnota2 < 0)
            {
                hodnota2 = 0;
            }

                    /////////////////////////////////////////////////////////////////////////////
                    //verze 1.5     28.12.2013
                    //pravy snimac (hodnota2), reseni teplotni zavislosti a chybneho referencniho napeti pro pravy kanal
                    //levy snimac (hodnota1), reseni teplotni zavislosti a zakmitavani po pusteni snimace

                    copy_hodnota1 = hodnota1;
                    copy_hodnota2 = hodnota2;

                    hodnota1_prumer = 0;
                    hodnota2_prumer = 0;
                    min_hodnota1 = 500;
                    min_hodnota2 = 500;
                    max_hodnota1 = 0;
                    max_hodnota2 = 0;

                    for (int i = 0; i <= memlen - 2; i++)//ulozeni poslednich x vzorku do pameti
                    {
                        mem1[i] = mem1[i + 1];
                        if (mem1[i] < min_hodnota1)
                        { min_hodnota1 = mem1[i]; }
                        if (mem1[i] > max_hodnota1)
                        { max_hodnota1 = mem1[i]; }

                        mem2[i] = mem2[i + 1];
                        if (mem2[i] < min_hodnota2)
                        { min_hodnota2 = mem2[i]; }
                        if (mem2[i] > max_hodnota2)
                        { max_hodnota2 = mem2[i]; }
                    }
                    mem1[memlen - 1] = copy_hodnota1_minula;
                    mem2[memlen - 1] = copy_hodnota2_minula;

                    if (mem1[memlen - 1] < min_hodnota1)
                    { min_hodnota1 = mem1[memlen - 1]; }
                    if (mem1[memlen - 1] > max_hodnota1)
                    { max_hodnota1 = mem1[memlen - 1]; }

                    if (mem2[memlen - 1] < min_hodnota2)
                    { min_hodnota2 = mem2[memlen - 1]; }
                    if (mem2[memlen - 1] > max_hodnota2)
                    { max_hodnota2 = mem2[memlen - 1]; }//^^^zjisteni minimalni a maximalni hodnoty poslednich x vzorku^^^


                        if ((max_hodnota1 - min_hodnota1) <= 20)//pokud je rozmezi kmitani posl x vzorku mensi nez 20, spocitam prumer
                        {
                            for (int i = 0; i <= memlen - 1; i++)
                            {
                                hodnota1_prumer = hodnota1_prumer + mem1[i];
                            }
                            hodnota1_prumer = hodnota1_prumer / memlen;//prumerna hodnota minulych x vzorku, ktere minimalne kmitaly
                            kompenzace1 = hodnota1_prumer;  //pokud x poslednich vzorku minimalne kmitalo, tak nastavim kompenzaci, jako prumernou
                            //hodnotu techto nekmitavych vzorku
                            kompenzovana1 = 0;              //pokud vzorky minimalne kmitaly, predpokladame, ze neni snimac stisknuty => 0
                            stisk1 = false;
                        }
                        else//pokud poslednich x vzorku v pameti zakmitavalo vice, provedeme kompenzacni vypocet
                        {
                            int bigger_than = 0;

                            if (copy_hodnota1 < kompenzace1)//pokud je hodnota snimace mensi nez prumerna hodnota, povazuju ji za prum. hodnotu
                            { copy_hodnota1 = kompenzace1; }

                            //pokud je hodnota snimace vetsi nez prumerna hodnota a je aktivni stav fall, aktivuje se stav stisk
                            if (copy_hodnota1 > (kompenzace1 + 10) && fall1 == true)
                            { stisk1 = true; }

                            for (int i = 0; i < 8; i++)
                            {
                                if (mem1[memlen - 2 - i] > (kompenzace1) && Math.Abs(copy_hodnota1_minula - kompenzace1) < 8)
                                {
                                    bigger_than++;
                                }
                            }

                            if (bigger_than >= 5)
                            { fall1 = true; }
                            //pokud je 5 vzorku z 8 poslednich zkoumanych vetsi nez prumer a soucasne se aktualni hodnota pohybuje kolem prumeru,
                            //aktivuje se stav fall2

                            kompenzovana1 = copy_hodnota1_minula - kompenzace1;//vypocet kompenzovane hodnoty rozdilem hodnoty snimace a kompenzace

                        }
                    
                    if ((max_hodnota2 - min_hodnota2) <= 20 * 2)//pokud je rozmezi kmitani posl x vzorku mensi nez 20, spocitam prumer
                    {
                        for (int i = 0; i <= memlen - 1; i++)
                        {
                            hodnota2_prumer = hodnota2_prumer + mem2[i];
                        }
                        hodnota2_prumer = hodnota2_prumer / memlen;//prumerna hodnota minulych x vzorku, ktere minimalne kmitaly
                        kompenzace2 = hodnota2_prumer;  //pokud x poslednich vzorku minimalne kmitalo, tak nastavim kompenzaci, jako prumernou
                                                        //hodnotu techto nekmitavych vzorku
                        kompenzovana2 = 0;              //pokud vzorky minimalne kmitaly, predpokladame, ze neni snimac stisknuty => 0
                        stisk2 = false;
                    }

                    else//pokud poslednich x vzorku v pameti zakmitavalo vice, provedeme kompenzacni vypocet
                    {
                        int bigger_than = 0;

                        if (copy_hodnota2 < kompenzace2)//pokud je hodnota snimace mensi nez prumerna hodnota, povazuju ji za prum. hodnotu
                        { copy_hodnota2 = kompenzace2; }

                        //pokud je hodnota snimace vetsi nez prumerna hodnota a je aktivni stav fall, aktivuje se stav stisk
                        if (copy_hodnota2 > (kompenzace2 + 25) && fall2 == true)
                        { stisk2 = true; }

                        for (int i = 0; i < 8; i++)
                        {
                            if (mem2[memlen - 2 - i] > (kompenzace2) && Math.Abs(copy_hodnota2_minula - kompenzace2) < 8)
                            {
                                bigger_than++;
                            }
                        }

                        if (bigger_than >= 5)
                        { fall2 = true; }
                        //pokud je 5 vzorku z 8 poslednich zkoumanych vetsi nez prumer a soucasne se aktualni hodnota pohybuje kolem prumeru,
                        //aktivuje se stav fall2

                        kompenzovana2 = copy_hodnota2_minula - kompenzace2;//vypocet kompenzovane hodnoty rozdilem hodnoty snimace a kompenzace

                    }

                    if (kompenzovana1 < 0) { kompenzovana1 = 0; }//zapornou hodnotu neuvazujeme
                    if (kompenzovana2 < 0) { kompenzovana2 = 0; }//zapornou hodnotu neuvazujeme
                    hodnota1 = kompenzovana1;//do promenne pro levy snimac ulozim vykompenzovanou hodnotu
                    hodnota2 = kompenzovana2;//do promenne pro levy snimac ulozim vykompenzovanou hodnotu


                    if (fall1 == true)//pokud je aktivni stav fall - tedy v poslednich 5 vzorcich byla hodnota snimace vyssi nez prumerna(kompenzace)
                    {
                        fall1_counter++;
                        if (fall1_counter == 15 || stisk1 == true)//stav fall je aktivni po dobu 15 vzorku, pokud nedojde k jeho ukonceni aktivnim stavem "stisk"
                        {
                            fall1 = false;
                            fall1_counter = 0;
                        }
                        else
                        {
                            hodnota1 = 0;               //zobrazeni nulove nekmitave hodnoty
                            copy_hodnota1 = kompenzace1;//pri aktivnim stavu fall beru misto hodnoty ze snimace hodnotu posledniho prumeru,
                        }                               //to slouzi k vyfiltrovani podkmitu, ktery je zpusoben kontaktem ruky se snimacem
                    }

                    if (fall2 == true)//pokud je aktivni stav fall - tedy v poslednich 5 vzorcich byla hodnota snimace vyssi nez prumerna(kompenzace)
                    {
                        fall2_counter++;
                        if (fall2_counter == 15 || stisk2 == true)//stav fall je aktivni po dobu 15 vzorku, pokud nedojde k jeho ukonceni aktivnim stavem "stisk"
                        {
                            fall2 = false;
                            fall2_counter = 0;
                        }
                        else
                        {
                            hodnota2 = 0;               //zobrazeni nulove nekmitave hodnoty
                            copy_hodnota2 = kompenzace2;//pri aktivnim stavu fall beru misto hodnoty ze snimace hodnotu posledniho prumeru,
                        }                               //to slouzi k vyfiltrovani podkmitu, ktery je zpusoben kontaktem ruky se snimacem
                    }

                    copy_hodnota1_minula = copy_hodnota1;
                    copy_hodnota2_minula = copy_hodnota2;   //zpracovani hodnoty snimace je zpozdeno o jeden krok, aby bylo mozne vyfiltrovat podkmit
                                                            //do pole pameti poslednich x vzorku ulozim upravenou hodnotu snimace, aby bylo mozne
                                                            //pocitat prumer pro kompenzaci z relevantnejsich hodnot (bez podkmitu)
               ////////////////////////////////////////////////////////////////////////////////////////////////   
                    if (PONG_GAME)
                    {
                        hodnota2 = hodnota2 * 2;
                        hodnota1 = hodnota1 * 2;
                    }
       
                // pokud jsou obe hodnoty stejne, tak jsou oba budiky zelene, jinak je zeleny ten s vyssi hodnotou
                if((hodnota1 > 10)||(hodnota2 > 10)){
                if (hodnota1 == hodnota2) { aq1.DialColor = Color.Green; aq2.DialColor = Color.Green; }
                else
                {
                    if (hodnota1 > hodnota2) { aq1.DialColor = Color.Green; aq2.DialColor = Color.Red; }
                    else { aq1.DialColor = Color.Red; aq2.DialColor = Color.Green; }
                }

                }
                // funkce na zaznamenavani maximalni sily
                if (hodnota1 > 20)
                {
                    blik = true;
                    if (hodnota1 > max1)
                    {
                        max1 = hodnota1;
                        lblNadpis.ForeColor = System.Drawing.Color.Black;
                    }
                }
                
                if (hodnota2 > 20)
                {
                    blik = true;
                    if (hodnota2 > max2)
                    {
                        max2 = hodnota2;
                        lblNadpis.ForeColor = System.Drawing.Color.Black;
                    }
                }
            
                // pokud neni nic zmacknute, tak se rozblika nadpis
                if ((hodnota1 < 20) &&( hodnota2 < 20))
                {
                    if (blik2 == true)
                    {
                        lblNadpis.ForeColor = System.Drawing.Color.Black;
                        aq1.DialColor = Color.Orange; aq2.DialColor = Color.Black;
                        
                    }
                    else { lblNadpis.ForeColor = System.Drawing.Color.Red;
                           aq1.DialColor = Color.Black; aq2.DialColor = Color.Orange;
                         }
                       
                } // blika nadpis
                    
               
             
                // po preteceni timeru se zapise maximum do tabulky slavy
                if (zap == true)
                {

                    if (max1 > max2) score_win = max1;
                    else score_win = max2;
                    this.Invoke((MethodInvoker)delegate { high_score(score_win); });  
                    zap = false;
                }
            
                // zde se aktualizuji namerene hodnoty na budiky a labely
                this.BeginInvoke((MethodInvoker)delegate
                {
                    if (PROGRAM_STATE== 1)
                    {
                        aq1.Value = hodnota1;
                        aq2.Value = hodnota2;
                        lblHodnota1.Text = hodnota1.ToString();
                        lblHodnota2.Text = hodnota2.ToString();
                        fg.AddValues(new Int32[2] { hodnota1, hodnota2 });

                        label10.Text = max1.ToString();
                        label11.Text = max2.ToString();
                    }
                });

                policko[0] = hodnota1;
                policko[1] = hodnota2;
                return policko;
            
        }

        private void Hlavni_Load(object sender, EventArgs e)
        {
            //nastaveni pong_pnl
            this.pong_window.Size = new System.Drawing.Size((int)(Screen.PrimaryScreen.Bounds.Size.Width * 0.47 + 298.4), (int)(Screen.PrimaryScreen.Bounds.Size.Height * 0.8 + 35));
            this.pong_window.Location = new Point(Screen.PrimaryScreen.Bounds.Size.Width / 2 - this.pong_window.Size.Width / 2, Screen.PrimaryScreen.Bounds.Size.Height / 2 - this.pong_window.Size.Height / 2);

            this.pong_pnl.Size = new System.Drawing.Size(this.pong_window.Size.Width - 200, (int)(this.pong_window.Size.Height - this.pong_window.Size.Height / 3));
            this.pong_pnl.Location = new Point(Screen.PrimaryScreen.Bounds.Size.Width / 2 - this.pong_pnl.Size.Width / 2, Screen.PrimaryScreen.Bounds.Size.Height / 2 - this.pong_pnl.Size.Height / 2 + 50);

            this.pong_lblScore2.Location = new System.Drawing.Point(this.pong_window.Size.Width / 2 + 150, Screen.PrimaryScreen.Bounds.Size.Height / 2 - (this.pong_pnl.Size.Height / 2 - 50) - this.pong_lblScore2.Size.Height - this.pong_window.Location.Y - 5);
            this.pong_lblScore1.Location = new System.Drawing.Point(this.pong_window.Size.Width / 2 - 150 - this.pong_lblScore1.Size.Width, this.pong_lblScore2.Location.Y);

            //velikost odrazecich plejtu
            this.pong_plate_1.Size = this.pong_plate_2.Size = new System.Drawing.Size(32, (int)(pong_pnl.Size.Height * 0.25));

            SIZE_X = this.pong_pnl.Size.Width;
            SIZE_Y = this.pong_pnl.Size.Height;
            pong_ball = this.ball.Size.Width;
            plate_width = this.pong_plate_1.Size.Width;
            plate_height = this.pong_plate_1.Size.Height;
            ball_pos_x = this.pong_pnl.Size.Width / 2 - this.ball.Size.Width / 2;
            ball_pos_y = this.pong_pnl.Size.Height / 2;

            //pocatecni pozice ballu
            l_ball_pos_x = ball_pos_x;
            l_ball_pos_y = ball_pos_y;

            //pocatecni pozice plejtu
            pong_plate_2.Location = new Point(this.pong_pnl.Size.Width - this.pong_plate_2.Size.Width - 10, this.pong_pnl.Size.Height - this.pong_plate_2.Size.Height - 10);
            pong_plate_1.Location = new Point(10, this.pong_pnl.Size.Height - this.pong_plate_1.Size.Height - 10);
            ball.Location = new Point(ball_pos_x, ball_pos_y);

            //nastaveni pro pocatecni stav PROGRAM_STATE = 0, - obrazovka pro vyber modu
            this.control_timer.Enabled = true;       //zapnuti timeru, jehoz rutina obstarava ovladani programu pomoci snimacu
            if (PROGRAM_STATE== 0)
            {
                //zobrazeni uvodni obrazovky pro vyber modu
                this.ball_timer.Enabled = false;
                this.plate_timer.Enabled = false;
                this.lblNadpis.Visible = false;                 //schovame nadpis
                this.pnl.Visible = false;                       //schovani hlavniho panelu se vsemi prvky
                PONG_GAME = false;
                this.pong_window.Visible = false;
                this.pong_pnl.Visible = false;
                this.lblPong.Visible = false;
                this.lblInfo.Visible = false;
            }

            foreach (string arg in Environment.GetCommandLineArgs())
            {
                if (arg == "-f")
                {
                    this.TopMost = true;
                    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
                    this.ControlBox = false;
                    this.Location = new Point(0, 0);
                    this.Size = Screen.PrimaryScreen.Bounds.Size;
                    Cursor.Position = new Point(Screen.PrimaryScreen.Bounds.Size.Width, Screen.PrimaryScreen.Bounds.Size.Height);
                    this.Cursor.Dispose();//schovat kurzor
                }
            }

            // pri spusteni aplikace se nastavi komponenty, nastavi a otevre se komunikacni port,
            // spusti se komunikacni vlakno Cyclic

            DataGridViewTextBoxColumn datumColumn = new DataGridViewTextBoxColumn();
            datumColumn.DataPropertyName = "datum";
            datumColumn.HeaderText = "datum:";

            DataGridViewTextBoxColumn scoreColumn = new DataGridViewTextBoxColumn();
            scoreColumn.DataPropertyName = "Score";
            scoreColumn.HeaderText = "Score";
            dg1.Columns.Add(scoreColumn);
            dg1.Columns.Add(datumColumn);
            dg1.EditMode = DataGridViewEditMode.EditOnEnter;
            dg1.BackgroundColor = Color.Honeydew;
                    
            nacti_txt();

            aq1.MaxValue = MaxValue;
            aq2.MaxValue = MaxValue;
            fg.MaxValue = MaxValue;

            pnl.Location = new Point((Int32)Math.Round((this.Width - pnl.Width) / 2.0), (Int32)Math.Round((this.Height - pnl.Height) / 2.0));
            lblNadpis.Location = new Point((Int32)Math.Round((this.Width - lblNadpis.Width) / 2.0), (Int32)Math.Round((pnl.Location.Y - lblNadpis.Height) / 2.0));

            Port.BaudRate = 9600;
            Port.PortName = ComPort;
            Port.Parity = System.IO.Ports.Parity.None;
            Port.StopBits = System.IO.Ports.StopBits.One;
            Port.DataBits = 8;
            Port.Encoding = Encoding.ASCII;
            Port.Handshake = System.IO.Ports.Handshake.None;
            if (Port.IsOpen)
            {
                ssWarning.Text = "Already connected.";
                return;
            }
            try
            {
                Port.Open();
                ssWarning.Text = "Connected.";
                Cyclic = new Thread(new ThreadStart(CyclicRoutine));
                Cyclic.Start();
            }
            catch (Exception)
            {
                ssWarning.Text = "Connection problem.";
            }

            timer1.Enabled = true;
            timer3.Enabled = true;
            timer5.Enabled = true;
        }

        private void Hlavni_FormClosing(object sender, FormClosingEventArgs e)
        {
            // ukonceni aplikace
            if (Cyclic != null)
                if (Cyclic.IsAlive) Cyclic.Abort();
            if (Port.IsOpen) Port.Close();
        }

        /*Zobrazeni datumu ve Status Labelu*/
        private void Date_Tick(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            StLabel1.Text = dt.ToString();
        }

        private void nacti_txt()
        {

            dg1.Rows.Clear();

            try
            {
                FileStream file = new FileStream(@"C:\temp\score.txt", FileMode.Open);
                StreamReader sr = new StreamReader(file);
                string dataRow = ""; // Variable to store each row.

                object[] row;

                while ((dataRow = sr.ReadLine()) != null)
                {
                    if (dataRow != "")
                    {
                        row = dataRow.Split(';'); // Split the dataRow string variable and store each data into an Object array.
                        dg1.Rows.Add(row); // Add the row.
                    }
                }
                sr.Close();
            }
            catch (Exception)
            {
                if (MessageBox.Show("neni vytvoren soubor C://temp/score.txt \n laskav? ho vytvo? a zkus to znova \n\n aplikace se nyní vypne!!! ", "hlasneni", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK) { Close(); }
                else Close();
            }


            // pocitadlo radku v tabulce
            if (dg1 != null)
            {

                for (int count = 0; (count <= (dg1.Rows.Count - 2)); count++)
                {
                    dg1.Rows[count].HeaderCell.Value = string.Format((count + 1).ToString(), "0");
                }
            }
            // kdyz je textak neplny, tak se vygeneruje prazdne pole
            if (dg1.RowCount <= 5) {

                dg1.Rows.Clear();
                for (int i = 0; i < 5; i++)
                {
                    
                    dg1.Rows.Add("0", "N/A"); // prida radek
                    dg1.Rows[i].HeaderCell.Value = string.Format((i + 1).ToString(), "0");
                }
            }

            // nacte data do stringu pro praci kdyz se zmeni max score
            for (int i = 0; i < dg1.Rows.Count - 1; i++)
            {
                if (i < dg1.Rows.Count - 2) { score += dg1.Rows[i].Cells[0].Value.ToString() + ';'; }
                else score += dg1.Rows[i].Cells[0].Value.ToString();

                if (i < dg1.Rows.Count - 2) { datum += dg1.Rows[i].Cells[1].Value.ToString() + ';'; }
                else datum += dg1.Rows[i].Cells[1].Value.ToString();
            }

            string[] arrString = score.Split(new char[] { ';',':' });//you can define your own way to split the string
            string[] arrString2 = datum.Split(new char[] { ';',':' });//you can define your own way to split the string
            arrscore = new int[arrString.Length];
            arrdatum = new string[arrString2.Length];


            score_max = 0;
            score_min = 2000;
            for (int i = 0; i < arrString.Length; i++)
            {
                try
                {
                    arrscore[i] = Int16.Parse(arrString[i], CultureInfo.CurrentCulture);
                }
                catch (Exception) { }
                arrdatum[i] = arrString2[i];

                if (arrscore[i] > score_max) score_max = arrscore[i];
                if (arrscore[i] < score_min) score_min = arrscore[i];
            }
        }

        // ulozi score do textaku
        private void uloz_score()
        {
            try
            {
                FileStream file = new FileStream(@"C:\temp\score.txt", FileMode.Open);
                StreamWriter sw = new StreamWriter(file);
                int rowcount = dg1.Rows.Count;
                for (int i = 0; i < rowcount - 1; i++)
                {
                    sw.WriteLine(dg1.Rows[i].Cells[0].Value.ToString() + ";" +
                                dg1.Rows[i].Cells[1].Value.ToString());
                }
                sw.Close();
            }
            catch (Exception)
            {
                if (MessageBox.Show("neni vytvoren soubor C://temp/score.txt \n laskav? ho vytvo?", "hlasneni", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK) { Close(); }
                else Close();
            }
        }
        
        // provadi aktualizaci tabulky z highscore
        private void high_score(int cislo)
        {

            int flag = 0, flag2 = 0;
            if (cislo > score_max)
            {
                if (cislo == score_max) goto nic;

                if (arrscore != null) // pokud neni prazdny textak
                {

                    for (int i = arrscore.Length - 1; i > 0; i--)
                    {
                        arrscore[i] = arrscore[i - 1];
                        arrdatum[i] = arrdatum[i - 1];

                    }
                    arrscore[0] = cislo;
                    arrdatum[0] = DateTime.Now.ToShortDateString();
                }
                else // pokud je prazdny textak
                {
                    arrscore = new int[5];
                    arrdatum = new string[5];
                    for (int i = 0; i < 5; i++)
                    {
                        arrscore[i] = 0;
                        arrdatum[i] = " ";
                        
                    }
                    arrscore[0] = cislo;
                    arrdatum[0] = DateTime.Now.ToShortDateString();
                }
            }

            if ((cislo > score_min) && (cislo < score_max))
            {

                if (cislo == score_min) goto nic;

                for (int i = 0; i < arrscore.Length; i++)
                {
                    if (arrscore[i] == cislo) goto nic;
                    if (arrscore[i] > cislo) flag = 0;
                    else flag = 1;

                    if (flag == 0)
                    {
                        arrscore[i] = arrscore[i];
                        arrdatum[i] = arrdatum[i];
                    }

                    else
                    {
                        if (flag2 == 0)
                        {

                            for (int j = arrscore.Length - 1; j > i; j--)
                            {
                                arrscore[j] = arrscore[j - 1];
                                arrdatum[j] = arrdatum[j - 1];

                            }
                            arrscore[i] = cislo;
                            arrdatum[i] = DateTime.Now.ToShortDateString();
                            goto pocitej;
                        }
                        else
                        {
                            arrscore[i] = arrscore[i];
                            arrdatum[i] = arrdatum[i];

                        }
                    }
                }
            }

        pocitej: ;
            dg1.Rows.Clear();

            score_max = 0;
            score_min = 2000;
            for (int i = 0; i < arrscore.Length; i++)
            {
                dg1.Rows.Add(arrscore[i].ToString(), arrdatum[i].ToString()); // prida radek
                dg1.Rows[i].HeaderCell.Value = string.Format((i + 1).ToString(), "0");
                if (arrscore[i] > score_max) score_max = arrscore[i];
                if (arrscore[i] < score_min) score_min = arrscore[i];
            }
            uloz_score();
        nic: ;

        }

        private void tick(object sender, EventArgs e)
        {
            zap = true; 
        }

        private void ball_timer_tick(object sender, EventArgs e)
        {
            if(connected)
            {
                if (l_ball_pos_x >= (SIZE_X - 1 - pong_ball) && course == 0) { course = 0; pong_start[0] = 0; pong_out = 1; pong_score[0]++; pong_lblScore1.Text = pong_score[0].ToString(); }
                if (l_ball_pos_x >= (SIZE_X - 1 - pong_ball) && course == 1) { course = 0; pong_start[0] = 0; pong_out = 1; pong_score[0]++; pong_lblScore1.Text = pong_score[0].ToString(); }
                if (l_ball_pos_x <= 1 && course == 3) { course = 0; pong_start[0] = 0; pong_out = 1; pong_score[1]++; pong_lblScore2.Text = pong_score[1].ToString(); }//l_ball_pos_x <= 1 - kvuli ramecku
                if (l_ball_pos_x <= 1 && course == 2) { course = 0; pong_start[0] = 0; pong_out = 1; pong_score[1]++; pong_lblScore2.Text = pong_score[1].ToString(); }

	            if(pong_start[0] == 0)
	            {
                    ball_pos_x = this.pong_pnl.Size.Width / 2 - this.ball.Size.Width;
                    ball_pos_y = this.pong_pnl.Size.Height / 2;
                    plate1_drift = false;
                    plate2_drift = false;
	            }

	            if(pong_out == 1)
	            {	
		            pong_out = 0;
	            }

	            if(pong_start[0] != 0)
	            {
	                switch(course)
	                {
	                    case 0:
	                    ball_pos_x = ball_pos_x + pong_step;
	                    ball_pos_y = ball_pos_y + pong_step;
	                    break;

	                    case 1:
	                    ball_pos_x = ball_pos_x + pong_step;
	                    ball_pos_y = ball_pos_y - pong_step;
	                    break;

	                    case 2:
	                    ball_pos_x = ball_pos_x - pong_step;
	                    ball_pos_y = ball_pos_y - pong_step;
	                    break;

	                    case 3:
	                    ball_pos_x = ball_pos_x - pong_step;
	                    ball_pos_y = ball_pos_y + pong_step;
	                    break;
	                }
                    //podminky, aby micek nevyjel z hraciho pole
	            if((ball_pos_x + pong_ball) > (SIZE_X -1)){ball_pos_x = SIZE_X - 1 - pong_ball;}
	            if((ball_pos_y + pong_ball) > (SIZE_Y -1)){ball_pos_y = SIZE_Y - 1 - pong_ball;}
	            if((ball_pos_x) <= 0){ball_pos_x = 0;}
	            if((ball_pos_y) <= pong_size_y){ball_pos_y = pong_size_y;}
	            }

                ball.Location = new Point(ball_pos_x, ball_pos_y);
	            l_ball_pos_x = ball_pos_x;
	            l_ball_pos_y = ball_pos_y;

	            if(ball_pos_y >= (SIZE_Y - 1 - pong_ball) && course == 0){course = 1;}
	            if(ball_pos_y <= pong_size_y && course == 2){course = 3;}
	            if(ball_pos_y >= (SIZE_Y - 1 - pong_ball) && course == 3){course = 2;}
	            if(ball_pos_y <= pong_size_y && course == 1){course = 0;}

                if ((ball_pos_x + pong_ball) >= pong_plate_2.Location.X)
                {
                    if ((ball_pos_y + pong_ball) >= (plate2 - plate_height / 2) && (ball_pos_y) <= (plate2 + plate_height / 2) && course == 0)//kdyz je ball v rozmezi plejtu
                    {
                        if ((ball_pos_x + pong_ball) <= (pong_plate_2.Location.X + 4))
                        {
                            course = 3;
                        }

                    }
                    if ((ball_pos_y + pong_ball) >= (plate2 - plate_height / 2) && (ball_pos_y) <= (plate2 + plate_height / 2) && course == 1)//kdyz je ball v rozmezi plejtu
                    {
                        if ((ball_pos_x + pong_ball) <= (pong_plate_2.Location.X + 4))
                        {
                            course = 2;
                        }
                    }
                }


                if ((ball_pos_x) <= (pong_plate_1.Location.X + pong_plate_1.Size.Width))
                {
                    if ((ball_pos_y + pong_ball) >= (plate1 - plate_height / 2) && (ball_pos_y) <= (plate1 + plate_height / 2) && course == 3)//kdyz je ball v rozmezi plejtu
	                {
                        if ((ball_pos_x) > (pong_plate_1.Location.X + pong_plate_1.Size.Width - 4))
                        {
                            course = 0;
                        }
                    }
                    if ((ball_pos_y + pong_ball) >= (plate1 - plate_height / 2) && (ball_pos_y) <= (plate1 + plate_height / 2) && course == 2)//kdyz je ball v rozmezi plejtu
                    {
                        if ((ball_pos_x) > (pong_plate_1.Location.X + pong_plate_1.Size.Width - 4))
                        {
                            course = 1;
                        }
                    }
	            }

	            if(pong_start[0] == 0)
	            {pong_start[0] = 1; pong_out =0;}

                }//end of - if(connected)

                if (pong_score[0] == 3 && pong_score[1] == 0 || pong_score[0] == 0 && pong_score[1] == 3 || pong_score[0] == 10 || pong_score[1] == 10)//pokud bude stav score 3:0, nebo 0:3, usuzuji, ze nikdo nehraje a hodim game over
                { 
                    //zastavim herni casovace
                    this.ball_timer.Enabled = false;
                    this.plate_timer.Enabled = false;

                    PROGRAM_STATE = 3;
                }
        }
        

        private void pong_move_plates()
        {
            if (pong_start[1] == 0)
            {
                plate_start = SIZE_Y - plate_height / 2 - 10;					//the start y position of plate - vztazeno ke stredu plejtu
                plate1 = plate2 = plate_start;					//the strat y position of plate - vztazeno ke stredu plejtu
            }

            if (pong_start[1] != 0)
            {

                if (plate1_drift == false) { plate1 = plate_start - hodnota[0]; }
                if (plate2_drift == false) { plate2 = plate_start - hodnota[1]; }
            }

            //osetreni, aby plejty nevyjely z hraciho pole nahoru
            if ((plate1 - plate_height / 2) <= (pong_size_y + 2) && plate1_drift == false) { plate1 = pong_size_y + 10 + plate_height / 2; }
            if ((plate2 - plate_height / 2) <= (pong_size_y + 2) && plate2_drift == false) { plate2 = pong_size_y + 10 + plate_height / 2; }

            if (l_ball_pos_x < (pong_plate_1.Location.X + pong_plate_1.Size.Width - 4))
            {

                if (l_ball_pos_y + pong_ball >= (plate1 - plate_height / 2) && l_ball_pos_y <= plate1 + plate_height / 2)
                {
                    if ((l_ball_pos_y + pong_ball / 2) <= plate1)
                    {
                        plate1 = l_ball_pos_y + pong_ball + plate_height / 2;
                        plate1_drift = true;
                    }
                    if ((l_ball_pos_y + pong_ball / 2) > plate1)
                    {
                        plate1 = l_ball_pos_y - plate_height / 2;
                        plate1_drift = true;
                    }
                }
            }

            if ((l_ball_pos_x + pong_ball) > (pong_plate_2.Location.X + 4))//pokud je ball za hranou plejtu2 v souradnici X
            {

                if (l_ball_pos_y + pong_ball >= (plate2 - plate_height / 2) && l_ball_pos_y <= plate2 + plate_height / 2)//pokud se ball muze odrazit od plejtu (podminka hran ballu a platu pro odrazeni)
                {
                    if ((l_ball_pos_y + pong_ball / 2) <= plate2)//pokud se Y stred ballu nachazi v horni polovine plejtu2 (plejt najel na ball zdola)
                    {
                        plate2 = l_ball_pos_y + pong_ball + plate_height / 2;//plejt2 sjede pod ball v ose Y
                        plate2_drift = true;
                    }
                    if ((l_ball_pos_y + pong_ball / 2) > plate2)//pokud se Y stred ballu nachazi ve spodni polovine plejtu2 (plejt najel na ball shora)
                    {
                        plate2 = l_ball_pos_y - plate_height / 2;//plejt2 vyjede nad ball v ose Y
                        plate2_drift = true;
                    }
                }
            }

            pong_plate_1.Location = new Point(10, plate1 - plate_height / 2);

            pong_plate_2.Location = new Point(SIZE_X - 10 - plate_width, plate2 - plate_height / 2);

            l_plate1 = plate1;
            l_plate2 = plate2;

            if (pong_start[1] == 0)
            { pong_start[1] = 1; }

        }


        private void control_timer_tick(object sender, EventArgs e)
        {

            if (PROGRAM_STATE== 0)//obrazovka pro vyber modu
            {
                if (LAST_PROGRAM_STATE!= PROGRAM_STATE)
                {
                    //tady se provede zobrazeni obrazovky, pokud se PROGRAM_STATEnerovna LAST_PROGRAM_STATE
                    this.ball_timer.Enabled = false;
                    this.plate_timer.Enabled = false;
                    this.lblNadpis.Visible = true;                 //schovame nadpis
                    this.lblNadpis.Text = "Vyzkoušej svoji sílu";
                    this.lblNadpis.Location = new System.Drawing.Point(Screen.PrimaryScreen.Bounds.Size.Width / 2 - this.lblNadpis.Width / 2, 100);
                    this.pnl.Visible = false;                       //schovani hlavniho panelu se vsemi prvky
                    PONG_GAME = false;
                    this.pong_window.Visible = false;
                    this.pong_pnl.Visible = false;
                    this.lblPong.Visible = false;
                    this.lblInfo.Visible = false;
                    this.sila_picture.Size = new System.Drawing.Size((int)(Screen.PrimaryScreen.Bounds.Size.Width * 0.375 + 80), (int)((Screen.PrimaryScreen.Bounds.Size.Width * 0.375 + 80) * 0.491));
                    this.sila_picture.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
                    this.pong_picture.Size = new System.Drawing.Size((int)(Screen.PrimaryScreen.Bounds.Size.Width * 0.375 + 80), (int)((Screen.PrimaryScreen.Bounds.Size.Width * 0.375 + 80) * 0.647));
                    this.pong_picture.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
                    this.sila_picture.Location = new System.Drawing.Point((int)(Screen.PrimaryScreen.Bounds.Size.Width / 4 - sila_picture.Size.Width / 2), (int)(Screen.PrimaryScreen.Bounds.Size.Height / 2 - sila_picture.Size.Height / 2));
                    this.pong_picture.Location = new System.Drawing.Point((int)(Screen.PrimaryScreen.Bounds.Size.Width / 4 * 3 - pong_picture.Size.Width / 2), (int)(Screen.PrimaryScreen.Bounds.Size.Height / 2 - pong_picture.Size.Height / 2));
                    this.lblMenu_left1.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)(Screen.PrimaryScreen.Bounds.Size.Height * 0.0179 + 15.668), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                    this.lblMenu_left2.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)(Screen.PrimaryScreen.Bounds.Size.Height * 0.0179 + 10.668), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                    this.lblMenu_right1.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)(Screen.PrimaryScreen.Bounds.Size.Height * 0.0179 + 15.668), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                    this.lblMenu_right2.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)(Screen.PrimaryScreen.Bounds.Size.Height * 0.0179 + 10.668), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                    this.lblMenu_right1.Location = new System.Drawing.Point((int)(Screen.PrimaryScreen.Bounds.Size.Width / 4 * 3 - lblMenu_right1.Size.Width / 2), (int)(pong_picture.Size.Height + pong_picture.Location.Y + (Screen.PrimaryScreen.Bounds.Size.Height * 0.107 - 65.56)));
                    this.lblMenu_right2.Location = new System.Drawing.Point((int)(Screen.PrimaryScreen.Bounds.Size.Width / 4 * 3 - lblMenu_right2.Size.Width / 2), (int)(lblMenu_right1.Location.Y + lblMenu_right1.Size.Height));
                    this.lblMenu_left1.Location = new System.Drawing.Point((int)(Screen.PrimaryScreen.Bounds.Size.Width / 4 - lblMenu_left1.Size.Width / 2), (int)(lblMenu_right1.Location.Y));
                    this.lblMenu_left2.Location = new System.Drawing.Point((int)(Screen.PrimaryScreen.Bounds.Size.Width / 4 - lblMenu_left2.Size.Width / 2), (int)(lblMenu_right2.Location.Y));
                    this.sila_picture.Visible = true;
                    this.pong_picture.Visible = true;
                    this.lblMenu_left1.Visible = true;
                    this.lblMenu_left2.Visible = true;
                    this.lblMenu_right1.Visible = true;
                    this.lblMenu_right2.Visible = true;
                    LAST_PROGRAM_STATE= PROGRAM_STATE;
                }

                if (hodnota[0] >= menu_press)
                {
                        PROGRAM_STATE= 1;     //prepnu na Mereni                
                }

                if (hodnota[1] >= menu_press)
                {
                         PROGRAM_STATE= 2;     //Prepnu na Pong
                        pong_score[0] = pong_score[1] = 0;
                }
           
            
            }


            if (PROGRAM_STATE== 1)//mod mereni sily
            {
                if (LAST_PROGRAM_STATE!= PROGRAM_STATE)
                {
                    //tady se provede zobrazeni obrazovky pro Mereni sily, pokud se PROGRAM_STATEnerovna LAST_PROGRAM_STATE
                    this.lblNadpis.Text = "Máš sílu? Tak se ukaž!!";
                    this.lblNadpis.Location = new System.Drawing.Point(Screen.PrimaryScreen.Bounds.Size.Width / 2 - this.lblNadpis.Width / 2, 100);
                    this.pong_window.Visible = false;
                    PONG_GAME = false;
                    this.pnl.Visible = true;                       //zobrazeni hlavniho panelu se vsemi prvky
                    this.lblPong.Visible = false;
                    this.lblInfo.Visible = false;
                    this.pong_lblScore1.Visible = false;
                    this.pong_lblScore2.Visible = false;
                    this.pong_plate_1.Visible = false;
                    this.pong_plate_2.Visible = false;
                    this.ball.Visible = false;
                    this.pong_window.Visible = false;
                    this.pong_pnl.Visible = false;
                    this.sila_picture.Visible = false;
                    this.pong_picture.Visible = false;
                    this.lblMenu_left1.Visible = false;
                    this.lblMenu_left2.Visible = false;
                    this.lblMenu_right1.Visible = false;
                    this.lblMenu_right2.Visible = false;
                    LAST_PROGRAM_STATE= PROGRAM_STATE;
                }

                if (hodnota[0] <= 10 && hodnota[1] <= 10)        //pokud nejsou snimace stisknute
                {
                    if (this.no_press_timer.Enabled == false && PROGRAM_STATE!= 0)      //jen pokud casovac nebezi, zapnu ho (aby se stale neresetoval stale)
                    {
                        this.no_press_timer.Interval = 15000;
                        this.no_press_timer.Enabled = true; 
                    }
                }
                else 
                {
                    if (this.no_press_timer.Enabled == true) { this.no_press_timer.Enabled = false; }//jen pokud casovac bezi, vypnu ho (aby se stale neresetoval stale)
                }
             
            }

            if (PROGRAM_STATE== 2)//mod hra pong
            {
                if (LAST_PROGRAM_STATE!= PROGRAM_STATE)
                {
                    
                    //tady se provede zobrazeni obrazovky pro Pong, pokud se PROGRAM_STATEnerovna LAST_PROGRAM_STATE
                    this.no_press_timer.Enabled = false;
                    
                    this.lblNadpis.Text = "Pong";
                    this.lblNadpis.Location = new System.Drawing.Point(Screen.PrimaryScreen.Bounds.Size.Width / 2 - this.lblNadpis.Width / 2, 100);
                    this.pnl.Visible = false;                       //schovani hlavniho panelu se vsemi prvky
                    PONG_GAME = true;
                    this.pong_window.Visible = true;
                    this.pong_plate_1.Visible = true;
                    this.pong_plate_2.Visible = true;
                    
                    this.pong_pnl.Visible = true;
                    this.lblPong.Visible = false;
                    this.lblInfo.Visible = true;
                    this.pong_lblScore1.Visible = true;
                    this.pong_lblScore2.Visible = true;
                    this.sila_picture.Visible = false;
                    this.pong_picture.Visible = false;
                    this.lblMenu_left1.Visible = false;
                    this.lblMenu_left2.Visible = false;
                    this.lblMenu_right1.Visible = false;
                    this.lblMenu_right2.Visible = false;
                    pong_score[0] = pong_score[1] = 0;
                    pong_lblScore1.Text = pong_score[0].ToString();
                    pong_lblScore2.Text = pong_score[1].ToString();


                    second_counter++;

                    if (second_counter == second_counter_ticks && PONG_GAME_START != true)
                    {
                        seconds_to_display--;
                        second_counter = 0;

                        if (seconds_to_display >= 2)
                        {
                            this.lblInfo.Text = (seconds_to_display - 1).ToString();
                        }
                        if (seconds_to_display == 1)
                        {
                            this.lblInfo.Text = "START";
                        }
                        if (seconds_to_display == 0)
                        {
                            PONG_GAME_START = true;
                        }
                        this.lblInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)((Screen.PrimaryScreen.Bounds.Size.Width * 0.0125 + 24) * 2 / 3), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                        this.lblInfo.Location = new System.Drawing.Point(this.pong_pnl.Size.Width / 2 - this.lblInfo.Size.Width / 2, this.pong_pnl.Size.Height / 2 - this.lblInfo.Size.Height / 2);
                    }

                    if(PONG_GAME_START)//uz je odstarotvano pomoci zobrazenych labelu
                    {
                        LAST_PROGRAM_STATE= PROGRAM_STATE;
                        this.ball_timer.Enabled = true;
                        this.plate_timer.Enabled = true;
                        this.ball.Visible = true;
                        this.lblInfo.Visible = false;
                    }
                }
            }


            if (PROGRAM_STATE== 3)//pong - game over, moznost nove hry pongu
            {
                if (LAST_PROGRAM_STATE!= PROGRAM_STATE)
                {
                    this.ball.Visible = false;
                    if (pong_score[0] == 3 && pong_score[1] == 0 || pong_score[0] == 0 && pong_score[1] == 3)
                    { this.lblPong.Text = "KONEC HRY"; }
                    if (pong_score[0] == 10)
                    { this.lblPong.Text = "Hrá? vlevo vyhrál!!!"; }
                    if (pong_score[1] == 10)
                    { this.lblPong.Text = "Hrá? vpravo vyhrál!!!"; }
                    this.lblInfo.Text = "Pro novou hru STISKNI";
                    this.lblPong.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)(Screen.PrimaryScreen.Bounds.Size.Width * 0.0125 + 24), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                    this.lblInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", (float)((Screen.PrimaryScreen.Bounds.Size.Width * 0.0125 + 24) * 2/3), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
                    this.lblPong.Location = new System.Drawing.Point(this.pong_pnl.Size.Width / 2 - this.lblPong.Size.Width / 2, this.pong_pnl.Size.Height / 2 - this.lblPong.Size.Height / 2 -80);
                    this.lblInfo.Location = new System.Drawing.Point(this.pong_pnl.Size.Width / 2 - this.lblInfo.Size.Width / 2, this.pong_pnl.Size.Height / 2 - this.lblInfo.Size.Height / 2);
                    this.lblPong.Visible = true;
                    this.lblInfo.Visible = true;
                    PONG_GAME = false;
                    LAST_PROGRAM_STATE= PROGRAM_STATE;

                    PONG_GAME_START = false;
                    second_counter = second_counter_ticks - 1;
                    seconds_to_display = 5;

                    this.no_press_timer.Enabled = false;
                    this.no_press_timer.Interval = 10000;
                    this.no_press_timer.Enabled = true;
                }

                if (hodnota[0] >= 10 || hodnota[1] >= 10)        //pokud je nektery ze snimacu stisknut
                {
                    this.no_press_timer.Enabled = false;
                    PROGRAM_STATE= 2;
                }
            }
        }

        private void plate_timer_tick(object sender, EventArgs e)
        {
            pong_move_plates();
        }

        private void timer3_tick(object sender, EventArgs e)
        {
            max2 = 0;
            max1 = 0;
        }

        private void timer300(object sender, EventArgs e)
        {
            if (blik2 == false)
            {
                blik2 = true;
            }
            else blik2 = false;

            if (this.lblMenu_left1.Visible == true)
            {
                if (this.lblMenu_left1.ForeColor == System.Drawing.Color.Black)
                {
                    this.lblMenu_left1.ForeColor = System.Drawing.Color.DimGray;
                    this.lblMenu_left2.ForeColor = System.Drawing.Color.DimGray;
                    this.lblMenu_right1.ForeColor = System.Drawing.Color.Black;
                    this.lblMenu_right2.ForeColor = System.Drawing.Color.Black;
                }
                else
                {
                    this.lblMenu_left1.ForeColor = System.Drawing.Color.Black;
                    this.lblMenu_left2.ForeColor = System.Drawing.Color.Black;
                    this.lblMenu_right1.ForeColor = System.Drawing.Color.DimGray;
                    this.lblMenu_right2.ForeColor = System.Drawing.Color.DimGray;
                }
            }
        }

        private void no_press_timer_tick(object sender, EventArgs e)//spusti se, pokud hodnota obou snimacu je cca 0 (nestiskle snimace), pokud se hodnota zmeni pri behu casovace, casovac se vypne, pokud casovac
        {                                                             //dobehne, nastavi se stavova promenna a ukonci se hra, program prejde do modu vyberu (hra nebo mereni sily)    
            PROGRAM_STATE= 0;
        }

        private void Hlavni_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.S)
            {
                if (!SPEED_UP_PONG)
                {
                    SPEED_UP_PONG = true;
                    this.ball_timer.Interval = 10;
                }
                else
                {
                    SPEED_UP_PONG = false;
                    this.ball_timer.Interval = 100;
                }
            }
            if (e.KeyCode == Keys.Escape)
            {
                Close();
            }

        } 
    }
}
