using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Text;
using System.Windows.Forms;


namespace Teplomer
{
    public partial class Form1 : Form
    {
        static public int pocetCidel;
        int interval;
        string soubor;
        bool otevreno, novy;
        public double[,] konstanty;
        public double[,] knst; //implicitní změřené hodnoty
        double maximum, minimum;

        public Form1()
        {
            InitializeComponent();
            otevreno = false;
            novy = false;
            knst = new double[4,3] {{-3.4550e-06, 0.26832, -263.67}, 
                                    {-3.2003e-06, 0.26679, -263.24},
                                    {-3.2615e-07, 0.26352, -259.57},
                                    {-2.4454e-06, 0.26414, -262.55}};
        }
        private void ulozit()
        {

            System.IO.StreamWriter sw = new System.IO.StreamWriter(soubor);
            sw.Write(pocetCidel.ToString() + "\r\n" + interval.ToString() + "\r\n");
            for (int i = 0; i < pocetCidel; i++)
                sw.Write(konstanty[i, 0].ToString() + "\r\n" + konstanty[i, 1].ToString() + "\r\n" + konstanty[i, 2].ToString() + "\r\n");
            for (int i = 0; i < dataGridView1.RowCount - 1; i++)
                for (int j = 0; j < pocetCidel; j++)
                    sw.Write(dataGridView1[j + 1, i].Value.ToString() + "\r\n");
            sw.Close();
        }
        private void ulozitJako()
        {
            DialogResult res;
            saveFileDialog1.Reset();
            saveFileDialog1.Filter = "(*.txt)|*.txt";
            while (!saveFileDialog1.ValidateNames || saveFileDialog1.FileName.Length <= 0)
            {
                res = saveFileDialog1.ShowDialog();
                if (res == DialogResult.Cancel)
                    return;
            }
            System.IO.StreamWriter sw = new System.IO.StreamWriter(saveFileDialog1.FileName);
            sw.Write(pocetCidel.ToString() + "\r\n" + interval.ToString() + "\r\n");
            for (int i = 0; i < pocetCidel; i++)
                sw.Write(konstanty[i, 0].ToString() + "\r\n" + konstanty[i, 1].ToString() + "\r\n" + konstanty[i, 2].ToString() + "\r\n");
            for (int i = 0; i < dataGridView1.RowCount - 1; i++)
                for (int j = 0; j < pocetCidel; j++)
                    sw.Write(dataGridView1[j + 1, i].Value.ToString() + "\r\n");
            sw.Close();

        }
        private void otevřítToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (otevreno)
            {
                DialogResult okno = MessageBox.Show("Chcete uložit změny v souboru:" + soubor.ToString(), "Uložit?", MessageBoxButtons.YesNoCancel);
                if (okno == DialogResult.Yes)
                    ulozit();
            }
            else if (novy)
            {
                DialogResult okno = MessageBox.Show("Chcete uložit změny v souboru: bez názvu.txt?", "Uložit?", MessageBoxButtons.YesNoCancel);
                if (okno == DialogResult.Yes)
                {
                    ulozitJako();
                }
                else if (okno == DialogResult.Cancel)
                    return;
            }
            openFileDialog1.ShowDialog();
            if (System.IO.File.Exists(openFileDialog1.FileName))
            {
                try
                {
                    soubor = openFileDialog1.FileName;
                    System.IO.StreamReader sr = new System.IO.StreamReader(soubor);
                    openFileDialog1.Reset();
                    pocetCidel = System.Convert.ToInt32(sr.ReadLine());
                    konstanty = new double[pocetCidel, 3];
                    interval = System.Convert.ToInt32(sr.ReadLine());
                    for (UInt16 i = 0; i < pocetCidel; i++)
                    {
                        konstanty[i, 0] = System.Convert.ToDouble(sr.ReadLine());
                        konstanty[i, 1] = System.Convert.ToDouble(sr.ReadLine());
                        konstanty[i, 2] = System.Convert.ToDouble(sr.ReadLine());
                    }
                    dataGridView1.ColumnCount = 0;
                    dataGridView1.ColumnCount = pocetCidel + 1;
                    dataGridView1.Columns[0].Name = "číslo měření";
                    maximum = double.MinValue;
                    minimum = double.MaxValue;
                    for (UInt16 i = 0; i < pocetCidel; i++)
                    {
                        dataGridView1.Columns[i + 1].Name = "odpor " + (i + 1).ToString() + " [Ω]";
                    }
                    string data;
                    for (int i = 0; (data = sr.ReadLine()) != null; i++)
                    {
                        dataGridView1.Rows.Add();
                        dataGridView1[0, i].Value = (i + 1).ToString();
                        dataGridView1[1, i].Value = data;
                        if (pocetCidel > 1)
                            dataGridView1[2, i].Value = sr.ReadLine();
                        if (pocetCidel > 2)
                            dataGridView1[3, i].Value = sr.ReadLine();
                        if (pocetCidel > 3)
                            dataGridView1[4, i].Value = sr.ReadLine();
                    }
                    obnovit_tabulku(new object(), new EventArgs());
                    otevreno = true;
                    novy = false;
                    vykresleni(pictureBox1.CreateGraphics(), new PaintEventArgs(pictureBox1.CreateGraphics(), new Rectangle()));
                    sr.Close();
                }
                catch
                {
                    MessageBox.Show("Soubor má nesprávný formát");
                    dataGridView1.RowCount = 1;
                    novy = otevreno = false;
                }

            }

        }
        private void obnovit_tabulku(object sender, EventArgs e)
        {
            Color[] barvy =  {Color.Gray, Color.Blue, Color.Red, Color.Green };
            if (dataGridView1.RowCount == 0)
                return;
            dataGridView2.RowCount = dataGridView1.RowCount;
            dataGridView2.ColumnCount = dataGridView1.ColumnCount;
            dataGridView2.Columns[0].Name = "t[s]";
            dataGridView2.EnableHeadersVisualStyles = false;
            for (UInt16 i = 0; i < pocetCidel; i++)
            {
                dataGridView2.Columns[i + 1].Name = "teplota " + (i + 1).ToString() + " [°C]";
                dataGridView2.Columns[i + 1].HeaderCell.Style.BackColor = barvy[i];
            }
            for (int i = 0; i < dataGridView1.RowCount; i++)
            {
                double hodnota;
                dataGridView2[0, i].Value = (i * interval).ToString();
                hodnota = Convert.ToDouble(dataGridView1[1, i].Value);
                hodnota = Math.Pow(hodnota, 2) * konstanty[0, 0] + hodnota * konstanty[0, 1] + konstanty[0, 2];
                dataGridView2[1, i].Value = hodnota;
                maximum = hodnota > maximum ? hodnota : maximum;
                minimum = hodnota < minimum ? hodnota : minimum;
                if (pocetCidel > 1)
                {
                    hodnota = Convert.ToDouble(dataGridView1[2, i].Value);
                    hodnota = Math.Pow(hodnota, 2) * konstanty[1, 0] + hodnota * konstanty[1, 1] + konstanty[1, 2];
                    dataGridView2[2, i].Value = hodnota;
                    maximum = hodnota > maximum ? hodnota : maximum;
                    minimum = hodnota < minimum ? hodnota : minimum;
                }
                if (pocetCidel > 2)
                {
                    hodnota = Convert.ToDouble(dataGridView1[3, i].Value);
                    hodnota = Math.Pow(hodnota, 2) * konstanty[2, 0] + hodnota * konstanty[2, 1] + konstanty[2, 2];
                    dataGridView2[3, i].Value = hodnota;
                    maximum = hodnota > maximum ? hodnota : maximum;
                    minimum = hodnota < minimum ? hodnota : minimum;
                }
                if (pocetCidel > 3)
                {
                    hodnota = Convert.ToDouble(dataGridView1[4, i].Value);
                    hodnota = Math.Pow(hodnota, 2) * konstanty[3, 0] + hodnota * konstanty[3, 1] + konstanty[3, 2];
                    dataGridView2[4, i].Value = hodnota;
                    maximum = hodnota > maximum ? hodnota : maximum;
                    minimum = hodnota < minimum ? hodnota : minimum;
                }
            }
        }
        private void nastaveníKonstantToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (otevreno == false && novy == false)
            {
                MessageBox.Show("Pokud nejsou k dispozici hodnoty měření, není možné upravovat konstanty.");
                return;
            }
            konst dialog = new Teplomer.konst();
            //*****************************************************
            // Vyplnění tabulky
            dialog.tA1.Text = konstanty[0, 0].ToString();
            dialog.tB1.Text = konstanty[0, 1].ToString();
            dialog.tC1.Text = konstanty[0, 2].ToString();
            if (pocetCidel > 1)
            {
                dialog.tA2.Text = konstanty[1, 0].ToString();
                dialog.tB2.Text = konstanty[1, 1].ToString();
                dialog.tC2.Text = konstanty[1, 2].ToString();
            }
            if (pocetCidel > 2)
            {
                dialog.tA3.Text = konstanty[2, 0].ToString();
                dialog.tB3.Text = konstanty[2, 1].ToString();
                dialog.tC3.Text = konstanty[2, 2].ToString();
            }
            if (pocetCidel > 3)
            {
                dialog.tA4.Text = konstanty[3, 0].ToString();
                dialog.tB4.Text = konstanty[3, 1].ToString();
                dialog.tC4.Text = konstanty[3, 2].ToString();
            }
            dialog.ShowDialog();
            if (dialog.ukonceni)
                return;

