using UnityEngine;
using System.Collections.Generic;

public class Test : MonoBehaviour
{
		public GameObject floor;
		public List<Material> Mats;
		public Texture2D border;
		GameObject[,] Stage = new GameObject[32, 32];
		public static GameObject speedUpToken;// = (GameObject)Resources.Load("speedUpPlane");
		public static GameObject speedDownToken;// = (GameObject)Resources.Load("speedDownPlane");
		public static GameObject bonusToken;// = (GameObject)Resources.Load("bonusPlane");
		public static GameObject coinTokenn;// = (GameObject)(Resources.Load("coin"));

		public static AudioClip nextLevel;

		public static int[,] world;
		public static float AtyaraBegin = -11;
		// Use this for initialization
		void Start ()
		{
				if (PlayerPrefs.GetInt ("Double Way", 0) == 1)
						Globals.pathWidth = 2;
				Messenger.AddListener ("startgame", new Callback (delegate () {
						Globals.IsGamePaused = false;
				}));
				Messenger.AddListener ("loadCredits", new Callback (delegate() {
						Application.LoadLevel ("about");
				}));

				GameObject.FindGameObjectWithTag ("Player").transform.position = new Vector3 (6, 1, 6);
				speedUpToken = (GameObject)Resources.Load ("speedUpPlane");
				speedDownToken = (GameObject)Resources.Load ("speedDownPlane");
				bonusToken = (GameObject)Resources.Load ("bonusPlane");
				coinTokenn = (GameObject)(Resources.Load ("coin"));
				nextLevel = (AudioClip)Resources.Load ("Sounds/level");
				for (int i = 0; i < 32; i++) {
						for (int j = 0; j < 32; j++) {
								GameObject newFloor = Instantiate (floor, new Vector3 (i * 2, 0, j * 2), Quaternion.identity) as GameObject;
								Stage [i, j] = newFloor;
								Stage [i, j].AddComponent<Token> ();
						}
				}
				if (Globals.set == 0) {
						Messenger<Vector2>.AddListener ("cube movement", YourLifeOrYourLife);
				}
				Globals.Level = 0;
				rotate.speed = 2.5f;
				NewMap ();
		}
		public static float speedUpTime = 3;
		public static float bonusTime = 3;
		public static bool SelfMovement = false;
		float alphaFadeValue = 0;
		public Texture2D blackTexture;
		float last = 0;
		void Update ()
		{
				if (Time.timeSinceLevelLoad - ColorLast > 0.5)
						UpdateColors ();

				if (Input.GetKey ("r"))
						Glowing = true;

				if (Glowing)
						EnterGlow ();/*GameOver();*/
				if (Globals.Lifes == 0 || CubePos.x > 32 || CubePos.x < -1 || CubePos.y > 32 || CubePos.y < -1) {
						GameObject.FindGameObjectWithTag ("Player").renderer.material.color = new Color (Mats [0].color.r, Mats [0].color.g, Mats [0].color.b, 1 - alphaFadeValue);
						Globals.dying = true;
						rotate.speed = 0.3f;
				}
				if (alphaFadeValue > 0.9f) {
						Messenger<Vector2>.RemoveListener ("cube movement", listenerRemoved);
						rotate.speed = 3.0f;
						Globals.dying = false;
						Application.LoadLevel ("gameOver");
				}


				// Debug.Log("OMG");

				if (SelfMovement && Time.timeSinceLevelLoad - selfBegin > speedUpTime) {
						SelfMovement = false;
						rotate.speed = Mathf.Min (7, 2.5f + Globals.Level * 0.3f);
						//Camera.main.GetComponent<>().enabled = false;
				}
				if (SelfMovement)
						MoveSelf ();
				if (Time.timeSinceLevelLoad - AtyaraBegin < bonusTime) {
						ChangeBottom ();
				}
				RotateCamera ();
		}

