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;

namespace Teplomer
{
    public partial class Import : Form
    {
        public uint pocetZarizeni = 0;
        public bool transfer = false;
        public byte odpoved = 0;

        public uint pocet_cidel = 0;
        public byte cidla = 0;
        public string intervaly;
        public bool zaznamenano = false;
        public System.Collections.Queue fronta;

        FTDI zarizeni = new FTDI();
        public Import()
        {
            InitializeComponent();
            dataGridView1.ColumnCount = 5;
            dataGridView1.Columns[0].Name = "id";
            dataGridView1.Columns[1].Name = "čidla";
            dataGridView1.Columns[2].Name = "interval";
            dataGridView1.Columns[3].Name = "typ";
            dataGridView1.Columns[4].Name = "počet záznamů";
            zpracovat.Enabled = false;
            nacist.Enabled = false;
            Smazat.Enabled = false;
            comboBox1_Click(comboBox1, new EventArgs());
            if (pocetZarizeni < 1)
                MessageBox.Show("K počítači není připojeno žádné podporované zařízení");
            if (pocetZarizeni == 1) 
                otevrit_Click(otevrit, new EventArgs());
            timer1.Interval = 900;
            timer2.Interval = 1100;
        }
        private void Import_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (zarizeni.IsOpen)
                zarizeni.Close();
            timer1.Stop();
            timer2.Stop();
        }
        private void otevrit_Click(object sender, EventArgs e)
        {
            if (zarizeni.IsOpen)//zavřít
            {
                timer1.Stop();
                timer2.Stop();
                zarizeni.Close();
                comboBox1.Enabled = true;
                zpracovat.Enabled = false;
                nacist.Enabled = false;
                Smazat.Enabled = false;
                otevrit.Text = "Otevřít";
                toolStripStatusLabel1.Text = "Neotevřeno";
                return;
            }
            zarizeni.OpenBySerialNumber(comboBox1.Text);
            if (!zarizeni.IsOpen)
            {
                timer1.Stop();
                timer2.Stop();
                MessageBox.Show("Zařízení se nepodařilo otevřít");
                toolStripStatusLabel1.Text = "Zařízení se nepodařilo otevřít";
                comboBox1.Enabled = true;
                zpracovat.Enabled = false;
                nacist.Enabled = false;
                Smazat.Enabled = false;
                return;
            }
            comboBox1.Enabled = false;
            otevrit.Enabled = true;
            dataGridView1.RowCount = 0;
            toolStripStatusLabel1.Text = "Otevřeno";
            otevrit.Text = "Zavřít";
            timer1.Start();
        }
        private void comboBox1_Click(object sender, EventArgs e)
        {
            zarizeni.GetNumberOfDevices(ref pocetZarizeni);
            comboBox1.Items.Clear();
            if (pocetZarizeni < 1)
            {
                otevrit.Enabled = false;
                return;
            }
            else
            {
                FTDI.FT_DEVICE_INFO_NODE[] idCIsla = new FTDI.FT_DEVICE_INFO_NODE[pocetZarizeni];
                zarizeni.GetDeviceList(idCIsla);
                foreach (FTDI.FT_DEVICE_INFO_NODE a in idCIsla)
                {
                    comboBox1.Items.Add(a.SerialNumber.ToString());
                    comboBox1.SelectedIndex = 0;
                }
                otevrit.Enabled = true;
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!transfer)
            {
                uint a = 0;
                byte[] zapis = new byte[] {0xAA};
                zarizeni.Write(zapis, 1, ref a);
                toolStripStatusLabel1.Text = "PC→dev";
                timer2.Start();
            }
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            byte[] data = new byte [10];
            uint pocet = 0, a = 0;
            zarizeni.GetRxBytesAvailable(ref pocet);
            if (pocet == 0)
            {
                otevrit_Click(otevrit, new EventArgs());
                MessageBox.Show("Zařízení bylo odpojeno");
                return;
            }
            zarizeni.Read(data, pocet, ref a);
            while (a == 0) 
                ;
            if (data[0] == 0xAA)
            {
                otevrit_Click(otevrit, new EventArgs());
                MessageBox.Show("Zařízení je zaneprázdněno");
            }
            else if (data[0] != 0x55)
            {
                timer1.Stop();
                timer2.Stop();
                MessageBox.Show("HEM2");
            }
            toolStripStatusLabel1.Text = "PC←dev";
            zpracovat.Enabled = true;
        }
        private void zpracovat_Click(object sender, EventArgs e)
        {
            zpracovat.Enabled = false;
            nacist.Enabled = false;
            Smazat.Enabled = false;
            dataGridView1.RowCount = 0;
            fronta = new System.Collections.Queue();
            byte[] data = new byte[] {0xF0, 0, 0, 0, 0};
            uint pocet = 0, a = 0;
            timer1.Stop();
            timer2.Stop();
            zarizeni.Write(data, 1, ref a);//zápis požadavku
            while (a == 0)
                ;
            while (true)
            {
                while (true)                     //čekání na 0x00
                {
                    zarizeni.GetRxBytesAvailable(ref pocet);
                    if (pocet > 0)
                        break;
                }
                zarizeni.Read(data, 1, ref a);// čtení
                while (a == 0)
                    ;
                if (data[0] != 0x00)
                {
                    continue;
                }
                break;
            }
            while (true)                    //čtení dat
            {
                while(true)                 //čtení prvního bytu
                {
                    zarizeni.GetRxBytesAvailable(ref pocet);
                    if (pocet > 0)
                        break;
                }
                zarizeni.Read(data, 1, ref a);
                while (a == 0)
                    ;
                if (data[0] == 0xFF)        //test na poslední prvek
                    break;

                fronta.Enqueue(data[0]);
                while(true)                 //čekání na dalších 5 bytů
                {
                    zarizeni.GetRxBytesAvailable(ref pocet);
                    if (pocet >= 5)
                        break;
                }
                zarizeni.Read(data, 5,ref a);
                while (a < 5)
                    ;
                fronta.Enqueue(data[0]);
                fronta.Enqueue(data[1]);
                fronta.Enqueue(data[2]);
                fronta.Enqueue(data[3]);
                fronta.Enqueue(data[4]);
            }
            //--------------------------------------
            dataGridView1.ColumnCount = 5;
            for (int i = 0; fronta.Count > 0; i++)
            {
                dataGridView1.RowCount++;
                dataGridView1.Rows[i].Cells[0].Value = (((UInt16)((byte)fronta.Dequeue())) << 8 )+ (byte)fronta.Dequeue();//id
                a = (byte)fronta.Dequeue();//počet čidel
                for (int j = 4; j < 8; j++)
                {
                    if ((a & (1 << j)) > 0)
                        dataGridView1.Rows[i].Cells[1].Value += "o";
                    else
                        dataGridView1.Rows[i].Cells[1].Value += "x";
                }
                switch (a & 0x0F)
                {
                    case 0:
                        dataGridView1.Rows[i].Cells[2].Value = "1s";
                        break;
                    case 1:
                        dataGridView1.Rows[i].Cells[2].Value = "2s";
                        break;
                    case 2: 
                        dataGridView1.Rows[i].Cells[2].Value = "5s";
                        break;
                    case 3: 
                        dataGridView1.Rows[i].Cells[2].Value = "10s";
                        break;
                    case 4: 
                        dataGridView1.Rows[i].Cells[2].Value = "30s";
                        break;
                    case 5: 
                        dataGridView1.Rows[i].Cells[2].Value = "1min";
                        break;
                    case 6: 
                        dataGridView1.Rows[i].Cells[2].Value = "2min";
                        break;
                    case 7: 
                        dataGridView1.Rows[i].Cells[2].Value = "5min";
                        break;
                    case 8: 
                        dataGridView1.Rows[i].Cells[2].Value = "10min";
                        break;
                    case 9: 
                        dataGridView1.Rows[i].Cells[2].Value = "30min";
                        break;
                    default:
                        dataGridView1.Rows[i].Cells[2].Value = "neznámo(?)";
                        break;
                }

                a = (byte)fronta.Dequeue();
                for (int j = 0; j < 4; j++)
                {
                    if ((a & (1 << j)) > 0)
                        dataGridView1.Rows[i].Cells[3].Value += "Ni ";
                    else
                        dataGridView1.Rows[i].Cells[3].Value += "Pt ";
                }
                dataGridView1.Rows[i].Cells[4].Value = (((UInt16)((byte)fronta.Dequeue())) << 8) + (byte)fronta.Dequeue();//délka
            }
            if (dataGridView1.RowCount > 0)
                nacist.Enabled = true;
            timer1.Start();
            zpracovat.Enabled = true;
            Smazat.Enabled = true;
        }
        private void nacist_Click(object sender, EventArgs e)
        {
            zpracovat.Enabled = false;
            nacist.Enabled = false;
            uint pocet = 0, a = 0;
            fronta = new System.Collections.Queue();
            byte id1 = Convert.ToByte((Convert.ToUInt16(dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[0].Value)) >> 8);
            byte id2 = System.Convert.ToByte(dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[0].Value);
            byte[] data = new byte[] { 0x0F, id1, id2, 0, 0, 0, 0};

            for (int i = 0; i < 4; i++)
            {
                if (dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[1].Value.ToString()[i] == 'o')
                    pocet_cidel++;
            }
            for (int i = 0; i < 4; i++)
                if (dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString()[i*3].ToString() + dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString()[i*3 + 1] + dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString()[i*3 + 2] == "Ni ")
                    cidla |= (byte)(1 << i);
            
            timer1.Stop();
            timer2.Stop();

            zarizeni.Write(data, 3, ref a);//zápis požadavku na záznam
            while (a < 3)
                ;
            while (true)
            {
                while (true)                     //čekání na 0x00
                {
                    zarizeni.GetRxBytesAvailable(ref pocet);
                    if (pocet > 0)
                        break;
                }
                zarizeni.Read(data, 1, ref a);// čtení
                while (a == 0)
                    ;
                if (data[0] != 0x00)
                {
                    continue;
                }
                break;
            }
            while (true)                    //čtení dat
            {
                while (true)                 //čtení prvního bytu
                {
                    zarizeni.GetRxBytesAvailable(ref pocet);
                    if (pocet > 0)
                        break;
                }
                zarizeni.Read(data, 1, ref a);
                while (a == 0)
                    ;
                if (data[0] == 0xFF)        //test na poslední prvek
                    break;

                fronta.Enqueue(data[0]);
                while (true)                 //čekání na všechny byty
                {
                    zarizeni.GetRxBytesAvailable(ref pocet);
                    if (pocet >= (pocet_cidel*2-1))
                        break;
                }
                zarizeni.Read(data, pocet_cidel * 2 - 1, ref a);
                while (a < pocet_cidel * 2-1)
                    ;
                for (int i = 0; i < pocet_cidel*2-1; i++)
                    fronta.Enqueue(data[i]);
            }
            intervaly = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[2].Value.ToString();
            zaznamenano = true;
            this.Close();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[] {0x77};
            uint pocet = 0;
            DialogResult okno = MessageBox.Show("Skutečně smazat všechna data v paměti přístroje?", "Smazat?", MessageBoxButtons.YesNoCancel);
            if (okno == DialogResult.No || okno == DialogResult.Cancel)
            {
                return;
            }
            timer1.Stop();
            timer2.Stop();
            Smazat.Enabled = false;
            zarizeni.Write(data, 1, ref pocet);//zápis 0x77
            while (pocet < 1) 
                ;
            zarizeni.GetRxBytesAvailable(ref pocet);
            while (pocet < 1)                   //čekání na data
                zarizeni.GetRxBytesAvailable(ref pocet);
            zarizeni.Read(data, 1, ref pocet);  //čtení dat
            while (pocet < 1)
                ;
            if (data[0] != 0x55)                //Test na 0x55
            {
                MessageBox.Show("Neznámá chyba");
                timer1.Start();
                return;
            }
            data[0] = 0xEE;
            zarizeni.Write(data, 1, ref pocet);//zápis 0xEE
            while (pocet < 1)
                ;
            zarizeni.GetRxBytesAvailable(ref pocet);
            while (pocet < 1)                   //čekání na data
                zarizeni.GetRxBytesAvailable(ref pocet);
            zarizeni.Read(data, 1, ref pocet);  //čtení dat
            while (pocet < 1)
                ;
            if (data[0] != 0xAA)                //Test na 0xAA
            {
                MessageBox.Show("Neznámá chyba");
                timer1.Start();
                return;
            }
            timer1.Start();
            MessageBox.Show("Smazáno");
            Smazat.Enabled = true;
        }
        
    }
}
