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 ModbusTCP;

namespace PLC_Monitor
{
    public partial class Form1 : Form
    {
        private ModbusTCP.Master MBmaster;
        //private TextBox txtData;
        //private Label labData;
        List<RadioButton> IN = new List<RadioButton>();
        List<RadioButton> OUT = new List<RadioButton>();

        List<Boolean> Input = new List<Boolean>();
        List<Boolean> Output = new List<Boolean>();
        byte out_stav;
        bool rucne = false;
        byte ziadane = 0;
        public Form1()
        {
            InitializeComponent();
            for (int i = 0; i < 9; i++)
            {
                Input.Add(false);
                Output.Add(false);
            }
            IN.Add(IN1);
            IN.Add(IN2);
            IN.Add(IN3);
            IN.Add(IN4);
            IN.Add(IN5);
            IN.Add(IN_6);
            IN.Add(IN7);
            IN.Add(IN8);
            OUT.Add(OUT1);
            OUT.Add(OUT2);
            OUT.Add(OUT3);
            OUT.Add(OUT4);
            OUT.Add(OUT5);
            OUT.Add(OUT6);
            OUT.Add(OUT7);
            OUT.Add(OUT8);
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                System.Net.IPAddress adresa;
                if (System.Net.IPAddress.TryParse(textBox1.Text, out adresa))
                {
                    // Vytvor modbus master
                    MBmaster = new Master(textBox1.Text, 502);
                    MBmaster.OnResponseData += new ModbusTCP.Master.ResponseData(MBmaster_OnResponseData);
                    MBmaster.OnException += new ModbusTCP.Master.ExceptionData(MBmaster_OnException);
                    button1.Visible = false;
                    textBox1.Visible = false;
                    textBox2.Visible = false;
                    label1.Visible = false;
                    button2.Visible = true;
                }
            }
            catch (SystemException error)
            {
                MessageBox.Show(error.Message);
                button1.Visible = true;
                textBox1.Visible = true;
                textBox2.Visible = true;
                label1.Visible = true;
                button2.Visible = false;
            }
            rucne = false;
        }