		private float lastsp = 0;
		public Texture2D resume;
		void OnGUI ()
		{
				if (Globals.dying) {
						alphaFadeValue += Mathf.Clamp01 (Time.deltaTime / 5);

						GUI.color = new Color (0, 0, 0, alphaFadeValue);
						GUI.DrawTexture (new Rect (0, 0, Screen.width, Screen.height), blackTexture);
				} else if (GUI.Button (new Rect (Screen.width - resume.width, 0, resume.width, resume.height), resume))
				if (rotate.speed == 0)
						rotate.speed = lastsp;
				else {
						lastsp = rotate.speed;
						rotate.speed = 0;
				}
		}
		void listenerRemoved (Vector2 POS)
		{

		}
		void GameOver ()
		{
				//Oyuncu kaybedince (Baska bisey olcak hali yok zaten amk GameOver


		}
		void YourLifeOrYourLife (Vector2 POS)
		{
				if (POS.x < 32 && POS.y < 32 && POS.x >= 0 && POS.y >= 0 && world [(int)POS.x, (int)POS.y] == 0 && Globals.Lifes > 0)
						Globals.Lifes--;
				//Debug.Log(Globals.Lifes);
		}
		public static float selfBegin = 0;
		void MoveSelf ()
		{
				if (world [(int)CubePos.x + 1, (int)CubePos.y] == 1) {
						rotate.last = 0;
				} else if (world [(int)CubePos.x, (int)CubePos.y + 1] == 1) {
						rotate.last = 2;
				}
		}
		void ChangeBottom ()
		{
				world [(int)CubePos.x, (int)CubePos.y] = 1;
				Stage [(int)CubePos.x, (int)CubePos.y].renderer.material = Mats [0];
		}

		Vector3[] rotations = new Vector3[] { new Vector3 (0.005f, 0.005f, 0.005f), new Vector3 (-0.005f, -0.005f, -0.005f), new Vector3 (-0.005f, -0.005f, -0.005f), new Vector3 (0.005f, 0.005f, 0.005f),
                                new Vector3 (0, 0.005f, 0.005f), new Vector3 (0, -0.005f, -0.005f), };
		int rotI = 0;
		int i = 0;
		void RotateCamera ()
		{
				Camera.main.transform.Rotate (rotations [rotI]);
				if (i % 50 == 49)
						rotI = (rotI + 1) % rotations.Length;
				i++;
		}

		public static bool Glowing = false;
		bool Leaving = false;
		float iterations = 0;
		void EnterGlow ()
		{
				if (Leaving) {
						LeaveGlow ();
						return;
				}
				Camera.main.GetComponent<GlowEffect> ().enabled = true;
				Camera.main.GetComponent<GlowEffect> ().glowIntensity += 0.3f;
				iterations += 0.3f;
				if (iterations >= 1) {
						Camera.main.GetComponent<GlowEffect> ().blurIterations += 1;
						iterations = 0;
				}

				if (Camera.main.GetComponent<GlowEffect> ().blurIterations >= 5) {
						NewMap ();
						Leaving = true;
				}
		}

		void LeaveGlow ()
		{
				Camera.main.GetComponent<GlowEffect> ().glowIntensity -= 0.3f;
				iterations += 0.3f;
				if (iterations >= 1) {
						Camera.main.GetComponent<GlowEffect> ().blurIterations -= 1;
						iterations = 0;
				}

				if (Camera.main.GetComponent<GlowEffect> ().glowIntensity <= 0) {
						Camera.main.GetComponent<GlowEffect> ().enabled = false;
						Leaving = false;
						Glowing = false;

						last = Time.timeSinceLevelLoad;
				}
		}


