﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

[PrimaryObject]
public class Tinkercad : MonoBehaviour {

	public bool reset = false;
	[HideInInspector]
	public bool hiddenChildren = true;
	int children = 0;

	[HideInInspector]
	public bool getColors = false, setColors = false;

	[HideInInspector]
	public Material colorChangeMat;

	[HideInInspector]
	public int totalMats = 1;


	public Color color1;
	[VariableToggle("totalMats", 2)]
	public Color color2;
	[VariableToggle("totalMats", 3)]
	public Color color3;
	[VariableToggle("totalMats", 4)]
	public Color color4;
	[VariableToggle("totalMats", 5)]
	public Color color5;
	[VariableToggle("totalMats", 6)]
	public Color color6;
	[VariableToggle("totalMats", 7)]
	public Color color7;
	[VariableToggle("totalMats", 8)]
	public Color color8;
	[VariableToggle("totalMats", 9)]
	public Color color9;
	[VariableToggle("totalMats", 10)]
	public Color color10;
	[VariableToggle("totalMats", 11)]
	public Color color11;
	[VariableToggle("totalMats", 12)]
	public Color color12;
	[VariableToggle("totalMats", 13)]
	public Color color13;
	[VariableToggle("totalMats", 14)]
	public Color color14;
	[VariableToggle("totalMats", 15)]
	public Color color15;
	[VariableToggle("totalMats", 16)]
	public Color color16;
	[VariableToggle("totalMats", 17)]
	public Color color17;
	[VariableToggle("totalMats", 18)]
	public Color color18;
	[VariableToggle("totalMats", 19)]
	public Color color19;
	[VariableToggle("totalMats", 20)]
	public Color color20;

	[HideInInspector]
	public List<Color> totalColors;

	[HideInInspector]
	public MeshRenderer[] rends;

	void Awake () {
		TinkerIt ();
		PrepAndSet();
		if (GetComponent<Collider> ()) {
			GetComponent<Collider> ().isTrigger = true;
		}
	}

	void OnValidate () {
		if (gameObject.activeInHierarchy) {
			TinkerIt ();
			PrepAndSet ();
		}
		HideYoKids ();
	}

	void TinkerIt () {
		if ((transform.childCount != children || reset) && transform.childCount != 0) {
			children = 0;
			for (int i = 0; i < transform.childCount; i++) {
				if (transform.GetChild (i).name.Contains ("group")) {
					transform.GetChild (i).localEulerAngles = new Vector3 (-90f, 0f, 0f);
					if (!transform.GetChild (i).gameObject.GetComponent<Collider> () && transform.GetChild (i).gameObject.GetComponent<MeshRenderer> ()) {
						transform.GetChild (i).gameObject.AddComponent<MeshCollider> ();
					}
					children++;
				}
			}
		}
		reset = false;
	}

	// Preps the Asset for color changing fun!
	void PrepAndSet () {
		
		// Get the Mesh Renderers of the children
		rends = transform.GetComponentsInChildren<MeshRenderer> ();
		int actualRends = 0;

		// Make sure the renderers belong to the Tinkercad object
		foreach (MeshRenderer mesh in rends) {
			if (mesh.name.Contains ("group")) {
				actualRends++;
			}
		}

		// Throw an error if there are no mesh renderers
		if (rends.Length <= 0) {
			Debug.LogError ("The" + gameObject.name + " does not have any children with a Mesh Renderer. The Tinkercad script will not work without Mesh Renderers. Please remove this script from the GameObject.");
		}

		// Get the number of materials
		totalMats = actualRends;

		// Get/Set the ColorChangerMat if it's not already set (Editor Only)
		GetColorChangerMat ();

		// Don't execute the rest of the code of the colorChangeMat has not been assigned
		if (!colorChangeMat) {
			setColors = false;
			return;
		} else {
			setColors = true;
		}

		// Get the color value from old materials and assign them to the array copy, then to the actual materials
		if (setColors && totalMats <= 20) {
			for (int i = 0; i < totalMats; i++) {
				if (rends [i].name.Contains ("group")) {
					if (rends [i].sharedMaterial.name != "ColorChangerMat") {
						GetSpecificColor (i);
						if (colorChangeMat)
							rends [i].sharedMaterial = colorChangeMat;
					}
				}
			}
			ChangeColors ();
		} else if (totalMats > 20) {
			Debug.LogError ("The " + gameObject.name + " has too many materials on its children, so the Tinkercad script will not work. Please remove this script from the GameObject.");
		}
	}

