using Algorithms.Nw.ShortestPath;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using U.Graph;

namespace Algorithms.Nw.ShortestPathAllPairs
{
    public abstract class ShortestPathAllPairsAlgorithm : Algorithm
    {
        internal double[,] D;
        internal int[,] P;

        // ABSTRACT
        public abstract void run(Graph graph, bool keepTime);

        // GETTERS
        public double[,] getDistanceMatrix() { return this.D; }
        public int[,] getPrecedenceMatrix() { return this.P; }
        public List<int> getShortestPathAsNodeIndices(int s, int t)
        {
            int j = t;
            List<int> nodeIndices = new List<int>() { j };
            while (j != s)
            {
                j = P[s, j];
                if (j == -1) { return null; }
                nodeIndices.Add(j);
            }
            nodeIndices.Reverse();
            return nodeIndices;
        }
        public List<int> getShortestPathAsEdgeIndices(Graph graph, int s, int t)
        {
            int[,] I = graph.getIncidenceMatrix();
            int j = t;
            List<int> edgeIndices = new List<int>();
            while (j != s)
            {
                int i = P[s, j];
                if (j == -1) { return null; }
                int e = I[i, j];
                edgeIndices.Add(e);
                j = i;
            }
            edgeIndices.Reverse();
            return edgeIndices;
        }
        


        // try to delete
        public static List<int> getShortestPathAsEdgeIndices(Graph graph, int s, int t, int[,] P)
        {
            int[,] I = graph.getIncidenceMatrix();
            int j = t;
            List<int> edgeIndices = new List<int>();
            while (j != s)
            {
                int i = P[s, j];
                if (j == -1) { return null; }
                int e = I[i, j];
                edgeIndices.Add(e);
                j = i;
            }
            edgeIndices.Reverse();
            return edgeIndices;
        }



        // INTERNAL
        internal void setRowForSource(ShortestPathAlgorithm spa, int s, int N)
        {
            double[] d = spa.getDistanceVector();
            int[] p = spa.getPredecessorVector();
            for (int j = 0; j < N; j++)
            {
                this.D[s, j] = d[j];
                this.P[s, j] = p[j];
            }
        }

        // DISPOSE
        public void dispose()
        {
            Array.Clear(this.D, 0, this.D.Length); this.D = null;
            Array.Clear(this.P, 0, this.P.Length); this.P = null;
        }

    }
}
