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 ModbusLibrary;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;


namespace CraneControl
{
    public partial class frm : Form
    {
        public frm()
        {
            InitializeComponent();
        }
        const Int32 MAX_WORD_VALUE = 32766;
        const Int32 MAX_POSUV_SPEED_VALUE = 20000;
        const Int32 MAX_LANO_SPEED_VALUE = 2500;
        const Int32 DIGITAL_INPUTS_COUNT = 8;
        const Int32 DIGITAL_OUTPUTS_COUNT = 8;
        const Int32 ANALOG_INPUTS_COUNT = 6;
        const Int32 ANALOG_OUPUTS_COUNT = 4;
        const Int32 DEFAULT_POSUV_SPEED = 68;// mm/s
        const Int32 DEFAULT_LANO_SPEED = 120;// mm/s
        ModbusClient FClient = null;
        HTTPServer FWebServer = null;
        ModbusServer FServer;
        Thread FCommunicationThread = null;
        Boolean[] FDigitalOutputs = new Boolean[DIGITAL_OUTPUTS_COUNT];
        Boolean[] FDigitalInputs = new Boolean[DIGITAL_INPUTS_COUNT];
        UInt16[] FAnalogOutputs = new UInt16[ANALOG_OUPUTS_COUNT];
        UInt16[] FAnalogInputs = new UInt16[ANALOG_INPUTS_COUNT];
        Boolean FNavijeniDoprava = true;
        Boolean FDownedButton = false;
        Boolean FCommunicationError = true;
        Boolean FLastCommunicationError = true;
        UInt16 FCommunicationInterval = 0;
        UInt16 FAverageCommunicationInterval = 0;
        Int64 FCounterStart = 0;
        Int64 FCounterStop = 0;
        Int64 FCounterFrequency = 0;
        enum FImageResource{
            Jerab, Kocka, Lano, CommRed, CommGreen, Magnet, Nahoru, Nahoru_down, Dolu, Dolu_down, Vlevo, Vlevo_down, Vpravo, Vpravo_down, Stred, Stred_on
        }
        Image[] FImageResources = new Image[16];

        [DllImport("kernel32.dll")]
        private static extern bool QueryPerformanceCounter(out Int64 Count);

