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

namespace U.SUE
{
    public class LinkCost
    {
        private double freeFlowTravelTime;
        private double B;
        private double capacity;
        private double power;
        private double toll;
        private double tollFactor;
        private double length;
        private double distanceFactor;
        private double exponentialCoefficient;

        public LinkCost(double freeFlowTravelTime, double B, double capacity, double power, double toll, double tollFactor, double length, double distanceFactor, double exponentialCoefficient)
        {
            this.freeFlowTravelTime = freeFlowTravelTime;
            this.B = B;
            this.capacity = capacity;
            this.power = power;
            this.toll = toll;
            this.tollFactor = tollFactor;
            this.length = length;
            this.distanceFactor = distanceFactor;
            this.exponentialCoefficient = exponentialCoefficient;
        }


        // CALCULATORS
        public double getBPRCost(double flow) { return freeFlowTravelTime * (1 + B * Math.Pow(flow / capacity, power)) + toll * tollFactor + length * distanceFactor; }
        public double getBPRCostExponential(double flow) { return Math.Exp(exponentialCoefficient * getBPRCost(flow)); }

        public static double calcBprCost(double freeFlowTravelTime, double B, double capacity, double power, double toll, double tollFactor,
            double length, double distanceFactor, double flow)
        {
            return freeFlowTravelTime * (1 + B * Math.Pow(flow / capacity, power)) + toll * tollFactor + length * distanceFactor;
        }
        public static double calcBprCostExponential(double freeFlowTravelTime, double B, double capacity, double power, double toll, double tollFactor,
            double length, double distanceFactor, double exponentialCoefficient, double flow)
        {
            return Math.Exp(exponentialCoefficient * calcBprCost(freeFlowTravelTime, B, capacity, power, toll, tollFactor, length, distanceFactor, flow));
        }

        // SETTERS
        public void setFreeFlowTravelTime(double freeFlowTravelTime) { this.freeFlowTravelTime = freeFlowTravelTime; }

        // GETTERS
        public double getFreeFlowTravelTime() { return this.freeFlowTravelTime; }
        public double getB() { return this.B; }
        public double getCapacity() { return this.capacity; }
        public double getPower() { return this.power; }
        public double getToll() { return this.toll; }
        public double getTollFactor() { return this.tollFactor; }
        public double getLength() { return this.length; }
        public double getDistanceFactor() { return this.distanceFactor; }
        public double getExponentialCoefficient() { return this.exponentialCoefficient; }


        // COMMON
        public override string ToString()
        {
            List<double> args = new List<double>() { freeFlowTravelTime, B, capacity, power, toll, tollFactor, length, distanceFactor, exponentialCoefficient };
            return StrFunc.getFuncString(String.Empty, args);
        }

    }
}
