using System;

namespace Volpe.Cafe.MarketData
{
    /// <summary>
    /// Defines the auxiliary costs associated with the hybrid/electric vehicle.
    /// </summary>
    [Serializable]
    public class AuxiliaryHEVCosts : ICloneable, IAppendable
    {
        /// <summary>
        /// Gets or sets the cost associated with the hybrid/electric technology used on a vehicle.
        /// </summary>
        public double HevCost { get; set; }
        /// <summary>
        /// Gets or sets the vehicle tax credits (in $) claimed by the consumer for purchasing a hybrid/electric
        /// vehicle (SHEV, PHEV, BEV, or FCV).
        /// </summary>
        public double TaxCredit { get; set; }
        /// <summary>
        /// Gets or sets the manufacturer's battery tax credits (in $) passed through to the consumer for purchasing a
        /// hybrid/electric vehicle (SHEV, PHEV, BEV, or FCV).
        /// </summary>
        public double BatteryTaxCredit { get; set; }
        /// <summary>
        /// Gets or sets the additional cost that consumers are willing to pay for a hybrid/electric vehicle.
        /// </summary>
        public double ConsumerWTP { get; set; }

        /// <summary>
        /// Gets the burden cost incurred by a vehicle as a result of applying the hybrid/electric technology.
        /// </summary>
        public double TechBurden => this.HevCost - this.TaxCredit - this.BatteryTaxCredit - this.ConsumerWTP;

        /// <summary>
        /// Returns the string representation of this <see cref="AuxiliaryHEVCosts"/> instance.
        /// </summary>
        /// <returns>The string representation of the <see cref="AuxiliaryHEVCosts"/> instance.</returns>
        public override string ToString()
        {
            return $"{{HevCost={this.HevCost}, TaxCredit={this.TaxCredit}, BatteryTaxCredit={this.BatteryTaxCredit}, " +
                   $"ConsumerWTP={this.ConsumerWTP}, TechBurden={this.TechBurden}}}";
        }

        /// <summary>
        /// Resets all auxiliary costs to zero.
        /// </summary>
        public void Clear()
        {
            this.HevCost = 0;
            this.TaxCredit = 0;
            this.BatteryTaxCredit = 0;
            this.ConsumerWTP = 0;
        }

        /// <summary>
        /// Appends all values from the specified <see cref="AuxiliaryHEVCosts"/> object to this instance.
        /// </summary>
        public void Append(AuxiliaryHEVCosts value)
        {
            this.HevCost += value.HevCost;
            this.TaxCredit += value.TaxCredit;
            this.BatteryTaxCredit += value.BatteryTaxCredit;
            this.ConsumerWTP += value.ConsumerWTP;
        }

        /// <summary>
        /// Creates a new object that is a copy of the current <see cref="AuxiliaryHEVCosts"/> instance.
        /// </summary>
        /// <returns>A new object that is a copy of this <see cref="AuxiliaryHEVCosts"/>.</returns>
        public AuxiliaryHEVCosts Clone()
        {
            return new AuxiliaryHEVCosts
            {
                HevCost = this.HevCost,
                TaxCredit = this.TaxCredit,
                BatteryTaxCredit = this.BatteryTaxCredit,
                ConsumerWTP = this.ConsumerWTP,
            };
        }

        //----- explicit interface implementation -----
        void IAppendable.Append(IAppendable value)
        {
            this.Append((AuxiliaryHEVCosts)value);
        }
        object ICloneable.Clone()
        {
            return this.Clone();
        }

    }
}
