﻿using UnityEngine;
using UnityEditor;
using System.Collections;

using Arbor;

namespace ArborEditor
{
	public class ParameterContainerInternalInspector : Editor
	{
		ParameterContainerInternal _ParameterContainer;
		ListGUI _ParametersGUI;

		[System.Reflection.Obfuscation( Exclude = true )]
		void OnEnable()
		{
			_ParameterContainer = target as ParameterContainerInternal;

			_ParametersGUI = new ListGUI( serializedObject.FindProperty( "_Parameters" ) );

			_ParametersGUI.addButton = OnAddButton;
			_ParametersGUI.drawChild = OnDrawChild;
		}
		
		void AddParameterMenu(object value)
		{
			Undo.RecordObject(_ParameterContainer, "Parameter Added");
			Parameter.Type type = (Parameter.Type)value;
			_ParameterContainer.AddParam("New " + type.ToString(), type);
		}

		void OnAddButton()
		{
			GenericMenu genericMenu = new GenericMenu();
			foreach (object userData in System.Enum.GetValues(typeof(Parameter.Type)))
			{
				genericMenu.AddItem( EditorGUITools.GetTextContent( userData.ToString(),false), false, AddParameterMenu, userData);
			}
			genericMenu.ShowAsContext();
		}

		void OnDrawChild(SerializedProperty property)
		{
			EditorGUILayout.BeginHorizontal();

			SerializedProperty nameProperty = property.FindPropertyRelative("name");
			
			EditorGUI.BeginChangeCheck();
			string name = EditorGUILayout.TextField(nameProperty.stringValue, GUILayout.Width(EditorGUIUtility.labelWidth));
			if (EditorGUI.EndChangeCheck() && name != nameProperty.stringValue)
			{
				nameProperty.stringValue = _ParameterContainer.MakeUniqueName(name);
			}

			Parameter.Type type = EnumUtility.GetValueFromIndex<Parameter.Type>(property.FindPropertyRelative("type").enumValueIndex);
			switch (type)
			{
				case Parameter.Type.Int:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("intValue");
                        EditorGUI.BeginChangeCheck();
						int intValue = EditorGUILayout.IntField(valueProperty.intValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.intValue = intValue;
						}
					}
					break;
				case Parameter.Type.Float:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("floatValue");
						EditorGUI.BeginChangeCheck();
						float floatValue = EditorGUILayout.FloatField(valueProperty.floatValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.floatValue = floatValue;
						}
					}
					break;
				case Parameter.Type.Bool:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("boolValue");
						EditorGUI.BeginChangeCheck();
						bool boolValue = EditorGUILayout.Toggle(string.Empty,valueProperty.boolValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.boolValue = boolValue;
						}
					}
					break;
				case Parameter.Type.String:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("stringValue");
						EditorGUI.BeginChangeCheck();
						string stringValue = EditorGUILayout.TextField(valueProperty.stringValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.stringValue = stringValue;
						}
					}
					break;
				case Parameter.Type.GameObject:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("gameObjectValue");
						EditorGUI.BeginChangeCheck();
						GameObject gameObjectValue = EditorGUILayout.ObjectField(valueProperty.objectReferenceValue,typeof(GameObject),true) as GameObject;
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.objectReferenceValue = gameObjectValue;
						}
					}
					break;
				case Parameter.Type.Vector2:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("vector2Value");
						EditorGUI.BeginChangeCheck();
						Vector2 vector2Value = EditorGUILayout.Vector2Field(GUIContent.none, valueProperty.vector2Value);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.vector2Value = vector2Value;
						}
					}
					break;
				case Parameter.Type.Vector3:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("vector3Value");
						EditorGUI.BeginChangeCheck();
						Vector3 vector3Value = EditorGUILayout.Vector3Field(GUIContent.none, valueProperty.vector3Value);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.vector3Value = vector3Value;
						}
					}
					break;
				case Parameter.Type.Quaternion:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("quaternionValue");
						EditorGUI.BeginChangeCheck();
						Quaternion quaternionValue = EditorGUITools.RotationField(GUIContent.none, valueProperty.quaternionValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.quaternionValue = quaternionValue;
						}
					}
					break;
				case Parameter.Type.Rect:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("rectValue");
						EditorGUI.BeginChangeCheck();
						Rect rectValue = EditorGUILayout.RectField(GUIContent.none, valueProperty.rectValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.rectValue = rectValue;
						}
					}
					break;
				case Parameter.Type.Bounds:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("boundsValue");
						EditorGUI.BeginChangeCheck();
						Bounds boundsValue = EditorGUILayout.BoundsField(GUIContent.none, valueProperty.boundsValue);
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.boundsValue = boundsValue;
						}
					}
					break;
				case Parameter.Type.Transform:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("objectReferenceValue");
						EditorGUI.BeginChangeCheck();
						Transform transformValue = EditorGUILayout.ObjectField(valueProperty.objectReferenceValue, typeof(Transform),true) as Transform;
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.objectReferenceValue = transformValue;
						}
					}
					break;
				case Parameter.Type.RectTransform:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("objectReferenceValue");
						EditorGUI.BeginChangeCheck();
						RectTransform rectTransformValue = EditorGUILayout.ObjectField(valueProperty.objectReferenceValue, typeof(RectTransform), true) as RectTransform;
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.objectReferenceValue = rectTransformValue;
						}
					}
					break;
				case Parameter.Type.Rigidbody:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("objectReferenceValue");
						EditorGUI.BeginChangeCheck();
						Rigidbody rigidbodyValue = EditorGUILayout.ObjectField(valueProperty.objectReferenceValue, typeof(Rigidbody), true) as Rigidbody;
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.objectReferenceValue = rigidbodyValue;
						}
					}
					break;
				case Parameter.Type.Rigidbody2D:
					{
						SerializedProperty valueProperty = property.FindPropertyRelative("objectReferenceValue");
						EditorGUI.BeginChangeCheck();
						Rigidbody2D rigidbody2DValue = EditorGUILayout.ObjectField(valueProperty.objectReferenceValue, typeof(Rigidbody2D), true) as Rigidbody2D;
						if (EditorGUI.EndChangeCheck())
						{
							valueProperty.objectReferenceValue = rigidbody2DValue;
						}
					}
					break;
			}

			EditorGUILayout.EndHorizontal();
		}

		public override void OnInspectorGUI()
		{
			serializedObject.Update();

			_ParametersGUI.OnGUI();

			serializedObject.ApplyModifiedProperties();
		}
	}
}
