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

public class AMWriteBinaryData
{
	public AMWriteBinaryData(AnimatorData anime_data)
	{
		this.anime_data_ = anime_data;
		NDebug.AssertNull(this.anime_data_);
		NDebug.Assert(this.anime_data_.takes.Count == 1, "take over error.");
		this.total_frame_ = this.anime_data_.getCurrentTake().numFrames;
		this.frame_rate_ = this.anime_data_.getCurrentTake().frameRate;
	}

	public static bool PossibleBinaryConvert(AMTrack track)
	{
		return AMBinaryTranslation.CheckType(track) || AMBinaryRotation.CheckType(track) || AMBinaryProperty.CheckType(track) || AMBinaryMethod.CheckType(track);
	}

	public void CreateData(BinaryWriter binary)
	{
		binary.Write("BaseData");
		binary.Write(this.total_frame_);
		binary.Write(this.frame_rate_);
		AMTake currentTake = this.anime_data_.getCurrentTake();
		List<AMTrack> trackValues = currentTake.trackValues;
		for (int i = 0; i < trackValues.Count; i++)
		{
			trackValues[i].updateCache();
			if (AMBinaryTranslation.CheckType(trackValues[i]))
			{
				this.CreateBinaryTranslation(trackValues[i]).Write(binary);
			}
			else if (AMBinaryRotation.CheckType(trackValues[i]))
			{
				this.CreateBinaryRotation(trackValues[i]).Write(binary);
			}
			else if (AMBinaryProperty.CheckType(trackValues[i]))
			{
				this.CreateBinaryProperty(trackValues[i]).Write(binary);
			}
			else if (AMBinaryMethod.CheckType(trackValues[i]))
			{
				this.CreateBinaryMethod(trackValues[i]).Write(binary);
			}
		}
		binary.Write("Finish");
	}

	public AMBinaryTranslation CreateBinaryTranslation(AMTrack track_data)
	{
		if (!AMBinaryTranslation.CheckType(track_data))
		{
			return null;
		}
		AMTranslationTrack amtranslationTrack = track_data as AMTranslationTrack;
		AMBinaryTranslation ambinaryTranslation = new AMBinaryTranslation();
		this.CreateBaseData(track_data, amtranslationTrack.obj.gameObject, ambinaryTranslation);
		ambinaryTranslation.pos_array = new Vector3[this.total_frame_];
		for (int i = 1; i <= this.total_frame_; i++)
		{
			int num = i - 1;
			ambinaryTranslation.pos_array[num] = amtranslationTrack.getPositionAtFrame((float)i);
		}
		return ambinaryTranslation;
	}

	public AMBinaryRotation CreateBinaryRotation(AMTrack track_data)
	{
		if (!AMBinaryRotation.CheckType(track_data))
		{
			return null;
		}
		AMRotationTrack amrotationTrack = track_data as AMRotationTrack;
		AMBinaryRotation ambinaryRotation = new AMBinaryRotation();
		this.CreateBaseData(track_data, amrotationTrack.obj.gameObject, ambinaryRotation);
		ambinaryRotation.quaternion_array = new Quaternion[this.total_frame_];
		for (int i = 1; i <= this.total_frame_; i++)
		{
			int num = i - 1;
			ambinaryRotation.quaternion_array[num] = amrotationTrack.getRotationAtFrame((float)i);
		}
		return ambinaryRotation;
	}

	public AMBinaryProperty CreateBinaryProperty(AMTrack track_data)
	{
		if (!AMBinaryProperty.CheckType(track_data))
		{
			return null;
		}
		AMPropertyTrack prop_track = track_data as AMPropertyTrack;
		AMBinaryProperty ambinaryProperty = new AMBinaryProperty();
		ambinaryProperty.component_name = prop_track.getComponentName();
		ambinaryProperty.property_name = prop_track.propertyName;
		ambinaryProperty.value_type = (AMPropertyTrack.ValueType)prop_track.valueType;
		this.CreateBaseData(track_data, prop_track.obj, ambinaryProperty);
		if (prop_track.valueType == 2)
		{
			this.CreateBinaryPropertyGeneric<float>(ref ambinaryProperty.float_val_array, prop_track, () => (float)prop_track.getPropertyValueNumeric());
		}
		else if (prop_track.valueType == 0)
		{
			this.CreateBinaryPropertyGeneric<int>(ref ambinaryProperty.int_val_array, prop_track, () => (int)prop_track.getPropertyValueNumeric());
		}
		else if (prop_track.valueType == 5)
		{
			this.CreateBinaryPropertyGeneric<Vector3>(ref ambinaryProperty.vec3_val_array, prop_track, new Func<Vector3>(prop_track.getPropertyValueVector3));
		}
		else if (prop_track.valueType == 6)
		{
			this.CreateBinaryPropertyGeneric<Color>(ref ambinaryProperty.color_val_array, prop_track, new Func<Color>(prop_track.getPropertyValueColor));
		}
		return ambinaryProperty;
	}

	private void CreateBinaryPropertyGeneric<T>(ref T[] ref_array, AMPropertyTrack prop_track, Func<T> get_prop_func) where T : struct
	{
		ref_array = new T[this.total_frame_];
		for (int i = 1; i <= this.total_frame_; i++)
		{
			prop_track.previewFrame((float)i, false);
			int num = i - 1;
			ref_array[num] = get_prop_func();
		}
	}

	public AMBinaryMethod CreateBinaryMethod(AMTrack track_data)
	{
		if (!AMBinaryMethod.CheckType(track_data))
		{
			return null;
		}
		AMBinaryMethod ambinaryMethod = new AMBinaryMethod();
		List<AMBinaryMethod.MethodData> list = new List<AMBinaryMethod.MethodData>();
		AMEventTrack ameventTrack = track_data as AMEventTrack;
		List<AMAction> cache = ameventTrack.cache;
		this.CreateBaseData(track_data, ameventTrack.obj, ambinaryMethod);
		for (int i = 0; i < cache.Count; i++)
		{
			AMEventAction ameventAction = cache[i] as AMEventAction;
			list.Add(new AMBinaryMethod.MethodData
			{
				start_flame = ameventAction.startFrame - 1,
				component_name = ameventAction.methodInfo.DeclaringType.Name,
				method_name = ameventAction.methodName,
				param_list = ameventAction.parameters
			});
		}
		ambinaryMethod.method_data_array = list.ToArray();
		return ambinaryMethod;
	}

	private void CreateBaseData(AMTrack track_data, GameObject target_obj, AMBinaryDataBaseObject write_data)
	{
		write_data.obj = target_obj;
		write_data.object_tree_path = UTY.GetObjectTreePath(target_obj);
		write_data.total_frame = this.total_frame_;
		write_data.track_id = track_data.id;
	}

	private AnimatorData anime_data_;

	private int total_frame_;

	private int frame_rate_;
}
