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

//[ExecuteAlways]
public class AdaptiveTrack : MonoBehaviour {

	[Header("Outer Left Positions")]
	[ReadOnly]
	public Vector3 outerLeftTopFront = new Vector3 (-13, 1, 8);
	[ReadOnly]
	public Vector3 outerLeftTopBack = new Vector3 (-13, 1, 0);
	[ReadOnly]
	public Vector3 outerLeftBottomFront = new Vector3 (-13, -0.5f, 8);
	[ReadOnly]
	public Vector3 outerLeftBottomBack = new Vector3 (-13, -0.5f, 0);
	[ReadOnly]
	public Vector3 outerLeftTopFrontCol = new Vector3(-13, 6, 8);
	[ReadOnly]
	public Vector3 outerLeftTopBackCol = new Vector3(-13, 6, 0);

	[Header("Inner Left Positions")]
	[ReadOnly]
	public Vector3 innerLeftTopFront = new Vector3 (-12, 1, 8);
	[ReadOnly]
	public Vector3 innerLeftTopBack = new Vector3 (-12, 1, 0);
	[ReadOnly]
	public Vector3 innerLeftBottomFront = new Vector3 (-12, -0.5f, 8);
	[ReadOnly]
	public Vector3 innerLeftBottomBack = new Vector3 (-12, -0.5f, 0);
	[ReadOnly]
	public Vector3 innerLeftTopFrontCol = new Vector3(-12, 6, 8);
	[ReadOnly]
	public Vector3 innerLeftTopBackCol = new Vector3(-12, 6, 0);

	[Header("Middle Positions")]
	[ReadOnly]
	public Vector3 innerLeftMidFront = new Vector3 (-12, 0, 8);
	[ReadOnly]
	public Vector3 innerLeftMidBack = new Vector3 (-12, 0, 0);
	[ReadOnly]
	public Vector3 innerRightMidFront = new Vector3 (12, 0, 8);
	[ReadOnly]
	public Vector3 innerRightMidBack = new Vector3 (12, 0, 0);

	[Header("Inner Right Positions")]
	[ReadOnly]
	public Vector3 innerRightTopFront = new Vector3 (12, 1, 8);
	[ReadOnly]
	public Vector3 innerRightTopBack = new Vector3 (12, 1, 0);
	[ReadOnly]
	public Vector3 innerRightBottomFront = new Vector3 (12, -0.5f, 8);
	[ReadOnly]
	public Vector3 innerRightBottomBack = new Vector3 (12, -0.5f, 0);
	[ReadOnly]
	public Vector3 innerRightTopFrontCol = new Vector3(12, 6, 8);
	[ReadOnly]
	public Vector3 innerRightTopBackCol = new Vector3(12, 6, 0);

	[Header("Outer Right Positions")]
	[ReadOnly]
	public Vector3 outerRightTopFront = new Vector3 (13, 1, 8);
	[ReadOnly]
	public Vector3 outerRightTopBack = new Vector3 (13, 1, 0);
	[ReadOnly]
	public Vector3 outerRightBottomFront = new Vector3 (13, -0.5f, 8);
	[ReadOnly]
	public Vector3 outerRightBottomBack = new Vector3 (13, -0.5f, 0);
	[ReadOnly]
	public Vector3 outerRightTopFrontCol = new Vector3(13, 6, 8);
	[ReadOnly]
	public Vector3 outerRightTopBackCol = new Vector3(13, 6, 0);

	//[ReadOnly]
	public Material[] mats;
	#if UNITY_EDITOR
	[ReadOnly]
	public MeshConnectionsScript start, end;
	#endif


	#if UNITY_EDITOR

	void CheckForConnections () {
		if (!start) {
			start = GameObject.Find ("Start_Connection").GetComponent<MeshConnectionsScript> ();
		}
		if (!end) {
			end = GameObject.Find ("End_Connection").GetComponent<MeshConnectionsScript> ();
		}
	}

	public void GetConnections () {
		MeshConnectionsScript[] connections = FindObjectsOfType<MeshConnectionsScript>();

		for (int i = 0; i < connections.Length; i++) {
			if (connections [i].name == "Start_Connection") {
				start = connections [i];
			} else if (connections [i].name == "End_Connection") {
				end = connections [i];
			}
		}

		CreateCube ();
	}



