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

public class GameManagerScript : MonoBehaviour {

	private GameObject newTurret;
	private GameObject selectedTurret;
	private int buildableMask;
	private int turretMask;

	public GameObject turret;
	public GameObject enemy;
	public int enemyNumber = 10;
	public int money = 100;
	public int currentEnemy = 0;

	private ArrayList turretArray;
	private List<GameObject> enemyArray;

	private GameObject tManager;
	public GameObject enemyFactory;
	public GameObject turretFactory;

	private TurretFactoryScript tFactoryScript;

	private float lastSpawnTime;
	private float spawnRate = 1.5f;

	// Use this for initialization
	void Start () {
		tManager = GameObject.Find("TerrainManager");
		tFactoryScript = turretFactory.GetComponent<TurretFactoryScript>();

		lastSpawnTime = Time.time;
		buildableMask =  1 << LayerMask.NameToLayer("Buildable");
		turretMask =  1 << LayerMask.NameToLayer("Turrets");

		turretArray = new ArrayList();
		enemyArray = new List<GameObject>();
		
		createEnemies(tManager.GetComponent<TerrainCreator>().EnemyPath);
	}
	
	// Update is called once per frame
	void Update () {
		checkTurretTarget();
		checkInput();

		float currentTime = Time.time;

		if(currentTime - lastSpawnTime >= this.spawnRate && currentEnemy < enemyNumber) {
			EnemyBehaviour enemy = ((GameObject)enemyArray[currentEnemy]).GetComponent<EnemyBehaviour>();
			enemy.Active = true;

			TerrainCreator tCreator = tManager.GetComponent<TerrainCreator>();
			Vector3 startPosition = tCreator.RealEnemyStart.transform.position;
			startPosition.Set (startPosition.x, this.transform.localScale.y + 0.5f, startPosition.z);

			enemy.transform.position = startPosition;
			enemy.transform.LookAt(enemy.Path[1].RealPosition);
			currentEnemy++;
			currentTime = Time.time;
			lastSpawnTime = currentTime;
		}
	}

	void OnGUI() {
		// Create bulletTurret
		if(money - tFactoryScript.getTurretTypeCost((int)TurretFactoryScript.TurretType.bulletTurret) >= 0 && GUI.Button(new Rect(0, 0, 100, 100), "Torreta")) {
			newTurret = tFactoryScript.getTurret((int)TurretFactoryScript.TurretType.bulletTurret);
			money -= newTurret.GetComponent<TurretBehaviour>().cost;
		}

		if(selectedTurret != null) {
			TurretBehaviour tb = selectedTurret.GetComponent<TurretBehaviour>();

			string hudText = "Money: " + money.ToString() + "\n\n";
			hudText += "Turret Info: \n\n";
			hudText += "Level: " + tb.Level + "\n";
			hudText += "Damage: " + tb.damage * tb.Level + "\n";
			hudText += "Upgrade cost: " + tb.cost * tb.Level;

			GUIStyle style = GUI.skin.GetStyle("box");
			GUIContent content = new GUIContent(hudText);
			style.alignment = (TextAnchor)TextAlignment.Left;
			float infoPanelheight = style.CalcHeight(content, 150);

			GUI.Box(new Rect(Screen.width - 150, 10, 150, infoPanelheight), hudText);

			if((this.money - tb.cost * tb.Level >= 0) && tb.Level < tb.MaxLevel && !tb.LevelingUp && GUI.Button(new Rect(Screen.width - 150, infoPanelheight + 20, 150, 30), "Upgrade")) {
				this.money -= tb.cost * tb.Level;
				tb.levelUp();
			}
		}
		else {
			string hudText = "Money: " + money.ToString();

			GUIStyle style = GUI.skin.GetStyle("box");
			GUIContent content = new GUIContent(hudText);
			style.alignment = (TextAnchor)TextAlignment.Left;

			GUI.Box(new Rect(Screen.width - 150, 10, 150, style.CalcHeight(content, 150)), hudText);
		}
	}

	// Check input events like mouse to position turret or select one to update
	private void checkInput() {
		if(newTurret != null) {
			// posicionar la torreta donde el ratón, meterla en un array de torretas, hacer un array de enemigos.
			Ray rayo = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit;
			
			if(Physics.Raycast(rayo, out hit, 200, buildableMask)) {
				newTurret.transform.position = new Vector3(hit.transform.position.x, hit.transform.position.y + 1.5f, hit.transform.position.z);
			}
			
			if(Input.GetMouseButtonDown(0)) {
				TurretBehaviour tr = newTurret.GetComponent<TurretBehaviour>();
				tr.Target = searchNearestEnemy(newTurret);
				
				turretArray.Add(newTurret);
				newTurret = null;
			}
		}
		else if(Input.GetMouseButtonDown(0)) {
			Ray rayo = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit;
			
			if(Physics.Raycast(rayo, out hit, 200, turretMask)) {
				selectedTurret = hit.collider.gameObject;
			}
			else if(Physics.Raycast(rayo, out hit, 200)) {
				selectedTurret = null;
			}
		}
	}

	private GameObject searchNearestEnemy( GameObject turret) {
		Vector3 tPos = turret.transform.position;
		float distance = int.MaxValue;
		GameObject target = null;

		for(int i = 0 ; i < this.enemyArray.Count ; i++) {
			GameObject enemy = ((GameObject)this.enemyArray[i]);
			if(enemy != null && enemy.GetComponent<EnemyBehaviour>().Active) {
				Vector3 ePos = enemy.transform.position;

				float currentDistance = Vector3.Distance(tPos, ePos);

				if(currentDistance < distance) {
					target = enemy;
					distance = currentDistance;
				}
			}
		}
		return target;
	}

	private void createEnemies(List<Node> enemyPath) {
		EnemyFactoryScript em = enemyFactory.GetComponent<EnemyFactoryScript>();

		enemyArray = em.getEnemies((int)EnemyFactoryScript.EnemyType.normalEmeny, Random.Range(1, 6));
		enemyArray.AddRange(em.getEnemies((int)EnemyFactoryScript.EnemyType.slowEnemy, Random.Range(1, enemyNumber - enemyArray.Count)));

		for(int i = 0 ; i < enemyNumber ; i++) {
			((GameObject)enemyArray[i]).transform.position = new Vector3(-100, -100, -100);
			((GameObject)enemyArray[i]).GetComponent<EnemyBehaviour>().Path = enemyPath;
		}
	}

	private void checkTurretTarget() {
		for(int i = 0 ; i < turretArray.Count ; i++) {
			GameObject turret = ((GameObject)turretArray[i]);
			TurretBehaviour tb = turret.GetComponent<TurretBehaviour>();
			if(tb.Target == null) {
				tb.Target = searchNearestEnemy(turret);
			}
		}
	}
}
