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

[CustomEditor(typeof(T2AnimMono))]
public class T2AnimMonoEditor : Editor
{
    public T2Animation anim;

    public void LoadAnim(string path)
    {
        IOUtils.readData = File.ReadAllBytes(path);
        IOUtils.readByteIndex = 0;

        anim.version = IOUtils.ReadInt32();
        int blockLength = IOUtils.ReadInt32();
        anim.blocks = new T2AnimationBlock[blockLength];
        for (int i = 0; i < blockLength; i++)
        {
            anim.blocks[i] = new T2AnimationBlock();
            T2AnimationBlock block = anim.blocks[i];
            block.animID = IOUtils.ReadInt32();
            block.frameCount = IOUtils.ReadInt32();
            int nodeIndexLength = IOUtils.ReadInt32();
            int intialNodeLength = IOUtils.ReadInt32();
            if (nodeIndexLength != intialNodeLength)
            {
                Debug.Log("" + nodeIndexLength + "!=" + intialNodeLength);
            }
            block.translationsLength = IOUtils.ReadInt32();
            block.rotationsLength = IOUtils.ReadInt32();
            int keyFrameActionsLength = IOUtils.ReadInt32();
            block.frameScale = IOUtils.ReadFloat();
            block.blendLength = IOUtils.ReadInt16();
            block.blendStart = IOUtils.ReadInt16();
            block.blendEnd = IOUtils.ReadInt16();
            block.animSpeed = IOUtils.ReadFloat();
            block.loopFrame = IOUtils.ReadInt16();

            block.nodeIndexes = new T2AnimNodeIndex[nodeIndexLength];
            for (int j = 0; j < nodeIndexLength; j++)
            {
                block.nodeIndexes[j] = new T2AnimNodeIndex();
                T2AnimNodeIndex nodeIndex = block.nodeIndexes[j];
                nodeIndex.translationIndex = IOUtils.ReadInt16();
                nodeIndex.rotationIndex = IOUtils.ReadInt16();
            }

            block.initalNodes = new T2AnimInitalNode[intialNodeLength];
            for (int j = 0; j < intialNodeLength; j++)
            {
                block.initalNodes[j] = new T2AnimInitalNode();
                T2AnimInitalNode initalNode = block.initalNodes[j];
                initalNode.translation = IOUtils.ReadVector3();
                initalNode.rotation = IOUtils.ReadVector4();
            }

            block.yawOffsets = new float[block.frameCount];
            for (int j = 0; j < block.frameCount; j++)
            {
                block.yawOffsets[j] = IOUtils.ReadFloat();
            }

            block.translations = new Vector3[block.translationsLength * block.frameCount];
            for (int j = 0; j < block.translationsLength; j++)
            {
                for (int n = 0; n < block.frameCount; n++)
                {
                    int index = (j * block.frameCount) + n;
                    block.translations[index] = IOUtils.ReadVector3();
                }
            }

            block.rotations = new Vector4[block.rotationsLength * block.frameCount];
            for (int j = 0; j < block.rotationsLength; j++)
            {
                for (int n = 0; n < block.frameCount; n++)
                {
                    int index = (j * block.frameCount) + n;
                    block.rotations[index] = IOUtils.ReadVector4();
                }
            }

            block.keyFrameActions = new T2AnimKeyFrameAction[keyFrameActionsLength];
            for (int j = 0; j < keyFrameActionsLength; j++)
            {
                block.keyFrameActions[j] = new T2AnimKeyFrameAction();
                T2AnimKeyFrameAction action = block.keyFrameActions[j];
                action.frame = IOUtils.ReadInt16();
                action.eventType = IOUtils.ReadInt16();
                action.node = IOUtils.ReadInt16();
                action.offset = IOUtils.ReadVector3();
                for (int n = 0; n < action.args.Length; n++)
                {
                    action.args[n] = IOUtils.ReadFloat();
                }
            }
        }
    }

