using System;
using Volpe.Cafe.MarketData.Design;

namespace Volpe.Cafe.TechAnalysis
{
    /// <summary>
    /// Represents a single vehicle model affected by application of a candidate technology, and the initial year when
    /// the candidate technology may be applied on that vehicle.
    /// </summary>
    [Serializable]
    public struct AffectedVehicle
    {
        /// <summary>
        /// Initializes a new <see cref="AffectedVehicle"/> instance, using the specified <see cref="Vehicle"/> and
        /// application year.
        /// </summary>
        /// <param name="vehicle">A vehicle model affected by application of a pending technology.</param>
        /// <param name="applicationYear">
        ///     The year of initial application of a pending technology on an affected vehicle.
        /// </param>
        public AffectedVehicle(IVehicle vehicle, int applicationYear)
        {
            this.Vehicle = vehicle;
            this.ApplicationYear = applicationYear;
        }

        /// <summary>
        /// Represents an empty <see cref="AffectedVehicle"/> instance. This value is read-only.
        /// </summary>
        public static readonly AffectedVehicle Empty = new AffectedVehicle(null, 0);

        /// <summary>
        /// Gets a vehicle model affected by application of a pending technology.
        /// </summary>
        public IVehicle Vehicle { get; private set; }
        /// <summary>
        /// Gets the year of initial application of a pending technology on an affected vehicle model.
        /// </summary>
        public int ApplicationYear { get; private set; }

        //----- support for tuple-conversion -----
        /// <summary>
        /// Performs an implicit conversion from a tuple of MinYear, MaxYear integers to an associated
        /// <see cref="AffectedVehicle"/> object.
        /// </summary>
        public static implicit operator AffectedVehicle((IVehicle Vehicle, int ApplicationYear) value)
        {
            return new AffectedVehicle(value.Vehicle, value.ApplicationYear);
        }

        /// <summary>
        /// De-constructs the current value into a tuple of its components.
        /// </summary>
        public void Deconstruct(out IVehicle vehicle, out int applicationYear)
        {
            vehicle = this.Vehicle;
            applicationYear = this.ApplicationYear;
        }

    }
}
