using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using U.ListOperations;
using U.StringOperations;

namespace U.Graph.HelperMethods
{
    class GraphString
    {
        internal static int[] getArrInt(string str, Str.Delimiter delimiter)
        {
            str = Str.left(Str.right(str, str.Length - 1), str.Length - 2);
            return UArray.toArray(Str.toInt(Str.split(str, delimiter)));
        }
        internal static string[] getArrString(string str, Str.Delimiter delimiter)
        {
            str = Str.left(Str.right(str, str.Length - 1), str.Length - 2);
            return UArray.toArray(Str.split(str, delimiter));
        }

        // arg0
        internal static Node[] getNodes(string str)
        {
            List<string> lst = Str.split(str, Str.Delimiter.NewLine);
            lst.RemoveAt(0);
            Node[] arr = new Node[lst.Count];
            for (int i = 0; i < lst.Count; i++) { arr[i] = new Node(Str.split(lst[i], Str.Delimiter.Tab)); }
            return arr;
        }
        // arg1
        internal static Arc[] getArcs(string str)
        {
            List<string> lst = Str.split(str, Str.Delimiter.NewLine);
            lst.RemoveAt(0);
            Arc[] arr = new Arc[lst.Count];
            for (int i = 0; i < lst.Count; i++) { arr[i] = new Arc(Str.split(lst[i], Str.Delimiter.Tab)); }
            return arr;
        }
        // arg2
        internal static Path[] getPaths(string str)
        {
            List<string> lst = Str.split(str, Str.Delimiter.NewLine);
            lst.RemoveAt(0);
            Path[] arr = new Path[lst.Count];
            for (int i = 0; i < lst.Count; i++) { arr[i] = new Path(Str.split(lst[i], Str.Delimiter.Tab)); }
            return arr;
        }


        // Back to String
        internal static string toString(Graph graph)
        {
            List<string> args = toArgs(graph);
            return args[0] + ":" + Environment.NewLine + args[1] + ":" + Environment.NewLine + args[2] + ":" + Environment.NewLine + args[3] + ":";
        }
        internal static List<string> toArgs(Graph graph)
        {
            int N = graph.getNbNodes();
            int A = graph.getNbArcs();
            int P = graph.getNbPaths();
            List<string> args = new List<string>();
            
            string incidence = "incidence" + Environment.NewLine;
            string line = graph.getIncidenceMatrix()[0, 0].ToString();
            for (int j = 1; j < N; j++) { line = line + "," + graph.getIncidenceMatrix()[0, j].ToString(); }
            incidence = incidence + line;
            for (int i = 1; i < N; i++)
            {
                line = graph.getIncidenceMatrix()[i, 0].ToString();
                for (int j = 1; j < N; j++) { line = line + "," + graph.getIncidenceMatrix()[i, j].ToString(); }
                incidence = incidence + ";" + line;
            }
            

            string nodes = "nodes" + Environment.NewLine;
            Node node = graph.getNode(0);
            List<string> lst = new List<string>()
            {
                node.getLabel(),
                Str.inParenthesis(Str.combine(UList.toList(node.getOutArcIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                Str.inParenthesis(Str.combine(UList.toList(node.getInArcIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                //Str.inParenthesis(Str.combine(UList.toList(node.getPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                //Str.inParenthesis(Str.combine(UList.toList(node.getEmanatingPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                //Str.inParenthesis(Str.combine(UList.toList(node.getIncomingPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square)
            };
            nodes = nodes + Str.combine(lst, Str.Delimiter.Tab);
            for (int i = 1; i < N; i++)
            {
                node = graph.getNode(i);
                lst = new List<string>()
                {
                    node.getLabel(),
                    Str.inParenthesis(Str.combine(UList.toList(node.getOutArcIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    Str.inParenthesis(Str.combine(UList.toList(node.getInArcIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    //Str.inParenthesis(Str.combine(UList.toList(node.getPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    //Str.inParenthesis(Str.combine(UList.toList(node.getEmanatingPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    //Str.inParenthesis(Str.combine(UList.toList(node.getIncomingPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square)
                };
                nodes = nodes + Environment.NewLine + Str.combine(lst, Str.Delimiter.Tab);
            }


            string arcs = "arcs" + Environment.NewLine;
            Arc arc = graph.getArc(0);
            lst = new List<string>()
            {
                arc.getFromLabel(),
                arc.getToLabel(),
                arc.getFromIndex().ToString(),
                arc.getToIndex().ToString(),
                //Str.inParenthesis(Str.combine(UList.toList(arc.getPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                arc.getFlow().ToString(),
                arc.getCost().ToString()
            };
            arcs = arcs + Str.combine(lst, Str.Delimiter.Tab);
            for (int i = 1; i < A; i++)
            {
                arc = graph.getArc(i);
                lst = new List<string>()
                {
                    arc.getFromLabel(),
                    arc.getToLabel(),
                    arc.getFromIndex().ToString(),
                    arc.getToIndex().ToString(),
                    //Str.inParenthesis(Str.combine(UList.toList(arc.getPathIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    arc.getFlow().ToString(),
                    arc.getCost().ToString()
                };
                arcs = arcs + Environment.NewLine + Str.combine(lst, Str.Delimiter.Tab);
            }



            string paths = "paths" + Environment.NewLine;
            Path path = graph.getPath(0);
            lst = new List<string>()
            {
                //Str.inParenthesis(Str.combine(UList.toList(path.getNodeLabels()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                //Str.inParenthesis(Str.combine(UList.toList(path.getNodeIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                Str.inParenthesis(Str.combine(UList.toList(path.getArcIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                path.getFlow().ToString(),
                path.getCost().ToString()
            };
            paths = paths + Str.combine(lst, Str.Delimiter.Tab);
            for (int i = 1; i < P; i++)
            {
                path = graph.getPath(i);
                lst = new List<string>()
                {
                    //Str.inParenthesis(Str.combine(UList.toList(path.getNodeLabels()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    //Str.inParenthesis(Str.combine(UList.toList(path.getNodeIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    Str.inParenthesis(Str.combine(UList.toList(path.getArcIndices()), Str.Delimiter.Semicolon), Str.ParenthesisTypes.Square),
                    path.getFlow().ToString(),
                    path.getCost().ToString()
                };
                paths = paths + Environment.NewLine + Str.combine(lst, Str.Delimiter.Tab);
            }
            return new List<string>() { incidence, nodes, arcs, paths };
        }

    }
}
