using System;

namespace Volpe.Cafe.EffectsData
{
    /// <summary>
    /// Provides modeling effects for energy consumption from vehicle operation.
    /// </summary>
    [Serializable]
    public sealed class EnergyEffects : IAppendable
    {
        /// <summary>
        /// Gets or sets the vehicle on-road fleet (the survival weighted vehicle sales).
        /// </summary>
        public double Fleet { get; set; }

        /// <summary>
        /// Gets or sets the total vehicle miles traveled.
        /// </summary>
        public double VMT { get; set; }
        /// <summary>
        /// Gets or sets the vehicle miles traveled, assuming the fuel economy rebound effect is not present.
        /// </summary>
        public double VMTNoRebound { get; set; }

        /// <summary>
        /// Gets or sets the energy use in British thermal units (BTU).
        /// </summary>
        public double BTU { get; set; }
        /// <summary>
        /// Gets or sets the fuel consumption in liquid gallons or gasoline equivalent gallons (GEG).
        /// </summary>
        public double Gallons { get; set; }
        /// <summary>
        /// Gets or sets the fuel consumption in liquid gallons or gasoline equivalent gallons (GEG), using the rated
        /// vehicle fuel economy instead of the on-road fuel economy.
        /// </summary>
        public double RatedGallons { get; set; }
        /// <summary>
        /// Gets or sets the energy use in units native for a specific fuel type.
        /// </summary>
        public double NativeUnits { get; set; }

        /// <summary>
        /// Gets the average on-road fuel economy, using the on-road <see cref="Gallons"/> value.
        /// </summary>
        public double OnRoadFuelEconomy => (this.Gallons == 0) ? 0 : this.VMT / this.Gallons;
        /// <summary>
        /// Gets the average rated fuel economy, using the <see cref="RatedGallons"/> value.
        /// </summary>
        public double RatedFuelEconomy => (this.RatedGallons == 0) ? 0 : this.VMT / this.RatedGallons;

        /// <summary>
        /// Resets all energy effects values to zero.
        /// </summary>
        public void Clear()
        {
            this.Fleet = 0;
            this.VMT = 0;
            this.VMTNoRebound = 0;
            this.BTU = 0;
            this.Gallons = 0;
            this.RatedGallons = 0;
            this.NativeUnits = 0;
        }

        /// <summary>
        /// Appends all values from the specified <see cref="EnergyEffects"/> object to this instance.
        /// </summary>
        public void Append(EnergyEffects value)
        {
            this.Fleet += value.Fleet;
            this.VMT += value.VMT;
            this.VMTNoRebound += value.VMTNoRebound;
            this.BTU += value.BTU;
            this.Gallons += value.Gallons;
            this.RatedGallons += value.RatedGallons;
            this.NativeUnits += value.NativeUnits;
        }

        //----- explicit interface implementation -----
        void IAppendable.Append(IAppendable value)
        {
            this.Append((EnergyEffects)value);
        }

    }
}