	public void ClearConnections () {

		MeshFilter mf = GetComponent<MeshFilter> ();
		Mesh mesh = mf.sharedMesh;
		mesh.Clear ();

	}

	public void CreateCube () {

		//CheckForConnections ();

		MeshFilter mf = GetComponent<MeshFilter> ();
		Mesh mesh = mf.sharedMesh;

		// Vertices
		Vector3[] defaultVertices = new Vector3[] {
			// left front face
			outerLeftTopFront, // 0
			innerLeftTopFront, // 1
			outerLeftBottomFront, // 2
			innerLeftBottomFront, // 3

			// left back face
			innerLeftTopBack, // 4
			outerLeftTopBack, // 5
			innerLeftBottomBack, // 6
			outerLeftBottomBack, // 7

			// far left face
			outerLeftTopBack, // 8
			outerLeftTopFront, // 9
			outerLeftBottomBack, // 10
			outerLeftBottomFront, // 11

			// inner left face
			innerLeftTopFront, // 12
			innerLeftTopBack, // 13
			innerLeftMidFront, // 14
			innerLeftMidBack, // 15

			// left top face
			outerLeftTopBack, // 16
			innerLeftTopBack, // 17
			outerLeftTopFront, // 18
			innerLeftTopFront, // 19

			// bottom face
			outerLeftBottomFront, // 20
			outerRightBottomFront, // 21
			outerLeftBottomBack, // 22
			outerRightBottomBack, // 23

			//^//

			// right front face
			innerRightTopFront, // 24
			outerRightTopFront, // 25
			innerRightBottomFront, // 26
			outerRightBottomFront, // 27

			// right back face
			outerRightTopBack, // 28
			innerRightTopBack, // 29
			outerRightBottomBack, // 30
			innerRightBottomBack, // 31

			// far right face
			outerRightTopFront, // 32
			outerRightTopBack, // 33
			outerRightBottomFront, // 34
			outerRightBottomBack, // 35

			// inner right face
			innerRightTopBack, // 36
			innerRightTopFront, // 37
			innerRightMidBack, // 38
			innerRightMidFront, // 39

			// right top face
			innerRightTopBack, // 40
			outerRightTopBack, // 41
			innerRightTopFront, // 42
			outerRightTopFront, // 43

			//^//
			// mid front face
			innerLeftMidFront, // 44
			innerRightMidFront, // 45
			innerLeftBottomFront, // 46
			innerRightBottomFront, // 47

			// mid back face
			innerRightMidBack, // 48
			innerLeftMidBack, // 49
			innerRightBottomBack, // 50
			innerLeftBottomBack, // 51

			// mid top face
			innerLeftMidBack, // 52
			innerRightMidBack, // 53
			innerLeftMidFront, // 54
			innerRightMidFront // 55

		};

		Vector3[] adjustedVertices = new Vector3[] {
			// left front face
			start.outerLeftTopFront.position, // 0
			start.innerLeftTopFront.position, // 1
			start.outerLeftBottomFront.position, // 2
			start.innerLeftBottomFront.position, // 3

			// left back face
			end.innerLeftTopBack.position, // 4
			end.outerLeftTopBack.position, // 5
			end.innerLeftBottomBack.position, // 6
			end.outerLeftBottomBack.position, // 7

			// far left face
			end.outerLeftTopBack.position, // 8
			start.outerLeftTopFront.position, // 9
			end.outerLeftBottomBack.position, // 10
			start.outerLeftBottomFront.position, // 11

			// inner left face
			start.innerLeftTopFront.position, // 12
			end.innerLeftTopBack.position, // 13
			start.innerLeftMidFront.position, // 14
			end.innerLeftMidBack.position, // 15

			// left top face
			end.outerLeftTopBack.position, // 16
			end.innerLeftTopBack.position, // 17
			start.outerLeftTopFront.position, // 18
			start.innerLeftTopFront.position, // 19

			// bottom face
			start.outerLeftBottomFront.position, // 20
			start.outerRightBottomFront.position, // 21
			end.outerLeftBottomBack.position, // 22
			end.outerRightBottomBack.position, // 23

			//^//

			// right front face
			start.innerRightTopFront.position, // 24
			start.outerRightTopFront.position, // 25
			start.innerRightBottomFront.position, // 26
			start.outerRightBottomFront.position, // 27

			// right back face
			end.outerRightTopBack.position, // 28
			end.innerRightTopBack.position, // 29
			end.outerRightBottomBack.position, // 30
			end.innerRightBottomBack.position, // 31

			// far right face
			start.outerRightTopFront.position, // 32
			end.outerRightTopBack.position, // 33
			start.outerRightBottomFront.position, // 34
			end.outerRightBottomBack.position, // 35

			// inner right face
			end.innerRightTopBack.position, // 36
			start.innerRightTopFront.position, // 37
			end.innerRightMidBack.position, // 38
			start.innerRightMidFront.position, // 39

			// right top face
			end.innerRightTopBack.position, // 40
			end.outerRightTopBack.position, // 41
			start.innerRightTopFront.position, // 42
			start.outerRightTopFront.position, // 43

			//^//
			// mid front face
			start.innerLeftMidFront.position, // 44
			start.innerRightMidFront.position, // 45
			start.innerLeftBottomFront.position, // 46
			start.innerRightBottomFront.position, // 47

			// mid back face
			end.innerRightMidBack.position, // 48
			end.innerLeftMidBack.position, // 49
			end.innerRightBottomBack.position, // 50
			end.innerLeftBottomBack.position, // 51

			// mid top face
			end.innerLeftMidBack.position, // 52
			end.innerRightMidBack.position, // 53
			start.innerLeftMidFront.position, // 54
			start.innerRightMidFront.position // 55

		};

		// Triangles
		int[] mainTriangles = new int[] {
			
			// left front face
			0,2,3,
			3,1,0,

			// left back face
			4,6,7,
			7,5,4,

			// outer left face
			8,10,11,
			11,9,8,

			// inner left face
			12,14,15,
			15,13,12,

			// left top face
			16,18,19,
			19,17,16,

			// bottom face
			20,22,23,
			23,21,20,

			// right front face
			24,26,27,
			27,25,24,

			// right back face
			28,30,31,
			31,29,28,

			// outer right face
			32,34,35,
			35,33,32,

			// inner right face
			36,38,39,
			39,37,36,

			// right top face
			40,42,43,
			43,41,40
		};

		int[] subTriangles = new int[] {

			// mid front face
			44,46,47,
			47,45,44,

			// mid back face
			48,50,51,
			51,49,48,

			// mid top face
			52,54,55,
			55,53,52
		};

		// UVs
		Vector2[] uvs = new Vector2[] {
			
			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),


			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0),

