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 PathDgv
    {
        private List<DgvColumn> dgvCols;
        public Dgv dgv;
        

        public PathDgv(Control container)
        {
            this.dgvCols = new List<DgvColumn>()
            {
                //new DgvColumn("itr", false, true, 0.00, typeof(int), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.regularFontColor),
                new DgvColumn("w", true, true, 0.05, typeof(int), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("k", true, true, 0.05, typeof(int), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("Label", true, true, 0.125, typeof(string), String.Empty, true, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("# Arcs", true, true, 0.075, typeof(int), "#,###,##0", true, DataGridViewContentAlignment.MiddleRight, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("Marginal Dist.", true, false, 0.175, typeof(string), "#,###,##0.0000", false, DataGridViewContentAlignment.MiddleLeft, SueForm.editableColor, SueForm.regularFontColor),
                new DgvColumn("SUE Cost", true, true, 0.175, typeof(double), "#,###,##0.0000", true, DataGridViewContentAlignment.MiddleRight, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("SUE Ch. Prob.", true, true, 0.175, typeof(double), "#,###,##0.0000", true, DataGridViewContentAlignment.MiddleRight, SueForm.editableColor, SueForm.labelColor),
                new DgvColumn("SUE Flow", true, true, 0.175, typeof(double), "#,###,##0.0000", true, DataGridViewContentAlignment.MiddleRight, SueForm.editableColor, SueForm.labelColor),
            };
            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(string odLabel, string nodeLabels, string linkLabels)
        {
            DataTable dt = this.dgv.getEmptyDatatable();
            if (SueForm.sue.graph != null)
            {
                List<string> nodes = new List<string>();
                List<string> links = new List<string>();
                if (nodeLabels != String.Empty) { nodes = Str.split(nodeLabels, Str.Delimiter.Comma); }
                if (linkLabels != String.Empty) { links = Str.split(linkLabels, Str.Delimiter.Comma); }
                int w = getOdPair(odLabel);
                if (w != -1)
                {
                    OdPair od = SueForm.sue.graph.getOdPair(w);
                    for (int k = 0; k < od.getPathIndices().Length; k++)
                    {
                        Path path = SueForm.sue.graph.getPath(od.getPathIndices()[k]);
                        List<string> pathNodes = Str.split(path.getLabel(), Str.Delimiter.Dash);
                        bool include = true;
                        if (nodes.Count > 0)
                        {
                            include = UList.isSubsetOf(nodes, pathNodes);
                        }
                        if (include && links.Count > 0)
                        {
                            List<string> pathLinkLabels = new List<string>();
                            foreach (int a in path.getArcIndices()) { pathLinkLabels.Add(SueForm.sue.graph.getLink(a).getLabel()); }
                            include = UList.isSubsetOf(links, pathLinkLabels);
                        }
                        if (include)
                        {
                            DataRow dr = dt.NewRow();
                            dr[0] = w.ToString();
                            dr[1] = k.ToString();
                            dr[2] = path.getLabel();
                            dr[3] = path.getArcIndices().Length.ToString();
                            dr[4] = String.Empty;
                            dr[5] = path.getCost().ToString();
                            dr[6] = path.getProb().ToString();
                            dr[7] = path.getFlow().ToString();
                            if (od.getChoiceModel() != null)
                            {
                                if (od.getChoiceModel().getType() == DiscreteChoiceModel.ChoiceModel.Type.MDM)
                                {
                                    MDM mdm = (MDM)od.getChoiceModel();
                                    if (mdm.getMarginalDistributions() != null)
                                    {
                                        if (mdm.getMarginalDistributions()[k] != null) { dr[4] = mdm.getMarginalDistributions()[k].ToString(); }
                                        else { dr[4] = "null"; }
                                    }
                                }
                            }
                            dt.Rows.Add(dr);
                        }
                    }
                }
            }
            SueForm.pathDt = dt;
        }
        private int getOdPair(string odLabel) { for (int w = 0; w < SueForm.sue.graph.getOdPairs().Length; w++) { if (SueForm.sue.graph.getOdPair(w).getLabel() == odLabel) { return w; } } return -1; }




        // VALIDATING
        private void valueChanged(object sender, DataGridViewCellEventArgs e)
        {
            int r = e.RowIndex;
            int c = e.ColumnIndex;
            if (c != 4) { return; }
            string str = Str.trim(dgv.getCellValue(r, c));
            int w = dgv.getCellValueInt(r, 0);
            int k = dgv.getCellValueInt(r, 1);
            int index = dgv.getRowIndex(2, dgv.getCellValue(r, 2));
            OdPair od = SueForm.sue.graph.getOdPair(w);
            if (od.getChoiceModel() == null) { if (str != String.Empty) { dgv.setCellValue(r, c, String.Empty); } }
            else if (od.getChoiceModel().getType() != ChoiceModel.Type.MDM) { if (str != String.Empty) { dgv.setCellValue(r, c, String.Empty); } }
            else
            {
                Distribution dist = null;
                try
                {
                    dist = Distribution.fromString(str);
                    if (dist == null) { this.dgv.setDtValue(index, 4, "null"); }
                    else { this.dgv.setDtValue(index, 4, dist.ToString()); }
                }
                catch (Exception exc) { MessageBox.Show(exc.Message, "Validation Error!"); dgv.setCellValue(r, c, String.Empty); }
                MDM mdm = (MDM)od.getChoiceModel();
                mdm.setMarginalDistribution(dist, k);
                SueForm.odDgv.dgv.setDtValue(w, 4, mdm.ToString());
                SueForm.odDgv.dgv.setDataTable(SueForm.odDt);
            }
        }

        
    }
}
