using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


using CategoryTheory;
using DiagramUI;
using Regression;
using DataPerformer;
using GeneralLinearMethod;

namespace DataPerformerUI
{
    public partial class FormAliasRegression : Form, IUpdatableForm
    {
        private IObjectLabel label;
        private AliasRegression regression;

        private FormAliasRegression()
        {
            InitializeComponent();
        }

        public FormAliasRegression(IObjectLabel label)
            : this()
        {
            ResourceService.Resources.LoadControlResources(this);
            this.label = label;
            regression = label.Object as AliasRegression;
            UpdateFormUI();
            createAliasPanels(regression.Aliases.Count);
            fillAliasPanels();
            fillSelections();
            createMeasurementsPanel();
            measurements = regression.MeasuresNames;
            Hashtable t = regression.Aliases;
            if (t != null)
            {
                numericUpDownAliases.Value = t.Count;
            }
        }

        #region IUpdatableForm Members

        public void UpdateFormUI()
        {
            Text = label.Name;
        }

        #endregion


        private void createAliasPanels(int count)
        {
            List<string> al = new List<string>();
            DataConsumer.GetAliases(regression, al);
            panelAliases.Controls.Clear();
            int y = 0;
            for (int i = 0; i < count; i++)
            {
                RegressionAliasPanel panel = new RegressionAliasPanel(al);
                panel.Top = y;
                panel.Left = 0;
                panel.Width = panelAliases.Width;
                y += panel.Height;
                panelAliases.Controls.Add(panel);
                Panel pan = new Panel();
                pan.Height = 3;
                pan.BackColor = Color.Black;
                pan.Top = y;
                pan.Width = panelAliases.Width;
                pan.Left = 0;
                panelAliases.Controls.Add(pan);
                y += pan.Height;
            }
        }

        private void fillAliasPanels()
        {
            int i = 0;
            Hashtable t = regression.Aliases;
            foreach (Control c in panelAliases.Controls)
            {
                if (!(c is RegressionAliasPanel))
                {
                    continue;
                }
                RegressionAliasPanel p = c as RegressionAliasPanel;
                p.Object = t[i] as object[];
                ++i;
            }
        }

        private Hashtable aliases
        {
            get
            {
                int i = 0;
                Hashtable t = new Hashtable();
                foreach (Control c in panelAliases.Controls)
                {
                    if (!(c is RegressionAliasPanel))
                    {
                        continue;
                    }
                    RegressionAliasPanel p = c as RegressionAliasPanel;
                    t[i] = p.Object;
                    ++i;
                }
                return t;
            }
        }

        private void createMeasurementsPanel()
        {
            int y = 0;
            Hashtable t = regression.MeasuresNames;
            IDataConsumer cons = regression as IDataConsumer;
            for (int i = 0; i < cons.Count; i++)
            {
                IMeasurements m = regression[i];
                RegessionAliasMeasurePanel panel = new RegessionAliasMeasurePanel(m);
                panel.Table = t;
                panel.Top = y;
                panel.Left = 0;
                panel.Width = panelMeasurements.Width;
                panel.Table = t;
                panelMeasurements.Controls.Add(panel);
                y += panel.Height;
                Panel pan = new Panel();
                pan.Height = 3;
                pan.BackColor = Color.Black;
                pan.Top = y;
                pan.Width = panelMeasurements.Width;
                pan.Left = 0;
                panelMeasurements.Controls.Add(pan);
                y += pan.Height;
            }
        }

        private Hashtable measurements
        {
            get
            {
                Hashtable table = new Hashtable();
                foreach (Control c in panelMeasurements.Controls)
                {
                    if (!(c is RegessionAliasMeasurePanel))
                    {
                        continue;
                    }
                    RegessionAliasMeasurePanel p = c as RegessionAliasMeasurePanel;
                    Hashtable t = p.Table;
                    foreach (int i in t.Keys)
                    {
                        table[i] = t[i];
                    }
                }
                return table;
            }
            set
            {
                foreach (Control c in panelMeasurements.Controls)
                {
                    if (!(c is RegessionAliasMeasurePanel))
                    {
                        continue;
                    }
                    RegessionAliasMeasurePanel p = c as RegessionAliasMeasurePanel;
                    p.Table = value;
                }
            }
        }

        private void fillSelections()
        {
            List<IStructuredSelectionCollection> sel = regression.Selections;
            Hashtable t = regression.SelectionsNames;
            int y = 0;
            foreach (IStructuredSelectionCollection s in sel)
            {
                RegressionSelectionPanel panel = new RegressionSelectionPanel(regression, s);
                panel.Width = panelSelections.Width;
                panel.Left = 0;
                panel.Top = y;
                panelSelections.Controls.Add(panel);
                panel.Table = t;
                y += panel.Height;
                Panel pan = new Panel();
                pan.Height = 3;
                pan.BackColor = Color.Black;
                pan.Top = y;
                pan.Width = panelSelections.Width;
                pan.Left = 0;
                panelSelections.Controls.Add(pan);
                y += pan.Height;
            }
        }

        private Hashtable selections
        {
            get
            {
                Hashtable t = new Hashtable();
                foreach (Control c in panelSelections.Controls)
                {
                    if (!(c is RegressionSelectionPanel))
                    {
                        continue;
                    }
                    RegressionSelectionPanel p = c as RegressionSelectionPanel;
                    p.Fill(t);
                }
                return t;
            }
        }

        private void buttonAcceptAliasesNumber_Click(object sender, EventArgs e)
        {
            int n = (int)numericUpDownAliases.Value;
            createAliasPanels(n);

        }

        private void buttonAccept_Click(object sender, EventArgs e)
        {
            try
            {
                regression.Aliases = aliases;
                regression.MeasuresNames = measurements;
                regression.SelectionsNames = selections;
                regression.Init();
            }
            catch (Exception ex)
            {
                DefaultForm.ShowError(this, ex);
            }

        }

        private void buttonIterate_Click(object sender, EventArgs e)
        {
            try
            {
                regression.UpdateSelections();
                DataPerformerStrategy.Object.PrepareAll(label.Desktop);
                double s = regression.Iterate();
                regression.SetAliases();
                labelSigma0.Text = Math.Sqrt(regression.SquareResidual / regression.DataDimension) + "";
            }
            catch (Exception ex)
            {
                DefaultForm.ShowError(this, ex);
            }
        }
    }
}