﻿/*
 * File:			GAFAnimator.cs
 * Version:			1.0
 * Last changed:	2014/12/9 18:21
 * Author:			Alexey_Nikitin
 * Copyright:		© GAF Media
 * Project:			UnityVS.UnityProject.CSharp
 */

using UnityEngine;

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

using GAF.Assets;
using GAF.Data;
using GAF.Objects;
using GAF.Utils;


namespace GAF.Core
{
	[AddComponentMenu("GAF/GAFAnimator")]
	[RequireComponent(typeof(Animator))]
	[ExecuteInEditMode]
	public class GAFAnimator : GAFBaseMovieClip
	{
		private Animator m_Animator = null;

		public event System.Action<GAFAnimator, uint, uint>	on_frame_changed;
		public event System.Action<GAFBaseMovieClip>		on_clear;
 
		#region Interface

		public override void clear(bool destroyChildren = false)
		{
			if (on_clear != null)
				on_clear(this);

			base.clear(destroyChildren);
		}

		public override void reload()
		{
			if (!System.Object.Equals(asset, null) &&
				isInitialized &&
                !usePlaceholder)
			{
				if (!asset.isLoaded)
					asset.load();

				if (asset.isLoaded)
				{
					initResource(asset);

					if (resource != null &&
						resource.isReady)
					{
						m_IsLoaded = true;

						setIndividualMaterials();

						manager.reload();

						updateToFrameAnimatorWithRefresh((int)getCurrentFrameNumber());
					}
				}
			}
		}

		public override void initialize(GAFAnimationAsset _Asset, int _TimelineID, bool _BakeObjects)
		{
			if (!isInitialized)
			{
				settings.init(_Asset);

				m_IsInitialized = true;

				m_GAFAsset		= _Asset;
				m_TimelineID	= _TimelineID;
				m_Animator		= GetComponent<Animator>();

#if !UNITY_5_0
				m_Animator.cullingMode	= AnimatorCullingMode.BasedOnRenderers;
#else
				m_Animator.cullingMode	= AnimatorCullingMode.CullUpdateTransforms;
#endif
				m_Animator.hideFlags	= HideFlags.NotEditable;
				m_Animator.runtimeAnimatorController = _Asset.getTimelines().First((timeline) => timeline.id == _TimelineID).animatorController;

				manager.initialize(this, _BakeObjects);
			}
		}

		public void updateToFrameAnimator(int _FrameNumber)
		{
			if (m_IsInitialized && m_IsLoaded)
			{
				if (getCurrentFrameNumber() != _FrameNumber)
				{
					var states = getStates((uint)_FrameNumber, false);
					if (states != null)
					{
						manager.updateToFrame(states, false);
					}

					if (on_frame_changed != null)
						on_frame_changed(this, (uint)m_CurrentFrameNumber, (uint)_FrameNumber);

					m_CurrentFrameNumber = (int)_FrameNumber;
				}
			}
		}

		public void updateToFrameAnimatorWithRefresh(int _FrameNumber)
		{
			if (m_IsInitialized && m_IsLoaded)
			{
				var states = getStates((uint)_FrameNumber, true);
				if (states != null)
				{
					manager.updateToFrame(states, true);
				}

				if (on_frame_changed != null)
					on_frame_changed(this, (uint)m_CurrentFrameNumber, (uint)_FrameNumber);

				m_CurrentFrameNumber = (int)_FrameNumber;
			}
		}

		#endregion // Interface
	}
}
