using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public enum DamageType
{
    Fire,
    Earth,
    Wind,
    Water
}

public enum CharacterType
{
    Player,
    Demon
}

public class CharacterData : MonoBehaviour
{
    public float MaxHitPoints = 100;

    public float FireDefence = 0;
    public float EarthDefence = 0;
    public float WindDefence = 0;
    public float WaterDefence = 0;
    
    public CharacterType Type;
    public GameObject GlyphPrefab;

    public float Scale = 1;

    public float HitPoints { get; private set; }
    public Stack<DamageType> GlyphStack { get; private set; }
    int StartingGlyphsCount = 0;

    public delegate void GlyphStackHandler(Stack<DamageType> stack);
    public event GlyphStackHandler GlyphStackChanged;

    void Awake()
    {
        GlyphStack = new Stack<DamageType>();
    }

    // Use this for initialization
    void Start()
    {
        HitPoints = MaxHitPoints;
        StartingGlyphsCount = GlyphStack.Count;
        CharacterManager.instance.registerCharacter(this);
    }

    public void resetHitPoints()
    {
        HitPoints = MaxHitPoints;
    }

    void OnDestroy()
    {
        CharacterManager.instance.unregisterCharacter(this);
    }

    public bool isDead
    {
        get { return HitPoints < 0; }
    }

    public void doDamageToChar(float fireDamage, float earthDamage, float windDamage, float waterDamage)
    {
        float damage = 0;
        damage += Mathf.Max(0, fireDamage - FireDefence);
        damage += Mathf.Max(0, earthDamage - EarthDefence);
        damage += Mathf.Max(0, windDamage - WindDefence);
        damage += Mathf.Max(0, waterDamage - WaterDefence);

        HitPoints -= damage;
        if (HitPoints < 0)
        {
            StartCoroutine(die());
        }
        else
        {
            int looseGlyphsCount = Mathf.Max(0, (int)(GlyphStack.Count - (StartingGlyphsCount * HitPoints / MaxHitPoints)));
            looseGlyphs(looseGlyphsCount);
        }
    }

    private void looseGlyphs(int looseGlyphsCount)
    {
        while (looseGlyphsCount >= 1 && GlyphStack.Count > 0)
        {
            DamageType damagetype = GlyphStack.Pop();
            GameObject glyph = GameObject.Instantiate(GlyphPrefab, transform.position, Quaternion.identity) as GameObject;
            Glyph glyphComponent = glyph.GetComponent<Glyph>();
            glyphComponent.Type = damagetype;
            glyphComponent.HeightAboveGround = 0;
            glyphComponent.HeightVelocity = 0.05f;

            Vector2 randomDirection = new Vector2(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f));
            randomDirection.Normalize();
            glyph.rigidbody2D.velocity = randomDirection * 8;

            looseGlyphsCount -= 1;
        }
    }

    public void addGlyphToStack(DamageType damagetype)
    {
        GlyphStack.Push(damagetype);
        if (GlyphStackChanged != null)
        {
            GlyphStackChanged(GlyphStack);
        }
    }

    public DamageType popGlyphStack()
    {
        DamageType popDamageType = GlyphStack.Pop();
        if (GlyphStackChanged != null)
        {
            GlyphStackChanged(GlyphStack);
        }
        return popDamageType;
    }

    IEnumerator die()
    {
        looseGlyphs(GlyphStack.Count);
        DemonAI demonAI = GetComponent<DemonAI>();
        if (demonAI != null)
        {
			GetComponent<DemonController>().Die();
            Destroy(demonAI);
        }
        yield return new WaitForSeconds(1.0f);
        if (Type != CharacterType.Player)
        {
            Destroy(gameObject);
        }
        else
        {
            GameStateController.Instance.GameState = EGameState.GameOver;
        }
    }
}
