using DiscreteChoiceModel;
using StatisticalDistribution;
using SeSue.DGVs;
using SeSue.DGVs.Wizard;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using U.SUE;
using SeSue.Forms.Common;

namespace SeSue.Forms.Wizards
{
    public partial class MdmExpWizard : Form
    {
        private bool canChangeTabPage;
        private ApplyToDgv applyToDgv;
        private List<int> selectedOdIndices;
        private MdmExpParamsDgv paramsDgv;
        private List<double[]> locations;
        private List<double[]> rates;
        private ExponentialParamsDgv distParamsDgv;

        #region CONSTRUCTOR
        public MdmExpWizard(int w, int h)
        {
            this.Icon = Properties.Resources.logo;
            InitializeComponent();
            this.canChangeTabPage = false;
            if (Program.sueForm.WindowState != FormWindowState.Maximized) { this.Width = w; this.Height = h; }
            this.applyToDgv = new ApplyToDgv(this.splitTab1a.Panel1);
        } 
        #endregion

        #region APPLY TO
        private void btnNext1_Click(object sender, EventArgs e)
        {
            this.selectedOdIndices = this.applyToDgv.getSelectedOdIndices();
            if (selectedOdIndices.Count == 0) { Msg.show("Error.", "At least one OD pair should be selected.", this); return; }
            cbPaths_OdPairs.Items.Clear(); foreach (int w in this.selectedOdIndices) { cbPaths_OdPairs.Items.Add(SueForm.sue.graph.getOdPair(w).getLabel()); }
            this.paramsDgv = new MdmExpParamsDgv(splitTab2e.Panel1);
            canChangeTabPage = true; this.tab.SelectedIndex = 1; canChangeTabPage = false;
            if (this.cbScaling.SelectedIndex == -1) { this.cbScaling.SelectedIndex = 0; }
            if (this.cbCorrection.SelectedIndex == -1) { this.cbCorrection.SelectedIndex = 0; }
        } 
        #endregion

        #region SETTINGS
        private void cbScaling_SelectedIndexChanged(object sender, EventArgs e) { cbChanged(); }
        private void cbCorrection_SelectedIndexChanged(object sender, EventArgs e) { cbChanged(); }
        private void cbChanged()
        {
            int ind1 = cbScaling.SelectedIndex;
            int ind2 = cbCorrection.SelectedIndex;
            if (ind1 == 0 && ind2 == 0) { picBox.Image = Properties.Resources.exp_0_0; return; }
            if (ind1 == 0 && ind2 == 1) { picBox.Image = Properties.Resources.exp_0_1; return; }
            if (ind1 == 0 && ind2 == 2) { picBox.Image = Properties.Resources.exp_0_2; return; }
            if (ind1 == 1 && ind2 == 0) { picBox.Image = Properties.Resources.exp_1_0; return; }
            if (ind1 == 1 && ind2 == 1) { picBox.Image = Properties.Resources.exp_1_1; return; }
            if (ind1 == 1 && ind2 == 2) { picBox.Image = Properties.Resources.exp_1_2; return; }
            if (ind1 == 2 && ind2 == 0) { picBox.Image = Properties.Resources.exp_2_0; return; }
            if (ind1 == 2 && ind2 == 1) { picBox.Image = Properties.Resources.exp_2_1; return; }
            if (ind1 == 2 && ind2 == 2) { picBox.Image = Properties.Resources.exp_2_2; return; }
            if (ind1 == 3 && ind2 == 0) { picBox.Image = Properties.Resources.exp_3_0; return; }
            if (ind1 == 3 && ind2 == 1) { picBox.Image = Properties.Resources.exp_3_1; return; }
            if (ind1 == 3 && ind2 == 2) { picBox.Image = Properties.Resources.exp_3_2; return; }
            if (ind1 == 4 && ind2 == 0) { picBox.Image = Properties.Resources.exp_4_0; return; }
            if (ind1 == 4 && ind2 == 1) { picBox.Image = Properties.Resources.exp_4_1; return; }
            if (ind1 == 4 && ind2 == 2) { picBox.Image = Properties.Resources.exp_4_2; return; }
        }
        private void btnBack2_Click(object sender, EventArgs e) { canChangeTabPage = true; this.tab.SelectedIndex = 0; canChangeTabPage = false; }
        private void btnNext2_Click(object sender, EventArgs e)
        {
            cbPaths_OdPairs.Text = SueForm.sue.graph.getOdPair(selectedOdIndices[0]).getLabel(); tbPaths_Nodes.Text = String.Empty; tbPaths_Links.Text = String.Empty;
            this.distParamsDgv = new ExponentialParamsDgv(splitPaths.Panel2, this.selectedOdIndices, cbScaling.SelectedIndex, cbCorrection.SelectedIndex);
            canChangeTabPage = true; this.tab.SelectedIndex = 2; canChangeTabPage = false;
        } 
        #endregion

        #region MD PARAMS
        private void btnBack3_Click(object sender, EventArgs e) { this.distParamsDgv.dgv.remove(); canChangeTabPage = true; this.tab.SelectedIndex = 1; canChangeTabPage = false; }
        private void btnNext3_Click(object sender, EventArgs e)
        {
            this.locations = this.distParamsDgv.getLocations();
            this.rates = this.distParamsDgv.getRates();
            finalize();
            this.Close();
        } 
        #endregion

        #region FINALIZATION
        private void finalize()
        {
            for (int iw = 0; iw < selectedOdIndices.Count; iw++)
            {
                int w = selectedOdIndices[iw];
                OdPair od = SueForm.sue.graph.getOdPair(w);
                int K = od.getPathIndices().Length;
                double[] locationArr = this.locations[iw];
                double[] rateArr = this.rates[iw];
                Distribution[] mds = new Distribution[K];
                for (int k = 0; k < K; k++) { mds[k] = new ExponentialDist(locationArr[k], 1.0 / rateArr[k]); }
                MDM mdm = new MDM(mds, MDM.UtilityFunctionType.Additive, SueForm.varEpsilon);
                od.setChoiceModel(mdm);
                SueForm.odDt.Rows[w][4] = mdm.ToString();
            }
            SueForm.odDgv.dgv.setDataTable(SueForm.odDt);
            SueForm.pathDgv.newSue(Program.sueForm.cbPaths_OdPairs.Text, Program.sueForm.tbPaths_Nodes.Text, Program.sueForm.tbPaths_Links.Text);
            SueForm.pathDgv.dgv.setDataTable(SueForm.pathDt);
        } 
        #endregion

        #region OTHER
        private void tab_Selecting(object sender, TabControlCancelEventArgs e) { e.Cancel = !canChangeTabPage; }
        private void btnPathsFilter_Click(object sender, EventArgs e) { this.distParamsDgv.filter(cbPaths_OdPairs.Text, tbPaths_Nodes.Text, tbPaths_Links.Text); } 
        #endregion


    }
}
