using System;
using System.Collections.Generic;
using Volpe.Cafe.Data;
using Volpe.Cafe.Utils;
namespace Volpe.Cafe.Settings
{
    [Serializable]
    public sealed class Technology : ICloneable
    {
        #region 
        internal Technology()
        {
            this.OffCycleCredit = new RCDouble();
            this.Attributes     = new TechnologyAttributesTable();
            this.ImprvSynergies = new TechnologySynergies      ();
            this.CostSynergies  = new TechnologySynergies      ();
        }
        #endregion
        #region 
        #region 
        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public Technology Clone()
        {
            Technology tech     = new Technology();
            tech.Index          = this.Index;
            tech.Name           = this.Name;
            tech.Abbr           = this.Abbr;
            tech.Type           = this.Type;
            tech.OffCycleCredit = this.OffCycleCredit.Clone();
            tech.Attributes     = this.Attributes    .Clone();
            tech.ImprvSynergies = this.ImprvSynergies.Clone();
            tech.CostSynergies  = this.CostSynergies .Clone();
            tech.PhaseIn        = (double[])Interaction.CloneArray(this.PhaseIn, typeof(double));
            return tech;
        }
        #endregion
        #region 
        public double GetPhaseIn(ModelYear year, ModelYear startYear, int offset)
        {
            return this.GetPhaseIn(year.Index, startYear.Index, offset);
        }
        public double GetPhaseIn(int yrIndex, int startYrIndex, int offset)
        {
            int maxIndex = this.PhaseIn.Length - 1;
            int index = yrIndex - startYrIndex + offset;
            if (index > maxIndex)
            {
                if (maxIndex == 0)
                {   
                    return this.PhaseIn[0];
                }
                else
                {   
                    return Math.Min(1.0, Math.Max(0.0,
                        this.PhaseIn[maxIndex] + (this.PhaseIn[maxIndex] - this.PhaseIn[maxIndex - 1]) * (index - maxIndex)));
                }
            }
            else { return this.PhaseIn[index]; }
        }
        #endregion
        public override string ToString()
        {
            return "{" + this.Index.ToString("00") + "-" + this.Abbr + "}";
        }
        #endregion
        #region 
        public int Index;
        public string Name;
        public string Abbr;
        public TechnologyType Type;
        public RCDouble OffCycleCredit;
        public double[] PhaseIn;
        public TechnologyAttributesTable Attributes;
        public TechnologySynergies ImprvSynergies;
        public TechnologySynergies CostSynergies;
        #endregion
    }
}

