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

namespace UnityEditor
{
	[CustomEditor (typeof (GISSplatData))]
	internal class GISSplatDataEditor : Editor
	{
		GISSplatData m_TargetGISSplatData;

		SerializedProperty m_RowCount;
		SerializedProperty m_ColumnCount;
		SerializedProperty m_EastLongitude;
		SerializedProperty m_WestLongitude;
		SerializedProperty m_Northlatitude;
		SerializedProperty m_SouthLatitude;
		SerializedProperty m_Textures;

		Vector2 scrollPosition = new Vector2 (0, 0);
		private bool latLongInspectorFoldout = false;

		void OnEnable ()
		{
			m_TargetGISSplatData = target as GISSplatData;

			m_RowCount = serializedObject.FindProperty ("rowCount");
			m_ColumnCount = serializedObject.FindProperty ("columnCount");
			m_EastLongitude = serializedObject.FindProperty ("eastLongitude");
			m_WestLongitude = serializedObject.FindProperty ("westLongitude");
			m_Northlatitude = serializedObject.FindProperty ("northLatitude");
			m_SouthLatitude = serializedObject.FindProperty ("southLatitude");
			m_Textures = serializedObject.FindProperty ("m_Textures");
		}

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

			EditorGUI.BeginChangeCheck ();
			EditorGUILayout.IntSlider (m_ColumnCount, 1, GISSplatData.kMaxColumnCount);
			EditorGUILayout.IntSlider (m_RowCount, 1, GISSplatData.kMaxRowCount);
			if (EditorGUI.EndChangeCheck ())
			{
				// Refresh the serialize object
				serializedObject.ApplyModifiedProperties ();
				m_TargetGISSplatData.InitTextureArray ();
				serializedObject.Update ();
			}

			latLongInspectorFoldout = EditorGUILayout.Foldout (latLongInspectorFoldout, "Latitude Longitude");
			if (latLongInspectorFoldout)
			{
				GUILayout.BeginVertical ();
				EditorGUILayout.PropertyField (m_WestLongitude);
				EditorGUILayout.PropertyField (m_EastLongitude);
				EditorGUILayout.PropertyField (m_Northlatitude);
				EditorGUILayout.PropertyField (m_SouthLatitude);
				GUILayout.EndVertical ();
			}

			EditorGUILayout.Separator ();
			if (m_RowCount.intValue > 0 && m_ColumnCount.intValue > 0)
			{
				GUILayout.Label ("Assign textures", EditorStyles.boldLabel);

				scrollPosition = EditorGUILayout.BeginScrollView (scrollPosition);
				GUILayout.BeginVertical ();
				for (int i = 0; i < m_RowCount.intValue; ++i)
				{
					GUILayout.BeginHorizontal ();
					for (int j = 0; j < m_ColumnCount.intValue; ++j)
					{
						int index = i * m_ColumnCount.intValue + j;
						Texture2D objectTex = (Texture2D)m_Textures.GetArrayElementAtIndex (index).objectReferenceValue;

						EditorGUI.BeginChangeCheck ();
						Rect r = GUILayoutUtility.GetAspectRect (1, GUILayout.MinWidth (64));
						Texture2D tex = EditorGUI.ObjectField (r, objectTex, typeof (Texture2D), false) as Texture2D;
						if (EditorGUI.EndChangeCheck ())
						{
							if (ValidateTextureSize (tex, index))
							{
								m_Textures.GetArrayElementAtIndex (index).objectReferenceValue = tex;
							}
						}
					}
					GUILayout.EndHorizontal ();
				}
				GUILayout.EndVertical ();
				EditorGUILayout.EndScrollView ();
			}
			else
			{
				GUILayout.Label ("Assign the number of rows and columns");
			}

			serializedObject.ApplyModifiedProperties ();
		}
		
		private bool ValidateTextureSize (Texture2D tex, int index)
		{			
			// null object wins them all.
			if (tex == null)
			{
				return true;
			}

			// Check that if the texture has the same size as the rest of the texture
			int texImageWidth = tex.width;
			int texImageHeight = tex.height;
			for (int i = 0; i < m_Textures.arraySize; ++i)
			{
				Texture2D objectTex = (Texture2D)m_Textures.GetArrayElementAtIndex (i).objectReferenceValue;
				if (i == index || objectTex == null)
				{
					continue;
				}
				// Determine if the texture size is the same
				if (objectTex.width != texImageWidth || objectTex.height != texImageHeight)
				{
					Debug.LogError ("Texture size does not match the rest of the texture (s).");
					return false;
				}
			}

			return true;
		}

		public override bool HasPreviewGUI ()
		{
			return (target != null);
		}

		public override void OnPreviewGUI (Rect r, GUIStyle background)
		{
			EditorGUILayout.BeginVertical ();
			{
				if (m_ColumnCount.intValue > 0
					&& m_RowCount.intValue > 0
					&& m_Textures.arraySize > 0)
				{
					PreviewTexture (r);
				}
			}
			EditorGUILayout.EndVertical ();
		}

		private void PreviewTexture (Rect rect)
		{
			Event evt = Event.current;
			// Ignore these 2 events
			if (evt.type == EventType.Ignore || evt.type == EventType.Layout)
			{
				return;
			}

			Rect drawRect = rect;
			drawRect.width = rect.width / m_ColumnCount.intValue;
			drawRect.height = rect.height / m_RowCount.intValue;

			for (int i = 0; i < m_RowCount.intValue; ++i)
			{
				for (int j = 0; j < m_ColumnCount.intValue; ++j)
				{
					int index = i * m_ColumnCount.intValue + j;
					Texture2D tex = (Texture2D)m_Textures.GetArrayElementAtIndex (index).objectReferenceValue;
					if (tex != null)
					{
						GUI.DrawTexture (drawRect, tex);
					}

					drawRect.x += drawRect.width;
				}
				drawRect.y += drawRect.height;
				drawRect.x = rect.x;
			}
		}
	}
}