            //*******************************************************
            // Přepis konstant
            konstanty[0, 0] = Convert.ToDouble(dialog.tA1.Text);
            konstanty[0, 1] = Convert.ToDouble(dialog.tB1.Text);
            konstanty[0, 2] = Convert.ToDouble(dialog.tC1.Text);
            if (pocetCidel > 1)
            {
                konstanty[1, 0] = Convert.ToDouble(dialog.tA2.Text);
                konstanty[1, 1] = Convert.ToDouble(dialog.tB2.Text);
                konstanty[1, 2] = Convert.ToDouble(dialog.tC2.Text);
            }
            if (pocetCidel > 2)
            {
                konstanty[2, 0] = Convert.ToDouble(dialog.tA3.Text);
                konstanty[2, 1] = Convert.ToDouble(dialog.tB3.Text);
                konstanty[2, 2] = Convert.ToDouble(dialog.tC3.Text);
            }
            if (pocetCidel > 3)
            {
                konstanty[3, 0] = Convert.ToDouble(dialog.tA4.Text);
                konstanty[3, 1] = Convert.ToDouble(dialog.tB4.Text);
                konstanty[3, 2] = Convert.ToDouble(dialog.tC4.Text);
            }
            obnovit_tabulku(new object(), new EventArgs());
        }
        private void uložitJakoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ulozitJako();
        }
        private void uložitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (otevreno && !novy)
                ulozit();
            else
                ulozitJako();
        }
        private void zmena_velikosti(object sender, EventArgs e)
        {
            tabControl1.Height = this.Size.Height - 79;
            tabControl1.Width = this.Size.Width - 40;
            dataGridView1.Height = this.Size.Height - 117;
            dataGridView1.Width = this.Size.Width - 60;
            dataGridView2.Height = this.Size.Height - 117;
            dataGridView2.Width = this.Size.Width - 60;
            pictureBox1.Height = this.Size.Height - 117;
            pictureBox1.Width = this.Size.Width - 60;

        }
        private void vykresleni(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(Color.White);
            Pen pero = new Pen(Color.Black, 1);     // tvorba os
            pero.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
            Point bod1 = new Point(5, pictureBox1.Height - 15);
            Point bod2 = new Point(pictureBox1.Width - 15, pictureBox1.Height - 15);
            e.Graphics.DrawCurve(pero, new Point[] { bod1, bod2 });
            bod1 = new Point(15, pictureBox1.Height - 5);
            bod2 = new Point(15, 5);
            e.Graphics.DrawCurve(pero, new Point[] { bod1, bod2 });

            // tvorba popisků
            if (novy == false && otevreno == false)
                return;
            // osa X
            pero.EndCap = System.Drawing.Drawing2D.LineCap.Flat;

            int[] pole = new int[] {100, 50, 20, 10, 5, 1 };
            int rozdil_X = 1;

            for (int i = 0; i < 6 && 30 * (dataGridView1.RowCount) / pole[i] < (pictureBox1.Width - 30); i++)//*
                rozdil_X = pole[i];

            for (int i = 0; i < (dataGridView1.RowCount - 1) / rozdil_X + 1; i++)//*
            {
                bod1 = new Point(15 + i * (pictureBox1.Width - 20) / (dataGridView1.RowCount) * rozdil_X, pictureBox1.Height - 10);
                bod2 = new Point(15 + i * (pictureBox1.Width - 20) / (dataGridView1.RowCount) * rozdil_X, pictureBox1.Height - 20);
                e.Graphics.DrawCurve(pero, new Point[] { bod1, bod2 });
                e.Graphics.DrawString((rozdil_X * i).ToString(), Font, new SolidBrush(Color.DarkSlateBlue), new Point(15 + i * (pictureBox1.Width - 20) / (dataGridView1.RowCount) * rozdil_X, pictureBox1.Height - 12));
            }

            // osa Y

            int min_Y, max_Y, rozdil_Y = 1;
            if (minimum < 0)
                min_Y = ((int)minimum) / 10 * 10 - 10;
            else
                min_Y = ((int)minimum) / 10 * 10;

            if (maximum < 0)
                max_Y = ((int)maximum) / 10 * 10;
            else
                max_Y = ((int)maximum) / 10 * 10 + 10;


            for (int i = 0; i < 6 && 30 * (max_Y - min_Y) / pole[i] < (pictureBox1.Height - 30); i++)
                rozdil_Y = pole[i];

            for (int i = 0; i < (max_Y - min_Y) / rozdil_Y + 1; i++)
            {
                bod1 = new Point(10, pictureBox1.Height - 15 - i * (pictureBox1.Height - 30) / (max_Y - min_Y) * rozdil_Y);
                bod2 = new Point(20, pictureBox1.Height - 15 - i * (pictureBox1.Height - 30) / (max_Y - min_Y) * rozdil_Y);
                e.Graphics.DrawCurve(pero, new Point[] { bod1, bod2 });
                e.Graphics.DrawString((min_Y + rozdil_Y * i).ToString(), Font, new SolidBrush(Color.DarkSlateBlue), new Point(0, pictureBox1.Height - 15 - i * (pictureBox1.Height - 30) / (max_Y - min_Y) * rozdil_Y));
            }
            //vykreslení křivky
            Point[] body = new Point[(dataGridView1.RowCount)];//*
            Pen[] pera = new Pen[] { new Pen(Color.Black, 2), new Pen(Color.Blue, 2), new Pen(Color.Red, 2), new Pen(Color.Green, 2) };
            for (int pocet = 1; pocet < dataGridView2.ColumnCount; pocet++)
            {
                for (int i = 0; i < body.Length; i++)
                    body[i] = new Point(15 + i * (pictureBox1.Width - 20) / (dataGridView1.RowCount), (int)(pictureBox1.Height - (Convert.ToDouble(dataGridView2.Rows[i].Cells[pocet].Value) - min_Y) / (max_Y - min_Y) * (pictureBox1.Height - 30) - 15));

                if (radioButton2.Checked)
                    e.Graphics.DrawCurve(pera[pocet - 1], body);
                else
                    e.Graphics.DrawLines(pera[pocet - 1], body);
            }
        }
        private void ukončitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            vykresleni(pictureBox1.CreateGraphics(), new PaintEventArgs(pictureBox1.CreateGraphics(), new Rectangle()));
        }
        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Import okno = new Teplomer.Import();
            if (okno.pocetZarizeni < 1)
                return;
            okno.ShowDialog();
            if (!okno.zaznamenano)
                return;
            dataGridView1.RowCount = 0;
            pocetCidel = System.Convert.ToInt32(okno.pocet_cidel);
            dataGridView1.ColumnCount =pocetCidel + 1;
            dataGridView1.Columns[0].Name = "číslo vzorku";
            for (UInt16 i = 0; i < pocetCidel; i++)
            {
                dataGridView1.Columns[i + 1].Name = "odpor " + (i + 1).ToString() + " [Ω]";
            }
            double cislo;
            for (int j = 0; okno.fronta.Count > 0; j++ )
            {
                dataGridView1.RowCount++;
                dataGridView1.Rows[j].Cells[0].Value = j;
                for (int i = 0; i < pocetCidel; i++)
                {
                    cislo = (Convert.ToInt16(okno.fronta.Dequeue()) << 8) + Convert.ToInt16(okno.fronta.Dequeue());
                    cislo *= 4.096 / 8192;//napětí na A/D převodníku
                    cislo = (cislo - 2.048) / 11.51;// napětí na diagonále
                    cislo = 1130 * (cislo + 1.024) / (1.024 - cislo);//odpor
                    dataGridView1.Rows[dataGridView1.RowCount - 1].Cells[i + 1].Value = cislo;
                }
            }
            konstanty = new double[pocetCidel, 3];
            for (int j = 0,  i = 0; i < 4; i++)
            {
                if (okno.dataGridView1.Rows[okno.dataGridView1.SelectedRows[0].Index].Cells[1].Value.ToString().ToString()[i] == 'x')
                    continue;
                
                if ((okno.cidla & (1 << i)) > 1)  //Ni
                {
                    konstanty[j, 0] = -3e-05;
                    konstanty[j, 1] = 0.249;
                    konstanty[j++, 2] = -215.9;
                }
                else                            //Pt vyplní kalibrované konstanty
                {
                    konstanty[j, 0] = knst[i, 0];
                    konstanty[j, 1] = knst[i, 1];
                    konstanty[j++, 2] = knst[i, 2];
                }
            }
            switch (okno.intervaly)
            {
                case "1s": interval = 1; break;
                case "2s": interval = 2; break;
                case "5s": interval = 5; break;
                case "10s": interval = 10; break;
                case "30": interval = 30; break;
                case "1min": interval = 60; break;
                case "2min": interval = 120; break;
                case "5min": interval = 300; break;
                case "10min": interval = 600; break;
                case "30min": interval = 1800; break;
            }
            novy = true;
            otevreno = false;
            obnovit_tabulku(new object(), new EventArgs());
            vykresleni(pictureBox1.CreateGraphics(), new PaintEventArgs(pictureBox1.CreateGraphics(), new Rectangle()));
        }
    }
}
