using System;
using Volpe.Cafe.Utils;
using Volpe.Cafe.Data;
using System.Collections.Generic;
namespace Volpe.Cafe.Settings
{
    [Serializable]
    public sealed class TechnologyAttributes
    {
        #region 
        internal TechnologyAttributes() { }
        #endregion
        #region 
        internal TechnologyAttributes Clone()
        {
            TechnologyAttributes ta = new TechnologyAttributes();
            ta.TechnologyClass  = this.TechnologyClass;
            ta.Applicable       = this.Applicable;
            ta.YearAvailable    = this.YearAvailable;
            ta.YearRetired      = this.YearRetired;
            ta.ElectricRange    = this.ElectricRange;
            ta.DeltaWeightPCT   = this.DeltaWeightPCT;
            ta.DeltaWeightLBS   = this.DeltaWeightLBS;
            ta.LossOfValue      = this.LossOfValue;
            ta.FC               = this.FC;
            ta.FCPrimaryShare   = this.FCPrimaryShare;
            ta.CostTable            = (double[])Interaction.CloneArray(this.CostTable           , typeof(double));
            ta.MaintenanceCostTable = (double[])Interaction.CloneArray(this.MaintenanceCostTable, typeof(double));
            ta.RepairCostTable      = (double[])Interaction.CloneArray(this.RepairCostTable     , typeof(double));
            ta.StrandedCapital      = (double[])Interaction.CloneArray(this.StrandedCapital     , typeof(double));
            return ta;
        }
        #endregion
        #region 
        public TechnologyClass TechnologyClass;
        public bool Applicable;
        public int YearAvailable;
        public int YearRetired;
        public double ElectricRange;
        public double DeltaWeightPCT;
        public double DeltaWeightLBS;
        public double LossOfValue;
        public double FC;
        public double FCPrimaryShare;
        public double[] CostTable;
        public double[] MaintenanceCostTable;
        public double[] RepairCostTable;
        public double[] StrandedCapital;
        #endregion
    }
    [Serializable]
    public sealed class TechnologyAttributesTable
    {
        #region 
        internal TechnologyAttributesTable()
        {
            this._attributes = new TechnologyAttributes[(int)TechnologyClass.Max][];
            for (int i = 0; i < this._attributes.Length; i++)
            {
                this._attributes[i]    = new TechnologyAttributes[1];
                this._attributes[i][0] = new TechnologyAttributes();
            }
        }
        #endregion
        #region 
        internal TechnologyAttributesTable Clone()
        {
            TechnologyAttributesTable value = new TechnologyAttributesTable();
            for (int i = 0; i < this._attributes.Length; i++)
            {
                if (this._attributes[i] != null)
                {
                    value._attributes[i] = new TechnologyAttributes[this._attributes[i].Length];
                    for (int j = 0; j < this._attributes[i].Length; j++)
                    {
                        value._attributes[i][j] = this._attributes[i][j].Clone();
                    }
                }
            }
            return value;
        }
        internal void SetAttributes(TechnologyClass techClass, EngineSize engSize, TechnologyAttributes value)
        {
            int tcIndex = (int)techClass - 1;
            if (tcIndex < 0 || tcIndex >= (int)TechnologyClass.Max) { throw new ArgumentOutOfRangeException("techClass", ErrorStrings.TechClassNotValid); }
            int esIndex = (int)engSize;
            int esMax   = (engSize == EngineSize.None) ? 1 : 4;
            if      (this._attributes[tcIndex] == null) { this._attributes[tcIndex] = new TechnologyAttributes[esMax]; }
            else if (this._attributes[tcIndex].Length < esMax)
            {
                TechnologyAttributes[] newAttributes = new TechnologyAttributes[esMax];
                for (int i = 0; i < this._attributes[tcIndex].Length; i++)
                {
                    newAttributes[i] = this._attributes[tcIndex][i];
                }
                this._attributes[tcIndex] = newAttributes;
            }
            this._attributes[tcIndex][esIndex] = value;
        }
        public List<TechnologyAttributes> GetAttributesList()
        {
            List<TechnologyAttributes> list = new List<TechnologyAttributes>();
            for (int i = 0; i < this._attributes.Length; i++)
            {
                list.AddRange(this._attributes[i]);
            }
            return list;
        }
        #endregion
        #region 
        public TechnologyAttributes this[Vehicle veh] { get { return this[veh.TechnologyClass, veh.Engine.Description.EngineSize]; } }
        public TechnologyAttributes this[TechnologyClass techClass, EngineSize engSize]
        {
            get
            {
                int tcIndex = (int)techClass - 1;
                int esIndex = (int)engSize;
                if (tcIndex < 0 || tcIndex >= (int)TechnologyClass.Max) { throw new ArgumentOutOfRangeException("techClass", ErrorStrings.TechClassNotValid); }
                if (esIndex >= this._attributes[tcIndex].Length ||
                    this._attributes[tcIndex][esIndex] == null) { esIndex = 0; }    
                return this._attributes[tcIndex][esIndex];
            }
        }
        #endregion
        #region 
        TechnologyAttributes[][] _attributes;
        #endregion
    }
}

