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

public class ColorChanger : MonoBehaviour {

	// getColors is in here from previously collecting material colors
	// It's saved here as a back-up
	[HideInInspector]
	public bool getColors = false, setColors = false;

	[HideInInspector]
	public Material colorChangeMat;

	[HideInInspector]
	public int totalMats = 1;

	public bool canDrain = true;

	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;

	MeshRenderer rend;
	Material[] sharedMaterialsCopy;

	// This needs to be in Awake because it has to come before the material drain settings
	void Awake () {
		PrepAndSet();
	}

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

	// Preps the Asset for color changing fun!
	void PrepAndSet () {

		// Get the Mesh Renderer or say that the object needs a mesh renderer
		if (GetComponent<MeshRenderer> ()) {
			rend = GetComponent<MeshRenderer> ();
		} else {
			Debug.LogError ("The" + gameObject.name + " has no Mesh Renderer. The ColorChanger script will not work on an object without a Mesh Renderer. Please remove this script from the GameObject.");
		}

		// Get the number of materials
		totalMats = rend.sharedMaterials.Length;

		// Make a copy of the shared materials array
		sharedMaterialsCopy = rend.sharedMaterials;

		// 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 (rend.sharedMaterials[i].name != "ColorChangerMat") {
					GetSpecificColor (i);
					if(colorChangeMat)
						sharedMaterialsCopy[i] = colorChangeMat;
				}
			}
			rend.sharedMaterials = sharedMaterialsCopy;
			ChangeColors ();
		} else if (totalMats > 20) {
			Debug.LogError ("The " + gameObject.name + " has too many materials. The ColorChanger script will not work for this GameObject because it has too many materials. Please remove this script from the GameObject.");
		}
	}

	void DrainCheck () {
		#if UNITY_EDITOR
		if (canDrain && !GetComponent<MaterialDrainValue> ()) {
			gameObject.AddComponent<MaterialDrainValue> ();
		} else if (!canDrain && GetComponent<MaterialDrainValue> ()) {
			UnityEditor.EditorApplication.delayCall += () => {DestroyImmediate(GetComponent<MaterialDrainValue> ());};
		}
		#endif
	}

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

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

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

			// Get the current value of the material properties
			rend.GetPropertyBlock (propBlock, i);

			// 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
			rend.SetPropertyBlock (propBlock, i);
		}
	}

	/* Old Script used for getting Colors
	void GetColors () {
		for (int i = 0; i < rend.sharedMaterials.Length; i++) {
			if (i == 0) {
				color1 = rend.sharedMaterials [i].color;
			} else if (i == 1) {
				color2 = rend.sharedMaterials [i].color;
			} else if (i == 2) {
				color3 = rend.sharedMaterials [i].color;
			} else if (i == 3) {
				color4 = rend.sharedMaterials [i].color;
			} else if (i == 4) {
				color5 = rend.sharedMaterials [i].color;
			} else if (i == 5) {
				color6 = rend.sharedMaterials [i].color;
			} else if (i == 6) {
				color7 = rend.sharedMaterials [i].color;
			} else if (i == 7) {
				color8 = rend.sharedMaterials [i].color;
			} else if (i == 8) {
				color9 = rend.sharedMaterials [i].color;
			} else if (i == 9) {
				color10 = rend.sharedMaterials [i].color;
			}
		}
	}
	*/

	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
	}
}
