using UnityEngine;
using System.Collections;
using System;
using UnityEngine.EventSystems;

// Controlling the game
public class GameController : MonoBehaviour {

	public HitObject[] UsedObjects;
	HitObject[] HitObjects=new HitObject[1000];
	public int ObjectCount;
	int ColliderCount=0;
	// graphical object
	public GameObject Circle;
	public static GameController Instance;
	// Whole wave as object
	public GameObject PlayerWave;

	public Boolean SpawnWaveLocked = false;
	private float SpawnWaveCoolDown = 0.3f;

	public static Color WaveColor=Color.blue;
	public static float WaveDelay=0.3f;

	private int wavesUsed = 0;

	// Use this for initialization
	void Start () {
		Instance = this;
		ObjectCount = 0;
		UsedObjects = GameObject.FindObjectsOfType<HitObject> ();
		for (int i = 0; i < UsedObjects.Length; i++) {
			HitObjects [i] = UsedObjects [i];
			HitObjects [i].Init (i);
			if (HitObjects[i].Type == ObjectType.destroyable ||HitObjects[i].Type == ObjectType.destroyableObstacles) {
				ObjectCount++;
			}
		}
		ColliderCount = UsedObjects.Length;
	}
	
	// Update is called once per frame
	void Update () {
	
		// for testing purposes
		if (Input.GetKeyDown(KeyCode.A)) {
			SpawnPlayerWave (0,0);
		}
		if (Input.GetMouseButtonUp (0)) {
			if (!EventSystem.current.IsPointerOverGameObject ()) {
				Vector3 mousePosition = Input.mousePosition;
				Vector3 worldPosition = Camera.main.ScreenToWorldPoint (mousePosition);
				Collider2D collider = Physics2D.OverlapPoint (new Vector2 (worldPosition.x, worldPosition.y));

				if (collider) {
				//	Debug.Log (collider.name + " found at " + worldPosition);
					return;
				}

				SpawnPlayerWave (worldPosition.x, worldPosition.y);
			}
		}
	}


	// Spawns a Playerwave at position x,y and starts expanding it
	public void SpawnPlayerWave(float x, float y){
		if (!SpawnWaveLocked) {
			lockSpawnWaves ();
			wavesUsed++;
			HitObject playerWave = Instantiate (PlayerWave).GetComponent<HitObject> ();
			playerWave.transform.position = new Vector3 (x, y, -0.01f);
			playerWave.transform.rotation = Quaternion.Euler (0, 180, 0);
			//HitObjects [ObjectCount] = playerWave;
			//ObjectCount++;
			playerWave.MyStart();
			Prepare (playerWave);
			playerWave.Expand ();
		}
	}

	public void ObjectDestroyed(int i){
		ObjectCount=ObjectCount-1;
		ColliderCount = ColliderCount - 1;
		HitObjects[i]=HitObjects[ColliderCount];
		HitObjects [i].number = i;
		//TODO send to highscore

		if (ObjectCount <= 0) {
			Invoke ("finishLevel", 3);
		}
	}

	public void ObstacleDestrozed(int i){
		ColliderCount = ColliderCount - 1;
		HitObjects[i]=HitObjects[ColliderCount];
		HitObjects [i].number = i;
		//TODO send to highscore
	}

	void finishLevel() {
		GameLogic.Instance.finishLevelWith (wavesUsed);
	}

	// makes all necessarily preparations before expanding a wave
	public void Prepare(HitObject Target){
		Target.Distances= new Distance[ColliderCount];
		int count = 0;
		for (int i = 0; i < ColliderCount; i++) {
			if (HitObjects[i]!=Target) {
				Target.Distances[count]=Target.CalculateDistance(HitObjects[i]);
				count++;
			}
		}
		Array.Sort (Target.Distances, DistanceSorter.Instance);
	}

	public void lockSpawnWaves() {
		SpawnWaveLocked = true;
		StartCoroutine (unlockSpawnWaves ());
	}

	IEnumerator unlockSpawnWaves() {
		yield return new WaitForSeconds(SpawnWaveCoolDown);
		SpawnWaveLocked = false;
	}
}