		void NewMap ()
		{
				foreach (GameObject go in GameObject.FindGameObjectsWithTag("token")) {
						if (go.GetComponent<TokenScriptBase> () != null)
								go.GetComponent<TokenScriptBase> ().Dispose ();
				}

				rotate.speed += 0.3f;
				if (GameObject.FindGameObjectWithTag ("Player").transform.parent != null) {
						GameObject.FindGameObjectWithTag ("Player").transform.parent = null;
						GameObject.FindGameObjectWithTag ("Player").transform.position = new Vector3 (6, 1, 6);
				}

				Material lastMat = Mats [0];
				Mats.RemoveAt (0);
				Mats.Add (lastMat);

				Mats [0].mainTexture = null;
				for (int i = 1; i < Mats.Count; i++) {
						Mats [i].mainTexture = border;
				}

				int[,] lsq = GetLastSq ();

				FloorGenerator fg = new FloorGenerator ();
				world = fg.Generate (3, 3);

				for (int i = 0; i < 4; i++) {
						for (int j = 0; j < 4; j++) {
								world [i, j] = lsq [i, j];
						}
				}

				int isInst = 0;
				int maxI = 0;
				int maxJ = 0;
				for (int i = 31; i >= 0; i--) {
						if (isInst == 1)
								break;
						for (int j = 31; j >= 0; j--) {
								if (world [i, j] == 1) {
										Stage [i, j].AddComponent<lastBoxToken> ();
										isInst = 1;
										maxI = i;
										maxJ = j;
										break;
								}
						}
				}
				int count = 0;
				int timeToAlternateRoad = Random.Range (5, 15);
				int endOfAlternateRoad = Random.Range (20, 25);
				int altRoadX = 0, altRoadY = 0, endX = 0, endY = 0;
				for (int i = 0; i < 32; i++) {
						for (int j = 0; j < 32; j++) {
								if (world [i, j] == 1) {
										count++;
										GameObject.FindGameObjectWithTag ("Player").renderer.material.color = new Color (Mats [0].color.r, Mats [0].color.g, Mats [0].color.b, 0.5f);
										if (count < 28)
												Stage [i, j].GetComponent<Token> ().Tokens ();
										Stage [i, j].renderer.material = null;
										Stage [i, j].renderer.material = Mats [0];
										timeToAlternateRoad--;
										endOfAlternateRoad--;
										if (timeToAlternateRoad == 0) {
												altRoadX = i;
												altRoadY = j;
										}
										if (endOfAlternateRoad == 0) {
												endX = i;
												endY = j;
										}

								} else {
										Stage [i, j].renderer.material = null;
										Stage [i, j].renderer.material = GetSurroundMat;
								}
						}
				}

				for (int i = altRoadX; i < endX; i++) {
						world [i, altRoadY] = 1;
						Stage [i, altRoadY].AddComponent<coinToken> ();
						Stage [i, altRoadY].renderer.material = Mats [0];
				}

				for (int j = altRoadY; j < endY; j++) {
						world [endX, j] = 1;
						Stage [endX, j].AddComponent<coinToken> ();
						Stage [endX, j].renderer.material = Mats [0];
				}

				SelfMovement = true;
				selfBegin = Time.timeSinceLevelLoad;
				speedUpTime = 1;
				Globals.Level++;
				System.GC.Collect ();
		}

		float ColorLast = 0;
		void UpdateColors ()
		{
				bool a = false;
				//if (Random.Range(0, 5) <= 1) a = true;
				for (int i = 0; i < 32; i++) {
						for (int j = 0; j < 32; j++) {
								if (world [i, j] == 1) {
										Stage [i, j].renderer.material = Mats [0];
								} else {
										if (!a) {
												Stage [i, j].renderer.material = null;
												Stage [i, j].renderer.material = GetSurroundMat;
										} else {
												Stage [i, j].renderer.material = null;
												Stage [i, j].renderer.material = Mats [Random.Range (1, Mats.Count)];
										}
								}
						}
				}
				System.GC.Collect ();
				ColorLast = Time.timeSinceLevelLoad;
		}

		Material GetSurroundMat {
				get {
						return Mats [Random.Range (1, Mats.Count)];
						Material newMat = new Material (Mats [1]);
						newMat.color = new Color (Mats [0].color.r * (Random.Range (5, 10) / 10f), Mats [0].color.g * (Random.Range (5, 10) / 10f), Mats [0].color.b * (Random.Range (5, 10) / 10f));
						return newMat;
				}
		}

		int[,] GetLastSq ()
		{
				if (world == null || world.Length == 0)
						return new int[4, 4];

				int x = 0, y = 0;
				for (int i = 0; i < 32; i++) {
						for (int j = 0; j < 32; j++) {
								if (world [i, j] == 1) {
										if (i > x)
												x = i;
										if (j > y)
												y = j;
								}
						}
				}

				int[,] lastsq = new int[4, 4];
				for (int i = 3; i >= 0; i--) {
						for (int j = 3; j >= 0; j--) {
								if (world [x - i, y - j] == 1) {
										lastsq [3 - i, 3 - j] = 1;
								}
						}
				}

				return lastsq;
		}

		public static Vector2 CubePos {
				get {
						return new Vector2 ()
            {
                x = GameObject.FindGameObjectWithTag("Player").transform.position.x / 2,
                y = GameObject.FindGameObjectWithTag("Player").transform.position.z / 2
            };
				}
		}
}
