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

public class SpellController : MonoBehaviour {

	public int runeAmt;
	public PlayerMainController playerMover;
	public PlayerSummonController summonMover; 
	public SymbolManager symbolManager;
	public Material genieMaterial;
	
	public WizzardRuneParticles runeEffect;
	public SummoningParticleController summonEffect;
	public float upgradeDuration;
	public float summonDuration;
	
	private List<float> upgradeTime;
	private float summonTime;
	private Vector2 summonSpawnLoc;
 
	private int[] runeList;
	//0 = blank
	//1 = (Air) Vertical movement, gravity defiance
	//2 = (Earth) Carry capacity, movement while carrying
	//3 = (Fire) Horizontal movement

	// Use this for initialization
	void Start () { 
		runeList = new int[12];
		symbolManager.Init();
		symbolManager.UpdateAmt();
		symbolManager.UpdateRune();
		upgradeTime = new List<float>();
	}
	
	// Update is called once per frame
	void Update () {
		if(!playerMover.IsFrozen()){
			if (Input.GetKeyDown(KeyCode.Q)){
				AddRune(1); 
				runeEffect.runeColor = Color.green;
				Instantiate(runeEffect.gameObject).transform.position = transform.position;
			}
			if (Input.GetKeyDown(KeyCode.W)){
				AddRune(2); 
				runeEffect.runeColor = Color.blue;
				Instantiate(runeEffect.gameObject).transform.position = transform.position;
			}
			if (Input.GetKeyDown(KeyCode.E)){
				AddRune(3); 
				runeEffect.runeColor = Color.red;
				Instantiate(runeEffect.gameObject).transform.position = transform.position;
			}
			if (Input.GetKeyDown(KeyCode.Tab)){
				CastSpell ();
				Debug.Log("Cast");
			}
		}
	}

	void FixedUpdate(){
		if (upgradeTime.Count>0){
			for (int i=0; i<upgradeTime.Count; ++i){
				upgradeTime[i] -= Time.fixedDeltaTime;
				if (upgradeTime[i]<=0) {
					AddMaxRuneCount(1);
					upgradeTime.RemoveAt(i);
				}
			}
		}
		if (summonTime>0){
			CameraController.SetZoom(0.8f + (0.2f*summonTime/summonDuration));
			CameraController.SetOffset(new Vector2((1-summonTime/summonDuration)*playerMover.GetFaceDir(), summonTime/summonDuration));
			summonTime-= Time.fixedDeltaTime;
			if (summonTime<=0) Spawn();
		}
	}

	private void CastSpell(){
		if (runeAmt>0 && CheckRunes() &&	playerMover.CheckGrounded()){ 
			 
			Debug.Log(string.Format("{0}|{1}",playerMover.transform.position.x + playerMover.summonPos.x *(playerMover.GetFaceDir()), 
			                        playerMover.transform.position.y + playerMover.summonPos.y));
			summonSpawnLoc = new Vector2(playerMover.transform.position.x + playerMover.summonPos.x *(playerMover.GetFaceDir()), 
			                                             playerMover.transform.position.y + playerMover.summonPos.y);

			playerMover.SetPlayerFrozen(true);
			WizzardAnimScript.bCasting = true;

			Color[] runecol = new Color[runeAmt]; 
			for(int i=0;  i<runeAmt; ++i){ 
				if (runeList[i]==1) runecol[i]  = new Color(.2f,.9f,.2f);
				if (runeList[i]==2) runecol[i]  = new Color(.2f,.2f,.9f);
				if (runeList[i]==3) runecol[i]  = new Color(.9f,.2f,.2f); 
			}
			summonEffect.runeColors = runecol;

			Instantiate(summonEffect).transform.position = summonSpawnLoc;
			summonTime = summonDuration;

		}
	}

	private void Spawn(){
		summonMover.transform.position = summonSpawnLoc;
		summonMover.gameObject.SetActive(true); 
		summonMover.GainFocus();
		TallyRunes(); 
	}

	private void TallyRunes(){
		int[] tot = new int[5];
		int max = 0;
		for(int i=0;  i<runeAmt; ++i){
			tot[runeList[i]]++;	
			if (tot[runeList[i]] > max) max = tot[runeList[i]];
		}

		summonMover.SetJump(tot[1]);
		summonMover.SetLift(tot[2]);
		summonMover.SetMove(tot[3]);

		float lightMult = 1f/max;
		
		Color genieColor = new Color(tot[3]*lightMult * 0.5f, tot[1]*lightMult * 0.5f,tot[2]*lightMult * 0.5f);
		Color lightColor = new Color(tot[3]*lightMult, tot[1]*lightMult,tot[2]*lightMult );
		genieMaterial.SetColor ("_EmissionColor", genieColor);

		Light l = summonMover.GetComponentsInChildren<Light>()[0];
		l.color = genieColor;

		int spc = summonMover.GetSpCommandAmt();
		for(int i=0; i<spc; ++i){ 
			PlayerSummonController.SpCommand tmp = summonMover.spCommandList[i];
			if (tmp.activated){
				int cnt = 0;
				int len = tmp.sequenceLength;
				for(int j = 0; j<runeAmt - len + 1; ++j){
					for (int k = 0; k<len; ++k){
						if (tmp.commSequence[k] != runeList[j+k]) break;
						if (k==len-1)  ++cnt;
					}
				}
				summonMover.spCommandCharges[i]=cnt;
				Debug.Log(cnt);
			}
		}
		return;
	}

	private bool CheckRunes(){
		//checks if all runes are filled
		for(int i=0;  i<runeAmt; ++i){
			if (runeList[i] == 0) return false;
		}
		return true;
	}
	
	private void AddRune(int inp){
		if (runeAmt==0) return;
		for(int i=0;  i<runeAmt; ++i){
			if (runeList[i]==0){
				runeList[i]=inp;
				symbolManager.UpdateRune();
				return;
			} 
		} 
		for(int i=0;  i<runeAmt-1; ++i){ 
			runeList[i] = runeList[i+1];
		} 
		runeList[runeAmt-1] = inp;
		symbolManager.UpdateRune();
	}

	public void AddMaxRuneCount(int inp){
		runeAmt += inp;
		symbolManager.UpdateAmt();
	}

	public void ClearRunes(){
		for(int i=0;  i<runeAmt; ++i){
			runeList[i] = 0;
		}
		symbolManager.UpdateRune();
	}
	
	public int GetRuneNo(int index){
		return runeList[index];
	}

	public int GetMaxRuneCount(){
		return runeAmt;
	}

	void OnTriggerEnter2D(Collider2D other){ 
		if (other.gameObject.tag == "Powerup"){ 
			Destroy(other.gameObject);
			GameObject runeinst = Instantiate(playerMover.upgradeAnim);
			runeinst.transform.parent=playerMover.transform;
			runeinst.transform.position = playerMover.transform.position;

			upgradeTime.Add(upgradeDuration);
		}
	}
}