    public void SaveAnim(string path)
    {
        IOUtils.writeData.Clear();

        IOUtils.WriteInt32(anim.version);
        IOUtils.WriteInt32(anim.blocks.Length);
        for (int i = 0; i < anim.blocks.Length; i++)
        {
            T2AnimationBlock block = anim.blocks[i];
            IOUtils.WriteInt32(block.animID);
            IOUtils.WriteInt32(block.frameCount);
            IOUtils.WriteInt32(block.nodeIndexes.Length);
            IOUtils.WriteInt32(block.initalNodes.Length);
            IOUtils.WriteInt32(block.translationsLength);
            IOUtils.WriteInt32(block.rotationsLength);
            IOUtils.WriteInt32(block.keyFrameActions.Length);
            IOUtils.WriteFloat(block.frameScale);
            IOUtils.WriteInt16(block.blendLength);
            IOUtils.WriteInt16(block.blendStart);
            IOUtils.WriteInt16(block.blendEnd);
            IOUtils.WriteFloat(block.animSpeed);
            IOUtils.WriteInt16(block.loopFrame);

            for (int j = 0; j < block.nodeIndexes.Length; j++)
            {
                T2AnimNodeIndex nodeIndex = block.nodeIndexes[j];
                IOUtils.WriteInt16(nodeIndex.translationIndex);
                IOUtils.WriteInt16(nodeIndex.rotationIndex);
            }

            for (int j = 0; j < block.initalNodes.Length; j++)
            {
                T2AnimInitalNode initalNode = block.initalNodes[j];
                IOUtils.WriteVector3(initalNode.translation);
                IOUtils.WriteVector4(initalNode.rotation);
            }

            for (int j = 0; j < block.frameCount; j++)
            {
                IOUtils.WriteFloat(block.yawOffsets[j]);
            }

            for (int j = 0; j < block.translations.Length; j++)
            {
                IOUtils.WriteVector3(block.translations[j]);
            }

            for (int j = 0; j < block.rotations.Length; j++)
            {
                IOUtils.WriteVector4(block.rotations[j]);
            }

            for (int j = 0; j < block.keyFrameActions.Length; j++)
            {
                T2AnimKeyFrameAction action = block.keyFrameActions[j];
                IOUtils.WriteInt16(action.frame);
                IOUtils.WriteInt16(action.eventType);
                IOUtils.WriteInt16(action.node);
                IOUtils.WriteVector3(action.offset);
                for (int n = 0; n < action.args.Length; n++)
                {
                    IOUtils.WriteFloat(action.args[n]);
                }
            }
        }

        File.WriteAllBytes(path, IOUtils.writeData.ToArray());
    }

    public override void OnInspectorGUI()
    {
        T2AnimMono mb = target as T2AnimMono;
        anim = mb.anim;

        GUILayout.BeginHorizontal();
        EditorGUIUtility.labelWidth = 80.0f;
        mb.loadPath = EditorGUILayout.TextField("Load Folder", mb.loadPath);
        EditorGUIUtility.labelWidth = 0.0f;
        if (GUILayout.Button("...", GUILayout.Width(32.0f)))
        {
            string path = EditorUtility.OpenFolderPanel("Load File Default Folder", mb.loadPath, "");
            if (!string.IsNullOrEmpty(path))
            {
                mb.loadPath = path;
            }
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        EditorGUIUtility.labelWidth = 80.0f;
        mb.savePath = EditorGUILayout.TextField("Save Folder", mb.savePath);
        EditorGUIUtility.labelWidth = 0.0f;
        if (GUILayout.Button("...", GUILayout.Width(32.0f)))
        {
            string path = EditorUtility.OpenFolderPanel("Save File Default Folder", mb.savePath, "");
            if (!string.IsNullOrEmpty(path))
            {
                mb.savePath = path;
            }
        }
        GUILayout.EndHorizontal();

        if (GUILayout.Button("Load File"))
        {
            string path = EditorUtility.OpenFilePanel("Open Anim file", mb.loadPath, "anim");
            if (!string.IsNullOrEmpty(path))
            {
                LoadAnim(path);
            }
        }

        if (GUILayout.Button("Save File"))
        {
            string path = EditorUtility.SaveFilePanel("Save Anim file", mb.savePath, "", "anim");
            if (!string.IsNullOrEmpty(path))
            {
                SaveAnim(path);
            }
        }

        base.OnInspectorGUI();

        EditorUtility.SetDirty(target);
    }
}
