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

[Serializable]
public class AMOrientationTrack : AMTrack
{
	public override string getTrackType()
	{
		return "Orientation";
	}

	public bool setObject(Transform obj)
	{
		if (this.obj != obj)
		{
			this.obj = obj;
			return true;
		}
		return false;
	}

	public void addKey(int _frame, Transform target)
	{
		foreach (AMKey amkey in this.keys)
		{
			AMOrientationKey amorientationKey = (AMOrientationKey)amkey;
			if (amorientationKey.frame == _frame)
			{
				amorientationKey.target = target;
				this.updateCache();
				return;
			}
		}
		AMOrientationKey amorientationKey2 = ScriptableObject.CreateInstance<AMOrientationKey>();
		amorientationKey2.frame = _frame;
		amorientationKey2.target = target;
		amorientationKey2.easeType = 21;
		this.keys.Add(amorientationKey2);
		this.updateCache();
	}

	public override void updateCache()
	{
		this.updateOrientationCache(this.parentTake, false);
		base.updateCache();
	}

	public void updateOrientationCache(AMTake curTake, bool restoreRotation = false)
	{
		Quaternion rotation = this.obj.rotation;
		base.sortKeys();
		base.destroyCache();
		this.cache = new List<AMAction>();
		AMTranslationTrack translationTrackForTransform = curTake.getTranslationTrackForTransform(this.obj);
		for (int i = 0; i < this.keys.Count; i++)
		{
			AMOrientationAction amorientationAction = ScriptableObject.CreateInstance<AMOrientationAction>();
			amorientationAction.startFrame = this.keys[i].frame;
			if (this.keys.Count > i + 1)
			{
				amorientationAction.endFrame = this.keys[i + 1].frame;
			}
			else
			{
				amorientationAction.endFrame = -1;
			}
			amorientationAction.obj = this.obj;
			amorientationAction.startTarget = (this.keys[i] as AMOrientationKey).target;
			if (amorientationAction.endFrame != -1)
			{
				amorientationAction.endTarget = (this.keys[i + 1] as AMOrientationKey).target;
			}
			amorientationAction.easeType = (this.keys[i] as AMOrientationKey).easeType;
			amorientationAction.customEase = new List<float>(this.keys[i].customEase);
			if (translationTrackForTransform != null && !amorientationAction.isLookFollow())
			{
				amorientationAction.isSetStartPosition = true;
				amorientationAction.startPosition = translationTrackForTransform.getPositionAtFrame((float)amorientationAction.startFrame);
				amorientationAction.isSetEndPosition = true;
				amorientationAction.endPosition = translationTrackForTransform.getPositionAtFrame((float)amorientationAction.endFrame);
			}
			this.cache.Add(amorientationAction);
		}
		if (restoreRotation)
		{
			this.obj.rotation = rotation;
		}
	}

	public Transform getInitialTarget()
	{
		return (this.keys[0] as AMOrientationKey).target;
	}

	public override void previewFrame(float frame, AMTrack extraTrack = null)
	{
		if (this.cache == null || this.cache.Count <= 0)
		{
			return;
		}
		int i = 0;
		while (i < this.cache.Count)
		{
			if (frame <= (float)(this.cache[i] as AMOrientationAction).startFrame)
			{
				if (!(this.cache[i] as AMOrientationAction).startTarget)
				{
					return;
				}
				Vector3 worldPosition;
				if (this.cachedTranslationTrackStartTarget == null)
				{
					worldPosition = (this.cache[i] as AMOrientationAction).startTarget.position;
				}
				else
				{
					worldPosition = (this.cachedTranslationTrackStartTarget as AMTranslationTrack).getPositionAtFrame((float)(this.cache[i] as AMOrientationAction).startFrame);
				}
				this.obj.LookAt(worldPosition);
				return;
			}
			else if (frame <= (float)(this.cache[i] as AMOrientationAction).endFrame)
			{
				if (!(this.cache[i] as AMOrientationAction).startTarget || !(this.cache[i] as AMOrientationAction).endTarget)
				{
					return;
				}
				float num = frame - (float)this.cache[i].startFrame;
				if (num < 0f)
				{
					num = 0f;
				}
				float percentage = num / (float)this.cache[i].getNumberOfFrames();
				if ((this.cache[i] as AMOrientationAction).isLookFollow())
				{
					this.obj.rotation = (this.cache[i] as AMOrientationAction).getQuaternionAtPercent(percentage, null, null);
				}
				else
				{
					Vector3? startVector = (!(this.cachedTranslationTrackStartTarget == null)) ? new Vector3?((this.cachedTranslationTrackStartTarget as AMTranslationTrack).getPositionAtFrame((float)(this.cache[i] as AMOrientationAction).startFrame)) : null;
					Vector3? endVector = (!(this.cachedTranslationTrackEndTarget == null)) ? new Vector3?((this.cachedTranslationTrackEndTarget as AMTranslationTrack).getPositionAtFrame((float)(this.cache[i] as AMOrientationAction).endFrame)) : null;
					this.obj.rotation = (this.cache[i] as AMOrientationAction).getQuaternionAtPercent(percentage, startVector, endVector);
				}
				return;
			}
			else if (i == this.cache.Count - 2)
			{
				if (!(this.cache[i] as AMOrientationAction).endTarget)
				{
					return;
				}
				Vector3 worldPosition2;
				if (this.cachedTranslationTrackEndTarget == null)
				{
					worldPosition2 = (this.cache[i] as AMOrientationAction).endTarget.position;
				}
				else
				{
					worldPosition2 = (this.cachedTranslationTrackEndTarget as AMTranslationTrack).getPositionAtFrame((float)(this.cache[i] as AMOrientationAction).endFrame);
				}
				this.obj.LookAt(worldPosition2);
				return;
			}
			else
			{
				i++;
			}
		}
	}

