using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using ECOT.Engine.Statistics;

namespace ECOT.Game
{
    public interface ILevel
    {
        void LevelUp();
        int CheckLevel();
    }

    public abstract class Level<T> : ILevel
    {
        protected T owner = default(T);

        public Level(T owner)
        {
            this.owner = owner;
        }

        public T Owner
        {
            get { return this.owner; }
        }

        #region ILevel Membres

        public abstract void LevelUp();
        public abstract int CheckLevel();

        #endregion
    }

    public delegate void LevelEventHandler(Levelable owner);

    public abstract class Levelable
    {
        protected List<ILevel> levels = new List<ILevel>();
        protected int currentLevel = 0;

        public event LevelEventHandler OnLevelChange;

        public void AddLevel(ILevel level)
        {
            this.levels.Add(level);
        }

        public int Level
        {
            get { return this.currentLevel; }
            set
            {
                // Vérifie que le niveau est valide
                if (value > this.levels.Count)
                    return;

                // Leveling
                if (value == 0) return;
                while (value > this.currentLevel)
                    this.levels[this.currentLevel++].LevelUp();

                this.currentLevel = value;

                // Appelle l'événement OnLevelChange
                if (this.OnLevelChange != null)
                    this.OnLevelChange(this);
            }
        }

        public void UpdateLevel()
        {
            if (this.levels.Count == 0 || this.currentLevel == 0) return;

            int res = this.levels[this.currentLevel - 1].CheckLevel();
            if (res == 0) return;

            // Appelle l'événement OnLevelChange
            if (this.OnLevelChange != null)
                this.OnLevelChange(this);

            if (res == 1)
            {
                Debug.Assert(this.levels.Count >= this.currentLevel + 1);
                this.levels[this.currentLevel++].LevelUp();
            }
        }

        public int MaxLevel
        {
            get { return this.levels.Count; }
        }
    }
}