        private void MBmaster_OnResponseData(ushort ID, byte unit, byte function, byte[] values)
        {
            // ------------------------------------------------------------------
            // Seperate calling threads
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new Master.ResponseData(MBmaster_OnResponseData), new object[] { ID, unit, function, values });
                return;
            }

            // ------------------------------------------------------------------------
            // Identify requested data
            if (function == 3) 
            switch (ID)
            {
                case 3:
                    for (int i = 0; i < 8; i++)
                    {
                        Input[i]= IN[i].Checked = (values[1] & (1 << i)) != 0;
                        
                    }
                    for (int i = 0; i < 8; i++)
                    {
                        Output[i]= OUT[i].Checked = (values[3] & (1 << i)) != 0;
                    }
                    out_stav = values[3];
                    nastav_stav();
                    break;
                default:
                    break;
            }
        }

        void nastav_stav() {
            if (Input[1])
                button_stred.BackColor = Color.Lime;
            else
                button_stred.BackColor = Color.DarkGreen;

            if (Input[3])
                button_Doraz.BackColor = Color.Lime;
            else
                button_Doraz.BackColor = Color.Maroon;

            if (Input[4])
                button_vrch.BackColor = Color.Lime;
            else
                button_vrch.BackColor = Color.DarkGreen;

            if (Input[5])
                button_material.BackColor = Color.Lime;
            else
                button_material.BackColor = Color.Maroon;

            if (Input[6])

                button_spodok.BackColor = Color.Lime;
            else
                button_spodok.BackColor = Color.DarkGreen;

            button_GoDown.Visible = Output[0];
            button_GoUp.Visible=Output[2];

            if (Output[1])
                button_zelena_led.BackColor = Color.Lime;
            else
                button_zelena_led.BackColor = Color.DarkGreen;

            if (Output[5])
                button_Cervena_Led.BackColor = Color.Red;
            else
                button_Cervena_Led.BackColor = Color.Maroon;

            if (Output[4])
                this.panel1.BackgroundImage = global::PLC_Monitor.Properties.Resources.vrtacka_RUN;
            else
                this.panel1.BackgroundImage = global::PLC_Monitor.Properties.Resources.vrtacka;
        

        }
        private void MBmaster_OnException(ushort id, byte unit, byte function, byte exception)
        {
            string exc = "Modbus says error: ";
            switch (exception)
            {
                case Master.excIllegalFunction: exc += "Illegal function!"; break;
                case Master.excIllegalDataAdr: exc += "Illegal data adress!"; break;
                case Master.excIllegalDataVal: exc += "Illegal data value!"; break;
                case Master.excSlaveDeviceFailure: exc += "Slave device failure!"; break;
                case Master.excAck: exc += "Acknoledge!"; break;
                case Master.excGatePathUnavailable: exc += "Gateway path unavailbale!"; break;
                case Master.excExceptionTimeout: exc += "Slave timed out!"; break;
                case Master.excExceptionConnectionLost: exc += "Connection is lost!"; break;
                case Master.excExceptionNotConnected: exc += "Not connected!"; break;
            }

            MessageBox.Show(exc, "Modbus slave exception");
        }

        private void tick(object sender, EventArgs e)
        {
            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID			= 3;//read holding register
            ushort StartAddress = 12288;// 12288;
			byte Length			= 8;
			MBmaster.ReadHoldingRegister(ID, unit, StartAddress, Length);		
        }

        private void button2_Click(object sender, EventArgs e)
        {
            rucne = !rucne;

            byte[] vstup = new byte[4];

            if (rucne)
            {
                button2.Text = "Automaticky";
                vstup[1] = 0xFF;
                ziadane = out_stav;
                button_SET_DOWN.Visible = true;
                button_SET_UP.Visible = true;
                button_SET_RUN.Visible = true;
            }
            else
            {
                button2.Text = "Rucne";
                vstup[1] = 0x00;
                button_SET_DOWN.Visible = false;
                button_SET_UP.Visible = false;
                button_SET_RUN.Visible = false;
            }
            byte unit;
            vstup[3] = ziadane;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12290;// 12288;
            byte Length = 8;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);

            

        }

        private void Set_OUT(object sender, EventArgs e)
        {
            if (!rucne) return;
            RadioButton button = (RadioButton)sender;
            string text = button.Name;
            int cislo=Convert.ToInt32(text.Substring(3));
            ziadane ^= (byte)(1 << (cislo-1));

            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12290;// 12288;
            byte[] vstup = new byte[4];
            vstup[1] = 0xFF;
            vstup[3]=ziadane;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);		
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void SET_UP(object sender, MouseEventArgs e)
        {
            if (!rucne) return;
  
            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12290;// 12288;
            byte[] vstup = new byte[4];

            ziadane = (byte)(ziadane & 0xFE);
            ziadane = (byte)(ziadane | 0x4);

            vstup[1] = 0xFF;
            vstup[3] = ziadane;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);	
        }

        private void SET_STOP(object sender, MouseEventArgs e)
        {
            if (!rucne) return;

            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12290;// 12288;
            byte[] vstup = new byte[4];

            ziadane = (byte)(ziadane & 0xFA);

            vstup[1] = 0xFF;
            vstup[3] = ziadane;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);	
        }

        private void SET_DOWN(object sender, MouseEventArgs e)
        {
            if (!rucne) return;

            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12290;// 12288;
            byte[] vstup = new byte[4];

            ziadane = (byte)(ziadane & 0xFB);

            ziadane = (byte)(ziadane | 0x1);

            vstup[1] = 0xFF;
            vstup[3] = ziadane;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);	
        }

        private void vrtacka_zmen_stav(object sender, EventArgs e)
        {
            if (!rucne) return;

            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12290;// 12288;
            byte[] vstup = new byte[4];

            ziadane ^= (byte)(0x08);

            vstup[1] = 0xFF;
            vstup[3] = ziadane;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);	
        }

        private void Start(object sender, EventArgs e)
        {
            //if (!rucne) return;

            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12292;// 12288;
            byte[] vstup = new byte[4];

            vstup[1] = 0x01;
            vstup[3] = 0;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);	
        }

        private void stop(object sender, EventArgs e)
        {
            //if (!rucne) return;

            byte unit;
            if (MBmaster == null) return;
            if (!byte.TryParse(textBox2.Text, out unit)) return;
            ushort ID = 3;//read holding register
            ushort StartAddress = 12292;// 12288;
            byte[] vstup = new byte[4];

            ziadane ^= (byte)(0x10);

            vstup[1] = 0x03;
            vstup[3] = 0;
            MBmaster.WriteMultipleRegister(ID, unit, StartAddress, vstup);	
        }

    }
}
