using System;

namespace Volpe.Cafe.MarketData
{
    /// <summary>
    /// Defines vehicle-level compliance statistics.
    /// </summary>
    [Serializable]
    public class VehicleStatistics : ICloneable
    {
        //----- CAFE aggregation values -----
        /// <summary>
        /// Gets or sets the accumulated sales volumes for one or more vehicle models.
        /// </summary>
        public double Sales { get; set; }
        /// <summary>
        /// Gets or sets the accumulated sales volumes for one or more BEV models.
        /// </summary>
        public double BevSales { get; set; }

        /// <summary>
        /// Gets or sets the accumulated sales-weighted fuel economy targets for one or more vehicle models.
        /// </summary>
        public double FETarget { get; set; } // sumof_veh(sales * feTarget)
        /// <summary>
        /// Gets or sets the accumulated sales-weighted fuel economy 2-cycle ratings for one or more vehicle models.
        /// </summary>
        public double FE2Cycle { get; set; } // sumof_veh(sales / fe2Cycle)
        /// <summary>
        /// Gets or sets the accumulated sales-weighted fuel economy ratings for one or more vehicle models.
        /// </summary>
        public double FERating { get; set; } // sumof_veh(sales / feRating)

        //----- CO-2 aggregation values -----
        /// <summary>
        /// Gets or sets the accumulated sales volumes for one or more vehicle models, scaled by the EPA production
        /// multiplier, where applicable.
        /// </summary>
        public double CO2Sales { get; set; } // sumof_veh(sales * epaMultiplier)
        /// <summary>
        /// Gets or sets the accumulated sales volumes for one or more BEV models, scaled by the EPA production
        /// multiplier, where applicable.
        /// </summary>
        public double CO2BevSales { get; set; } // sumof_veh(bevSales * epaMultiplier)

        /// <summary>
        /// Gets or sets the accumulated sales-weighted CO-2 targets for one or more vehicle models.
        /// </summary>
        public double CO2Target { get; set; } // sumof_veh(co2Sales * co2Target)
        /// <summary>
        /// Gets or sets the accumulated sales-weighted CO-2 ratings for one or more vehicle models.
        /// </summary>
        public double CO2Rating { get; set; } // sumof_veh(co2Sales * co2Rating)

        /// <summary>
        /// Resets all vehicle statistics to zero.
        /// </summary>
        public void Clear()
        {
            // CAFE aggregation values
            this.Sales = 0;
            this.BevSales = 0;
            this.FETarget = 0;
            this.FE2Cycle = 0;
            this.FERating = 0;

            // CO-2 aggregation values
            this.CO2Sales = 0;
            this.CO2BevSales = 0;
            this.CO2Target = 0;
            this.CO2Rating = 0;
        }

        /// <summary>
        /// Appends all values from the specified <see cref="VehicleStatistics"/> object to this instance.
        /// </summary>
        /// <param name="value">
        ///     The <see cref="VehicleStatistics"/> object whose values to append to this instance.
        /// </param>
        public void Append(VehicleStatistics value)
        {
            // CAFE aggregation values
            this.Sales += value.Sales;
            this.BevSales += value.BevSales;
            this.FETarget += value.FETarget;
            this.FE2Cycle += value.FE2Cycle;
            this.FERating += value.FERating;

            // CO-2 aggregation values
            this.CO2Sales += value.CO2Sales;
            this.CO2BevSales += value.CO2BevSales;
            this.CO2Target += value.CO2Target;
            this.CO2Rating += value.CO2Rating;
        }

        /// <summary>
        /// Copies the elements of this <see cref="VehicleStatistics"/> instance to the specified value. 
        /// </summary>
        /// <param name="value">The value that is the destination of the copy operation.</param>
        public void CopyTo(VehicleStatistics value)
        {
            // CAFE aggregation values
            value.Sales = this.Sales;
            value.BevSales = this.BevSales;
            value.FETarget = this.FETarget;
            value.FE2Cycle = this.FE2Cycle;
            value.FERating = this.FERating;

            // CO-2 aggregation values
            value.CO2Sales = this.CO2Sales;
            value.CO2BevSales = this.CO2BevSales;
            value.CO2Target = this.CO2Target;
            value.CO2Rating = this.CO2Rating;
        }

        /// <summary>
        /// Creates a new object that is a copy of the current <see cref="VehicleStatistics"/> instance.
        /// </summary>
        /// <returns>A new object that is a copy of this <see cref="VehicleStatistics"/>.</returns>
        public VehicleStatistics Clone()
        {
            var value = new VehicleStatistics();
            this.CopyTo(value);
            return value;
        }

        //----- explicit interface implementation -----
        object ICloneable.Clone()
        {
            return this.Clone();
        }

    }
}
