using ECOT.Engine.Statistics;
using ECOT.Game.Buildings;

namespace ECOT.Game
{
    public abstract class CityLevel : Level<City>
    {
        private bool canEvolve = false;
        private bool hasAlreadyLvlUp = false;
        private int eta;
        private int level;

        public CityLevel(City owner, int level)
            : base(owner)
        {
            this.eta = this.DaysToEvolve;
            this.level = level;
        }

        public sealed override void LevelUp()
        {
            if (!hasAlreadyLvlUp)
                this.FirstCityUp();

            // Déclenchement de l'animation d'évolution
            if (this.owner.Level != 1)
                this.owner.IsEvolution = true;

            // Incrémente le niveau de la ville
            this.owner.LevelVariable.Value = this.level;

            this.CityUp();

            this.hasAlreadyLvlUp = true;
        }

        public sealed override int CheckLevel()
        {
            // Si la condition est respectée, on attend pendant la période de rétention
            if (this.CheckConditions())
            {
                // Si évolution en cours, on décrémente le nombre de jours restants
                if (this.canEvolve)
                {
                    this.eta--;

                    // Si le temps est écoulé, on évolue woooot !!
                    if (this.eta == 0)
                    {
                        return 1;
                    }
                }
                else
                {
                    this.canEvolve = true;
                }
            }
            else
            {
                this.canEvolve = false;
                this.eta = this.DaysToEvolve;
            }

            return 0;
        }

        protected void ChangeCityTexture()
        {
        }

        protected virtual void CityUp()
        {
            this.ChangeCityTexture();
        }

        protected virtual void FirstCityUp() { }

        protected abstract bool CheckConditions();

        public abstract double ReputationNeeded
        { get; }
        public abstract int PopulationNeeded
        { get; }
        public abstract int DaysToEvolve
        { get; }
        public abstract double PopulationFactor
        { get; }
        public abstract double PopulationBonus
        { get; }
        public abstract double BehaviourFactor
        { get; }
    }

    public class CityLevel1 : CityLevel
    {
        public CityLevel1(City city)
            : base(city, 1)
        {
        }

        #region Propriétés

        public override double ReputationNeeded
        {
            get { return 0.8; }
        }

        public override int PopulationNeeded
        {
            get { return 0; }
        }

        public override int DaysToEvolve
        {
            get { return 1; }
        }

        public override double PopulationFactor
        {
            get { return 0; }
        }

        public override double BehaviourFactor
        {
            get { return 0; }
        }

        public override double PopulationBonus
        {
            get { return 0; }
        }
        #endregion

protected override void FirstCityUp()
{
    this.owner.WaterDomain.ConstructDomain(this.owner, BuildingCategory.Water, this.owner.Population * 0.007, VariableComputeMode.IncrementalSum);
    this.owner.FoodDomain.ConstructDomain(this.owner, BuildingCategory.Food, this.owner.Population * 0.006, VariableComputeMode.IncrementalSum);
}

protected override void CityUp()
{
    // Besoins
    this.owner.WaterDomain.RegisterDomain();
    this.owner.FoodDomain.RegisterDomain();
    // Réputation
    this.owner.Reputation.Depend("waterRatio", this.owner.WaterDomain.Ratio, 144, 1.0);
    this.owner.Reputation.Depend("foodRatio", this.owner.FoodDomain.Ratio, 144, 1.0);
    GameController.Instance.RegisterVariable(SimulationPool.Daily, this.owner.Reputation);
}

protected override bool CheckConditions()
{
    return (this.owner.Reputation.Value >= this.ReputationNeeded);
}
    }

    public class CityLevel2 : CityLevel
    {
        public CityLevel2(City city)
            : base(city, 2)
        {
        }

        #region Propriétés

        public override double ReputationNeeded
        {
            get { return 0.8; }
        }

        public override int PopulationNeeded
        {
            get { return 0; }
        }

        public override int DaysToEvolve
        {
            get { return 1; }
        }

        public override double PopulationFactor
        {
            get { return 0; }
        }

        public override double BehaviourFactor
        {
            get { return 0; }
        }

        public override double PopulationBonus
        {
            get { return 0; }
        }
        #endregion

        protected override void FirstCityUp()
        {
        }

        protected override void CityUp()
        {
            base.CityUp();
        }

        protected override bool CheckConditions()
        {
            // A VOUS DE JOUER
            return false;
        }
    }

    public class CityLevel3 : CityLevel
    {
        public CityLevel3(City city)
            : base(city, 3)
        {
        }

        #region Propriétés

        public override double ReputationNeeded
        {
            get { return 0.8; }
        }

        public override int PopulationNeeded
        {
            get { return 0; }
        }

        public override int DaysToEvolve
        {
            get { return 1; }
        }

        public override double PopulationFactor
        {
            get { return 0; }
        }

        public override double BehaviourFactor
        {
            get { return 0; }
        }

        public override double PopulationBonus
        {
            get { return 0; }
        }
        #endregion

        protected override void FirstCityUp()
        {
        }

        protected override void CityUp()
        {
            base.CityUp();
        }

        protected override bool CheckConditions()
        {
            return false;
        }
    }
}