//----------------------------------------------
//            NGUI: Next-Gen UI kit
// Copyright © 2011-2012 Tasharen Entertainment
//----------------------------------------------

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// EditorGUILayout.ObjectField doesn't support custom components, so a custom wizard saves the day.
/// Unfortunately this tool only shows components that are being used by the scene, so it's a "recently used" selection tool.
/// </summary>

public class ComponentSelector : ScriptableWizard
{
	public delegate void OnSelectionCallback (MonoBehaviour obj);

	System.Type mType;
	OnSelectionCallback mCallback;
	MonoBehaviour[] mObjects;

	/// <summary>
	/// Draw a button + object selection combo filtering specified types.
	/// </summary>

	static public void Draw<T> (string buttonName, T obj, OnSelectionCallback cb, params GUILayoutOption[] options) where T : MonoBehaviour
	{
		GUILayout.BeginHorizontal();
		bool show = GUILayout.Button(buttonName, "DropDownButton", GUILayout.Width(76f));
#if !UNITY_3_4
		GUILayout.BeginVertical();
		GUILayout.Space(5f);
#endif
		T o = EditorGUILayout.ObjectField(obj, typeof(T), false, options) as T;
#if !UNITY_3_4
		GUILayout.EndVertical();
#endif
		if (o != null && Selection.activeObject != o.gameObject && GUILayout.Button("Edit", GUILayout.Width(40f)))
		{
			Selection.activeObject = o.gameObject;
		}
		GUILayout.EndHorizontal();
		if (show) Show<T>(cb);
		else if (o != obj) cb(o);
	}

	/// <summary>
	/// Draw a button + object selection combo filtering specified types.
	/// </summary>

	static public void Draw<T> (T obj, OnSelectionCallback cb, params GUILayoutOption[] options) where T : MonoBehaviour
	{
		Draw<T>(NGUITools.GetName<T>(), obj, cb, options);
	}

	/// <summary>
	/// Show the selection wizard.
	/// </summary>

	static void Show<T> (OnSelectionCallback cb) where T : MonoBehaviour
	{
		System.Type type = typeof(T);
		ComponentSelector comp = ScriptableWizard.DisplayWizard<ComponentSelector>("Select " + type.ToString());
		comp.mType = type;
		comp.mCallback = cb;
		comp.mObjects = Resources.FindObjectsOfTypeAll(type) as MonoBehaviour[];
	}

	/// <summary>
	/// Draw the custom wizard.
	/// </summary>

	void OnGUI ()
	{
		EditorGUIUtility.LookLikeControls(80f);

		if (mObjects.Length == 0)
		{
			GUILayout.Label("No recently used " + mType.ToString() + " components found.\nTry drag & dropping one instead.");
		}
		else
		{
			GUILayout.Label("Recently used components", "LODLevelNotifyText");
			NGUIEditorTools.DrawSeparator();

			MonoBehaviour sel = null;

			foreach (MonoBehaviour o in mObjects)
			{
				if (DrawObject(o))
				{
					sel = o;
				}
			}

			if (sel != null)
			{
				mCallback(sel);
				Close();
			}
		}
	}

	/// <summary>
	/// Draw details about the specified monobehavior in column format.
	/// </summary>

	bool DrawObject (MonoBehaviour mb)
	{
		bool retVal = false;

		GUILayout.BeginHorizontal();
		{
			if (EditorUtility.IsPersistent(mb.gameObject))
			{
				GUILayout.Label("Prefab", "AS TextArea", GUILayout.Width(80f), GUILayout.Height(20f));
			}
			else
			{
				GUI.color = Color.grey;
				GUILayout.Label("Object", "AS TextArea", GUILayout.Width(80f), GUILayout.Height(20f));
			}

			GUILayout.Label(NGUITools.GetHierarchy(mb.gameObject), "AS TextArea", GUILayout.Height(20f));
			GUI.color = Color.white;

			retVal = GUILayout.Button("Select", "ButtonLeft", GUILayout.Width(60f), GUILayout.Height(16f));
		}
		GUILayout.EndHorizontal();
		return retVal;
	}
}
