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

public class AnimatorData : MonoBehaviour
{
	[HideInInspector]
	public bool isPlaying
	{
		get
		{
			return this.nowPlayingTake != null && !this.isPaused;
		}
	}

	[HideInInspector]
	public string takeName
	{
		get
		{
			if (this.nowPlayingTake != null)
			{
				return this.nowPlayingTake.name;
			}
			return null;
		}
	}

	public float GetTakeTime()
	{
		return this.takeTime;
	}

	public object Invoker(object[] args)
	{
		switch ((int)args[0])
		{
		case 0:
			return this.isPlaying;
		case 1:
			return this.takeName;
		case 2:
			this.Play((string)args[1], true, 0f, (bool)args[2]);
			break;
		case 3:
			this.StopLoop();
			break;
		case 4:
			this.PauseLoop();
			break;
		case 5:
			this.ResumeLoop();
			break;
		case 6:
			this.Play((string)args[1], false, (float)args[2], (bool)args[3]);
			break;
		case 7:
			this.Play((string)args[1], true, (float)((int)args[2]), (bool)args[3]);
			break;
		case 8:
			this.PreviewValue((string)args[1], true, (float)args[2]);
			break;
		case 9:
			this.PreviewValue((string)args[1], false, (float)args[2]);
			break;
		case 10:
			if (this.takeName == null)
			{
				return 0f;
			}
			return this.elapsedTime;
		case 11:
			if (this.takeName == null)
			{
				return 0f;
			}
			return (float)this.nowPlayingTake.numFrames / (float)this.nowPlayingTake.frameRate;
		case 12:
			if (this.takeName == null)
			{
				return false;
			}
			return this.isPaused;
		}
		return null;
	}

	private void Start()
	{
		if (this.playOnStart)
		{
			this.Play(this.playOnStart.name, true, 0f, false);
			this.playOnStart = null;
		}
	}

	private void OnDrawGizmos()
	{
		if (!this.isAnimatorOpen)
		{
			return;
		}
		this.takes[this.currentTake].drawGizmos(this.gizmo_size, this.inPlayMode);
	}

	private void Update()
	{
		if (this.bAutoTimeUpdate)
		{
			NTime.UpdateNowTime(Time.time);
		}
		if (RhythmAction_Mgr.Instance)
		{
			this.isPaused = RhythmAction_Mgr.Instance.IsPause;
		}
		if (this.isPaused || this.nowPlayingTake == null)
		{
			return;
		}
		this.elapsedTime = NTime.time;
		if (this.elapsedTime >= this.takeTime)
		{
			this.nowPlayingTake.stopAudio();
			if (this.isLooping)
			{
				this.Execute(this.nowPlayingTake, true, 0f);
			}
			else
			{
				this.nowPlayingTake = null;
			}
		}
	}

	public void Play(string take_name, bool isFrame, float value, bool loop)
	{
		this.nowPlayingTake = this.getTake(take_name);
		if (this.nowPlayingTake)
		{
			this.isLooping = loop;
			this.Execute(this.nowPlayingTake, isFrame, value);
		}
	}

	public void Play(string take_name, bool isFrame, float value, bool loop, List<int> exclusion_track_id_list)
	{
		this.nowPlayingTake = this.getTake(take_name);
		if (this.nowPlayingTake)
		{
			this.isLooping = loop;
			if (exclusion_track_id_list == null || exclusion_track_id_list.Count == 0)
			{
				this.Execute(this.nowPlayingTake, isFrame, value);
			}
			else
			{
				this.ExecuteExclusionTrack(this.nowPlayingTake, exclusion_track_id_list, isFrame, value);
			}
		}
	}

	public void PreviewValue(string take_name, bool isFrame, float value)
	{
		AMTake take;
		if (this.nowPlayingTake && this.nowPlayingTake.name == this.takeName)
		{
			take = this.nowPlayingTake;
		}
		else
		{
			take = this.getTake(take_name);
		}
		if (!take)
		{
			return;
		}
		float num = value;
		if (!isFrame)
		{
			num *= (float)take.frameRate;
		}
		take.previewFrameInvoker(num);
	}

