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



/// <summary>
/// This script is currently archived if needed for later use.
/// </summary>
 
 
 
public class MagicPowers : MonoBehaviour {

	PlayerBase playerBase;

	// Magic Spells
	GameObject spellPrefab;
	public GameObject orb;
	public GameObject beam;
	public GameObject scatter;
	public GameObject burst;

	public LineRenderer drainer;
	bool draining = false;

	public Transform spawnPoint;
	public float spellTravelSpeed = 20f;
	public float drainSpeed = 0.5f;


	public GameObject wall;
	public GameObject activeWand;


	//[HideInInspector]
	public Transform magicSpawn, rightHand, leftHand;
	[HideInInspector]
	public bool autoFire, charging;

	Ray ray;
	RaycastHit hit;
	Vector3 dir;
	Animator pAnim;

	float gScale;
	bool canDrain;
	//[HideInInspector]
	public List<Material> drainMats;

	// Use this for initialization
	void Awake () {
		drainMats.Clear ();
		canDrain = false;
		pAnim = GetComponent<Animator> ();
		if (!playerBase)
			playerBase = GetComponent<PlayerBase> ();

		if (!spellPrefab)
			spellPrefab = orb;

		drainer.SetPosition (0, leftHand.transform.position);

	}
	
	// Update is called once per frame
	void Update () {

		drainer.SetPosition (0, leftHand.transform.position);
		if (!draining) {
			drainer.SetPosition (1, leftHand.transform.position);
		}
		
		ray = Camera.main.ViewportPointToRay (new Vector3 (0.5f, 0.5f, 0f));

		if (activeWand) 
			CheckCastInput (activeWand.GetComponent<WandScript> ().wand);

		if (Input.GetButtonDown ("Fire2")) {
			pAnim.SetLayerWeight (2, 1f);
			pAnim.SetTrigger ("RightClick");
			pAnim.SetBool ("Drain", true);



			if (Physics.Raycast (ray, out hit)) {
				dir = (hit.point - spawnPoint.position).normalized;
				if (hit.collider != null) {
					draining = true;


					if (hit.collider.gameObject.GetComponent<MeshRenderer> ()) {
						foreach (Material mat in hit.collider.gameObject.GetComponent<MeshRenderer> ().materials) {
							if (mat.HasProperty ("_Grayscale")) {
								drainMats.Add (mat);
							} else {
								drainMats.Clear ();
								break;
							}
						}
					}


					if (drainMats.Count != 0) {
						gScale = drainMats[0].GetFloat ("_Grayscale");
						canDrain = true;
					}
				}
			}
		}
		if (Input.GetButton ("Fire2")) {
			if (Physics.Raycast (ray, out hit)) {
				dir = (hit.point - spawnPoint.position).normalized;
				if (hit.collider != null) {
					drainer.SetPosition (1, hit.point);
				}
			}

			if (canDrain) {
				drainSpeed += 0.5f * Time.deltaTime;
				for (int i = 0; i < drainMats.Count; i++) {
					drainMats[i].SetFloat ("_Grayscale", Mathf.Lerp (gScale, 1f, drainSpeed));
				}
			}
		}
		if (Input.GetButtonUp ("Fire2")) {
			canDrain = false;
			draining = false;
			pAnim.SetBool ("Drain", false);
			drainMats.Clear ();
			drainSpeed = 0f;
		}
	}

	void CheckCastInput (Wand wand) {
		
		float startDamange = wand.damage;

		if (Input.GetButtonDown ("Fire1") && playerBase.wandMana > 0f) {
			if (wand.subType == WandSubType.Auto) {
				if (!autoFire) {

					autoFire = true;
					pAnim.SetTrigger ("LeftClick");
					pAnim.SetBool ("Auto", true);


					//StartCoroutine (AutoCast (wand));

				}
			} else if (wand.subType == WandSubType.Charged) {
				if (!charging) {
					
					charging = true;
					pAnim.SetTrigger ("LeftClick");
					pAnim.SetBool ("Charged", true);

					//StartCoroutine (ChargeCast (wand));
				}
			} else {
				CastSpell (wand);
			}
		}

		if (Input.GetButtonUp ("Fire1")) {
			if (wand.subType == WandSubType.Auto) {
				pAnim.SetBool ("Auto", false);
				autoFire = false;
			} else if (wand.subType == WandSubType.Charged) {
				pAnim.SetBool ("Charged", false);
				charging = false;
				//CastSpell (wand);
				//wand.damage = startDamange;
			}
		}
	}

	public void AnimCast () {
		dir = ray.direction;
		Quaternion rot = Quaternion.FromToRotation (spellPrefab.transform.forward, dir);
		GameObject spell = Instantiate (spellPrefab, spawnPoint.position, rot);
		spell.GetComponent<Rigidbody> ().velocity = dir * spellTravelSpeed;
		playerBase.wandMana = playerBase.wandMana - 2f;
		StartCoroutine (DestroyProjectile (spell));
	}