        [DllImport("kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out Int64 Frequency);

        public struct SIO
        {
            public Boolean Magnet;
            public Boolean MagnetCidlo;
            public Boolean KoleckoSensor;
            public Boolean Cidlo1;
            public Boolean Cidlo2;
            public Boolean Cidlo3;
            public Boolean Cidlo4;
            public Boolean Cidlo5;
            public Boolean LanoActive;
            public Boolean PosuvActive;
            public Boolean LanoSmer;//true..doprava
            public Boolean PosuvSmer;//true..doleva
            public UInt16 LanoSpeed;
            public UInt16 PosuvSpeed;
            public Int32 Pozice;//v mm
            public Int32 Lano;//v mm
        }
        public struct SGeometrie
        {
            public Int32 SvetlostPosuvu;
            public Int32 SvetlostLana;
            public Double PozicePrevod;
            public Double LanoPrevod;
            public Double PosuvPrevod;
            public Int32 PosuvNecitlivost;
            public Int32 LanoNecitlivost;
            public Double LanoOffset;
            public Double PosuvOffset;
            public Int32 PoziceLeftBorder;
            public Int32 PoziceRightBorder;
        }
        public SIO FIO = new SIO();
        SGeometrie FGeometrie = new SGeometrie();

        private void Init()
        {
            FIO.Magnet = false;
            FIO.MagnetCidlo = false;
            FIO.KoleckoSensor = false;
            FIO.Cidlo1 = false;
            FIO.Cidlo2 = false;
            FIO.Cidlo3 = false;
            FIO.Cidlo4 = false;
            FIO.Cidlo5 = false;
            FIO.LanoActive = false;
            FIO.PosuvActive = true;
            FIO.LanoSmer = false;
            FIO.PosuvSmer = false;
            FIO.LanoSpeed = 0;
            FIO.PosuvSpeed = 0;
            FIO.Pozice = 0;
            FIO.Lano = 0;
            FGeometrie.SvetlostPosuvu = 520;//mezi čidly 1 a 5
            FGeometrie.SvetlostLana = 285;//vzdalenost podlozky od spodku magnetu
            FGeometrie.PoziceLeftBorder = 6950;
            FGeometrie.PoziceRightBorder = 28650;
            FGeometrie.PozicePrevod = FGeometrie.SvetlostPosuvu / (Double)(FGeometrie.PoziceRightBorder - FGeometrie.PoziceLeftBorder);//0.0359;//hodnota v int na relativní pozici od 1.čidla
            FGeometrie.LanoPrevod = (135.07 - 54.81)/820.0;//0.03628;//rychlost v int na mm/s
            FGeometrie.PosuvPrevod = 0.0043333;//rychlost v int na mm/s
            FGeometrie.PosuvNecitlivost = 5100;//necitlivost motoru posuvu v int
            FGeometrie.LanoNecitlivost = 1670;//necitlivost motoru lana v int
            FGeometrie.PosuvOffset = 30.5882-(10000 * FGeometrie.PosuvPrevod);//q pro linearizaci prepoctu
            FGeometrie.LanoOffset = 100 - (2000 * FGeometrie.LanoPrevod);//q pro linearizaci prepoctu

            UInt16 i = 0;
            for (i = 0; i < DIGITAL_INPUTS_COUNT; i++)
                FDigitalInputs.SetValue((Boolean)false, i);
            for (i = 0; i < ANALOG_INPUTS_COUNT; i++)
                FAnalogInputs.SetValue((UInt16)0, i);
            for (i = 0; i < DIGITAL_OUTPUTS_COUNT; i++)
                FDigitalOutputs.SetValue((Boolean)false, i);
            for (i = 0; i < ANALOG_OUPUTS_COUNT; i++)
                FAnalogOutputs.SetValue((UInt16)0, i);
        }

        private void frm_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists("Web"))
            {
                File.AppendAllText("AppErrors.log", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + " : " + "Directory web not found." + Environment.NewLine);
                MessageBox.Show("Nenalezen adresář Web s webovým rozhraním.");
            }
            try
            {
                pbModel.Load("Images\\jerab.gif");
                FImageResources[(Int32)FImageResource.Kocka] = Image.FromFile("Images\\Kocka.gif");
                FImageResources[(Int32)FImageResource.CommRed] = Image.FromFile("Images\\comm_red.jpg");
                FImageResources[(Int32)FImageResource.CommGreen] = Image.FromFile("Images\\comm_green.jpg");
                FImageResources[(Int32)FImageResource.Magnet] = Image.FromFile("Images\\magnet.gif");
                FImageResources[(Int32)FImageResource.Lano] = Image.FromFile("Images\\lano.jpg");
                FImageResources[(Int32)FImageResource.Dolu] = Image.FromFile("Images\\dolu.jpg");
                FImageResources[(Int32)FImageResource.Dolu_down] = Image.FromFile("Images\\dolu_down.jpg");
                FImageResources[(Int32)FImageResource.Nahoru] = Image.FromFile("Images\\nahoru.jpg");
                FImageResources[(Int32)FImageResource.Nahoru_down] = Image.FromFile("Images\\nahoru_down.jpg");
                FImageResources[(Int32)FImageResource.Vlevo] = Image.FromFile("Images\\vlevo.jpg");
                FImageResources[(Int32)FImageResource.Vlevo_down] = Image.FromFile("Images\\vlevo_down.jpg");
                FImageResources[(Int32)FImageResource.Vpravo] = Image.FromFile("Images\\vpravo.jpg");
                FImageResources[(Int32)FImageResource.Vpravo_down] = Image.FromFile("Images\\vpravo_down.jpg");
                FImageResources[(Int32)FImageResource.Stred] = Image.FromFile("Images\\stred.jpg");
                FImageResources[(Int32)FImageResource.Stred_on] = Image.FromFile("Images\\stred_on.jpg");
            }
            catch
            {
                File.AppendAllText("AppErrors.log", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + " : " + "Load pictures error." + Environment.NewLine);
                MessageBox.Show("Chyba načítání zdrojů.");
            }

            //FServer = new ModbusServer(8, 8, 12, 12);
            //FServer.OnError += new EventHandler(ErrorEvent);
            //server.EstablishServer();
            FClient = new ModbusClient("10.0.0.15", 502);
            //FClient = new ModbusClient("127.0.0.1", 502);
            FClient.EventInvalidCreation = true;
            FClient.OnError += new EventHandler(ErrorEvent);
            Init();
            tmRepaint.Interval = 100;
            FWebServer = new HTTPServer(this);
            FWebServer.OnNotify += new EventHandler(HTTPNotifyEvent);
            //pbModel.SizeMode = PictureBoxSizeMode.StretchImage;
            QueryPerformanceFrequency(out FCounterFrequency);
        }

