﻿/*
 * File:			GAFAnimatorEditor.cs
 * Version:			1.0
 * Last changed:	2014/12/11 8:35
 * Author:			Alexey_Nikitin
 * Copyright:		© GAF Media
 * Project:			UnityVS.UnityProject.CSharp.Editor
 */

using System.Collections;
using System.Collections.Generic;
using System.Linq;

using UnityEditor;
using UnityEngine;
using UnityEditorInternal;

using GAF.Core;
using GAF.Assets;
using System.Reflection;

namespace GAFEditor.Core
{
    [CustomEditor(typeof(GAFAnimator))]
    [CanEditMultipleObjects]
    public class GAFAnimatorEditor : GAFBaseMovieClipEditor
    {
        private string m_MecanimResourcesPath = string.Empty;

        #region Properties

        new public List<GAFAnimator> targets
        {
            get
            {
                return base.targets.ToList().ConvertAll<GAFAnimator>(target => (GAFAnimator)target);
            }
        }

        new public GAFAnimator target
        {
            get
            {
                return base.target as GAFAnimator;
            }
        }

        public string mecanimResourcesPath
        {
            get
            {
                if (string.IsNullOrEmpty(m_MecanimResourcesPath))
                {
                    if (target.asset.hasMecanimCustomPath)
                    {
                        m_MecanimResourcesPath = target.asset.customMecanimPath;
                    }

                    else
                    {
                        var assetPath = AssetDatabase.GetAssetPath(target.asset);
                        var fileName = System.IO.Path.GetFileName(assetPath);

                        m_MecanimResourcesPath = assetPath.Substring(0, assetPath.Length - fileName.Length - 1) + target.asset.name + "_animator/";
                    }
                }

                return m_MecanimResourcesPath;
            }
        }

        #endregion // Properties

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

            drawAsset();
            drawResourcesState();
            drawPlaceholder();
            drawResourceManagement();
            drawSettings();
            drawPlayback();
            drawDataButtons();

            serializedObject.ApplyModifiedProperties();
        }

        protected override void drawPlayback()
        {
            var initializedProperty = serializedObject.FindProperty("m_IsInitialized");
            var assetProperty = serializedObject.FindProperty("m_GAFAsset");
            var timelineProperty = serializedObject.FindProperty("m_TimelineID");
            var currentSequenceIndex = serializedObject.FindProperty("m_SequenceIndex");

            if (!initializedProperty.hasMultipleDifferentValues &&
                initializedProperty.boolValue &&
                !assetProperty.hasMultipleDifferentValues &&
                 assetProperty.objectReferenceValue != null &&
                !timelineProperty.hasMultipleDifferentValues &&
                !currentSequenceIndex.hasMultipleDifferentValues)
            {
                var asset = (GAFAnimationAsset)assetProperty.objectReferenceValue;
                if (asset != null && asset.isLoaded)
                {
                    var timelineID = timelineProperty.intValue;
                    var sequences = asset.getSequences(timelineID);
                    var currentSequence = sequences.First(sequence => sequence.name == "Default");

                    GUILayout.Space(3f);
                    EditorGUILayout.LabelField("Sequence: " + currentSequence.name);

                    var currentFrameProperty = serializedObject.FindProperty("m_CurrentFrameNumber");

                    GUILayout.Space(3f);
                    m_ShowPlayback = EditorGUILayout.Foldout(m_ShowPlayback, "Playback");
                    if (m_ShowPlayback)
                    {
                        EditorGUILayout.BeginVertical(EditorStyles.textField);
                        {
                            if (!Application.isPlaying)
                            {
                                EditorGUI.BeginChangeCheck();
                                EditorGUI.showMixedValue = currentFrameProperty.hasMultipleDifferentValues;
                                EditorGUILayout.IntSlider(currentFrameProperty, (int)currentSequence.startFrame, (int)currentSequence.endFrame, new GUIContent(""));
                                EditorGUI.showMixedValue = false;
                                if (EditorGUI.EndChangeCheck())
                                {
                                    foreach (var target in targets)
                                    {
                                        target.updateToFrameAnimatorWithRefresh((int)currentFrameProperty.intValue);
                                    }
                                    serializedObject.ApplyModifiedProperties();
                                }
                            }
                            else
                            {
                                GUILayout.Space(3f);
                                EditorGUILayout.LabelField("Frames timeline:");

                                if (!currentFrameProperty.hasMultipleDifferentValues)
                                    EditorGUILayout.IntSlider(currentFrameProperty.intValue, (int)currentSequence.startFrame, (int)currentSequence.endFrame);
                            }

                            if (!currentFrameProperty.hasMultipleDifferentValues)
                            {
                                EditorGUILayout.BeginHorizontal();
                                {
                                    var currentEnabled = GUI.enabled;
                                    GUI.enabled = currentEnabled && (uint)currentFrameProperty.intValue > currentSequence.startFrame;
                                    if (GUILayout.Button("<<", EditorStyles.miniButtonLeft))
                                    {
                                        foreach (var target in targets)
                                        {
                                            target.updateToFrameAnimatorWithRefresh((int)currentSequence.startFrame);
                                            EditorUtility.SetDirty(target);
                                        }
                                    }
                                    GUI.enabled = currentEnabled;

                                    GUI.enabled = currentEnabled && (uint)currentFrameProperty.intValue > currentSequence.startFrame;
                                    if (GUILayout.Button("<", EditorStyles.miniButtonMid))
                                    {
                                        foreach (var target in targets)
                                        {
                                            target.updateToFrameAnimatorWithRefresh((int)(currentFrameProperty.intValue - 1));
                                            EditorUtility.SetDirty(target);
                                        }
                                    }

                                    GUI.enabled = currentEnabled && (uint)currentFrameProperty.intValue < currentSequence.endFrame;
                                    if (GUILayout.Button(">", EditorStyles.miniButtonMid))
                                    {
                                        foreach (var target in targets)
                                        {
                                            target.updateToFrameAnimatorWithRefresh((int)(currentFrameProperty.intValue + 1));
                                            EditorUtility.SetDirty(target);
                                        }
                                    }
                                    GUI.enabled = currentEnabled;

                                    GUI.enabled = currentEnabled && (uint)currentFrameProperty.intValue < currentSequence.endFrame;
                                    if (GUILayout.Button(">>", EditorStyles.miniButtonRight))
                                    {
                                        foreach (var target in targets)
                                        {
                                            target.updateToFrameAnimatorWithRefresh((int)currentSequence.endFrame);
                                            EditorUtility.SetDirty(target);
                                        }
                                    }
                                    GUI.enabled = currentEnabled;
                                }
                                EditorGUILayout.EndHorizontal();
                            }
                        }
                        EditorGUILayout.EndVertical();
                    }
                }
            }
        }

