using UnityEngine;
using System.Collections.Generic;

public class Turret : MonoBehaviour {

	public static List<Turret> allTurrets;

	public float range = 10f;
	public float rangeBoost = 1f;

	public float fireRate = 1f;
	public float fireRateBoost = 1f;

	public float damage = 1f;
	public float damageBoost = 1f;

	public string soundName = "Sniper";

	float fireCooldown = 0;

	float findCooldown = 0;

	GameObject myTarget;

	public Transform gunTurret;
	List<Transform> shootSpots;
	int currShootSpot = 0;

	public GameObject bulletPrefab;

	// Use this for initialization
	void Start () {
		if(allTurrets==null)
			allTurrets = new List<Turret>();

		allTurrets.Add(this);

		shootSpots = new List<Transform>(gunTurret.GetComponentsInChildren<Transform>());
		//shootSpots = gunTurret.GetComponentsInChildren<Transform>();
		shootSpots.Remove(gunTurret);

		UpdateBoosts();
	}

	public void UpdateBoosts() {
		// This is run continuously by BuildingPlacer!

		rangeBoost = 1;
		fireRateBoost = 1f;
		damageBoost = 1f;

		if(Booster.allBoosters != null) {
			foreach(Booster b in Booster.allBoosters) {
				b.TryApplyBoosts(this);
			}
		}

	}

	void OnDestroy() {
		allTurrets.Remove(this);
	}

	public float CurrentDamage() {
		return (damage + StatManager.current.bonusFlatDamage) * damageBoost;
	}
	
	public float CurrentDPS() {
		return CurrentDamage() / CurrentFireRate();
	}
	
	public float CurrentFireRate() {
		return fireRate / (fireRateBoost + StatManager.current.bonusFireRate);
	}

	public float CurrentRange() {
		return range * (rangeBoost + StatManager.current.bonusTurretRange);
	}
	

	// Update is called once per frame
	void Update () {
		fireCooldown -= Time.deltaTime * CurrentFireRate();
		findCooldown -= Time.deltaTime;

		FindTarget();
		RotateToTarget();

		if(fireCooldown <= 0) {
			Fire();
		}
	}

	void FindTarget() {
		if(findCooldown > 0)
			return;

		if(DemonLord.allDemonLords == null)
			return;

		findCooldown = Random.Range(0.1f, 0.3f);

		myTarget = null;
		float dist = Mathf.Infinity;

		foreach(DemonLord dl in DemonLord.allDemonLords) {
			float d = Vector2.Distance(dl.transform.position, this.transform.position);

			if(d > CurrentRange())
				continue;

			d = dl.lifeSpan;	// Fire at the weakest target

			if(myTarget == null || d < dist) {
				myTarget = dl.gameObject;
				dist = d;
			}
		}

	}

	void RotateToTarget() {
		if(myTarget == null)
			return;

		Vector3 dir = myTarget.transform.position - this.transform.position;
		float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

		gunTurret.rotation = Quaternion.Euler(0, 0, angle);
	}

	void Fire() {
		if(myTarget == null)
			return;

		Soulzooka s = GetComponent<Soulzooka>();
		int soulzookaCircleLevel = 0;
		if(s != null) {
			soulzookaCircleLevel = s.SoulToBullet(myTarget);
			if(soulzookaCircleLevel == 0) {
				// No souls available (or worth using)
				return;
			}
		}


		fireCooldown = CurrentFireRate();

		Transform sp = shootSpots[currShootSpot++ % shootSpots.Count];

		GameObject b = (GameObject)Instantiate( bulletPrefab, sp.position, sp.rotation );
		b.GetComponent<Bullet>().target = myTarget.transform;

		SoundManager.current.PlaySound(soundName);

		if(s == null) {
			// Regular Damage
			b.GetComponent<Bullet>().damage = CurrentDamage();
//			Debug.Log ("Fire bullet with damage: " + b.GetComponent<Bullet>().damage);
		}
		else {
			b.GetComponent<Bullet>().soulDamage = true;
			b.GetComponent<Bullet>().damage = (float)soulzookaCircleLevel * 0.05f + 0.05f;

		}

	}
}
