using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Animations;
using UnityEditor;

[System.Serializable]
public class TrackManagerWindow : SearchableEditorWindow {
    
	public GameObject mainTrack;
	public string toggleText = "", leftRightText = "", upDownText = "", leftRightSpecial = "", upDownSpecial = "";
	public int toggleInt = 0;
	public TrackManagerScript manager;
	public Vector2 scrollPosition = Vector2.zero;
	public Color buttonColor = Color.green, buttonColor2 = Color.cyan, buttonColor3 = Color.yellow, buttonColor4 = Color.red, buttonColor5 = Color.gray, buttonColor6 = Color.magenta;
	public Color lrColor, udColor;
	public Object guiSkinHolder;
	public int menuTab = 0, trackStyleTab = 0;
	public int straightTab = 0, leftRightTab = 0, upDownTab = 0, spiralLRT = 0, spiralUDT = 0, environmentSelect = -1;

	public float straightSlider = 1f;

	public string settingsLockCode = "";

	public int straightButtons = -1, turnButtons = -1, rampButtons = -1, spiralButtons = -1;

	public AdaptiveTrack adaptiveTrack;
	public bool trackActive = false, canLoop = true;
	public Color defaultColor;
	public GUIStyle buttonStyle, lableStyle;
	public GUISkin defaultSkin, customSkin;


	[MenuItem("Rocket Kart Racers/Open Track Manager Window", false, 26)]
	public static void DisplayWindow () {
		TrackManagerWindow window = GetWindow<TrackManagerWindow> ("Track Manager");
		window.minSize = new Vector2 (482f, 180f);
		if (!window.guiSkinHolder) {
			window.guiSkinHolder = Resources.Load<GUISkin> ("Button Images/CustomSkin");
		}
    }

    // Update is called once per frame
    void OnGUI ()  {
		
		if (!guiSkinHolder) {
			guiSkinHolder = Resources.Load<GUISkin> ("Button Images/CustomSkin");

			GUIUtility.ExitGUI ();
		}
		if (guiSkinHolder) {
			customSkin = (GUISkin)guiSkinHolder;
			buttonStyle = new GUIStyle (customSkin.button);
			lableStyle = new GUIStyle (customSkin.label);
		}

		defaultSkin = GUI.skin;
		defaultColor = GUI.backgroundColor;
			
		GUILayout.BeginArea (new Rect (0, 0, position.width, position.height));

		scrollPosition = GUILayout.BeginScrollView (scrollPosition, GUILayout.Width (position.width), GUILayout.Height (position.height));
		menuTab = GUILayout.Toolbar (menuTab, new string[] { "Tracks", "Environment", "Settings" });

		if (menuTab == 0) {
			settingsLockCode = "";
			PathwayDisplay ();
		} else if (menuTab == 1) {
			settingsLockCode = "";
			EnvironmentDisplay ();
		} else {
			SettingsDisplay ();
		}
		GUILayout.EndScrollView ();
		GUILayout.EndArea ();
		

    }

	void Update () {
		Repaint ();
	}

	void EnvironmentDisplay () {
		GUILayout.BeginHorizontal ();
		GUILayout.FlexibleSpace ();
		GUILayout.Label ("Click on an Object to place it in the Scene", EditorStyles.boldLabel);
		GUILayout.FlexibleSpace ();
		GUILayout.EndHorizontal ();

		GUILayout.BeginHorizontal ();
		GUILayout.FlexibleSpace ();
		GameObject[] environmentObjs = Resources.LoadAll<GameObject> ("Environment");
		string[] environmentNames = new string[environmentObjs.Length];
		for (int i = 0; i < environmentObjs.Length; i++) {
			environmentNames [i] = environmentObjs [i].name;
		}
		environmentSelect = GUILayout.SelectionGrid (environmentSelect, environmentNames, 6, GUILayout.Width (position.width * 19f / 20f));

		if (environmentSelect != -1) {
			GameObject newObj = GameObject.Instantiate (Resources.Load<GameObject> ("Environment/" + environmentNames [environmentSelect]), Vector3.zero, Quaternion.identity);
			newObj.name = newObj.name.Replace ("(Clone)", "");
			Undo.RegisterCreatedObjectUndo (newObj, "New Enviornment Object Instantiated");
			if (newObj.GetComponent<ColorChanger> ()) {
				newObj.GetComponent<ColorChanger> ().ConvertMaterials ();
			}
			Selection.activeTransform = newObj.transform;
			SceneView.lastActiveSceneView.FrameSelected ();
			environmentSelect = -1;
		}

		GUILayout.FlexibleSpace ();
		GUILayout.EndHorizontal ();
	}
		
