#region << Using Directives >>
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Volpe.Cafe.Data;
using Volpe.Cafe.Settings;
using Volpe.Cafe.Utils;
using Volpe.Cafe.Generic;
using Volpe.Cafe.MonteCarlo.Settings;
#endregion
namespace Volpe.Cafe.MonteCarlo.Data
{
    [Serializable]
    public class TrialInfo : ICloneable
    {
        #region 
        public TrialInfo() { }
        #endregion
        #region 
        #region 
        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public TrialInfo Clone()
        {
            TrialInfo value = new TrialInfo();
            value.Index                = this.Index;
            value.FuelPriceScaleFactor = this.FuelPriceScaleFactor;
            value.PaybackPeriod_OC     = this.PaybackPeriod_OC;
            value.ReboundEffect        = this.ReboundEffect;
            value.OnRoadGap_Gasoline   = this.OnRoadGap_Gasoline;
            value.OnRoadGap_Diesel     = this.OnRoadGap_Diesel;
            value.TechCostScaleFactor  = (double[])Interaction.CloneArray(this.TechCostScaleFactor, typeof(double));
            value.TechFCScaleFactor    = (double[])Interaction.CloneArray(this.TechFCScaleFactor  , typeof(double));
            return value;
        }
        #endregion
        public void InitializeTrial(Industry data, ModelingSettings settings)
        {
            MonteCarloSettings mcSettings = (MonteCarloSettings)settings.GetRuntimeSettings(typeof(MonteCarloSettings));
            List<Manufacturer> mfrs = data.Manufacturers;
            for (int j = 0, mfrCount = data.ManufacturerCount; j < mfrCount; j++)
            {
                mfrs[j].Description.PaybackPeriod_OC = this.PaybackPeriod_OC;
            }
            settings.OperatingModes.FuelPriceEstimates = Estimates.Average;
            settings.Parameters.UpdateForMonteCarlo(this.FuelPriceScaleFactor, mcSettings.FuelPriceStartYear,
                mcSettings.PriceShockAlpha, this.ReboundEffect, this.OnRoadGap_Gasoline, this.OnRoadGap_Diesel);
            List<Technology> techs = settings.Technologies;
            double[] costScale = this.TechCostScaleFactor;
            double[] fcScale   = this.TechFCScaleFactor;
            for (int i = 0; i < techs.Count; i++)
            {
                Technology tech = techs[i];
                List<TechnologyAttributes> techAttr = tech.Attributes.GetAttributesList();
                for (int j = 0; j < techAttr.Count; j++)
                {
                    if (techAttr[j].CostTable != null)
                    {
                        for (int k = 0; k < techAttr[j].CostTable.Length; k++)
                        {
                            techAttr[j].CostTable[k] *= costScale[i];
                        }
                        techAttr[j].FC *= fcScale[i];
                    }
                } 
            } 
        }
        public static string CreateCsvHeader()
        {
            string cost = string.Empty;
            string fc   = string.Empty;
            for (int i = 0; i < TechnologyIndexes.TechnologyCount; i++)
            {
                cost += "Cost_" + TechnologyIndexes.TechAbbr[i] + ",";
                fc   += "FC_"   + TechnologyIndexes.TechAbbr[i] + ",";
            }
            return "Index,FuelPriceScalar,PaybackPeriod_OC,ReboundEffect,OnRoadGap_Gasoline,OnRoadGap_Diesel," +
                cost + fc.Remove(fc.Length - 1, 1);
        }
        public string ToCsvString()
        {
            return
                this.Index                           + "," +
                this.FuelPriceScaleFactor            + "," +
                this.PaybackPeriod_OC                + "," +
                this.ReboundEffect                   + "," +
                this.OnRoadGap_Gasoline              + "," +
                this.OnRoadGap_Diesel                + "," +
                this.ToCsv(this.TechCostScaleFactor) + "," +
                this.ToCsv(this.TechFCScaleFactor  );
        }
        public void FromCsvString(string value)
        {
            string[] parts = value.Split(',');
            int partIndex = 0;
            this.Index                = int   .Parse(parts[partIndex++]);
            this.FuelPriceScaleFactor = double.Parse(parts[partIndex++]);
            this.PaybackPeriod_OC     = double.Parse(parts[partIndex++]);
            this.ReboundEffect        = double.Parse(parts[partIndex++]);
            this.OnRoadGap_Gasoline   = double.Parse(parts[partIndex++]);
            this.OnRoadGap_Diesel     = double.Parse(parts[partIndex++]);
            this.TechCostScaleFactor  = new double[TechnologyIndexes.TechnologyCount];
            this.TechFCScaleFactor    = new double[TechnologyIndexes.TechnologyCount];
            int techCount             = TechnologyIndexes.TechnologyCount;
            for (int i = 0; i < techCount; i++)
            {
                this.TechCostScaleFactor[i] = double.Parse(parts[partIndex + i]);
                this.TechFCScaleFactor  [i] = double.Parse(parts[partIndex + i + techCount]);
            }
        }
        string ToCsv(VCValue<double> value)
        {
            string result = "";
            for (int i = 0; i < VCValue<object>.Classes.Length; i++)
            {
                result += value.Items[i] + ",";
            }
            return result.Remove(result.Length - 1, 1);
        }
        string ToCsv(double[] arr)
        {
            string result = "";
            for (int i = 0, count = arr.Length; i < count; i++)
            {
                result += arr[i] + ",";
            }
            return result.Remove(result.Length - 1, 1);
        }
        #endregion
        #region 
        public int Index;
        public double FuelPriceScaleFactor;
        public double PaybackPeriod_OC;
        public double ReboundEffect;
        public double OnRoadGap_Gasoline;
        public double OnRoadGap_Diesel;
        public double[] TechCostScaleFactor;
        public double[] TechFCScaleFactor;
        #endregion
    }
}

