using UnityEngine;
using System.Collections;


public enum ElementalAspect
{
    Movement,
    Attack,
    Defense
}


public struct Element
{

	public static Element Soul = new Element(true, false, false);
	public static Element Electricity = new Element(true, true, false);
	public static Element Plasma = new Element(false, true, false);
	public static Element Fire = new Element(false, true, true);
	public static Element Mercury = new Element(false, false, true);
	public static Element Life = new Element(true, false, true);
	public static Element Null = new Element(false, false, false);
	public static Element Void = new Element(true, true, true);

	public enum Component
	{
		Soul,
		Plasma,
		Mercury,
	}

	private bool _hasSoul;
	private bool _hasPlasma;
	private bool _hasMercury;

	private Element(bool hasSoul, bool hasPlasma, bool hasMercury)
	{
		_hasSoul = hasSoul;
		_hasPlasma = hasPlasma;
		_hasMercury = hasMercury;
	}

	public Element AddElement(Element element)
	{
		if (element._hasSoul) {
			AddComponent(Component.Soul);
		} else if (element._hasPlasma) {
			AddComponent(Component.Plasma);
		} else if (element._hasMercury) {
			AddComponent(Component.Mercury);
		}
		return this;
	}

	public Element AddComponent(Component component)
	{
		if (component == Component.Soul) {
			_hasSoul = true;
		} else if (component == Component.Plasma) {
			_hasPlasma = true;
		} else if (component == Component.Mercury) {
			_hasMercury = true;
		}
		return this;
	}

	public Color Color
	{
		get
		{
			return new Color((_hasMercury ? 1f : 0f) , (_hasPlasma ? 1f : 0f), (_hasSoul ? 1f : 0f));
		}
	}

    public Material Material
    {
        get
        {
            return ElementalMaterials.Instance.GetMaterialForElement(this);
        }
    }

	public static bool operator ==(Element x, Element y)
	{
		if (x._hasSoul == y._hasSoul && 
			x._hasPlasma == y._hasPlasma && 
			x._hasMercury == y._hasMercury) return true;
		return false;
	}

	public static bool operator !=(Element x, Element y)
	{
		if (x._hasSoul == y._hasSoul && 
			x._hasPlasma == y._hasPlasma && 
			x._hasMercury == y._hasMercury) return false;
		return true;
	}

   public override bool Equals(object o) 
   {
      try {
         return (this == (Element)o);
      }
      catch {
         return false;
      }
   }

   public override int GetHashCode() 
   {
      return ((_hasSoul ? 1 : 0) * 100) +
      		 ((_hasPlasma ? 1 : 0) * 10) +
      		 ((_hasMercury ? 1 : 0));
   }

   public const float neighborDamage = 0.5f;
   public const float normalDamage = 1f;
   public const float oppositeDamage = 2f;

   public static Element ElementForComponent(Component component)
   {
   		if (component == Component.Soul) return Soul;
   		if (component == Component.Mercury) return Mercury;
   		return Plasma;
   }


   public static float ElementalDamageFactor(Element weapon, Component target)
   {
   		return ElementalDamageFactor(weapon, ElementForComponent(target));
   }

   public static float ElementalDamageFactor(Component weapon, Element target)
   {
   		return ElementalDamageFactor(ElementForComponent(weapon), target);
   }

   public static float ElementalDamageFactor(Component weapon, Component target)
   {
   		return ElementalDamageFactor(ElementForComponent(weapon), ElementForComponent(target));
   }

   public static float ElementalDamageFactor(Element weapon, Element target)
   {
	   	if (weapon == Void) return 0f;
	   	if (weapon == Null) return 1f;
   		if (weapon == target) return 0f;
   		if (weapon == Soul) {
   			if (target == Electricity) return neighborDamage;
   			if (target == Plasma) return normalDamage;
   			if (target == Fire) return oppositeDamage;
   			if (target == Mercury) return normalDamage;
   			if (target == Life) return neighborDamage;
   		}
   		if (weapon == Electricity) {
   			if (target == Soul) return neighborDamage;
   			if (target == Plasma) return neighborDamage;
   			if (target == Fire) return normalDamage;
   			if (target == Mercury) return oppositeDamage;
   			if (target == Life) return normalDamage;
   		}
   		if (weapon == Plasma) {
   			if (target == Soul) return normalDamage;
   			if (target == Electricity) return neighborDamage;
   			if (target == Fire) return neighborDamage;
   			if (target == Mercury) return normalDamage;
   			if (target == Life) return oppositeDamage;
   		}
   		if (weapon == Fire) {
   			if (target == Soul) return oppositeDamage;
   			if (target == Electricity) return normalDamage;
   			if (target == Plasma) return neighborDamage;
   			if (target == Mercury) return neighborDamage;
   			if (target == Life) return normalDamage;
   		}
   		if (weapon == Mercury) {
   			if (target == Soul) return normalDamage;
   			if (target == Electricity) return oppositeDamage;
   			if (target == Plasma) return normalDamage;
   			if (target == Fire) return neighborDamage;
   			if (target == Life) return neighborDamage;
   		}
   		if (weapon == Life) {
   			if (target == Soul) return neighborDamage;
   			if (target == Electricity) return normalDamage;
   			if (target == Plasma) return oppositeDamage;
   			if (target == Fire) return normalDamage;
   			if (target == Mercury) return neighborDamage;
   		}
   		return normalDamage;
   }

}