	public void Execute(AMTake take, bool isFrame = true, float value = 0f)
	{
		AMTween.Stop();
		float num = value;
		float num2 = value;
		if (!isFrame)
		{
			num *= (float)take.frameRate;
		}
		if (isFrame)
		{
			num2 /= (float)take.frameRate;
		}
		take.executeActions(num);
		this.elapsedTime = num2;
		this.takeTime = (float)take.numFrames / (float)take.frameRate;
		this.nowPlayingTake = take;
	}

	public void ExecuteExclusionTrack(AMTake take, List<int> exclusion_track_id_list, bool isFrame = true, float value = 0f)
	{
		AMTween.Stop();
		float num = value;
		float num2 = value;
		if (!isFrame)
		{
			num *= (float)take.frameRate;
		}
		if (isFrame)
		{
			num2 /= (float)take.frameRate;
		}
		take.executeActions(exclusion_track_id_list, num);
		this.elapsedTime = num2;
		this.takeTime = (float)take.numFrames / (float)take.frameRate;
		this.nowPlayingTake = take;
	}

	public void PauseLoop()
	{
		if (this.nowPlayingTake == null)
		{
			return;
		}
		this.isPaused = true;
		this.nowPlayingTake.stopAudio();
		AMTween.Pause();
	}

	public void ResumeLoop()
	{
		if (this.nowPlayingTake == null)
		{
			return;
		}
		AMTween.Resume();
		this.isPaused = false;
	}

	public void StopLoop()
	{
		if (this.nowPlayingTake != null)
		{
			this.nowPlayingTake.stopAudio();
			this.nowPlayingTake.stopAnimations();
			this.nowPlayingTake = null;
		}
		this.isLooping = false;
		this.isPaused = false;
		AMTween.Stop();
	}

	public int getCurrentTakeValue()
	{
		return this.currentTake;
	}

	public int getTakeCount()
	{
		return this.takes.Count;
	}

	public bool setCurrentTakeValue(int _take)
	{
		if (_take != this.currentTake)
		{
			this.getCurrentTake().previewFrame(1f, false, true, false, false);
			this.currentTake = _take;
			return true;
		}
		return false;
	}

	public AMTake getCurrentTake()
	{
		return this.takes[this.currentTake];
	}

	public AMTake getTake(string takeName)
	{
		foreach (AMTake amtake in this.takes)
		{
			if (amtake.name == takeName)
			{
				return amtake;
			}
		}
		Debug.LogError("Animator: Take '" + takeName + "' not found.");
		return new AMTake(null);
	}

	public void addTake()
	{
		string name = "Take" + (this.takes.Count + 1);
		AMTake amtake = ScriptableObject.CreateInstance<AMTake>();
		amtake.name = name;
		this.makeTakeNameUnique(amtake);
		amtake.frameRate = 24;
		amtake.numFrames = 1440;
		amtake.startFrame = 1f;
		amtake.selectedFrame = 1;
		amtake.selectedTrack = -1;
		amtake.playbackSpeedIndex = 2;
		amtake.trackKeys = new List<int>();
		amtake.trackValues = new List<AMTrack>();
		this.takes.Add(amtake);
		this.selectTake(this.takes.Count - 1);
	}

	public void deleteTake(int index)
	{
		if (this.playOnStart == this.takes[index])
		{
			this.playOnStart = null;
		}
		this.takes[index].destroy();
		this.takes.RemoveAt(index);
		if (this.currentTake >= index && this.currentTake > 0)
		{
			this.currentTake--;
		}
	}

	public void deleteCurrentTake()
	{
		this.deleteTake(this.currentTake);
	}

	public void selectTake(int index)
	{
		this.currentTake = index;
	}

