using UnityEngine;
using System.Collections;
using AX.InputSystem;
using System.Collections.Generic;

/// <summary>
/// 键鼠输入历史
/// </summary>
public struct CmdInfo
{
    public SceneType sceneType;//场景(建筑)类型
    public int frameNumber;//帧数
    public object command;//发生的命令
    //public GameObject gameObj;//操作的对象
    public long gameObjID;//操作对象的id
    public object arg;//命令参数
}

//public delegate void UIHandler(CmdArgs arg);
/// <summary>
/// UI输入历史
/// </summary>
public struct UIEventInfo
{
    public SceneType sceneType;//场景(建筑)类型
    public int frameNumber;//帧数
    //public UIHandler handler;//响应的UI事件,以带CmdArgs参数类型的委托记录
    public string uiComponentName;//控制UI行为的组件名
    public string functionName;//响应的UI事件里调用的方法的名字(在组件中)
    //public GameObject gameObj;//操作对象
    public long gameObjID;//操作对象的id
    public object arg;//参数
}

public class InputHistory
{
    public static readonly InputHistory Instance = new InputHistory();

    public List<CmdInfo> cmdInfos = new List<CmdInfo>();//记录键盘鼠标输入响应的命令信息
    public List<UIEventInfo> UIEventInfos = new List<UIEventInfo>();//记录操作UI响应的事件信息

    public void RegisterInputHistory(CmdInfo historyItem)
    {
        if (!(historyItem.command is Command))
        {
            throw (new System.ArgumentException("参数historyItem.command不是期望的Command类型!"));
        }

        if (historyItem.arg != null && !(historyItem.arg is CmdArgs))
        {
            throw (new System.ArgumentException("参数historyItem.arg不是期望的CmdArgs类型!"));
        }

        cmdInfos.Add(historyItem);

        var command = historyItem.command;
        //Debug.Log(command.GetType().Name + ":" + cmdInfos.Count);
    }

    public void RegisterInputHistory(UIEventInfo historyItem)
    {
        if (historyItem.arg != null && !(historyItem.arg is CmdArgs))
        {
            throw (new System.ArgumentException("参数historyItem.arg不是期望的CmdArgs类型!"));
        }

        UIEventInfos.Add(historyItem);

        var componentName = historyItem.uiComponentName;
        var functionName = historyItem.functionName;
        //Debug.Log(componentName + "(" + functionName + ")" + ":" + UIEventInfos.Count);
    }

    public void TestCmdReplay()
    {
        GameSettings.othersSettings.isReplayMode = true;//控制回放不记录UI输入操作历史

        Debug.Log(cmdInfos.Count);

        for (int i = 0; i < cmdInfos.Count; i++)
        {
            //cmdInfos[i].command.Execute(cmdInfos[i].gameObj, cmdInfos[i].arg);
        }
    }

    public void TestUIEventReplay()
    {
        GameSettings.othersSettings.isReplayMode = true;//控制回放不记录UI输入操作历史

        Debug.Log(UIEventInfos.Count);

        for (int i = 0; i < UIEventInfos.Count; i++)
        {
            //UIEventInfos[i].gameObj.SendMessage(UIEventInfos[i].functionName,UIEventInfos[i].arg);
        }
    }

    private int cmdInfosIndex = 0;
    private CmdInfo cmd = new CmdInfo();
    private int UIEventInfosIndex = 0;
    private UIEventInfo uiEvent = new UIEventInfo();
    private GameObject uiObj;
    public void Replay(InputHistory history)
    {
        while(cmdInfosIndex < history.cmdInfos.Count)
        {
            cmd = history.cmdInfos[cmdInfosIndex];
            if (InputManager.frameCount >= cmd.frameNumber)
            {
                Debug.Log(cmdInfosIndex);
                ((Command)cmd.command).Execute(cmd.gameObjID, (CmdArgs)cmd.arg);
                cmdInfosIndex++;
            }
            else
                break;
        }

        while(UIEventInfosIndex < history.UIEventInfos.Count)
        {
            uiEvent = history.UIEventInfos[UIEventInfosIndex];
            if (InputManager.frameCount >= uiEvent.frameNumber)
            {
                uiObj = EntitiesManager.Instance.GetEntityByID(uiEvent.gameObjID);
                if (uiObj != null)
                    uiObj.SendMessage(uiEvent.functionName, uiEvent.arg);
                UIEventInfosIndex++;
            }
            else
                break;
        }

        if (cmdInfosIndex == history.cmdInfos.Count && UIEventInfosIndex == history.UIEventInfos.Count)
        {
            GameSettings.othersSettings.isReplayOver = true;
        }
    }
}