	public void StopDrain () {
		StartCoroutine (DrainBeGone ());
	}


	IEnumerator DrainBeGone () {

		float t = 0;
		float layerWeight = 1;
		while (t < 1) {
			t += Time.deltaTime * 3f;
			layerWeight = Mathf.Lerp (1, 0, t);
			pAnim.SetLayerWeight (2, layerWeight);
			yield return null;
		}
		yield return null;
	}


	void CastSpell (Wand wand) {

		if (wand.type == WandType.Beam) {
			spellPrefab = beam;
		} else if (wand.type == WandType.Scatter) {
			spellPrefab = scatter;
		} else if (wand.type == WandType.Orb) {
			spellPrefab = orb;
		} else if (wand.type == WandType.Burst) {
			spellPrefab = burst;
		}


		if (wand.type == WandType.Scatter) {
			for (int i = 0; i < 15; i++) {
				dir = ray.direction;
				Quaternion rot = Quaternion.FromToRotation (spellPrefab.transform.forward, dir);
				rot.x += Random.Range (-0.05f, 0.05f);
				rot.y += Random.Range (-0.05f, 0.05f);
				GameObject spell = Instantiate (spellPrefab, spawnPoint.position, rot);
				spell.GetComponent<Rigidbody> ().velocity = spell.transform.forward * spellTravelSpeed;
				StartCoroutine (DestroyProjectile (spell));
			}
			playerBase.wandMana = playerBase.wandMana - 2f;
		} else if (wand.type == WandType.Burst) {
			StartCoroutine (BurstCast ());
		} else {

			StartCoroutine (NormalCast ());
			/*
			pAnim.SetTrigger ("LeftClick");

			dir = ray.direction;
			Quaternion rot = Quaternion.FromToRotation (spellPrefab.transform.forward, dir);
			GameObject spell = Instantiate (spellPrefab, spawnPoint.position, rot);
			spell.GetComponent<Rigidbody> ().velocity = dir * spellTravelSpeed;
			playerBase.wandMana = playerBase.wandMana - 2f;
			StartCoroutine (DestroyProjectile (spell));
			*/
		}
	}

	IEnumerator BurstCast () {
		for (int i = 0; i < 3; i++) {
			dir = ray.direction;
			Quaternion rot = Quaternion.FromToRotation (spellPrefab.transform.forward, dir);
			GameObject spell = Instantiate (spellPrefab, spawnPoint.position, rot);
			spell.GetComponent<Rigidbody> ().velocity = dir * spellTravelSpeed;
			playerBase.wandMana = playerBase.wandMana - 1f;
			StartCoroutine (DestroyProjectile (spell));
			yield return new WaitForSeconds (0.025f);
		}
	}

	IEnumerator NormalCast () {
		pAnim.SetTrigger ("LeftClick");
		/*
		yield return new WaitForSeconds (1f / 3f);
		dir = ray.direction;
		Quaternion rot = Quaternion.FromToRotation (spellPrefab.transform.forward, dir);
		GameObject spell = Instantiate (spellPrefab, spawnPoint.position, rot);
		spell.GetComponent<Rigidbody> ().velocity = dir * spellTravelSpeed;
		playerBase.wandMana = playerBase.wandMana - 2f;
		StartCoroutine (DestroyProjectile (spell));
		*/
		yield return null;
	}

	IEnumerator AutoCast (Wand wand) {
		while (autoFire && playerBase.wandMana > 0f) {
			CastSpell (wand);
			yield return new WaitForSeconds (0.25f);
		}
		yield return null;
	}

	IEnumerator ChargeCast (Wand wand) {
		float chargeTime = 0f;
		while (charging) {
			yield return new WaitForSeconds (0.01f);
			playerBase.wandMana = playerBase.wandMana - 0.1f;
			chargeTime++;
			if (chargeTime == 10) {
				if (wand.damage < wand.maxDamage) {
					wand.damage = wand.damage + 1f;
					chargeTime = 0;
				}
			}
		}
		yield return null;
	}

	void CreateBlock () {
		dir = ray.direction;
		//float factor;
		//float xUnit = Mathf.Round (transform.position.x / factor) * factor;
		//Vector3 playerUnitPos;
		//Mathf.Round
		//Quaternion rot = Quaternion.FromToRotation (spellPrefab.transform.forward, dir);
		//GameObject spell = Instantiate (wall, transform.position + new Vector3 , rot);
		//spell.GetComponent<Rigidbody> ().velocity = dir * spellTravelSpeed;
	}

	IEnumerator DestroyProjectile (GameObject magic) {
		yield return new WaitForSeconds (2f);
		Destroy (magic);
	}
}
