using Algorithms.Nw.PathGeneration;
using Algorithms.Nw.ShortestPathAllPairs;
using SeSue.Forms.Common;
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;

namespace SeSue.Forms.PathGeneration
{
    public partial class PGA : Form
    {
        public PGA() { InitializeComponent(); this.Icon = Properties.Resources.logo; }


        #region BGW PGA
        public List<List<List<int>>> getOdLstNodeIndices() { return this.odLstNodeIndices; }
        private List<List<List<int>>> odLstNodeIndices;
        private static double[] arcCosts;
        private int O;
        public void bgwPga_DoWork(object sender, DoWorkEventArgs e)
        {
            List<object> args = (List<object>)e.Argument;
            PathGenerationAlgorithm alg = (PathGenerationAlgorithm)args[0];
            int pathLim = (int)args[1];
            odLstNodeIndices = new List<List<List<int>>>();
            O = SueForm.sue.graph.getNbOdPairs();
            beforeRun();
            Algorithms.Timer timer = new Algorithms.Timer();
            timer.start();
            for (int w = 0; w < SueForm.sue.graph.getOdPairs().Length; w++)
            {
                bgwPga.ReportProgress(0, "Processing " + (w + 1).ToString() + " / " + O + " OD pair.");
                OdPair od = SueForm.sue.graph.getOdPair(w);
                int nbExistingPaths = od.getPathIndices().Length;
                alg.setExistingPathLabels(getExistingPathLabelsForOd(w));
                alg.run(SueForm.sue.graph, od.getOriIndex(), od.getDesIndex(), nbExistingPaths, pathLim, false);
                odLstNodeIndices.Add(alg.getPathsAsNodeIndicesList());
            }
            timer.stop();
            PgaInitializer.runTime = timer.getMiliseconds();
            afterRun();
            System.Threading.Thread.Sleep(100);
        }
        private void bgwPga_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Progress.hide(); }
        private void bgwPga_ProgressChanged(object sender, ProgressChangedEventArgs e) { Progress.setText((string)e.UserState); }
        #endregion

        #region BGW ALL PAIRS SP
        private void bgwAllPairsSp_DoWork(object sender, DoWorkEventArgs e)
        {
            List<object> args = (List<object>)e.Argument;
            ShortestPathAllPairsAlgorithm spapa = (ShortestPathAllPairsAlgorithm)args[0];
            Graph graph = (Graph)args[1];
            spapa.run(SueForm.sue.graph, true);
        }
        private void bgwAllPairsSp_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Progress.hide(); }
        #endregion

        #region HELPERS
        private static List<string> getExistingPathLabelsForOd(int w)
        {
            List<string> lst = new List<string>();
            OdPair od = SueForm.sue.graph.getOdPair(w);
            foreach (int k in od.getPathIndices()) { lst.Add(SueForm.sue.graph.getPath(k).getLabel()); }
            return lst;
        }
        private static void beforeRun()
        {
            arcCosts = new double[SueForm.sue.graph.getNbArcs()];
            for (int a = 0; a < SueForm.sue.graph.getNbArcs(); a++) { arcCosts[a] = SueForm.sue.graph.getArc(a).getCost(); }
            for (int a = 0; a < SueForm.sue.graph.getNbArcs(); a++) { SueForm.sue.graph.getArc(a).setCost(SueForm.sue.graph.getLink(a).getLinkCost().getFreeFlowTravelTime()); }
        }
        private void afterRun()
        {
            for (int a = 0; a < SueForm.sue.graph.getNbArcs(); a++) { SueForm.sue.graph.getArc(a).setCost(arcCosts[a]); }

            // path
            SueForm.sue.graph.insertPaths(odLstNodeIndices);
            SueForm.pathDgv.newSue(SueForm.sue.graph.getOdPair(0).getLabel(), String.Empty, String.Empty);

            // graph
            SueForm.statDgv.newSue();

            // node
            /*
            for (int i = 0; i < SueForm.sue.graph.getNbNodes(); i++)
            {
                Node node = SueForm.sue.graph.getNode(i);
                SueForm.nodesDgv.dgv.setDtValue(i, 5, node.getPathIndices().Length.ToString());
                SueForm.nodesDgv.dgv.setDtValue(i, 6, node.getEmanatingPathIndices().Length.ToString());
                SueForm.nodesDgv.dgv.setDtValue(i, 7, node.getIncomingPathIndices().Length.ToString());
            }//*/

            // od
            for (int w = 0; w < SueForm.sue.graph.getNbOdPairs(); w++)
            {
                OdPair od = SueForm.sue.graph.getOdPair(w);
                SueForm.odDgv.dgv.setDtValue(w, 2, od.getPathIndices().Length.ToString());
            }
        } 
        #endregion

        private void PGA_FormClosed(object sender, FormClosedEventArgs e) { this.Owner.Activate(); }

        

        

    }
}