	public Transform getStartTargetForFrame(float frame)
	{
		foreach (AMAction amaction in this.cache)
		{
			AMOrientationAction amorientationAction = (AMOrientationAction)amaction;
			if ((int)frame <= amorientationAction.endFrame)
			{
				return amorientationAction.startTarget;
			}
		}
		return null;
	}

	public Transform getEndTargetForFrame(float frame)
	{
		if (this.cache.Count > 1)
		{
			return (this.cache[this.cache.Count - 2] as AMOrientationAction).endTarget;
		}
		return null;
	}

	public Transform getTargetForFrame(float frame)
	{
		if (this.isFrameBeyondLastKeyFrame(frame))
		{
			return this.getEndTargetForFrame(frame);
		}
		return this.getStartTargetForFrame(frame);
	}

	public void drawGizmos(float gizmo_size, bool inPlayMode, int frame)
	{
		if (!this.obj)
		{
			return;
		}
		if (!inPlayMode)
		{
			foreach (AMAction amaction in this.cache)
			{
				if ((amaction as AMOrientationAction).startFrame > frame)
				{
					break;
				}
				if (frame >= (amaction as AMOrientationAction).startFrame && frame <= (amaction as AMOrientationAction).endFrame)
				{
					if ((amaction as AMOrientationAction).isLookFollow() && (amaction as AMOrientationAction).startTarget)
					{
						Gizmos.color = new Color(0.9607843f, 0.419607848f, 0.117647059f, 0.2f);
						Gizmos.DrawLine(this.obj.transform.position, (amaction as AMOrientationAction).startTarget.transform.position);
					}
					break;
				}
			}
		}
		Gizmos.color = new Color(0.9607843f, 0.419607848f, 0.117647059f, 1f);
		Vector3 position = this.obj.transform.position;
		float num = 1.2f * (gizmo_size / 0.1f);
		if (num < 0.1f)
		{
			num = 0.1f;
		}
		Vector3 vector = this.obj.forward * num;
		float num2 = 20f;
		float d = 0.3f * num;
		Gizmos.DrawRay(position, vector);
		Vector3 a = Quaternion.LookRotation(vector) * Quaternion.Euler(0f, 180f + num2, 0f) * new Vector3(0f, 0f, 1f);
		Vector3 a2 = Quaternion.LookRotation(vector) * Quaternion.Euler(0f, 180f - num2, 0f) * new Vector3(0f, 0f, 1f);
		Gizmos.DrawRay(position + vector, a * d);
		Gizmos.DrawRay(position + vector, a2 * d);
	}

	public bool isFrameBeyondLastKeyFrame(float frame)
	{
		return this.keys.Count > 0 && (int)frame > this.keys[this.keys.Count - 1].frame;
	}

	public bool hasTarget(Transform obj)
	{
		foreach (AMAction amaction in this.cache)
		{
			AMOrientationAction amorientationAction = (AMOrientationAction)amaction;
			if (amorientationAction.startTarget == obj || amorientationAction.endTarget == obj)
			{
				return true;
			}
		}
		return false;
	}

	public override AnimatorTimeline.JSONInit getJSONInit()
	{
		if (!this.obj || this.keys.Count <= 0)
		{
			return null;
		}
		AnimatorTimeline.JSONInit jsoninit = new AnimatorTimeline.JSONInit();
		jsoninit.type = "orientation";
		jsoninit.go = this.obj.gameObject.name;
		Transform initialTarget = this.getInitialTarget();
		int frame = this.keys[0].frame;
		AMTrack amtrack = null;
		if (frame > 0)
		{
			amtrack = this.parentTake.getTranslationTrackForTransform(initialTarget);
		}
		Vector3 value = initialTarget.transform.position;
		if (amtrack)
		{
			value = (amtrack as AMTranslationTrack).getPositionAtFrame((float)frame);
		}
		AnimatorTimeline.JSONVector3 jsonvector = new AnimatorTimeline.JSONVector3();
		jsonvector.setValue(value);
		jsoninit.position = jsonvector;
		return jsoninit;
	}

	public override List<GameObject> getDependencies()
	{
		List<GameObject> list = new List<GameObject>();
		if (this.obj)
		{
			list.Add(this.obj.gameObject);
		}
		foreach (AMKey amkey in this.keys)
		{
			AMOrientationKey amorientationKey = (AMOrientationKey)amkey;
			if (amorientationKey.target)
			{
				list.Add(amorientationKey.target.gameObject);
			}
		}
		return list;
	}

	public override List<GameObject> updateDependencies(List<GameObject> newReferences, List<GameObject> oldReferences)
	{
		bool flag = false;
		for (int i = 0; i < oldReferences.Count; i++)
		{
			if (!flag && this.obj && oldReferences[i] == this.obj.gameObject)
			{
				this.obj = newReferences[i].transform;
				flag = true;
			}
			foreach (AMKey amkey in this.keys)
			{
				AMOrientationKey amorientationKey = (AMOrientationKey)amkey;
				if (amorientationKey.target && oldReferences[i] == amorientationKey.target.gameObject)
				{
					amorientationKey.target = newReferences[i].transform;
				}
			}
		}
		return new List<GameObject>();
	}

	public Transform obj;

	public AMTrack cachedTranslationTrackStartTarget;

	public AMTrack cachedTranslationTrackEndTarget;
}