	void PathwayDisplay () {
		if (Selection.transforms.Length == 1 && Selection.transforms [0].GetComponent<ModularTrack> ()) {

			float scaler2x2 = (position.height * 7f / 12f < position.width * 2f / 11f) ? position.height * 7f / 12f : position.width * 2f / 11f;
			float width3x = (position.height * 7f / 8f < position.width * 3f / 11f) ? position.height * 7f / 8f : position.width * 3f / 11f;
			float height1x = (position.height * 7f / 24f < position.width * 1f / 11f) ? position.height * 7f / 24f : position.width * 1f / 11f;

			GUILayout.BeginVertical ();
			GUILayout.BeginHorizontal ();
			GUILayout.FlexibleSpace ();
			GUILayout.BeginVertical ();

			// Turns
			GUILayout.Label ("Straights", lableStyle, GUILayout.Width(scaler2x2));
			if (GUILayout.Button (new GUIContent ("Find Start", "Finds and focuses on the starting track piece."), GUILayout.Width (scaler2x2), GUILayout.Height (21f))) {
				Selection.activeTransform = GameObject.FindGameObjectWithTag ("StartFinish").transform;
				SceneView.lastActiveSceneView.FrameSelected ();
			}

			GUI.backgroundColor = buttonColor6;

			GUIContent[] straightsContent = new GUIContent[] {
				new GUIContent ("Small", Resources.Load<Texture> ("Button Images/straight_small"), TrackToolTip ("straight", "small")),
				new GUIContent ("Medium", Resources.Load<Texture> ("Button Images/straight_medium"), TrackToolTip ("straight", "medium")),
				new GUIContent ("Long", Resources.Load<Texture> ("Button Images/straight_long"), TrackToolTip ("straight", "long")),
				new GUIContent ("XL", Resources.Load<Texture> ("Button Images/straight_xl"), TrackToolTip ("straight", "xl"))
			};

			string[] straightTexts = new string[] {
				"Straights/Straight_Small",
				"Straights/Straight_Medium",
				"Straights/Straight_Long",
				"Straights/Straight_XL"
			};

			straightButtons = GUILayout.SelectionGrid (straightButtons, straightsContent, 2, buttonStyle, GUILayout.Width(scaler2x2), GUILayout.Height(scaler2x2));
			if (straightButtons != -1) {
				toggleText = straightTexts [straightButtons];
				AddTrack (Selection.transforms [0].GetComponent<ModularTrack> ());
				straightButtons = -1;
			}

			GUILayout.EndVertical ();

			GUILayout.FlexibleSpace ();


			GUILayout.BeginVertical ();

			// Turns
			GUILayout.Label ("Turns", lableStyle, GUILayout.Width(width3x));

			GUI.backgroundColor = defaultColor;
			leftRightTab = GUILayout.Toolbar (leftRightTab, CreateArrows ("spiral track", "Left"), GUILayout.Width(width3x));
			if (leftRightTab == 0) {
				GUI.backgroundColor = buttonColor;
				leftRightText = "left";
			} else {
				GUI.backgroundColor = buttonColor2;
				leftRightText = "right";
			}

			GUIContent[] turnsContent = new GUIContent[] {
				new GUIContent ("15°", Resources.Load<Texture> ("Button Images/15deg_" + leftRightText), TrackToolTip ("turn", leftRightText, "15°", false)),
				new GUIContent ("30°", Resources.Load<Texture> ("Button Images/30deg_" + leftRightText), TrackToolTip ("turn", leftRightText, "30°", false)),
				new GUIContent ("45°", Resources.Load<Texture> ("Button Images/45deg_" + leftRightText), TrackToolTip ("turn", leftRightText, "45°", false)),
				new GUIContent ("60°", Resources.Load<Texture> ("Button Images/60deg_" + leftRightText), TrackToolTip ("turn", leftRightText, "60°", false)),
				new GUIContent ("90°", Resources.Load<Texture> ("Button Images/90deg_" + leftRightText), TrackToolTip ("turn", leftRightText, "90°", false)),
				new GUIContent ("180°", Resources.Load<Texture> ("Button Images/180deg"), TrackToolTip ("turn", leftRightText, "180°", false))
			};

			string[] turnTexts = new string[] {
				(leftRightTab == 0) ? "Turns/Turn_Left_15deg" : "Turns/Turn_Right_15deg",
				(leftRightTab == 0) ? "Turns/Turn_Left_30deg" : "Turns/Turn_Right_30deg",
				(leftRightTab == 0) ? "Turns/Turn_Left_45deg" : "Turns/Turn_Right_45deg",
				(leftRightTab == 0) ? "Turns/Turn_Left_60deg" : "Turns/Turn_Right_60deg",
				(leftRightTab == 0) ? "Turns/Turn_Left_90deg" : "Turns/Turn_Right_90deg",
				(leftRightTab == 0) ? "Turns/Turn_Left_180deg" : "Turns/Turn_Right_180deg"
			};

			turnButtons = GUILayout.SelectionGrid (turnButtons, turnsContent, 3, buttonStyle, GUILayout.Width(width3x), GUILayout.Height(scaler2x2));
			if (turnButtons != -1) {
				toggleText = turnTexts [turnButtons];
				AddTrack (Selection.transforms [0].GetComponent<ModularTrack> ());
				turnButtons = -1;
			}

			GUILayout.EndVertical ();

			GUILayout.FlexibleSpace ();

			GUILayout.BeginVertical ();

			// Ramps
			GUILayout.Label ("Ramps", lableStyle, GUILayout.Width(scaler2x2));

			GUI.backgroundColor = defaultColor;
			upDownTab = GUILayout.Toolbar (upDownTab, CreateArrows ("spiral track", "Up"), GUILayout.Width(scaler2x2));
			if (upDownTab == 0) {
				GUI.backgroundColor = buttonColor3;
				upDownText = "up";
			} else {
				GUI.backgroundColor = buttonColor4;
				upDownText = "down";
			}

			GUIContent[] rampsContent = new GUIContent[] {
				new GUIContent ("15°", Resources.Load<Texture> ("Button Images/ramp_15deg_" + upDownText), TrackToolTip ("ramp", upDownText + "wards", "15°", false)),
				new GUIContent ("30°", Resources.Load<Texture> ("Button Images/ramp_30deg_" + upDownText), TrackToolTip ("ramp", upDownText + "wards", "30°", false)),
				new GUIContent ("45°", Resources.Load<Texture> ("Button Images/ramp_45deg_" + upDownText), TrackToolTip ("ramp", upDownText + "wards", "45°", false)),
				new GUIContent ("60°", Resources.Load<Texture> ("Button Images/ramp_60deg_" + upDownText), TrackToolTip ("ramp", upDownText + "wards", "60°", false))
			};

			string[] rampTexts = new string[] {
				(upDownTab == 0) ? "Ramps/Ramp_Up_15deg" : "Ramps/Ramp_Down_15deg",
				(upDownTab == 0) ? "Ramps/Ramp_Up_30deg" : "Ramps/Ramp_Down_30deg",
				(upDownTab == 0) ? "Ramps/Ramp_Up_45deg" : "Ramps/Ramp_Down_45deg",
				(upDownTab == 0) ? "Ramps/Ramp_Up_60deg" : "Ramps/Ramp_Down_60deg"
			};

			rampButtons = GUILayout.SelectionGrid (rampButtons, rampsContent, 2, buttonStyle, GUILayout.Width(scaler2x2), GUILayout.Height(scaler2x2));
			if (rampButtons != -1) {
				toggleText = rampTexts [rampButtons];
				AddTrack (Selection.transforms [0].GetComponent<ModularTrack> ());
				rampButtons = -1;
			}

			GUILayout.EndVertical ();

			// Special

			GUILayout.FlexibleSpace ();
			GUILayout.BeginVertical ();
			GUILayout.BeginVertical ();

			// Ramps
			GUILayout.Label ("Spirals & Items", lableStyle);

			GUILayout.BeginHorizontal ();
			GUI.backgroundColor = defaultColor;
			spiralLRT = GUILayout.Toolbar (spiralLRT, CreateArrows ("spiral track", "Left"));
			if (spiralLRT == 0) {
				lrColor = buttonColor;
				leftRightSpecial = "left";
			} else {
				lrColor = buttonColor2;
				leftRightSpecial = "right";
			}

			GUI.backgroundColor = defaultColor;
			spiralUDT = GUILayout.Toolbar (spiralUDT, CreateArrows ("spiral track", "Up"));
			if (spiralUDT == 0) {
				udColor = buttonColor3;
				upDownSpecial = "up";
			} else {
				udColor = buttonColor4;
				upDownSpecial = "down";
			}

			Color tempColor = (lrColor + udColor) / 2f;

			GUI.backgroundColor = tempColor;

			GUILayout.EndHorizontal ();

			GUILayout.EndVertical ();
			GUILayout.BeginVertical ();

			GUIContent[] spiralsContent = new GUIContent[] {
				new GUIContent ("Full", Resources.Load<Texture> ("Button Images/spiral_full_" + leftRightSpecial + "_" + upDownSpecial), TrackToolTip ("spiral", upDownSpecial + "wards", leftRightSpecial, "full")),
				new GUIContent ("Half", Resources.Load<Texture> ("Button Images/spiral_half_" + leftRightSpecial + "_" + upDownSpecial), TrackToolTip ("spiral", upDownSpecial + "wards", leftRightSpecial, "half")),
				new GUIContent ("Quarter", Resources.Load<Texture> ("Button Images/spiral_quarter_" + leftRightSpecial + "_" + upDownSpecial), TrackToolTip ("spiral", upDownSpecial + "wards", leftRightSpecial, "quarter")),
				new GUIContent ("Item Box", Resources.Load<Texture> ("Button Images/ItemBox"), "Creates a small straight piece with an item box. Item boxes can be added/moved using the attached script.")
			};

			string[] spiralTexts = new string[] {
				(spiralLRT == 0) ? ((spiralUDT == 0) ? "Spirals/Spiral_Left_Up" : "Spirals/Spiral_Left_Down") : ((spiralUDT == 0) ? "Spirals/Spiral_Right_Up" : "Spirals/Spiral_Right_Down"),
				(spiralLRT == 0) ? ((spiralUDT == 0) ? "Spirals/Spiral_Half_Left_Up" : "Spirals/Spiral_Half_Left_Down") : ((spiralUDT == 0) ? "Spirals/Spiral_Half_Right_Up" : "Spirals/Spiral_Half_Right_Down"),
				(spiralLRT == 0) ? ((spiralUDT == 0) ? "Spirals/Spiral_Quarter_Left_Up" : "Spirals/Spiral_Quarter_Left_Down") : ((spiralUDT == 0) ? "Spirals/Spiral_Quarter_Right_Up" : "Spirals/Spiral_Quarter_Right_Down"),
				"Special/Item Track"
			};

			spiralButtons = GUILayout.SelectionGrid (spiralButtons, spiralsContent, 3, buttonStyle, GUILayout.Width(width3x), GUILayout.Height(scaler2x2));
			if (spiralButtons != -1) {
				toggleText = spiralTexts [spiralButtons];
				AddTrack (Selection.transforms [0].GetComponent<ModularTrack> ());
				spiralButtons = -1;
			}

			//GUI.backgroundColor = defaultColor;
			//GUILayout.Label ("Loop Display", lableStyle);
			trackStyleTab = 0; //GUILayout.Toolbar (trackStyleTab, new string[] { "On", "Off" }, GUILayout.Width(width3x));
			if (!adaptiveTrack) {
				adaptiveTrack = GameObject.FindObjectOfType<AdaptiveTrack> ();
			}
			if (trackStyleTab == 0) {
				adaptiveTrack.GetConnections ();
				trackActive = adaptiveTrack.CheckCollision ();
			} else {
				adaptiveTrack.ClearConnections ();
				trackActive = false;
			}

			GUILayout.EndVertical ();
			GUILayout.EndVertical ();

			GUILayout.FlexibleSpace ();
			GUILayout.EndHorizontal ();
			GUILayout.EndVertical ();

			/*
			if (Selection.transforms [0].name.Contains ("Straight")) {
				GUILayout.Label ("Straight Piece Length", lableStyle);
				GUILayout.BeginHorizontal ();
				GUILayout.FlexibleSpace ();
				straightSlider = Selection.transforms [0].localScale.z;
				straightSlider = EditorGUILayout.Slider (straightSlider, 0.1f, 10f);
				Selection.transforms [0].localScale = new Vector3 (Selection.transforms [0].localScale.x, Selection.transforms [0].localScale.y, straightSlider);
				GUILayout.FlexibleSpace ();
				GUILayout.EndHorizontal ();
			}*/
			GUILayout.FlexibleSpace ();

		} else if (Selection.transforms.Length > 1) {
			GUI.backgroundColor = defaultColor;
			EditorGUILayout.BeginVertical ();
			GUILayout.FlexibleSpace ();
			EditorGUILayout.BeginHorizontal ();
			GUILayout.FlexibleSpace ();
			GUILayout.Label ("Too many tracks selected. Please select a single track piece to begin editing.", lableStyle);
			GUILayout.FlexibleSpace ();
			EditorGUILayout.EndHorizontal ();
			GUILayout.FlexibleSpace ();
			EditorGUILayout.EndVertical ();
		} else {
			GUI.backgroundColor = defaultColor;
			EditorGUILayout.BeginVertical ();
			GUILayout.FlexibleSpace ();
			EditorGUILayout.BeginHorizontal ();
			GUILayout.FlexibleSpace ();
			GUILayout.Label ("Please select a track piece to begin editing.", lableStyle);
			GUILayout.FlexibleSpace ();
			EditorGUILayout.EndHorizontal ();
			GUILayout.FlexibleSpace ();
			EditorGUILayout.EndVertical ();
		}
	}