        private void frm_FormClosing(object sender, FormClosingEventArgs e)
        {
            FClient.OnError -= ErrorEvent;
            FWebServer.Stop();
            if (FCommunicationThread != null)
                if (FCommunicationThread.IsAlive) FCommunicationThread.Abort();
            tmRepaint.Enabled = false;
            //FServer.ShutdownServer();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            tmRepaint.Enabled = true;
            FCommunicationThread = new Thread(Communicate);
            FCommunicationThread.Start();
            FClient.ConnectClient();
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            tmRepaint.Enabled = false;
            FCommunicationThread.Abort();
            FCommunicationError = true;
            FLastCommunicationError = true;
            FClient.DisconnectClient();
            pbCommunication.Image = FImageResources[(Int32)FImageResource.CommRed];
        }

        private void ErrorEvent(object sender, EventArgs e)
        {
            ModbusLibrary.ErrorEventArgs chyba = (ModbusLibrary.ErrorEventArgs)e;
            //MessageBox.Show(chyba.ErrorCode.ToString()+" - "+chyba.Message);
            //ErrorMsg = chyba.ErrorCode.ToString() + " - " + chyba.Message + "\n";
                File.AppendAllText("AppErrors.log", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + " : " + chyba.ErrorCode.ToString() + " - " + chyba.Message + Environment.NewLine);
            //pbCommunication.Load("Images\\comm_red.jpg");
            //MessageBox.Show(pbCommunication.Image.PropertyItems.GetValue(0).ToString());
        }

        private void HTTPNotifyEvent(object sender, EventArgs e)
        {
            HTTPServer.NotifyEventArgs chyba = (HTTPServer.NotifyEventArgs)e;
            //MessageBox.Show(chyba.ErrorCode.ToString()+" - "+chyba.Message);
            //ErrorMsg = udalost.Message + "\n";
                File.AppendAllText("HTTPErrors.log", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + " : " + chyba.Message + Environment.NewLine);
        }

        private void tmRepaint_Tick(object sender, EventArgs e)
        {
            if (FLastCommunicationError != FCommunicationError)
            {
                if (FCommunicationError == true)
                {
                    pbCommunication.Image = FImageResources[(Int32)FImageResource.CommRed];
                }
                else
                {
                    pbCommunication.Image = FImageResources[(Int32)FImageResource.CommGreen];
                }
                FLastCommunicationError = FCommunicationError;
            }
            pbModel.Invalidate();
            lblPozice.Text = FIO.Pozice.ToString();
            lblPosuv.Text = Math.Round(GetPosuvRychlost()).ToString();
            lblLano.Text = Math.Round(GetLanoRychlost()).ToString();
        }

