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

namespace SeSue.Classes
{
    class SueWriter
    {
        public static List<string> getLines(Sue sue)
        {
            List<string> lines = new List<string>();
            string line = String.Empty;

            Graph graph = sue.graph;
            MSA msa = sue.msa;
            int N = graph.getNbNodes();
            int A = graph.getNbArcs();
            int P = graph.getNbPaths();
            int O = graph.getNbOdPairs();
            int[,] I = graph.getIncidenceMatrix();

            /*
            lines.Add("incidence");
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (I[i, j] > -1)
                    {
                        lines.Add(i.ToString() + "," + j.ToString() + "," + I[i, j].ToString());
                    }
                }
            }//*/
            /*
            string line = graph.getIncidenceMatrix()[0, 0].ToString();
            for (int j = 1; j < N; j++) { line = line + "," + graph.getIncidenceMatrix()[0, j].ToString(); }
            string 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;
            }
            lines.Add(incidence);//*/
            //lines.Add(":");

            lines.Add("nodes");
            foreach (Node node in graph.getNodes())
            {
                line = node.getLabel() + '\t';

                line = line + node.getStrOutArcIndices() + '\t' + node.getStrInArcIndices();
                /*
                line = line + "[";
                if (node.getOutArcIndices().Length > 0)
                {
                    line = line + node.getOutArcIndices()[0].ToString();
                    for (int i = 1; i < node.getOutArcIndices().Length; i++) { line = line + ";" + node.getOutArcIndices()[i].ToString(); }
                }
                line = line + "]" + '\t';

                line = line + "[";
                if (node.getInArcIndices().Length > 0)
                {
                    line = line + node.getInArcIndices()[0].ToString();
                    for (int i = 1; i < node.getInArcIndices().Length; i++) { line = line + ";" + node.getInArcIndices()[i].ToString(); }
                }
                line = line + "]";// +'\t';*/

                /*
                line = line + "[";
                if (node.getPathIndices().Length > 0)
                {
                    line = line + node.getPathIndices()[0].ToString();
                    for (int i = 1; i < node.getPathIndices().Length; i++) { line = line + ";" + node.getPathIndices()[i].ToString(); }
                }
                line = line + "]" + '\t';

                line = line + "[";
                if (node.getEmanatingPathIndices().Length > 0)
                {
                    line = line + node.getEmanatingPathIndices()[0].ToString();
                    for (int i = 1; i < node.getEmanatingPathIndices().Length; i++) { line = line + ";" + node.getEmanatingPathIndices()[i].ToString(); }
                }
                line = line + "]" + '\t';

                line = line + "[";
                if (node.getIncomingPathIndices().Length > 0)
                {
                    line = line + node.getIncomingPathIndices()[0].ToString();
                    for (int i = 1; i < node.getIncomingPathIndices().Length; i++) { line = line + ";" + node.getIncomingPathIndices()[i].ToString(); }
                }
                line = line + "]";//*/
                lines.Add(line);
            }
            lines.Add(":");

            lines.Add("arcs");
            foreach (Link arc in graph.getLinks())
            {
                line = arc.getFromLabel() + '\t' +
                    arc.getToLabel() + '\t' +
                    arc.getFromIndex().ToString() + '\t' +
                    arc.getToIndex().ToString() + '\t';
                /*
                line = line + "[";
                if (arc.getPathIndices().Length > 0)
                {
                    line = line + arc.getPathIndices()[0].ToString();
                    for (int i = 1; i < arc.getPathIndices().Length; i++) { line = line + ";" + arc.getPathIndices()[i].ToString(); }
                }//*/
                line = line +// "]" + '\t' +
                    arc.getFlow().ToString() + '\t' +
                    arc.getCost().ToString() + '\t' +
                    arc.getLinkCost().getFreeFlowTravelTime().ToString() + '\t' +
                    arc.getLinkCost().getB().ToString() + '\t' +
                    arc.getLinkCost().getCapacity().ToString() + '\t' +
                    arc.getLinkCost().getPower().ToString() + '\t' +
                    arc.getLinkCost().getToll().ToString() + '\t' +
                    arc.getLinkCost().getTollFactor().ToString() + '\t' +
                    arc.getLinkCost().getLength().ToString() + '\t' +
                    arc.getLinkCost().getDistanceFactor().ToString() + '\t' +
                    arc.getLinkCost().getExponentialCoefficient().ToString() + '\t' +
                    arc.getCostAdd().ToString() + '\t' +
                    arc.getCostMul().ToString();
                lines.Add(line);
            }
            lines.Add(":");

            lines.Add("paths");
            foreach (Path path in graph.getPaths())
            {
                //line = path.getLabel() + '\t';

                /*line = "[";
                line = line + path.getNodeLabels()[0];
                for (int i = 1; i < path.getNodeLabels().Length; i++) { line = line + ";" + path.getNodeLabels()[i]; }
                line = line + "]" + '\t';//*/

                /*line = line + "[";
                line = line + path.getNodeIndices()[0].ToString();
                for (int i = 1; i < path.getNodeIndices().Length; i++) { line = line + ";" + path.getNodeIndices()[i].ToString(); }
                line = line + "]" + '\t';//*/

                line = "[";
                line = line + path.getArcIndices()[0].ToString();
                for (int i = 1; i < path.getArcIndices().Length; i++) { line = line + ";" + path.getArcIndices()[i].ToString(); }
                line = line + "]" + '\t';

                line = line + path.getFlow().ToString() + '\t' +
                    path.getCost().ToString() + '\t' +
                    path.getOdPairIndex().ToString() + '\t' +
                    path.getProb().ToString();
                lines.Add(line);
            }
            lines.Add(":");

            lines.Add("odpairs");
            foreach (OdPair od in graph.getOdPairs())
            {
                line = //od.getLabel() + '\t' +
                    od.getOriLabel() + '\t' +
                    od.getDesLabel() + '\t' +
                    od.getOriIndex().ToString() + '\t' +
                    od.getDesIndex().ToString() + '\t' +
                    od.getDemand().ToString() + '\t';
                if (od.getChoiceModel() == null) { line = line + "null" + '\t'; }
                else { line = line + od.getChoiceModel().ToString() + '\t'; }

                line = line + "[";
                if (od.getPathIndices().Length > 0)
                {
                    line = line + od.getPathIndices()[0].ToString();
                    for (int i = 1; i < od.getPathIndices().Length; i++) { line = line + ";" + od.getPathIndices()[i].ToString(); }
                }
                line = line + "]";
                lines.Add(line);
            }
            lines.Add(":");

            lines.Add("MSA");
            line = msa.getStepSize().ToString() + '\t' +
                msa.getMaxNbIterations().ToString() + '\t' +
                msa.getRmseThreshold().ToString() + '\t' +
                msa.getNbIterations().ToString() + '\t' +
                msa.getSolutionMiliseconds().ToString();
            lines.Add(line);

            if (msa.getLinkFlows().Count > 0)
            {
                line = Str.combine(msa.getLinkFlows()[0], Str.Delimiter.Comma);
                for (int i = 1; i < msa.getLinkFlows().Count; i++) { line = line + ";" + Str.combine(msa.getLinkFlows()[i], Str.Delimiter.Comma); }
                lines.Add(line);
                lines.Add(Str.combine(msa.getRmse(), Str.Delimiter.Semicolon));
            }
            lines.Add(":");


            return lines;
        }

    }
}