	void SettingsDisplay () {

		if (settingsLockCode != "3118") {
			GUILayout.BeginHorizontal ();
			GUILayout.FlexibleSpace ();
			GUILayout.BeginVertical ();
			GUILayout.FlexibleSpace ();
			GUILayout.Label ("Enter Code");
			GUIStyle passwordStyle = new GUIStyle (EditorStyles.textField);
			passwordStyle.alignment = TextAnchor.MiddleCenter;
			settingsLockCode = GUILayout.PasswordField (settingsLockCode, '*', 4, passwordStyle);
			GUILayout.FlexibleSpace ();
			GUILayout.EndVertical ();
			GUILayout.FlexibleSpace ();
			GUILayout.EndHorizontal ();
		} else {
		
			GUILayout.Label ("GUISkin", EditorStyles.boldLabel);
			guiSkinHolder = EditorGUILayout.ObjectField ("Style Skin", guiSkinHolder, typeof(GUISkin), false);
			GUILayout.Label ("Button Settings", EditorStyles.boldLabel);
			buttonColor = EditorGUILayout.ColorField ("Button Color 1", buttonColor);
			buttonColor2 = EditorGUILayout.ColorField ("Button Color 2", buttonColor2);
			buttonColor3 = EditorGUILayout.ColorField ("Button Color 3", buttonColor3);
			buttonColor4 = EditorGUILayout.ColorField ("Button Color 4", buttonColor4);
			buttonColor5 = EditorGUILayout.ColorField ("Button Color 5", buttonColor5);
			//buttonColor6 = EditorGUILayout.ColorField ("Button Color 6", buttonColor6);
			//buttonColor7 = EditorGUILayout.ColorField ("Button Color 7", buttonColor7);
		
			/* For Future Reference //
			if (GUILayout.Button (AssetPreview.GetAssetPreview (Selection.activeObject))) {
				Texture2D newTexture = AssetPreview.GetAssetPreview (Selection.activeObject);
				byte[] bytes = newTexture.EncodeToPNG ();
				File.WriteAllBytes ("Assets/Custom Track Pieces/"+Selection.activeObject.name+" Texture.png", bytes);
				AssetDatabase.Refresh ();
			}*/
		}
	}

