using System;
using System.Collections.Generic;
using Volpe.Cafe.Initializers;

namespace Volpe.Cafe.ModelSettings
{
    /// <summary>
    /// Provides costs relating to a single vehicle technology.
    /// </summary>
    [Serializable]
    public sealed class TechnologyCosts
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TechnologyCosts"/> class.
        /// </summary>
        public TechnologyCosts(Dictionary<string, object> values)
        {
            DataObjectInitializer.SetPropertyValues(this, values);
        }


        /// <summary>Gets the lowest model year for which technology cost data is available.</summary>
        public int MinMY { get; private set; }
        /// <summary>Gets the highest model year for which technology cost data is available.</summary>
        public int MaxMY { get; private set; }

        /// <summary>Gets a table of learned out cost estimates for the current technology.</summary>
        private double[] CostTable { get; set; }
        /// <summary>
        /// Gets a table of learned out maintenance and repair cost estimates for the current technology.
        /// </summary>
        private double[] MaintRepairCostTable { get; set; }
        /// <summary>
        /// Gets a table of learning rates associated with battery cost estimates for the current technology.
        /// </summary>
        private double[] BatteryLearningRateTable { get; set; }


        /// <summary>
        /// Returns the learned out cost estimates for a technology during the specified model year.
        /// </summary>
        /// <remarks>
        /// If the provided year is out of bounds of the range of model years for which technology cost data is
        /// available, the cost data at either <see cref="MinMY"/> or <see cref="MaxMY"/> will be returned.
        /// </remarks>
        public double GetCost(int year)
        {
            return this.CostTable[this.GetYearIndex(year)];
        }

        /// <summary>
        /// Returns the learned out maintenance and repair cost estimates for a technology during the specified model
        /// year.
        /// </summary>
        /// <remarks>
        /// If the provided year is out of bounds of the range of model years for which technology cost data is
        /// available, the cost data at either <see cref="MinMY"/> or <see cref="MaxMY"/> will be returned.
        /// </remarks>
        public double GetMaintRepairCost(int year)
        {
            return this.MaintRepairCostTable[this.GetYearIndex(year)];
        }

        /// <summary>
        /// Returns the learning rates associated with battery cost estimates for a technology during the specified
        /// model year.
        /// </summary>
        /// <remarks>
        /// If the provided year is out of bounds of the range of model years for which technology cost data is
        /// available, the cost data at either <see cref="MinMY"/> or <see cref="MaxMY"/> will be returned.
        /// </remarks>
        public double GetBatteryLearningRate(int year)
        {
            return this.BatteryLearningRateTable[this.GetYearIndex(year)];
        }

        private int GetYearIndex(int year)
        {
            return Math.Max(Math.Min(year, this.MaxMY) - this.MinMY, 0);
        }

    }
}
