using System;
using Volpe.Cafe.Generic;

namespace Volpe.Cafe.DfsSrModels
{
    /// <summary>
    /// Represents a forecast fleet used to store aggregated sales projections from individual forecast vehicles for
    /// each fleet.
    /// </summary>
    [Serializable]
    public class ForecastFleet
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ForecastFleet"/> class, using the forecast data for the
        /// specified fleets.
        /// </summary>
        public ForecastFleet(ForecastFleetData carData, ForecastFleetData truckData, ForecastFleetData hdpuvData)
        {
            this.SetForecastData(carData, truckData, hdpuvData);
        }

        /// <summary>
        /// Gets the forecast fleet data associated with the light-duty car fleet for the specified year.
        /// </summary>
        public ForecastFleetData CarForecastData { get; private set; }
        /// <summary>
        /// Gets the forecast fleet data associated with the light-duty truck fleet for the specified year.
        /// </summary>
        public ForecastFleetData TruckForecastData { get; private set; }
        /// <summary>
        /// Gets the forecast fleet data associated with the combined (car + truck) light-duty fleet for the specified
        /// year.
        /// </summary>
        public ForecastFleetData LightDutyForecastData { get; private set; }
        /// <summary>
        /// Gets the forecast fleet data associated with the HDPUV fleet for the specified year.
        /// </summary>
        public ForecastFleetData HdpuvForecastData { get; private set; }

        /// <summary>
        /// Returns a new <see cref="ForecastFleet"/> instance using the forecast data obtained from the specified
        /// <paramref name="value"/>.
        /// </summary>
        public static ForecastFleet FromVCValue(VCValue<ForecastFleetData> value)
        {
            return new ForecastFleet(value.Ldv, value.Ldt12a, value.Ldt2b3);
        }

        /// <inheritdoc cref="FromVCValue"/>
        public static ForecastFleet FromRCAltValue(RCAltValue<ForecastFleetData> value)
        {
            return new ForecastFleet(value.PassengerCar, value.LightTruck, value.HDPUV);
        }

        /// <inheritdoc cref="FromVCValue"/>
        public static ForecastFleet FromRCValue(RCValue<ForecastFleetData> value)
        {
            var passengerCar = ForecastFleetData.Combine(value.DomesticCar, value.ImportedCar);
            return new ForecastFleet(passengerCar, value.LightTruck, value.HDPUV);
        }

        /// <summary>
        /// Sets the forecast data for the specified fleets.
        /// </summary>
        public virtual void SetForecastData(
            ForecastFleetData carData, ForecastFleetData truckData, ForecastFleetData hdpuvData)
        {
            this.CarForecastData = carData;
            this.TruckForecastData = truckData;
            this.LightDutyForecastData = ForecastFleetData.Combine(carData, truckData);
            this.HdpuvForecastData = hdpuvData;
        }

        /// <summary>
        /// Returns a new <see cref="VCValue{T}"/> object that encapsulates the forecast data from this instance.
        /// </summary>
        /// <remarks>
        /// Note that the <see cref="LightDutyForecastData"/> value is lost during the conversion and will need to be
        /// recomputed by the caller if required.
        /// </remarks>
        public virtual VCValue<ForecastFleetData> ToVCValue()
        {
            var value = new VCValue<ForecastFleetData>(
                this.CarForecastData, this.TruckForecastData, this.HdpuvForecastData);
            return value;
        }

        /// <summary>
        /// Returns a new <see cref="RCAltValue{T}"/> object that encapsulates the forecast data from this instance.
        /// </summary>
        /// <inheritdoc cref="ToVCValue" path="/remarks"/>
        public virtual RCAltValue<ForecastFleetData> ToRCAltValue()
        {
            var value = new RCAltValue<ForecastFleetData>(
                this.CarForecastData, this.TruckForecastData, this.HdpuvForecastData);
            return value;
        }

    }
}