	public void AddTrack (ModularTrack selectedTrack) {
		GameObject newTrackObj = GameObject.Instantiate (NewTrack (toggleText), selectedTrack.track.pivotObject.position, selectedTrack.track.pivotObject.rotation);
		Undo.RegisterCreatedObjectUndo (newTrackObj, "Added Track Piece.");
		ModularTrack newTrack = newTrackObj.GetComponent<ModularTrack>();
		PrefabUtility.RecordPrefabInstancePropertyModifications (newTrackObj);
		Undo.RecordObject (newTrack, "Added Track Properties");
		newTrackObj.name = newTrackObj.name.Replace ("(Clone)", "");
		newTrackObj.transform.parent = selectedTrack.transform.parent;
		newTrackObj.transform.SetSiblingIndex (selectedTrack.transform.GetSiblingIndex () + 1);

		ModularTrack tempTrackEnd = selectedTrack.endLink;

		ModularTrack[] myTracks;

		if (tempTrackEnd) {
			myTracks = new ModularTrack[] {
				selectedTrack,
				newTrack,
				tempTrackEnd
			};
		} else {
			myTracks = new ModularTrack[] {
				selectedTrack,
				newTrack
			};
		}

		//Undo.RecordObjects (myTracks, "Link and ParentConstraint Values changed");

		// Update prior links
		PrefabUtility.RecordPrefabInstancePropertyModifications (selectedTrack.gameObject);
		Undo.RecordObject (selectedTrack, "Track Piece Being Added to.");
		selectedTrack.endLink = newTrack;


		PrefabUtility.RecordPrefabInstancePropertyModifications (newTrackObj);
		Undo.RecordObject (newTrack, "Added Track Properties");
		newTrack.startLink = selectedTrack;

		// Undate endlink
		newTrack.endLink = tempTrackEnd;

		// Update endlink if it exists
		if (tempTrackEnd) {
			PrefabUtility.RecordPrefabInstancePropertyModifications (tempTrackEnd.gameObject);
			Undo.RecordObject (tempTrackEnd, "Added Additional Track Properties");
			tempTrackEnd.startLink = newTrack;
		}

		// Update the parent constraints for the tracks
		AssignParentConstraints (myTracks);

		if (!newTrack.CheckCollision() || !newTrack.CollisionCheckLoop(newTrack)) {
			UnityEditor.EditorApplication.delayCall += () => { DestroyImmediate (newTrackObj); };
			if (tempTrackEnd) {
				if (EditorUtility.DisplayDialog ("Track Overlap Error", "Cannont place track piece here because it causes an intersection farther along the track.", "Ok")) {
					// Makes student aware of error
				}
			} else {
				if (EditorUtility.DisplayDialog("Track Overlap Error", "Cannont place track on top of existing track.", "Ok")) {
					// Makes student aware of error
				}
			}
		} else {
			if (newTrack.GetComponent<ColorChanger> ()) {
				newTrack.GetComponent<ColorChanger> ().ConvertMaterials ();
			}
			if (newTrack.GetComponentInChildren<ColorChanger> ()) {
				foreach (Transform child in newTrack.transform) {
					if (child.GetComponent<ColorChanger> ()) {
						child.GetComponent<ColorChanger> ().ConvertMaterials ();
					}
				}
			}
			Selection.activeTransform = newTrack.transform;
			SceneView.lastActiveSceneView.FrameSelected ();
			//Undo.RegisterCreatedObjectUndo (newTrackObj, "New Track Piece Spawned");
		}
	}

