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

namespace U.Graph
{
    public class Arc
    {
        private string fromLabel;
        private string toLabel;
        private int fromIndex;
        private int toIndex;
        //private int[] pathIndices;
        private double flow;
        private double cost;


        // CONSTRUCTORS
        private Arc() { }
        public Arc(string fromLabel, string toLabel)
        {
            this.fromLabel = fromLabel;
            this.toLabel = toLabel;
        }
        public Arc(List<string> args)
        {
            this.fromLabel = args[0];
            this.toLabel = args[1];
            this.fromIndex = Convert.ToInt32(args[2]);
            this.toIndex = Convert.ToInt32(args[3]);
            //this.pathIndices = GraphString.getArrInt(args[4], Str.Delimiter.Semicolon);
            this.flow = Convert.ToDouble(args[4]);
            this.cost = Convert.ToDouble(args[5]);
        }
        // to delete
        public Arc(string strArc)
        {
            StrFunc sf = new StrFunc(strArc);
            List<string> lst = Str.split(sf.getFuncName(), Str.Delimiter.Dash);
            if (lst.Count != 2) { throw new InvalidArcException(strArc); }
            if (sf.getArgs().Count < 2) { throw new InvalidArcException(strArc); }
            this.fromLabel = lst[0];
            this.toLabel = lst[1];
            this.flow = sf.getArgDouble(0);
            this.cost = sf.getArgDouble(1);
        }



        // SETTERS
        internal void setFromIndex(int fromIndex) { this.fromIndex = fromIndex; }
        internal void setToIndex(int toIndex) { this.toIndex = toIndex; }
        //public void setPathIndices(int[] pathIndices) { this.pathIndices = pathIndices; }
        public void setFlow(double flow) { this.flow = flow; }
        public void setCost(double cost) { this.cost = cost; }

        // GETTERS
        public string getFromLabel() { return this.fromLabel; }
        public string getToLabel() { return this.toLabel; }
        public int getFromIndex() { return this.fromIndex; }
        public int getToIndex() { return this.toIndex; }
        //public int[] getPathIndices() { return this.pathIndices; }
        public double getFlow() { return this.flow; }
        public double getCost() { return this.cost; }

        //COMMON
        public string getLabel() { return Str.combine(fromLabel, toLabel, Str.Delimiter.Dash); }
        public override string ToString()
        {
            List<double> args = new List<double>() { this.flow, this.cost };
            return StrFunc.getFuncString(getLabel(), args);
        }
        public bool Equals(Arc arc) { return this.fromLabel == arc.getFromLabel() && this.toLabel == arc.getToLabel(); }
        public Arc clone() { return null; }//TODO


        // EXCEPTIONS
        public class InvalidArcException : Exception { public InvalidArcException(string message) : base("Invalid arc: " + message + ".") { } }

    }
}