        private void Communicate()
        {
            Boolean last = true;
            while (1 == 1)
            {
                last = !last;
                QueryPerformanceCounter(out FCounterStart);
                FDigitalOutputs.SetValue((Boolean)FIO.Magnet, 0);
                FDigitalOutputs.SetValue((Boolean)FIO.PosuvSmer, 1);
                FDigitalOutputs.SetValue((Boolean)FIO.LanoSmer, 2);
                FDigitalOutputs.SetValue((Boolean)FIO.LanoActive, 3);
                //FDigitalOutputs.SetValue((Boolean)last, 4);
                if ((FIO.Pozice <= 0) && (FIO.PosuvSpeed >= FGeometrie.PosuvNecitlivost) && (FIO.PosuvSmer == true))
                {
                    FIO.PosuvSpeed = 0;
                    FIO.LanoSpeed = 0;
                }
                if ((FIO.Pozice >= FGeometrie.SvetlostPosuvu) && (FIO.PosuvSpeed >= FGeometrie.PosuvNecitlivost) && (FIO.PosuvSmer == false))
                {
                    FIO.PosuvSpeed = 0;
                    FIO.LanoSpeed = 0;
                }
                if ((FIO.MagnetCidlo == true) && (FIO.LanoSpeed >= FGeometrie.LanoNecitlivost) && (FIO.LanoSmer == FNavijeniDoprava) && (FIO.LanoActive == true)) FIO.LanoSpeed = 0;
                FAnalogOutputs.SetValue((UInt16)((FIO.PosuvSpeed > MAX_POSUV_SPEED_VALUE) ? MAX_POSUV_SPEED_VALUE : FIO.PosuvSpeed), 0);
                FAnalogOutputs.SetValue((UInt16)((FIO.LanoSpeed > MAX_LANO_SPEED_VALUE) ? MAX_LANO_SPEED_VALUE : FIO.LanoSpeed), 1);
                

                //FClient.ConnectClient();
                FCommunicationError = FClient.RefreshMomentum(FDigitalOutputs, FAnalogOutputs, ref FDigitalInputs, ref FAnalogInputs);
                //FClient.DisconnectClient();

                if (FCommunicationError == false)
                {
                    FIO.MagnetCidlo = (Boolean)FDigitalInputs.GetValue(0);
                    FIO.Cidlo1 = (Boolean)FDigitalInputs.GetValue(1);
                    FIO.Cidlo2 = (Boolean)FDigitalInputs.GetValue(2);
                    FIO.Cidlo3 = (Boolean)FDigitalInputs.GetValue(3);
                    FIO.Cidlo4 = (Boolean)FDigitalInputs.GetValue(4);
                    FIO.Cidlo5 = (Boolean)FDigitalInputs.GetValue(5);
                    FIO.KoleckoSensor = (Boolean)FDigitalInputs.GetValue(6);
                    CountIO((UInt16)FAnalogInputs.GetValue(0));
                    //pbModel.Invalidate();
                }
                FCommunicationInterval = 0;
                while (FCommunicationInterval < 10)
                {
                    QueryPerformanceCounter(out FCounterStop);
                    FCommunicationInterval = (UInt16)Math.Round(1000 * (FCounterStop - FCounterStart) / (Double)FCounterFrequency);
                }
                if (FAverageCommunicationInterval != 0) FAverageCommunicationInterval = (UInt16)Math.Round((FAverageCommunicationInterval + FCommunicationInterval) / 2.0);
                else FAverageCommunicationInterval = FCommunicationInterval;
            }
        }

        private void btnHTTPstart_Click(object sender, EventArgs e)
        {
            FWebServer.Start();
        }

        private void btnHTTPstop_Click(object sender, EventArgs e)
        {
            FWebServer.Stop();
        }