	public void AddTurn (ModularTrack selectedTrack, string direction, string degrees) {

		ModularTrack tempTrackEnd = selectedTrack.endLink;
		direction = (direction == "left") ? "Left" : "Right";
		string otherDirection = (direction == "Left") ? "Right" : "Left";

		// Spawn each track piece of the turn and assign a ModularTrack variable
		GameObject turnStart = GameObject.Instantiate (NewTrack ("Turns/Turn_" + direction + "_" + degrees + "deg"), selectedTrack.track.pivotObject.position, selectedTrack.track.pivotObject.rotation);
		ModularTrack turnStartTrack = turnStart.GetComponent<ModularTrack>();
		Undo.RegisterCreatedObjectUndo (turnStart, "Turn Track Spawned - 1");

		GameObject turnMiddle = GameObject.Instantiate (NewTrack ("Straights/Straight_Small"), turnStartTrack.track.pivotObject.position, turnStartTrack.track.pivotObject.rotation);
		ModularTrack turnMiddleTrack = turnMiddle.GetComponent<ModularTrack>();
		Undo.RegisterCreatedObjectUndo (turnMiddle, "Turn Track Spawned - 2");

		GameObject turnEnd = GameObject.Instantiate (NewTrack ("Turns/Turn_" + otherDirection + "_" + degrees + "deg"), turnMiddleTrack.track.pivotObject.position, turnMiddleTrack.track.pivotObject.rotation);
		ModularTrack turnEndTrack = turnEnd.GetComponent<ModularTrack>();
		Undo.RegisterCreatedObjectUndo (turnEnd, "Turn Track Spawned - 3");

		// Update prior link
		selectedTrack.endLink = turnStartTrack;
		turnStartTrack.startLink = selectedTrack;

		// Update new track links
		turnStartTrack.endLink = turnMiddleTrack;
		turnMiddleTrack.startLink = turnStartTrack;

		turnMiddleTrack.endLink = turnEndTrack;
		turnEndTrack.startLink = turnMiddleTrack;

		// Undate endlink
		turnEndTrack.endLink = tempTrackEnd;
		tempTrackEnd.startLink = turnEndTrack;

		ModularTrack[] tracks = new ModularTrack[] {
			selectedTrack,
			turnStartTrack,
			turnMiddleTrack,
			turnEndTrack,
			tempTrackEnd
		};

		AssignParentConstraints (tracks);

	}

