using UnityEngine;
using System.Collections;

public class AnimateTest : MonoBehaviour 
{
	private GameObject[] models;
 	private Animation[] modelsAnimation;
	private Vector3[] positions;

	private GameObject curModel = null;

	public  int currentModelIndex = -1;
	private int lastModelIndex = -1;

	private string[] animationNames;
	private MeshFilter[] meshFilters;
	private SkinnedMeshRenderer[] meshRenderers;
	
	public  int currentAnimationIndex;
	private int lastAnimationIndex;
	
	
	void Start()
	{
		if (models == null || (models != null && models.Length == 0))
		{
			if (models != null)
			{
				models = null;
			}
	        modelsAnimation = GetComponentsInChildren<Animation>();
			models = new GameObject[modelsAnimation.Length];
			positions = new Vector3[modelsAnimation.Length];
			int index = 0;
			foreach (Animation animation in modelsAnimation)
			{
				models[index] = animation.transform.gameObject as GameObject;
				DeactivateModel(models[index], index);
				index++;
			}
			if (models != null && models.Length > 0 && models[0] != null )
			{
				currentModelIndex = 0;
				UpdateModel(models[0]);
			}
		}
	}
	
	void DeactivateModel(GameObject model, int index = -1)
	{
		if (model != null)
		{
			if (index == -1)
			{
				positions[currentModelIndex] = model.transform.position;
			}
			else
			{
				positions[index] = model.transform.position;
			}
			model.animation.Stop ();
			model.animation.playAutomatically = false;
			model.active = false;
			model.transform.position = new Vector3(1000.0f, 1000.0f, 1000.0f);
		}
	}
	
	void ActivateModel(GameObject model)
	{
		if (model != null)
		{
			model.animation.Stop ();
			model.animation.playAutomatically = true;
			model.active = true;
			model.transform.position = positions[currentModelIndex];			

			meshFilters = null;
			meshFilters = modelsAnimation[currentModelIndex].GetComponentsInChildren<MeshFilter>();
			meshRenderers = null;
			meshRenderers = modelsAnimation[currentModelIndex].GetComponentsInChildren<SkinnedMeshRenderer>();
		}
	}
	
	void UpdateModel(GameObject newModel, int prevIndex = -1) 
	{
		if (newModel != null)
		{
			currentAnimationIndex = -1;
			DeactivateModel(curModel, prevIndex);
			
			animationNames = null;
			int numAnimations = newModel.animation.GetClipCount();
			if (numAnimations > 0)
			{
				animationNames = new string[numAnimations];
			
				int index = 0;
				foreach (AnimationState state in newModel.animation)
				{
					animationNames[index++] = state.clip.name;
					state.wrapMode = WrapMode.Loop;
				}
				currentAnimationIndex = 0;
				lastAnimationIndex = 0;
			}
					
			curModel = newModel;
			ActivateModel(curModel);
		}
	}
	
	void Update ()
	{
		if (models != null && models.Length > 1)
		{
			int tmpIndex = currentModelIndex;
			if (Input.GetKeyDown(KeyCode.Return))
			{
				if (Input.GetKey (KeyCode.LeftShift))
				{
					do
					{
						currentModelIndex--;
						if (currentModelIndex <= -1) currentModelIndex = models.Length - 1;
					}
					while (models[currentModelIndex] == null);			
				}
				else
				{
					do
					{
						currentModelIndex++;
						if (currentModelIndex >= models.Length) currentModelIndex = 0;
					}
					while (models[currentModelIndex] == null);
				}
				UpdateModel(models[currentModelIndex], tmpIndex);
				lastModelIndex = currentModelIndex;
			}
			if (lastModelIndex != currentModelIndex)
			{
				currentModelIndex = currentModelIndex < 0 ? 0 : currentModelIndex;
				currentModelIndex = currentModelIndex >= models.Length ? models.Length : currentModelIndex;
				UpdateModel(models[currentModelIndex], lastModelIndex);
				lastModelIndex = currentModelIndex;
			}
		}
		if (curModel != null)
		{
			if (Input.GetKeyDown(KeyCode.Space))
			{
				if (Input.GetKey (KeyCode.LeftShift))
				{
					currentAnimationIndex--;
					if (currentAnimationIndex <= -1) currentAnimationIndex = animationNames.Length - 1;
				}
				else
				{
					currentAnimationIndex++;
					if (currentAnimationIndex >= animationNames.Length) currentAnimationIndex = 0;
				}
				StartAnimation();
				lastAnimationIndex = currentAnimationIndex;
			}
			if (lastAnimationIndex != currentAnimationIndex)
			{
				currentAnimationIndex = currentAnimationIndex < 0 ? 0 : currentAnimationIndex;
				currentAnimationIndex = currentAnimationIndex >= animationNames.Length ? models.Length : currentAnimationIndex;
				StartAnimation();
				lastAnimationIndex = currentAnimationIndex;
			}
		}
	}
	
	private void StartAnimation()
	{
		curModel.animation.CrossFade(animationNames[currentAnimationIndex]); 
	}

	void OnGUI()
	{
		if (curModel != null)
		{
			string label = "[" + (currentModelIndex + 1).ToString() + "/" + models.Length.ToString() + "]";
			GUI.Label(new Rect(10, 10, 60, 24), "Model");
			GUI.Label(new Rect(80, 10, 40, 24), label);
			GUI.Label(new Rect(240, 10, 300, 24), curModel.name);
			if (models.Length > 2)
			{
				currentModelIndex = (int)GUI.HorizontalSlider(new Rect(130, 15, 100, 16), (float)currentModelIndex, 0.0f, (float)(models.Length - 1));
			}
			if (animationNames.Length > 0)
			{
				label = "[" + (currentAnimationIndex + 1).ToString() + "/" + animationNames.Length.ToString() + "]";
				GUI.Label(new Rect(10, 26, 60, 24), "Animation");
				GUI.Label(new Rect(80, 26, 40, 24), label);
				GUI.Label(new Rect(240, 26, 300, 24), animationNames[currentAnimationIndex]);
				if (animationNames.Length > 2)
				{
					currentAnimationIndex = (int)GUI.HorizontalSlider(new Rect(130, 31, 100, 16), (float)currentAnimationIndex, 0.0f, (float)(animationNames.Length - 1));
				}
			}
			
			int y = 44;
			if (meshRenderers != null && meshRenderers.Length > 0)
			{
				foreach (SkinnedMeshRenderer renderer in meshRenderers)
				{
					renderer.enabled = GUI.Toggle(new Rect(10, y, 200, 16), renderer.enabled, renderer.name);
					y += 16;
				}
			}
			if (meshFilters != null && meshFilters.Length > 0)
			{
				foreach (MeshFilter mesh in meshFilters)
				{
					mesh.renderer.enabled = GUI.Toggle(new Rect(10, y, 200, 16), mesh.renderer.enabled, mesh.name);
					y += 16;
				}
			}
		}
	}
}
