using System;
using Volpe.Cafe.Generic;
using RC = Volpe.Cafe.RegulatoryClass;

namespace Volpe.Cafe.EffectsModels.Data
{
    /// <summary>
    /// Provides a subset of modeling effects data for a single model year, primarily used for displaying progress
    /// information in the user interface.
    /// </summary>
    [Serializable]
    public class EffectsDataLite
    {
        /// <summary>
        /// Provides a subset of modeling effects data for a single model year, based on either a vehicle's "initial"
        /// or its "final" state.
        /// </summary>
        [Serializable]
        public class DataItem
        {
            /// <summary>Gets the vehicle on-road fleet (the survival weighted vehicle sales).</summary>
            public RCAltFuelValue Fleet { get; } = new RCAltFuelValue();
            /// <summary>Gets the total vehicle miles traveled.</summary>
            public RCAltFuelValue VMT { get; } = new RCAltFuelValue();
            /// <summary>Gets the fuel consumption in liquid gallons or gasoline equivalent gallons (GEG).</summary>
            public RCAltFuelValue Gallons { get; } = new RCAltFuelValue();

            /// <summary>
            /// Gets the total emissions of various pollutants, resulting from all stages of fuel production and 
            /// distribution, and from vehicle operation.
            /// </summary>
            public MonetizedPollutantValue<RCAltFuelValue> Emissions { get; }
                = new MonetizedPollutantValue<RCAltFuelValue>(() => new RCAltFuelValue());

            /// <summary>Gets the retail fuel expenditures.</summary>
            public RCAltFuelValue RetailFuelCosts { get; } = new RCAltFuelValue();

            /// <summary>
            /// Gets the owner and societal costs arising from damage caused by emissions from various pollutants.
            /// </summary>
            public MonetizedPollutantValue<RCAltFuelValue> EmissionCosts { get; }
                = new MonetizedPollutantValue<RCAltFuelValue>(() => new RCAltFuelValue());

            /// <summary>
            /// Calculates and returns the total costs arising from damage caused by various emissions, for the
            /// specified regulatory class and fuel type.
            /// </summary>
            /// <param name="regClass">
            ///     The regulatory class for which to obtain the total emissions damage costs.
            /// </param>
            /// <param name="fuelType">
            ///     The fuel type for which to obtain the total emissions damage costs.
            /// </param>
            /// <returns>The total emissions damage costs for the specified regulatory class and fuel type.</returns>
            public double GetTotalEmissionDamage(RC regClass, FuelType fuelType)
            {
                return
                    this.EmissionCosts.CO [regClass, fuelType] +
                    this.EmissionCosts.VOC[regClass, fuelType] +
                    this.EmissionCosts.NOx[regClass, fuelType] +
                    this.EmissionCosts.SO2[regClass, fuelType] +
                    this.EmissionCosts.PM [regClass, fuelType] +
                    this.EmissionCosts.CO2[regClass, fuelType] +
                    this.EmissionCosts.CH4[regClass, fuelType] +
                    this.EmissionCosts.N2O[regClass, fuelType];
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="EffectsDataLite"/> class.
        /// </summary>
        /// <param name="modelYear">The model year for which the effects data are calculated.</param>
        public EffectsDataLite(int modelYear)
        {
            this.ModelYear = modelYear;
        }

        /// <summary>
        /// Gets the model year for which the effects data are calculated.
        /// </summary>
        public int ModelYear { get; }

        /// <summary>
        /// Gets a subset of modeling effects data, based on the "initial" state of the vehicle, before any new vehicle
        /// technology application.
        /// </summary>
        public DataItem InitialState { get; } = new DataItem();

        /// <summary>
        /// Gets a subset of modeling effects data, based on the "final" state of the vehicle at the end of the model
        /// year, after application of any applicable vehicle technology.
        /// </summary>
        public DataItem FinalState { get; } = new DataItem();

    }
}