	public void AssignParentConstraints (ModularTrack[] tracks) {

		for (int i = 1; i < tracks.Length; i++) {
			if (tracks [i].GetComponent<ParentConstraint>().sourceCount > 0) {
				tracks [i].GetComponent<ParentConstraint> ().RemoveSource (0);
			}
			// Adjust Positions - This is done first because constraints are bugged in that they are not executed at the correct time.
			// The positions need to be updated first in order for the code to run propperly
			tracks [i].AdjustLinkPositions (tracks [i]);
		}

		for (int i = 1; i < tracks.Length; i++) {
			// Adjust Constraints
			ConstraintSource startSource = new ConstraintSource ();
			startSource.sourceTransform = tracks[i-1].track.pivotObject;
			startSource.weight = 1;

			tracks [i].GetComponent<ParentConstraint>().AddSource (startSource);
			tracks [i].GetComponent<ParentConstraint>().locked = true;
			tracks [i].GetComponent<ParentConstraint>().constraintActive = true;
		}
	}



	public GameObject NewTrack (string trackName) {
		UnityEngine.Object trackPiece = Resources.Load (trackName);
		return (GameObject)trackPiece;
	}

	GUIContent[] CreateArrows (string type, string direction) {
		string other = (direction == "Left") ? "Right" : "Down";

		if (type == "spiral track") {
			GUIContent[] special = new GUIContent[] {
				new GUIContent (Resources.Load<Texture> ("Button Images/" + direction + "Arrow"), DirectionToolTip (type, direction)),
				new GUIContent (Resources.Load<Texture> ("Button Images/" + other + "Arrow"), DirectionToolTip (type, other))
			};
			return special;
		}

		GUIContent[] content = new GUIContent[] {
			new GUIContent (" " + direction, Resources.Load<Texture> ("Button Images/" + direction + "Arrow"), DirectionToolTip (type, direction)),
			new GUIContent (" " + other, Resources.Load<Texture> ("Button Images/" + other + "Arrow"), DirectionToolTip (type, other))
		};
		return content;
	}

	string DirectionToolTip (string type, string direction) {

		direction = direction.ToLower ();

		return "Switches the " + type + " direction to " + direction + ".";
	}

	string TrackToolTip (string type, string direction, string degree, bool looped) {
		string end = (looped) ? " This piece is mirrored to allow the track to remain connected." : "";
		string aOrAn = (direction.StartsWith ("a") || direction.StartsWith ("e") || direction.StartsWith ("i") || direction.StartsWith ("o") || direction.StartsWith ("u")) ? "an " : "a ";
		return "Creates " + aOrAn + direction + " " + type + " piece at a " + degree + " angle." + end;
	}

	string TrackToolTip (string type, string rampDir, string turnDir, string size) {
		return "Creates a " + size + " " + type + " piece going " + rampDir + " and to the " + turnDir + ".";
	}

	string TrackToolTip (string type, string size) {
		string aOrAn = (type.StartsWith ("a") || type.StartsWith ("e") || type.StartsWith ("i") || type.StartsWith ("o") || type.StartsWith ("u") || type.StartsWith ("x")) ? "an " : "a ";
		return "Creates " + aOrAn + size + " " + type + " piece.";
	}
}