	public void selectTake(string name)
	{
		for (int i = 0; i < this.takes.Count; i++)
		{
			if (this.takes[i].name == name)
			{
				this.selectTake(i);
				break;
			}
		}
	}

	public void makeTakeNameUnique(AMTake take)
	{
		bool flag = false;
		int num = 0;
		do
		{
			if (flag)
			{
				flag = false;
			}
			foreach (AMTake amtake in this.takes)
			{
				if (amtake != take && amtake.name == take.name)
				{
					if (num > 0)
					{
						take.name = take.name.Substring(0, take.name.Length - 3);
					}
					num++;
					string name = take.name;
					take.name = string.Concat(new object[]
					{
						name,
						"(",
						num,
						")"
					});
					flag = true;
					break;
				}
			}
		}
		while (flag);
	}

	public string[] getTakeNames()
	{
		string[] array = new string[this.takes.Count + 1];
		for (int i = 0; i < this.takes.Count; i++)
		{
			array[i] = this.takes[i].name;
		}
		array[array.Length - 1] = "Create new...";
		return array;
	}

	public int getTakeIndex(AMTake take)
	{
		for (int i = 0; i < this.takes.Count; i++)
		{
			if (this.takes[i] == take)
			{
				return i;
			}
		}
		return -1;
	}

	public bool setCodeLanguage(int codeLanguage)
	{
		if (this.codeLanguage != codeLanguage)
		{
			this.codeLanguage = codeLanguage;
			return true;
		}
		return false;
	}

	public bool setGizmoSize(float gizmo_size)
	{
		if (this.gizmo_size != gizmo_size)
		{
			this.gizmo_size = gizmo_size;
			foreach (UnityEngine.Object @object in UnityEngine.Object.FindObjectsOfType(typeof(AMTarget)))
			{
				if ((@object as AMTarget).gizmo_size != gizmo_size)
				{
					(@object as AMTarget).gizmo_size = gizmo_size;
				}
			}
			return true;
		}
		return false;
	}

	public void deleteAllTakesExcept(AMTake take)
	{
		for (int i = 0; i < this.takes.Count; i++)
		{
			if (!(this.takes[i] == take))
			{
				this.deleteTake(i);
				i--;
			}
		}
	}

	public void mergeWith(AnimatorData _aData)
	{
		foreach (AMTake amtake in _aData.takes)
		{
			this.takes.Add(amtake);
			this.makeTakeNameUnique(amtake);
		}
	}

	public List<GameObject> getDependencies(AMTake _take = null)
	{
		if (_take != null)
		{
			return _take.getDependencies().ToList<GameObject>();
		}
		List<GameObject> list = new List<GameObject>();
		foreach (AMTake amtake in this.takes)
		{
			list = list.Union(amtake.getDependencies()).ToList<GameObject>();
		}
		return list;
	}

	public List<GameObject> updateDependencies(List<GameObject> newReferences, List<GameObject> oldReferences)
	{
		List<GameObject> list = new List<GameObject>();
		foreach (AMTake amtake in this.takes)
		{
			list = list.Union(amtake.updateDependencies(newReferences, oldReferences)).ToList<GameObject>();
		}
		return list;
	}

	public List<AMTake> takes = new List<AMTake>();

	public AMTake playOnStart;

	[HideInInspector]
	public bool isAnimatorOpen;

	[HideInInspector]
	public bool isInspectorOpen;

	[HideInInspector]
	public bool inPlayMode;

	[HideInInspector]
	public float zoom = 0.4f;

	[HideInInspector]
	public int currentTake;

	[HideInInspector]
	public int codeLanguage;

	[HideInInspector]
	public float gizmo_size = 0.05f;

	[HideInInspector]
	public float width_track = 150f;

	[HideInInspector]
	public bool autoKey;

	[HideInInspector]
	public float elapsedTime;

	public bool bAutoTimeUpdate = true;

	private AMTake nowPlayingTake;

	private bool isPaused;

	private bool isLooping;

	private float takeTime;
}
