using DiscreteChoiceModel;
using StatisticalDistribution;
using SeSue.FormClasses.Dgv;
using SeSue.Forms;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using U.ListOperations;
using U.StringOperations;
using U.SUE;

namespace SeSue.DGVs
{
    public class OdDgv
    {
        private List<DgvColumn> dgvCols;
        public Dgv dgv;
        

        public OdDgv(Control container)
        {
            this.dgvCols = new List<DgvColumn>()
            {
                new DgvColumn("w", true, true, 0.10, typeof(int), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("Label", true, true, 0.10, typeof(string), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("# Paths", true, true, 0.10, typeof(int), "#,###,##0", true, DataGridViewContentAlignment.MiddleRight, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("Demand", true, false, 0.10, typeof(double), String.Empty, true, DataGridViewContentAlignment.MiddleRight, SueForm.editableColor, SueForm.regularFontColor),
                new DgvColumn("Choice Model", true, false, 0.60, typeof(string), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.regularFontColor),
            };
            this.dgv = new Dgv(null, dgvCols, SueForm.editableColor, SueForm.gridColor, true, false, SueForm.rowHeight, SueForm.headerVertPadding, false, false, false, true, false, true, DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText, DataGridViewSelectionMode.CellSelect, ScrollBars.Vertical, DockStyle.Fill);
            container.Controls.Add(dgv);
            this.dgv.getDataGridView().CellValidating += new DataGridViewCellValidatingEventHandler(validating);
            this.dgv.getDataGridView().CellValueChanged += new DataGridViewCellEventHandler(valueChanged);
        }

        public void newSue()
        {
            DataTable dt = this.dgv.getEmptyDatatable();
            if (SueForm.sue.graph != null)
            {
                for (int w = 0; w < SueForm.sue.graph.getOdPairs().Length; w++)
                {
                    OdPair od = SueForm.sue.graph.getOdPair(w);
                    DataRow dr = dt.NewRow();
                    dr[0] = w.ToString();
                    dr[1] = od.getLabel();
                    dr[2] = od.getPathIndices().Length.ToString();
                    dr[3] = od.getDemand().ToString();
                    if (od.getChoiceModel() != null) { dr[4] = od.getChoiceModel().ToString(); }
                    else { dr[4] = "null"; }
                    dt.Rows.Add(dr);
                }
            }
            SueForm.odDt = dt;
        }


        // VALIDATING
        private void valueChanged(object sender, DataGridViewCellEventArgs e)
        {
            int r = e.RowIndex;
            int c = e.ColumnIndex;
            int w = dgv.getCellValueInt(r, 0);
            OdPair od = SueForm.sue.graph.getOdPair(w);
            string val = dgv.getCellValue(r, c);
            int K = this.dgv.getCellValueInt(r, 2);
            if (c == 4)
            {
                 // Dgv Cell Value Changes
                if (val.ToUpper() == "DUE") { val = "Det(Max)"; }
                else if (val == String.Empty) { val = "null"; }
                else
                {
                    try
                    {
                        ChoiceModel cmPre = ChoiceModel.fromString(val);
                        if (cmPre == null) { }
                        else if (cmPre.getType() == ChoiceModel.Type.Logit)
                        {
                            Logit logit = (Logit)cmPre;
                            if (logit.getCorrectionTerms() == null) { logit.setCorrectionTerms(UArray.sameValues(1.0, K)); }
                            else if (logit.getCorrectionTerms().Length == 1) { logit.setCorrectionTerms(UArray.sameValues(logit.getCorrectionTerms()[0], K)); }
                            else if (logit.getCorrectionTerms().Length != K)
                            {
                                MessageBox.Show("Nb of correction terms is not equal to the number of alternatives (routes).", "Validation Error!");
                                val = "null";
                            }
                            if (val != "null") { val = logit.ToString(); }
                        }
                        else if (cmPre.getType() == ChoiceModel.Type.Weibit)
                        {
                            Weibit weibit = (Weibit)cmPre;
                            if (weibit.getCorrectionTerms() == null) { weibit.setCorrectionTerms(UArray.sameValues(1.0, K)); }
                            else if (weibit.getCorrectionTerms().Length == 1) { weibit.setCorrectionTerms(UArray.sameValues(weibit.getCorrectionTerms()[0], K)); }
                            else if (weibit.getCorrectionTerms().Length != K)
                            {
                                MessageBox.Show("Nb of correction terms is not equal to the number of alternatives (routes).", "Validation Error!");
                                val = "null";
                            }
                            if (val != "null") { val = weibit.ToString(); }
                        }
                        else if (cmPre.getType() == ChoiceModel.Type.MDM)
                        {
                            MDM mdm = (MDM)cmPre;
                            if (mdm.getMarginalDistributions() == null) { mdm.setIdenticalMarginalDistributions(null, K); }
                            else if (mdm.getMarginalDistributions().Length == 1) { mdm.setIdenticalMarginalDistributions(mdm.getMarginalDistributions()[0], K); }
                            else if (mdm.getMarginalDistributions().Length != K)
                            {
                                MessageBox.Show("Nb of marginal distributions is not equal to the number of alternatives (routes).", "Validation Error!");
                                val = "null";
                            }
                            if (val != "null") { val = mdm.ToString(); }
                        }
                    }
                    catch (Exception) { val = "null"; }
                }
                dgv.setCellValue(r, c, val);
                // After Cell Value changes
                ChoiceModel cm = ChoiceModel.fromString(val);
                od.setChoiceModel(cm);
                SueForm.pathDgv.newSue(Program.sueForm.cbPaths_OdPairs.Text, Program.sueForm.tbPaths_Nodes.Text, Program.sueForm.tbPaths_Links.Text);
                SueForm.pathDgv.dgv.setDataTable(SueForm.pathDt);
            }
        }
        private void validating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            int r = e.RowIndex;
            int c = e.ColumnIndex;
            int w = dgv.getCellValueInt(r, 0);
            OdPair od = SueForm.sue.graph.getOdPair(w);
            string val = e.FormattedValue.ToString();
            int K = this.dgv.getCellValueInt(r, 2);
            string header = this.dgv.getDataGridView().Columns[c].HeaderText;
            if (c == 3)
            {
                if (!Str.isNumeric(val)) { MessageBox.Show(header + " should be numeric.", "Validation Error!"); e.Cancel = true; }
                else if (Convert.ToDouble(val) <= 0) { MessageBox.Show("Demand should be nonnegative.", "Validation Error!"); e.Cancel = true; }
                od.setDemand(dgv.getCellValueDbl(r, c));
            }
            else if (c == 4) { }
        }
        public static void setNonMdmPaths(int w)
        {
            int K = SueForm.sue.graph.getOdPair(w).getPathIndices().Length;
            for (int k = 0; k < K; k++)
            {
                int pathInd = SueForm.odPathDtIndices[w][k];
                int dgvInd = SueForm.pathDgv.dgv.getRowIndex(0, pathInd.ToString());
                SueForm.pathDgv.dgv.setCellReadOnly(dgvInd, 4, true);
                SueForm.pathDgv.dgv.setCellBackColor(dgvInd, 4, SueForm.readOnlyColor);
                SueForm.pathDgv.dgv.setCellForeColor(dgvInd, 4, SueForm.readOnlyColor);
                SueForm.pathDgv.dgv.setDtValue(pathInd, 4, String.Empty);
            }
        }
        public static void setMdmPaths(int w)
        {
            int K = SueForm.sue.graph.getOdPair(w).getPathIndices().Length;
            MDM mdm = (MDM)SueForm.sue.graph.getOdPair(w).getChoiceModel();
            for (int k = 0; k < K; k++)
            {
                int pathInd = SueForm.odPathDtIndices[w][k];
                int dgvInd = SueForm.pathDgv.dgv.getRowIndex(0, pathInd.ToString());
                SueForm.pathDgv.dgv.setCellReadOnly(dgvInd, 4, false);
                SueForm.pathDgv.dgv.setCellBackColor(dgvInd, 4, SueForm.editableColor);
                SueForm.pathDgv.dgv.setCellForeColor(dgvInd, 4, SueForm.regularFontColor);
                string str = "null";
                if (mdm.getMarginalDistributions() != null) { if (mdm.getMarginalDistributions()[k] != null) { str = mdm.getMarginalDistributions()[k].ToString(); } }
                SueForm.pathDgv.dgv.setDtValue(pathInd, 4, str);
            }
        }



    }
}
