#region << Using Directives >>
using System;
#endregion
namespace Volpe.Cafe.Generic
{
    [Serializable]
    public class RCValue<T> : ICloneable
    {
        #region 
        public RCValue()
        {
            this.Items = new T[Classes.Length];
        }
        public RCValue(T passengerCar, T lightTruck, T lightTruck2b3)
        {
            this.Items = new T[] { passengerCar, lightTruck, lightTruck2b3 };
        }
        #endregion
        #region 
        #region 
        public static bool operator ==(RCValue<T> value1, RCValue<T> value2)
        {
            return Equals(value1, value2);
        }
        public static bool operator !=(RCValue<T> value1, RCValue<T> value2)
        {
            return !Equals(value1, value2);
        }
        #endregion
        #region 
        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public RCValue<T> Clone()
        {
            RCValue<T> value = new RCValue<T>();
            this.CopyTo(value);
            return value;
        }
        protected void CopyTo(RCValue<T> value)
        {
            for (int i = 0; i < this.Items.Length; i++)
            {
                value.Items[i] = this.Items[i];
            }
        }
        #endregion
        #region 
        public override string ToString()
        {
            string s = string.Empty;
            for (int i = 0; i < this.Items.Length; i++)
            {
                if (i > 0) { s += ", "; }
                s += (Names[i] + "=" + this.Items[i].ToString());
            }
            return "{" + s + "}";
        }
        public override int GetHashCode()
        {
            int hash = 0;
            for (int i = 0; i < this.Items.Length; i++)
            {
                hash = hash ^ this.Items[i].GetHashCode();
            }
            return hash;
        }
        public override bool Equals(object obj)
        {
            return (obj is RCValue<T>) ? this.Equals((RCValue<T>)obj) : base.Equals(obj);
        }
        public bool Equals(RCValue<T> value)
        {
            return Equals(this, value);
        }
        public static bool Equals(RCValue<T> value1, RCValue<T> value2)
        {
            if (object.ReferenceEquals(value1, null) && object.ReferenceEquals(value2, null)) { return true ; }
            if (object.ReferenceEquals(value1, null) || object.ReferenceEquals(value2, null)) { return false; }
            for (int i = 0; i < value1.Items.Length; i++)
            {
                if (!value1.Items[i].Equals(value2.Items[i])) { return false; }
            }
            return true;
        }
        #endregion
        public void Clear()
        {
            for (int i = 0; i < this.Items.Length; i++)
            {
                this.Items[i] = default(T);
            }
        }
        protected int GetIndex(RegulatoryClass regClass)
        {
            return (int)regClass - 1;
        }
        #endregion
        #region 
        public T this[RegulatoryClass regClass]
        {
            get { return this.Items[this.GetIndex(regClass)]; }
            set { this.Items[this.GetIndex(regClass)] = value; }
        }
        public T[] Items { get; private set; }
        #endregion
        #region 
        public static readonly RegulatoryClass[] Classes = new RegulatoryClass[] { RegulatoryClass.PassengerCar,
                                                                                   RegulatoryClass.LightTruck,
                                                                                   RegulatoryClass.LightTruck2b3 };
        public static readonly string[] Names = new string[] { "Passenger Car",
                                                               "Light Truck",
                                                               "Light Truck 2b/3" };
        #endregion
    }
}

