using System;
using System.Collections.Generic;
using Volpe.Cafe;
using Volpe.Cafe.Utils;
namespace Volpe.Cafe.Data
{
    [Serializable]
    public sealed class Engine : Component
    {
        #region 
        [Serializable]
        public sealed class CDescription
        {
            #region 
            internal CDescription() : base() { }
            #endregion
            #region 
            internal CDescription Clone()
            {
                CDescription ed = new CDescription();
                ed.Code                 = this.Code;
                ed.Manufacturer         = this.Manufacturer;
                ed.Family               = this.Family;
                ed.Configuration        = this.Configuration;
                ed.Fuel                 = this.Fuel;
                ed.EngineOilViscosity   = this.EngineOilViscosity;
                ed.Cycle                = this.Cycle;
                ed.FuelSystem           = this.FuelSystem;
                ed.Aspiration           = this.Aspiration;
                ed.ValvetrainDesign     = this.ValvetrainDesign;
                ed.ValveActuationTiming = this.ValveActuationTiming;
                ed.ValveLift            = this.ValveLift;
                ed.Cylinders            = this.Cylinders;
                ed.ValvesPerCylinder    = this.ValvesPerCylinder;
                ed.Deactivation         = this.Deactivation;
                ed.Displacement         = this.Displacement;
                ed.Horsepower           = this.Horsepower;
                ed.Torque               = this.Torque;
                ed.EngineSize           = this.EngineSize;
                ed.UsedTechnologies      = (int[])Interaction.CloneArray(this.UsedTechnologies     , typeof(int));
                ed.AvailableTechnologies = (int[])Interaction.CloneArray(this.AvailableTechnologies, typeof(int));
                return ed;
            }
            public override string ToString()
            {
                return this.Horsepower  .ToString("0"  ) + "hp - " +
                       this.Displacement.ToString("0.0") + "L " +
                       this.Configuration + this.Cylinders + " (" +
                       this.Aspiration + ")";
            }
            #endregion
            #region 
            public int Code;
            public string Manufacturer;
            public string Family;
            public string Configuration;
            public FuelType Fuel;
            public string EngineOilViscosity;
            public char Cycle;
            public string FuelSystem;
            public string Aspiration;
            public string ValvetrainDesign;
            public string ValveActuationTiming;
            public string ValveLift;
            public int Cylinders;
            public int ValvesPerCylinder;
            public double Deactivation;
            public double Displacement;
            public double Horsepower;
            public double Torque;
            public EngineSize EngineSize;
            public int[] UsedTechnologies;
            public int[] AvailableTechnologies;
            #endregion
        }
        #endregion
        #region 
        Engine() : base() { }
        internal Engine(Engine.CDescription description) : base()
        {
            this._description = description;
        }
        #endregion
        #region 
        internal Engine Clone()
        {
            Engine eng = new Engine();
            eng._description = this._description.Clone();
            this.CopyTo(eng);
            return eng;
        }
        internal void SetParent(int parentCode)
        {
            if (parentCode != -1)
            {
                Engine[] engs = this._manufacturer.Engines.ToArray();
                for (int i = 0; i < engs.Length; i++)
                {
                    if (parentCode == engs[i]._description.Code) { this._parent = engs[i]; break; }
                }
            }
        }
        internal void SetParent(Engine value)
        {
            this._parent = value;
        }
        public Engine Split(List<Vehicle> vehicles, int newCode)
        {
            Engine eng = (Engine)this.Clone();
            newCode = Math.Max(newCode, eng._manufacturer.GetNextEngineCode());
            eng._description.Code = newCode;
            eng._manufacturer.LastEngCode = newCode;
            for (int i = 0, vehCount = vehicles.Count; i < vehCount; i++)
            {
                vehicles[i].SetEngine(eng);
            }
            this.SplitTo(vehicles, eng);
            return eng;
        }
        #endregion
        #region 
        public override int[] TechnologyList { get { return TechnologyIndexes.EngineLevel; } }
        public Engine.CDescription Description { get { return this._description; } }
        public Engine Parent { get { return (Engine)this._parent; } }
        #endregion
        #region 
        Engine.CDescription _description;
        #endregion
    }
}