        protected override void drawSettings()
        {
            GUILayout.Space(3f);
            m_ShowSettings = EditorGUILayout.Foldout(m_ShowSettings, "Settings");

            if (m_ShowSettings)
            {
                var settingProperty = serializedObject.FindProperty("m_Settings");
                EditorGUILayout.BeginVertical(EditorStyles.textField);
                {
                    GUILayout.Space(10f);
                    EditorGUI.BeginChangeCheck();
                    var hasIndividualMaterialProperty = settingProperty.FindPropertyRelative("m_HasIndividualMaterial");
                    drawProperty(hasIndividualMaterialProperty, new GUIContent("Has individual material: ", "​"));
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.ApplyModifiedProperties();

                        foreach (var _target in targets)
                        {
                            _target.reload();
                        }
                    }

                    var previouseState = GUI.enabled;
                    GUI.enabled = previouseState && !hasIndividualMaterialProperty.hasMultipleDifferentValues && hasIndividualMaterialProperty.boolValue;
                    EditorGUI.BeginChangeCheck();
                    var animationColotrProperty = settingProperty.FindPropertyRelative("m_AnimationColor");
                    drawProperty(animationColotrProperty, new GUIContent("Animation color: ", "​"));
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.ApplyModifiedProperties();

                        foreach (var _target in targets)
                        {
                            _target.reload();
                        }
                    }
                    GUI.enabled = previouseState;

                    GUILayout.Space(3f);

                    drawSortingID();

                    GUILayout.Space(3f);
                    EditorGUI.BeginChangeCheck();
                    var layerOrderProperty = settingProperty.FindPropertyRelative("m_SpriteLayerValue");
                    drawProperty(layerOrderProperty, new GUIContent("Sorting layer order: ", "The overlay priority of this animation within its layer. Lower numbers are rendered first and subsequent numbers overlay those below.​"));
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.ApplyModifiedProperties();
                        reloadTargets();
                    }

                    GUILayout.Space(10f);
                    EditorGUI.BeginChangeCheck();
                    var pixelsPerUnitProperty = settingProperty.FindPropertyRelative("m_PixelsPerUnit");
                    drawProperty(pixelsPerUnitProperty, new GUIContent("Pixels per unit: ", "Ability to scale animation by changing the size of the mesh.​"));
                    if (EditorGUI.EndChangeCheck())
                    {
                        pixelsPerUnitProperty.floatValue = Mathf.Clamp(pixelsPerUnitProperty.floatValue, 0.001f, 1000f);
                        serializedObject.ApplyModifiedProperties();
                        reloadTargets();
                    }

                    var assetProperty = serializedObject.FindProperty("m_GAFAsset");
                    if (!assetProperty.hasMultipleDifferentValues &&
                         assetProperty.objectReferenceValue != null)
                    {
                        drawScales(assetProperty);
                        drawCsfs(assetProperty);
                    }

                    GUILayout.Space(10f);
                    EditorGUI.BeginChangeCheck();
                    drawProperty(settingProperty.FindPropertyRelative("m_PivotOffset.x"), new GUIContent("Pivot offset X: ", ""));
                    GUILayout.Space(3f);
                    drawProperty(settingProperty.FindPropertyRelative("m_PivotOffset.y"), new GUIContent("Pivot offset Y: ", ""));
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.ApplyModifiedProperties();
                        reloadTargets();
                    }

                    GUILayout.Space(10f);
                    EditorGUI.BeginChangeCheck();
                    drawProperty(settingProperty.FindPropertyRelative("m_ZLayerScale"), new GUIContent("Z Layer scale: ", "Multiplier for distace between subojects"));
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.ApplyModifiedProperties();
                        reloadTargets();
                    }
                }
                EditorGUILayout.EndVertical();
            }
        }
    }
}