	void GetSpecificColor (int i) {
		if (i > 19)
			return;

		if (i == 0) {
			color1 = rends[i].sharedMaterial.color;
		} else if (i == 1) {
			color2 = rends[i].sharedMaterial.color;
		} else if (i == 2) {
			color3 = rends[i].sharedMaterial.color;
		} else if (i == 3) {
			color4 = rends[i].sharedMaterial.color;
		} else if (i == 4) {
			color5 = rends[i].sharedMaterial.color;
		} else if (i == 5) {
			color6 = rends[i].sharedMaterial.color;
		} else if (i == 6) {
			color7 = rends[i].sharedMaterial.color;
		} else if (i == 7) {
			color8 = rends[i].sharedMaterial.color;
		} else if (i == 8) {
			color9 = rends[i].sharedMaterial.color;
		} else if (i == 9) {
			color10 = rends[i].sharedMaterial.color;
		} else if (i == 10) {
			color11 = rends[i].sharedMaterial.color;
		} else if (i == 11) {
			color12 = rends[i].sharedMaterial.color;
		} else if (i == 12) {
			color13 = rends[i].sharedMaterial.color;
		} else if (i == 13) {
			color14 = rends[i].sharedMaterial.color;
		} else if (i == 14) {
			color15 = rends[i].sharedMaterial.color;
		} else if (i == 15) {
			color16 = rends[i].sharedMaterial.color;
		} else if (i == 16) {
			color17 = rends[i].sharedMaterial.color;
		} else if (i == 17) {
			color18 = rends[i].sharedMaterial.color;
		} else if (i == 18) {
			color19 = rends[i].sharedMaterial.color;
		} else if (i == 19) {
			color20 = rends[i].sharedMaterial.color;
		}
	}

	void ChangeColors () {
		totalColors = new List<Color> ();
		totalColors.Clear ();
		for (int i = 0; i < totalMats; i++) {
			// Create a Property Block to change a material's color
			MaterialPropertyBlock propBlock = new MaterialPropertyBlock ();

			// Get the current value of the material properties
			rends[i].GetPropertyBlock (propBlock, 0);

			// Set the new value
			if (i == 0) {
				propBlock.SetColor ("_Color", color1);
				totalColors.Add (color1);
			} else if (i == 1) {
				propBlock.SetColor ("_Color", color2);
				totalColors.Add (color2);
			} else if (i == 2) {
				propBlock.SetColor ("_Color", color3);
				totalColors.Add (color3);
			} else if (i == 3) {
				propBlock.SetColor ("_Color", color4);
				totalColors.Add (color4);
			} else if (i == 4) {
				propBlock.SetColor ("_Color", color5);
				totalColors.Add (color5);
			} else if (i == 5) {
				propBlock.SetColor ("_Color", color6);
				totalColors.Add (color6);
			} else if (i == 6) {
				propBlock.SetColor ("_Color", color7);
				totalColors.Add (color7);
			} else if (i == 7) {
				propBlock.SetColor ("_Color", color8);
				totalColors.Add (color8);
			} else if (i == 8) {
				propBlock.SetColor ("_Color", color9);
				totalColors.Add (color9);
			} else if (i == 9) {
				propBlock.SetColor ("_Color", color10);
				totalColors.Add (color10);
			} else if (i == 10) {
				propBlock.SetColor ("_Color", color11);
				totalColors.Add (color11);
			} else if (i == 11) {
				propBlock.SetColor ("_Color", color12);
				totalColors.Add (color12);
			} else if (i == 12) {
				propBlock.SetColor ("_Color", color13);
				totalColors.Add (color13);
			} else if (i == 13) {
				propBlock.SetColor ("_Color", color14);
				totalColors.Add (color14);
			} else if (i == 14) {
				propBlock.SetColor ("_Color", color15);
				totalColors.Add (color15);
			} else if (i == 15) {
				propBlock.SetColor ("_Color", color16);
				totalColors.Add (color16);
			} else if (i == 16) {
				propBlock.SetColor ("_Color", color17);
				totalColors.Add (color17);
			} else if (i == 17) {
				propBlock.SetColor ("_Color", color18);
				totalColors.Add (color18);
			} else if (i == 18) {
				propBlock.SetColor ("_Color", color19);
				totalColors.Add (color19);
			} else if (i == 19) {
				propBlock.SetColor ("_Color", color20);
				totalColors.Add (color20);
			}

			// Apply the new value
			rends[i].SetPropertyBlock (propBlock, 0);
		}
	}

	void HideYoKids () {
		if (hiddenChildren) {
			for (int i = 0; i < transform.childCount; i++)
				if (transform.GetChild (i).name.Contains ("group"))
					transform.GetChild (i).hideFlags = HideFlags.HideInHierarchy;
		} else
			for (int i = 0; i < transform.childCount; i++)
				transform.GetChild(i).hideFlags = HideFlags.None;
	}

	void GetColorChangerMat () {
		#if UNITY_EDITOR
		if (!colorChangeMat || colorChangeMat.name != "ColorChangerMat") {
			string[] assetName = AssetDatabase.FindAssets("ColorChangerMat");
			colorChangeMat =AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(assetName[0]));
		}
		#else
		if (colorChangeMat && colorChangeMat.name != "ColorChangerMat") {
			colorChangeMat = null;
		}
		#endif
	}
}