			new Vector2 (0, 1),
			new Vector2 (0, 0),
			new Vector2 (1, 1),
			new Vector2 (1, 0)
		};

		mesh.Clear ();

		if (start && end) {
			mesh.vertices = adjustedVertices;
		} else {
			mesh.vertices = defaultVertices;
		}

		mesh.uv = uvs;
		mesh.subMeshCount = 2;

		GetComponent<MeshRenderer>().materials = mats;

		mesh.SetTriangles(mainTriangles, 0);
		mesh.SetTriangles(subTriangles, 1);

		mesh.RecalculateNormals();
		mesh.RecalculateBounds();

		MeshCollider meshCol = GetComponent<MeshCollider>();
		Mesh colMesh = meshCol.sharedMesh;

		if (colMesh == null)
        {
			colMesh = new Mesh();
			colMesh.name = "Generated Mesh";
        }

		colMesh.Clear();

		Vector3[] defaultColVertices = new Vector3[] {
			// left front face
			outerLeftTopFrontCol, // 0
			innerLeftTopFrontCol, // 1
			outerLeftBottomFront, // 2
			innerLeftBottomFront, // 3

			// left back face
			innerLeftTopBackCol, // 4
			outerLeftTopBackCol, // 5
			innerLeftBottomBack, // 6
			outerLeftBottomBack, // 7

			// far left face
			outerLeftTopBackCol, // 8
			outerLeftTopFront, // 9
			outerLeftBottomBack, // 10
			outerLeftBottomFront, // 11

			// inner left face
			innerLeftTopFrontCol, // 12
			innerLeftTopBackCol, // 13
			innerLeftMidFront, // 14
			innerLeftMidBack, // 15

			// left top face
			outerLeftTopBackCol, // 16
			innerLeftTopBackCol, // 17
			outerLeftTopFront, // 18
			innerLeftTopFront, // 19

			// bottom face
			outerLeftBottomFront, // 20
			outerRightBottomFront, // 21
			outerLeftBottomBack, // 22
			outerRightBottomBack, // 23

			//^//

			// right front face
			innerRightTopFrontCol, // 24
			outerRightTopFrontCol, // 25
			innerRightBottomFront, // 26
			outerRightBottomFront, // 27

			// right back face
			outerRightTopBackCol, // 28
			innerRightTopBackCol, // 29
			outerRightBottomBack, // 30
			innerRightBottomBack, // 31

			// far right face
			outerRightTopFrontCol, // 32
			outerRightTopBackCol, // 33
			outerRightBottomFront, // 34
			outerRightBottomBack, // 35

			// inner right face
			innerRightTopBackCol, // 36
			innerRightTopFrontCol, // 37
			innerRightMidBack, // 38
			innerRightMidFront, // 39

			// right top face
			innerRightTopBackCol, // 40
			outerRightTopBackCol, // 41
			innerRightTopFront, // 42
			outerRightTopFront, // 43

			//^//
			// mid front face
			innerLeftMidFront, // 44
			innerRightMidFront, // 45
			innerLeftBottomFront, // 46
			innerRightBottomFront, // 47

			// mid back face
			innerRightMidBack, // 48
			innerLeftMidBack, // 49
			innerRightBottomBack, // 50
			innerLeftBottomBack, // 51

			// mid top face
			innerLeftMidBack, // 52
			innerRightMidBack, // 53
			innerLeftMidFront, // 54
			innerRightMidFront // 55

		};

		Vector3[] adjustedColVertices = new Vector3[] {
			// left front face
			start.outerLeftTopFront.position + new Vector3(0,5,0), // 0
			start.innerLeftTopFront.position + new Vector3(0,5,0), // 1
			start.outerLeftBottomFront.position, // 2
			start.innerLeftBottomFront.position, // 3

			// left back face
			end.innerLeftTopBack.position + new Vector3(0,5,0), // 4
			end.outerLeftTopBack.position + new Vector3(0,5,0), // 5
			end.innerLeftBottomBack.position, // 6
			end.outerLeftBottomBack.position, // 7

			// far left face
			end.outerLeftTopBack.position + new Vector3(0,5,0), // 8
			start.outerLeftTopFront.position + new Vector3(0,5,0), // 9
			end.outerLeftBottomBack.position, // 10
			start.outerLeftBottomFront.position, // 11

			// inner left face
			start.innerLeftTopFront.position + new Vector3(0,5,0), // 12
			end.innerLeftTopBack.position + new Vector3(0,5,0), // 13
			start.innerLeftMidFront.position, // 14
			end.innerLeftMidBack.position, // 15

			// left top face
			end.outerLeftTopBack.position + new Vector3(0,5,0), // 16
			end.innerLeftTopBack.position + new Vector3(0,5,0), // 17
			start.outerLeftTopFront.position, // 18
			start.innerLeftTopFront.position, // 19

			// bottom face
			start.outerLeftBottomFront.position, // 20
			start.outerRightBottomFront.position, // 21
			end.outerLeftBottomBack.position, // 22
			end.outerRightBottomBack.position, // 23

			//^//

			// right front face
			start.innerRightTopFront.position + new Vector3(0,5,0), // 24
			start.outerRightTopFront.position + new Vector3(0,5,0), // 25
			start.innerRightBottomFront.position, // 26
			start.outerRightBottomFront.position, // 27

			// right back face
			end.outerRightTopBack.position + new Vector3(0,5,0), // 28
			end.innerRightTopBack.position + new Vector3(0,5,0), // 29
			end.outerRightBottomBack.position, // 30
			end.innerRightBottomBack.position, // 31

			// far right face
			start.outerRightTopFront.position + new Vector3(0,5,0), // 32
			end.outerRightTopBack.position + new Vector3(0,5,0), // 33
			start.outerRightBottomFront.position, // 34
			end.outerRightBottomBack.position, // 35

			// inner right face
			end.innerRightTopBack.position + new Vector3(0,5,0), // 36
			start.innerRightTopFront.position + new Vector3(0,5,0), // 37
			end.innerRightMidBack.position, // 38
			start.innerRightMidFront.position, // 39

			// right top face
			end.innerRightTopBack.position + new Vector3(0,5,0), // 40
			end.outerRightTopBack.position + new Vector3(0,5,0), // 41
			start.innerRightTopFront.position, // 42
			start.outerRightTopFront.position, // 43

			//^//
			// mid front face
			start.innerLeftMidFront.position, // 44
			start.innerRightMidFront.position, // 45
			start.innerLeftBottomFront.position, // 46
			start.innerRightBottomFront.position, // 47

			// mid back face
			end.innerRightMidBack.position, // 48
			end.innerLeftMidBack.position, // 49
			end.innerRightBottomBack.position, // 50
			end.innerLeftBottomBack.position, // 51

			// mid top face
			end.innerLeftMidBack.position, // 52
			end.innerRightMidBack.position, // 53
			start.innerLeftMidFront.position, // 54
			start.innerRightMidFront.position // 55

		};

		// Triangles
		int[] mainColTriangles = new int[] {
			
			// left front face
			0,2,3,
			3,1,0,

			// left back face
			4,6,7,
			7,5,4,

			// outer left face
			8,10,11,
			11,9,8,

			// inner left face
			12,14,15,
			15,13,12,

			// left top face
			16,18,19,
			19,17,16,

			// bottom face
			20,22,23,
			23,21,20,

			// right front face
			24,26,27,
			27,25,24,

			// right back face
			28,30,31,
			31,29,28,

			// outer right face
			32,34,35,
			35,33,32,

			// inner right face
			36,38,39,
			39,37,36,

			// right top face
			40,42,43,
			43,41,40,
			
			// mid front face
			44,46,47,
			47,45,44,

			// mid back face
			48,50,51,
			51,49,48,

			// mid top face
			52,54,55,
			55,53,52
		};

		if (start && end)
		{
			colMesh.vertices = adjustedColVertices;
		}
		else
		{
			colMesh.vertices = defaultColVertices;
		}

		colMesh.SetTriangles(mainColTriangles, 0);
		//colMesh.SetTriangles(subTriangles, 1);

		colMesh.RecalculateNormals();
		colMesh.RecalculateBounds();

		meshCol.sharedMesh = colMesh;
	}
	/*
	public bool CheckCollision () {
		ModularTrack[] tracks = GameObject.FindObjectsOfType<ModularTrack> ();

		for (int i = 0; i < tracks.Length; i++) {
			if (GetComponent<MeshCollider> ().bounds.Intersects (tracks [i].GetComponent<MeshCollider> ().bounds)) {
				if (tracks [i].endLink) {
					Debug.Log (tracks [i].name);
					GetComponent<MeshFilter> ().mesh.Clear ();
					return false;
				}
			}
		}

		return true;
	}
	*/

	public bool CheckCollision () {
		if (!GetComponent<MeshFilter> ().sharedMesh) {
			return false;
		}
		/*
		GameObject worldCenter = new GameObject ("Center");
		Instantiate (worldCenter, GetComponent<MeshFilter> ().sharedMesh.bounds.center, Quaternion.identity, worldCenter.transform);
		Transform centerObj = worldCenter.transform.GetChild (0); 

		worldCenter.transform.rotation = transform.rotation;
		worldCenter.transform.localScale = transform.localScale;

		Vector3 centerPos = centerObj.position;

		UnityEditor.EditorApplication.delayCall += () => { DestroyImmediate (worldCenter); };

		centerPos = centerPos + transform.position;
		*/
		Collider[] hitChecks = Physics.OverlapBox (GetComponent<MeshFilter> ().sharedMesh.bounds.center, GetComponent<MeshFilter> ().sharedMesh.bounds.size / 2.1f, transform.rotation);
		//Debug.Log (GetComponent<MeshFilter> ().mesh.bounds.size);
		//DebugValueChecks ();

		for (int i = 0; i < hitChecks.Length; i++) {
			if (hitChecks [i].transform == transform || !hitChecks [i].GetComponent<ModularTrack> ()) {
				//Debug.Log ("here");
				continue;
			}
			if (hitChecks [i].GetComponent<ModularTrack> ().endLink && hitChecks [i].GetComponent<ModularTrack> ().startLink) {
				//Debug.Log (gameObject.name + " at " + gameObject.transform.position + ", " + gameObject.transform.eulerAngles + " & " + hitChecks [i].name + " at " + hitChecks [i].transform.position + ", " + hitChecks [i].transform.eulerAngles);
				//Debug.Log (hitChecks [i].name);
				ClearConnections ();
				return false;
			}
		}

		return true;
	}
	#endif
}