        private void MouseControl(object sender, MouseEventArgs e)
        {
            if (((PictureBox)sender).Name == "pbNahoru")
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (FDownedButton == true)
                    {
                        pbNahoru.Image = FImageResources[(Int32)FImageResource.Nahoru];
                        FDownedButton = false;
                        FIO.LanoSpeed = 0;
                        if (FIO.LanoActive) FIO.LanoActive = false;
                    }
                    else
                    {
                        pbNahoru.Image = FImageResources[(Int32)FImageResource.Nahoru_down];
                        FDownedButton = true;
                        SetLanoRychlost(DEFAULT_LANO_SPEED, true);
                    }
                }
            }
            if (((PictureBox)sender).Name == "pbDolu")
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (FDownedButton == true)
                    {
                        pbDolu.Image = FImageResources[(Int32)FImageResource.Dolu];
                        FDownedButton = false;
                        FIO.LanoSpeed = 0;
                        if (FIO.LanoActive) FIO.LanoActive = false;
                    }
                    else
                    {
                        pbDolu.Image = FImageResources[(Int32)FImageResource.Dolu_down];
                        FDownedButton = true;
                        SetLanoRychlost(DEFAULT_LANO_SPEED, false);
                    }
                }
            }
            if (((PictureBox)sender).Name == "pbVpravo")
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (FDownedButton == true)
                    {
                        pbVpravo.Image = FImageResources[(Int32)FImageResource.Vpravo];
                        FDownedButton = false;
                        FIO.PosuvSpeed = 0;
                        FIO.LanoSpeed = 0;
                        if (FIO.LanoActive) FIO.LanoActive = false;
                    }
                    else
                    {
                        pbVpravo.Image = FImageResources[(Int32)FImageResource.Vpravo_down];
                        FDownedButton = true;
                        SetPosuvRychlost(DEFAULT_POSUV_SPEED, false);
                        SetLanoRychlostSynchro();
                    }
                }
            }
            if (((PictureBox)sender).Name == "pbVlevo")
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (FDownedButton == true)
                    {
                        pbVlevo.Image = FImageResources[(Int32)FImageResource.Vlevo];
                        FDownedButton = false;
                        FIO.PosuvSpeed = 0;
                        FIO.LanoSpeed = 0;
                        if (FIO.LanoActive) FIO.LanoActive = false;
                    }
                    else
                    {
                        pbVlevo.Image = FImageResources[(Int32)FImageResource.Vlevo_down];
                        FDownedButton = true;
                        SetPosuvRychlost(DEFAULT_POSUV_SPEED, true);
                        SetLanoRychlostSynchro();
                    }
                }
            }
            if (((PictureBox)sender).Name == "pbStred")
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (FDownedButton == true)
                    {
                        FDownedButton = false;
                        
                    }
                    else
                    {
                        FDownedButton = true;
                        if (FIO.Magnet == true)
                        {
                            FIO.Magnet = false;
                        }
                        else
                        {
                            FIO.Magnet = true;
                        }
                    }
                    if (FIO.Magnet == true)
                    {
                        pbStred.Image = FImageResources[(Int32)FImageResource.Stred_on];
                    }
                    else
                    {
                        pbStred.Image = FImageResources[(Int32)FImageResource.Stred];
                    }
                }
            }
        }

        private void CountIO(UInt16 PoziceSensorValue)
        {
            //Pozice 7140..28962
            FIO.Pozice = (Int32)Math.Round((PoziceSensorValue - FGeometrie.PoziceLeftBorder) * FGeometrie.PozicePrevod);
            if (FIO.Pozice < 0) FIO.Pozice = 0;
            if (FIO.Pozice > FGeometrie.SvetlostPosuvu) FIO.Pozice = FGeometrie.SvetlostPosuvu;
            /*
            if (FIO.PosuvSpeed >= FGeometrie.PosuvNecitlivost)
            {
                if (FIO.PosuvSmer == true) FIO.Lano = FIO.Lano + (Int32)Math.Round((FIO.PosuvSpeed - FGeometrie.PosuvNecitlivost) * FGeometrie.PosuvPrevod * FCommunicationInterval/1000.0);
                else FIO.Lano = FIO.Lano - (Int32)Math.Round((FIO.PosuvSpeed - FGeometrie.PosuvNecitlivost) * FGeometrie.PosuvPrevod * FCommunicationInterval / 1000.0);
            }
            if (FIO.LanoSpeed >= FGeometrie.LanoNecitlivost)
            {
                if (FIO.LanoSmer == FNavijeniDoprava) FIO.Lano = FIO.Lano - (Int32)Math.Round((FIO.LanoSpeed - FGeometrie.LanoNecitlivost) * FGeometrie.LanoPrevod * FCommunicationInterval / 1000.0);
                else FIO.Lano = FIO.Lano + (Int32)Math.Round((FIO.LanoSpeed - FGeometrie.LanoNecitlivost) * FGeometrie.LanoPrevod * FCommunicationInterval / 1000.0);
            }
            */
            if (FIO.PosuvSpeed >= FGeometrie.PosuvNecitlivost)
            {
                if (FIO.PosuvSmer == true) FIO.Lano = FIO.Lano - (Int32)Math.Round(GetPosuvRychlost() * FCommunicationInterval / 1000.0);
                else FIO.Lano = FIO.Lano + (Int32)Math.Round(GetPosuvRychlost() * FCommunicationInterval / 1000.0);
            }
            if (FIO.LanoSpeed >= FGeometrie.LanoNecitlivost)
            {
                if (FIO.LanoSmer == FNavijeniDoprava) FIO.Lano = FIO.Lano - (Int32)Math.Round(GetLanoRychlost() * FCommunicationInterval / 1000.0);
                else FIO.Lano = FIO.Lano + (Int32)Math.Round(GetLanoRychlost() * FCommunicationInterval / 1000.0);
            }
            if (FIO.MagnetCidlo == true) FIO.Lano = 0;
            if (FIO.Lano < 0) FIO.Lano = 0;
            if (FIO.Lano > FGeometrie.SvetlostLana) FIO.Lano = FGeometrie.SvetlostLana;
        }

        private void pbModel_Paint(object sender, PaintEventArgs e)
        {
            Graphics canvas = e.Graphics;
            Int32 cidla_r = (int)Math.Round(0.008 * pbModel.Width);
            //FIO.Pozice = FGeometrie.SvetlostPosuvu;
            Double pozice_K = 0.158 + FIO.Pozice / (Double)FGeometrie.SvetlostPosuvu * (0.535 - 0.158);
            Double lano_K = 0.32 + FIO.Lano / (Double)FGeometrie.SvetlostLana * (0.75 - 0.32);
            if (FIO.Cidlo1 == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round(0.22 * pbModel.Width), (int)Math.Round(0.157 * pbModel.Height), cidla_r, cidla_r));
            if (FIO.Cidlo2 == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round(0.338 * pbModel.Width), (int)Math.Round(0.155 * pbModel.Height), cidla_r, cidla_r));
            if (FIO.Cidlo3 == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round(0.458 * pbModel.Width), (int)Math.Round(0.155 * pbModel.Height), cidla_r, cidla_r));
            if (FIO.Cidlo4 == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round(0.555 * pbModel.Width), (int)Math.Round(0.155 * pbModel.Height), cidla_r, cidla_r));
            if (FIO.Cidlo5 == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round(0.653 * pbModel.Width), (int)Math.Round(0.156 * pbModel.Height), cidla_r, cidla_r));
            canvas.DrawImage(FImageResources[(Int32)FImageResource.Kocka], new Rectangle((int)Math.Round(pozice_K * pbModel.Width), (int)Math.Round(0.04 * pbModel.Height), (int)Math.Round(0.12 * pbModel.Width), (int)Math.Round(0.3 * pbModel.Height)));
            //0.158 - 0.535
            if (FIO.MagnetCidlo == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round((0.19 + pozice_K - 0.158) * pbModel.Width), (int)Math.Round(0.218 * pbModel.Height), cidla_r, cidla_r));
            if (FIO.KoleckoSensor == true) canvas.FillEllipse(Brushes.Yellow, new Rectangle((int)Math.Round((0.258 + pozice_K - 0.158) * pbModel.Width), (int)Math.Round(0.057 * pbModel.Height), cidla_r, cidla_r));
            canvas.DrawImage(FImageResources[(Int32)FImageResource.Magnet], new Rectangle((int)Math.Round((0.22 + (0.597 - 0.22) / (0.535 - 0.158) * (pozice_K - 0.158)) * pbModel.Width), (int)Math.Round(lano_K * pbModel.Height), (int)Math.Round(0.04 * pbModel.Width), (int)Math.Round(0.12 * pbModel.Height)));
            //X:0.22 - 0.597 ; Y:0.32 - 0.75
            canvas.DrawImage(FImageResources[(Int32)FImageResource.Lano], new Rectangle((int)Math.Round((0.237 + (0.613 - 0.237) / (0.535 - 0.158) * (pozice_K - 0.158)) * pbModel.Width), (int)Math.Round(0.33 * pbModel.Height), (int)Math.Round(0.0027 * pbModel.Width), (int)Math.Round((lano_K - 0.32) * pbModel.Height)));
            //X:0.237 - 0.613 ; Y:0.33 - 0.753 (0.423)
        }

        private void pbModel_MouseMove(object sender, MouseEventArgs e)
        {
            //label4.Text = e.X.ToString() + " - " + e.Y.ToString();
        }

        private void SetPosuvRychlost(Double RychlostMmS, Boolean Doprava)
        {
            FIO.PosuvSmer = Doprava;
            FIO.PosuvSpeed = (UInt16)Math.Round((RychlostMmS - FGeometrie.PosuvOffset)/FGeometrie.PosuvPrevod);
            if (FIO.PosuvSpeed > MAX_POSUV_SPEED_VALUE) FIO.PosuvSpeed = MAX_POSUV_SPEED_VALUE;
            if (FIO.PosuvSpeed < FGeometrie.PosuvNecitlivost) FIO.PosuvSpeed = 0;
        }

        private void SetLanoRychlost(Double RychlostMmS, Boolean Navijet)
        {
            if (!FIO.LanoActive) FIO.LanoActive = true;
            if (Navijet) FIO.LanoSmer = FNavijeniDoprava;
            else FIO.LanoSmer = !FNavijeniDoprava;
            FIO.LanoSpeed = (UInt16)Math.Round((RychlostMmS - FGeometrie.LanoOffset) / FGeometrie.LanoPrevod);
            if (FIO.LanoSpeed > MAX_LANO_SPEED_VALUE) FIO.LanoSpeed = MAX_LANO_SPEED_VALUE;
            if (FIO.LanoSpeed < FGeometrie.LanoNecitlivost) FIO.LanoSpeed = 0;
        }

        private void SetLanoRychlostSynchro()
        {
            if (!FIO.LanoActive) FIO.LanoActive = true;
            if (!FIO.PosuvSmer) FIO.LanoSmer = FNavijeniDoprava;
            else FIO.LanoSmer = !FNavijeniDoprava;
            FIO.LanoSpeed = (UInt16)Math.Round((GetPosuvRychlost() - FGeometrie.LanoOffset) / FGeometrie.LanoPrevod);
            if (FIO.LanoSpeed > MAX_LANO_SPEED_VALUE) FIO.LanoSpeed = MAX_LANO_SPEED_VALUE;
            if (FIO.LanoSpeed < FGeometrie.LanoNecitlivost) FIO.LanoSpeed = 0;
        }

        public Double GetPosuvRychlost()
        {
            if (FIO.PosuvSpeed < FGeometrie.PosuvNecitlivost) return 0;
            else return FGeometrie.PosuvPrevod * FIO.PosuvSpeed + FGeometrie.PosuvOffset;
        }

        public Double GetLanoRychlost()
        {
            if (FIO.LanoSpeed < FGeometrie.LanoNecitlivost) return 0;
            else return FGeometrie.LanoPrevod * FIO.LanoSpeed + FGeometrie.LanoOffset;
        }
    }
}
