using UnityEngine;
using System.IO;
using System;
using SFB;
using System.Collections;

public enum GeneralOptionPanelEvent
{
    MouseGudies, BuildingModel, EditModel
}

/// <summary>
/// 用于持续检测用户的鼠标输入，并且做出对应UI的响应,这是一个测试中的脚本，之后需要重构
/// </summary>
public class MainMenuController : MonoBehaviour
{
    private Transform _Transform;
    private MainMenuView _MainMenuView;
    private MainMenuModel _MainMenuModel;

    private GeneralOptionPanelController GeneralOptionPanel;
    private BuildingOptionPanelController BuildingOptionPanel;
    private SelectView _SelectView;

    /// <summary>
    /// 用于指示当前选择的时间组序号,默认为0
    /// </summary>
    private int _SelectedBPMGroupIndex = 0;

    [SerializeField] private bool isGuidesEnabled = true;//是否启用鼠标参考线
    [SerializeField] private bool isBuildingModelEnabled = false;//目前是否是创建模式，左键点击放置物件
    [SerializeField] private bool optionHasBeenCreated = false;//是否已经创建了一个会话选项，再次点击退出会话
    [SerializeField] private bool isAnyModelEnabled = false;//是否处于任何一种专注模式之下，这会关闭通常选项，使得用户右键会直接弹出该模式下的菜单
    [SerializeField] private bool isAnyCoroutineEnabled = false;//目前是否有创造新物件的协程正在运行,防止重复开启协程

    /// <summary>
    /// 用于在不同对象之间传递歌曲当前时间的全局容器,只负责传递,只在主控中赋值
    /// </summary>
    private SongInformationContainer _SongTimeContainer;
    private BaseNote _preGeneratedObject;


    /// <summary>
    /// 当歌曲时间发生变化事触发该事件,传入的时间为改变后的时间,更新之后的UI
    /// </summary>
    private event Action<float> OnTimeChange;


    #region Unity生命周期函数
    void Start()
    {
        _MainMenuView = gameObject.GetComponent<MainMenuView>();
        _MainMenuModel = gameObject.GetComponent<MainMenuModel>();
        _Transform = gameObject.GetComponent<Transform>();
        //启用传递歌曲信息的容器
        _SongTimeContainer = new SongInformationContainer();
        _SongTimeContainer.UpdateSongInformation(0);

        Application.targetFrameRate = 60;

        //初始化各个界面
        InitTopPenal();
        InitProgressBar();
        InitAllOptionPanel();

        _SelectView = _MainMenuView.NotePool.Get(_MainMenuView.MainMenuSelectView);
        _SelectView.Init(0, _SongTimeContainer, _MainMenuModel.MainBPMGroup);

        //注册事件
        OnTimeChange += _MainMenuView.TopPanel.ChangeTimeText;
        OnTimeChange += ChangeProgressBar;
    }
    void Update()
    {
        //使用鼠标滚轮来控制当前时间
        ChangeTimeWhitMouseScroll(Input.mouseScrollDelta.y);
        //在数据层更新当前的歌曲时间
        _SongTimeContainer.UpdateSongInformation(_MainMenuModel.SongCurrentTime);

        //检查当前输入
        CheckUserInput();
    }
    #endregion
    #region 时间变化事件相关函数
    /// <summary>
    /// 通过鼠标滚轮更改时间
    /// </summary>
    private void ChangeTimeWhitMouseScroll(float value)
    {
        _MainMenuModel.SongCurrentTime += value * _MainMenuModel.MainBPMGroup.Beat / 4;
        if (value == 0) return;
        OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
    }
    /// <summary>
    /// 改变进度条
    /// </summary>
    private void ChangeProgressBar(float time)
    {
        _MainMenuView.ProgressBar.progressSlider.value = _MainMenuModel.Song.time / _MainMenuModel.Song.clip.length;
    }

    #endregion
    #region TopPenal相关代码
    /// <summary>
    /// 初始化顶部的UI控件
    /// </summary>
    private void InitTopPenal()
    {
        //基准BPM输入窗口
        _MainMenuView.TopPanel.BaseBPMInputField.onEndEdit?.AddListener(OnBaseBPMInputFieldEndEdit);
        _MainMenuView.TopPanel.BaseBPMInputField.text = _MainMenuModel.PersistentChartData.globalConfig.baseBPM.ToString();
        //当前时间输入窗口
        _MainMenuView.TopPanel.SongCurrentTimeInputField?.onEndEdit.AddListener(OnCurrentTimeInputFieldEndEdit);
        _MainMenuView.TopPanel.SongCurrentTimeInputField.text = _MainMenuModel.SongCurrentTime.ToString();
        //
        _MainMenuView.TopPanel.PlaySongButton.onClick.AddListener(OnPlaySongButtonClick);
        _MainMenuView.TopPanel.StopSongButton.onClick.AddListener(OnStopSongButtonClick);
    }
    Coroutine _runningCoroutine;
    /// <summary>
    /// 开始播放按钮绑定的方法
    /// </summary>
    private void OnPlaySongButtonClick()
    {
        if (_MainMenuModel.Song.isPlaying) return;
        _MainMenuModel.Song.Play();
        _runningCoroutine = StartCoroutine(InPlaying());
    }
    /// <summary>
    /// 暂停播放按钮绑定的方法
    /// </summary>
    private void OnStopSongButtonClick()
    {
        _MainMenuModel.Song.Pause();
        StopCoroutine(_runningCoroutine);
    }
    /// <summary>
    /// 歌曲在播放时开启的额外进程,实时监测歌曲是否在播放
    /// </summary>
    private IEnumerator InPlaying()
    {
        /*
         * 协程只在按钮事件中开启或者停止
         */
        while (_MainMenuModel.Song.isPlaying)
        {
            OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
            yield return null;
        }
    }
    /// <summary>
    /// 当BaseBPM被编辑时触发的函数
    /// </summary>
    private void OnBaseBPMInputFieldEndEdit(string str)
    {
        var temp = _MainMenuModel.PersistentChartData.globalConfig.baseBPM = float.Parse(str);
        _MainMenuView.TopPanel.StatusBar.text = "现在歌曲BaseBPM已经被更改为: " + temp.ToString() + " (ゝ∀･)";
    }
    /// <summary>
    /// 当前时间被编辑时触发的函数
    /// </summary>
    private void OnCurrentTimeInputFieldEndEdit(string str)
    {
        _MainMenuModel.SongCurrentTime = float.Parse(str);
        _MainMenuView.TopPanel.StatusBar.text = "已定位时间至: " + str + " (・ω・)";
    }
    #endregion
    #region 进度条相关函数
    /// <summary>
    /// 初始化进度条
    /// </summary>
    private void InitProgressBar()
    {
        //替换进度条的贴图,并且设置为开启状态
        _MainMenuView.ProgressBar.waveFormImage.texture = AudioWaveFormVisualization.BakeAudioWaveform(_MainMenuModel.Song.clip);
        _MainMenuView.ProgressBar.waveFormImage.gameObject.SetActive(true);

        _MainMenuView.ProgressBar.OnDrag += () =>
        {
            //拖到尾时退出
            if (_MainMenuView.ProgressBar.progressSlider.value == 1)
            {
                return;
            }
            //同步歌曲时间
            _MainMenuModel.SongCurrentTime = _MainMenuView.ProgressBar.progressSlider.value * _MainMenuModel.Song.clip.length;
            OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
        };
    }
    /// <summary>
    /// 预览谱面,按下空格开启,抬起空格时间回归原位
    /// </summary>
    private IEnumerator ChartPreview(float startTime)
    {
        IEnumerator Play()
        {
            while (!Input.GetKeyUp(KeyCode.Space))
            {
                if (!_MainMenuView.ProgressBar.isDrag)
                {
                    //_MainMenuView.ProgressBar.progressSlider.value = _MainMenuModel.Song.time / _MainMenuModel.Song.clip.length;
                    OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
                }
                OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
                yield return null;
            }
            _MainMenuModel.Song.Pause();
        }
        yield return Play();
        //回到开启的时间
        _MainMenuModel.SongCurrentTime = startTime;
        OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
    }
    #endregion
    /// <summary>
    /// 监听用户的输入
    /// </summary>
    private void CheckUserInput()
    {
        //之后需要更改为事件系统
        if (Input.GetMouseButtonDown(0))//鼠标左键
        {
            OnLeftClickCreateNewNote(_preGeneratedObject);
        }
        if (Input.GetMouseButtonDown(1))//鼠标右键
        {
            OnRightClickBuildingOptionPanelBehavior();
            OnRightClickGeneralOptionPanelBehavior();
        }
        if (Input.GetMouseButtonDown(2))//鼠标中键
        {
            print("鼠标中键被按下！");
        }
        if (Input.GetMouseButtonDown(3))//鼠标侧键
        {
            print("鼠标侧键被按下！");
        }
        if (Input.GetKeyDown(KeyCode.Space))//空格键
        {
            _MainMenuModel.Song.Play();
            StartCoroutine(ChartPreview(_MainMenuModel.SongCurrentTime));
        }
        if (Input.GetKeyDown(KeyCode.Escape))//ESC键
        {
            if (isBuildingModelEnabled)
            {
                isBuildingModelEnabled = false;
                isAnyModelEnabled = false;
                _MainMenuView.TopPanel.StatusBar.text = "创建模式已退出 (ﾉ>ω<)ﾉ";
                CloseBuildingOptionPanel();
            }//使用ESC退出建造模式
        }
        if (Input.GetKeyDown(KeyCode.F))
        {
            ReadFile();
        }
    }

    #region 文件读写
    /// <summary>
    /// 文件写入操作
    /// </summary>
    private void WriteFile(string fileName, string content)
    {
        // 构建完整路径（推荐使用持久化数据路径）

        string filePath = StandaloneFileBrowser.SaveFilePanel("选择文件夹", Application.persistentDataPath, fileName, "");
        try
        {
            // 创建目录（如果不存在）
            Directory.CreateDirectory(Path.GetDirectoryName(filePath));
            // 写入文件
            File.WriteAllText(filePath, content);
            _MainMenuView.TopPanel.StatusBar.text = "文件写入成功: (σ′▽‵)′▽‵)σ  " + filePath;
        }
        catch (System.Exception e)
        {
            _MainMenuView.TopPanel.StatusBar.text = "写入文件失败: (´;ω;`)" + e.Message;
        }
        CloseGeneralOptionPanel();
    }
    /// <summary>
    /// 选择谱面文件,读取
    /// </summary>
    private void ReadFile()
    {
        string[] filePath = StandaloneFileBrowser.OpenFolderPanel("选择文件夹", Application.persistentDataPath, false);
        try
        {
            _MainMenuModel.ReadChartByPath(filePath[0] + "\\Chart.json");
        }
        catch (System.NullReferenceException e)
        {
            _MainMenuView.TopPanel.StatusBar.text = "空引用异常!" + e.Message;
            return;
        }
        catch (System.IndexOutOfRangeException e)
        {
            _MainMenuView.TopPanel.StatusBar.text = "读取已取消 " + e.Message;
            return;
        }
    }


    #endregion
    #region 创建实例
    /// <summary>
    /// 创建新的note实例的函数
    /// </summary>
    private void CreateNewNote(Vector3 mouseWorldPos, NoteController note, int timingGroup)
    {
        _MainMenuView.TopPanel.StatusBar.text = "已创建 " + note.gameObject.name;

        var selfRef = _MainMenuModel.CreateNewNoteDataItem(_MainMenuModel.SongCurrentTime, mouseWorldPos.x, mouseWorldPos.y, timingGroup);
        var Go = _MainMenuView.NotePool.Get(note);

        Go.Init(
            new Vector2(
                mouseWorldPos.x,
                mouseWorldPos.y),
            _MainMenuModel.SongCurrentTime,
            _SongTimeContainer,
            _MainMenuModel.MainBPMGroup);

        Go.SelfRef = selfRef;
    }
    /// <summary>
    /// 创建新的drag实例的函数
    /// </summary>
    private void CreateNewDrag(Vector3 mouseWorldPos, DragController drag, int timingGroup)
    {
        _MainMenuView.TopPanel.StatusBar.text = "已创建 " + drag.gameObject.name;

        var selfRef = _MainMenuModel.CreateNewDragDataItem(_MainMenuModel.SongCurrentTime, mouseWorldPos.x, mouseWorldPos.y, timingGroup);
        var Go = _MainMenuView.NotePool.Get(drag);

        Go.Init(
            new Vector2(
                mouseWorldPos.x,
                mouseWorldPos.y),
            _MainMenuModel.SongCurrentTime,
            _SongTimeContainer,
            _MainMenuModel.MainBPMGroup);

        Go.SelfRef = selfRef;
    }
    /// <summary>
    /// 创建新的Flick实例的函数
    /// </summary>
    private IEnumerator CreateNewFlick(Vector3 mouseWorldPos, FlickController flick, int timingGroup)
    {
        _MainMenuView.TopPanel.StatusBar.text = "当前位置信息已录入,请将鼠标移动至四周点击确定方向,原地点击不选择方向,右键取消创建";
        FlickDirection direction = FlickDirection.Any;
        Vector3 currentMousePos = new Vector3();

        IEnumerator WaitSecondClick()
        {
            yield return null;//卡掉最开始true状态
            while (!Input.GetMouseButtonDown(0))
            {
                yield return null;//等待至左键再次按下
            }
            currentMousePos = Camera.main.ScreenToWorldPoint(
                new Vector3(Input.mousePosition.x, Input.mousePosition.y, 8));//这里获取鼠标目前的位置
        }
        yield return WaitSecondClick();
        isAnyCoroutineEnabled = false;
        //这里开始依据所得坐标获取向量以确定位置
        var tempVector = currentMousePos - mouseWorldPos;
        float sqrMagnitude = tempVector.sqrMagnitude;

        // 模平方小于等于1视为任意方向
        if (sqrMagnitude <= 1f)
        {
            direction = FlickDirection.Any;
        }
        else
        {
            // 计算向量角度（弧度转角度）
            float angle = Mathf.Atan2(tempVector.y, tempVector.x) * Mathf.Rad2Deg;

            // 转换为0-360度范围
            if (angle < 0) angle += 360f;

            // 划分8个45度区域并添加22.5度偏移使区域居中
            int sector = (int)((angle + 22.5f) / 45f) % 8;

            // 映射到方向枚举
            direction = sector switch
            {
                0 => FlickDirection.Right,
                1 => FlickDirection.RightUp,
                2 => FlickDirection.Up,
                3 => FlickDirection.LeftUp,
                4 => FlickDirection.Left,
                5 => FlickDirection.LeftDown,
                6 => FlickDirection.Down,
                7 => FlickDirection.RightDown,
                _ => FlickDirection.Any // 安全后备
            };
        }
        _MainMenuView.TopPanel.StatusBar.text = "第一次点击位置:" + mouseWorldPos.ToString() + "第二次点击位置" + currentMousePos.ToString() + " 结果为:" + direction;

        var selfRef = _MainMenuModel.CreateNewFlickDataItem(_MainMenuModel.SongCurrentTime, mouseWorldPos.x, mouseWorldPos.y, timingGroup, direction);
        var Go = _MainMenuView.NotePool.Get(flick);
        //初始化一个实例
        Go.Init(
            new Vector2(
                mouseWorldPos.x,
                mouseWorldPos.y),
            _MainMenuModel.SongCurrentTime,
            _SongTimeContainer,
            direction,
            _MainMenuView.FlickSpritePairs,
            _MainMenuModel.MainBPMGroup
            );

        Go.SelfRef = selfRef;
    }
    private IEnumerator CreateNewDataFlow(Vector3 mouseWorldPos, DataFlowController dataFlow, int timingGroup)
    {
        ReferencePointLocation reference = ReferencePointLocation.Near;
        float startTime = _MainMenuModel.SongCurrentTime;
        float endTime=0;

        _MainMenuView.TopPanel.StatusBar.text = "当前位置时间信息已录入,请选择第二个位置,右键取消创建";

        Vector3 currentMousePos = new Vector3();

        //这里开始进行位置选择逻辑
        IEnumerator WaitSecondClick()
        {
            yield return null;//卡掉最开始true状态
            while (!Input.GetMouseButtonDown(0))
            {
                yield return null;//等待至左键再次按下
            }
            currentMousePos = Camera.main.ScreenToWorldPoint(
                new Vector3(
                    Input.mousePosition.x, 
                    Input.mousePosition.y, 
                    8));//这里获取鼠标目前的位置
            endTime = _MainMenuModel.SongCurrentTime;
        }
        yield return WaitSecondClick();

        _MainMenuView.TopPanel.StatusBar.text = "按[1-6]数字按键确定样式,[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom]";

        //这里开始类型选择逻辑
        IEnumerator WaitNumKeyDown()
        {
            yield return null;
            bool isReferenceSelected = false;
            while (!(Input.GetMouseButtonDown(0) && isReferenceSelected))
            {

                if (Input.GetKeyDown(KeyCode.Alpha1)|| Input.GetKeyDown(KeyCode.Keypad1))
                {
                    reference = ReferencePointLocation.Near;
                    isReferenceSelected = true;
                    _MainMenuView.TopPanel.StatusBar.text = $"当前位置为{reference},[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom],再次单击确定选择";
                }

                if (Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2))
                {
                    reference = ReferencePointLocation.Far;
                    isReferenceSelected = true;
                    _MainMenuView.TopPanel.StatusBar.text = $"当前位置为{reference},[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom],再次单击确定选择";
                }

                if (Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3))
                {
                    reference = ReferencePointLocation.RightTop;
                    isReferenceSelected = true;
                    _MainMenuView.TopPanel.StatusBar.text = $"当前位置为{reference},[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom],再次单击确定选择";
                }

                if (Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4))
                {
                    reference = ReferencePointLocation.RightBottom;
                    isReferenceSelected = true;
                    _MainMenuView.TopPanel.StatusBar.text = $"当前位置为{reference},[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom],再次单击确定选择";
                }

                if (Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5))
                {
                    reference = ReferencePointLocation.LeftTop;
                    isReferenceSelected = true;
                    _MainMenuView.TopPanel.StatusBar.text = $"当前位置为{reference},[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom],再次单击确定选择";
                }

                if (Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6))
                {
                    reference = ReferencePointLocation.LeftBottom;
                    isReferenceSelected = true;
                    _MainMenuView.TopPanel.StatusBar.text = $"当前位置为{reference},[Near, Far, RightTop, RightBottom, LeftTop, LeftBottom],再次单击确定选择";
                }

                yield return null;//等待至左键再次按下
            }
        }

        yield return WaitNumKeyDown();
        isAnyCoroutineEnabled = false;

        var selfRef = _MainMenuModel.CreateNewSnakeDataItem(
            startTime,
            mouseWorldPos.x,
            mouseWorldPos.y, 
            currentMousePos.x, 
            currentMousePos.y,
            endTime, 
            timingGroup,
            reference);

        var Go = _MainMenuView.NotePool.Get(dataFlow);
        Go.Init(
            mouseWorldPos, 
            currentMousePos, 
            startTime,
            endTime,
            0.4f, 
            _SongTimeContainer,
            _MainMenuModel.MainBPMGroup,
            reference
            );

        Go.SelfRef = selfRef;
        _MainMenuView.TopPanel.StatusBar.text = "开始位置:"+ mouseWorldPos.ToString()+" 时间:"+startTime+" 结束位置:"+ currentMousePos.ToString()+" 时间:"+ endTime;
    }
        /// <summary>
        /// 点击左键时创建新的物件
        /// </summary>
        private void OnLeftClickCreateNewNote(BaseNote preGeneratedObject)
    {
        if (!(isBuildingModelEnabled && !BuildingOptionPanel.gameObject.activeSelf)) return;
        Vector3 mousePos = Input.mousePosition;
        //处于创造模式下，单击左键将会创造预备创造的物件
        switch (preGeneratedObject)
        {
            case NoteController:
                {
                    CreateNewNote(
                        Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, 8)),
                        _MainMenuView.NotePrefab,
                        _MainMenuModel.MainBPMGroup.GroupNum);
                    break;
                }
            case DragController:
                {
                    CreateNewDrag(
                        Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, 8)),
                        _MainMenuView.DragPrefab,
                        _MainMenuModel.MainBPMGroup.GroupNum);
                    break;
                }
            case FlickController:
                {
                    if (isAnyCoroutineEnabled) break;//防止首尾嵌套
                    StartCoroutine(
                        CreateNewFlick(
                            Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, 8)),
                            _MainMenuView.FlickPrefab,
                            _MainMenuModel.MainBPMGroup.GroupNum)
                        );
                    isAnyCoroutineEnabled = true;
                    break;
                }
            case DataFlowController:
                {
                    if (isAnyCoroutineEnabled) break;//防止首尾嵌套
                    StartCoroutine(
                    CreateNewDataFlow(Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, 8)),
                            _MainMenuView.DataFlowPrefab,
                            _MainMenuModel.MainBPMGroup.GroupNum)
                        );
                    isAnyCoroutineEnabled = true;
                    break;
                }
            case null:
                {
                    UnityEngine.Debug.LogError("存在空引用异常，请检查预制体是否被正常加载");
                    break;
                }
            default: print("存在非法输入亦或是不存在该类型"); break;
        }
    }
    #endregion
    #region 右键会话窗口
    /// <summary>
    /// 初始化所有右键会话窗口
    /// </summary>
    private void InitAllOptionPanel()
    {
        GeneralOptionPanel = Instantiate(_MainMenuView.GeneralOptionPanel, _Transform);
        BuildingOptionPanel = Instantiate(_MainMenuView.BuildingOptionPanel, _Transform);

        GeneralOptionPanel.gameObject.SetActive(false);
        BuildingOptionPanel.gameObject.SetActive(false);

        //鼠标右键界面初始化业务逻辑
        InitGeneralOptionPanel();
        InitBuildingOptionPanel();
    }
    /// <summary>
    /// 初始化通常会话窗口
    /// </summary>
    void InitGeneralOptionPanel()
    {
        GeneralOptionPanel.MouseGudies.onClick.AddListener(null);
        GeneralOptionPanel.BuildingModel.onClick.AddListener(OpenBuildOptionPanel);
        GeneralOptionPanel.EditModel.onClick.AddListener(null);
        GeneralOptionPanel.Output.onClick.AddListener(()=> WriteFile("Chart.json", _MainMenuModel.GetChartJson()));

    }
    /// <summary>
    /// 初始化建造窗口
    /// </summary>
    void InitBuildingOptionPanel()
    {
        BuildingOptionPanel.NoteButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.NoteButton.gameObject, _MainMenuView.NotePrefab));
        BuildingOptionPanel.DragButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.DragButton.gameObject, _MainMenuView.DragPrefab));
        BuildingOptionPanel.FlickButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.FlickButton.gameObject, _MainMenuView.FlickPrefab));
        BuildingOptionPanel.DataFlowButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.DataFlowButton.gameObject, _MainMenuView.DataFlowPrefab));
    }
    /// <summary>
    /// 任意创建模式下的note按钮被点击时，替换预备放置的物件，打印输出当前按钮的信息，关闭当前窗口
    /// </summary>
    void OnBuildingModelButtonClick(GameObject buttonObject, BaseNote preGeneratedObject)
    {
        _MainMenuView.TopPanel.StatusBar.text = buttonObject.name + "已经启用,按ESC可退出创建模式 (ゝ∀･)⌒☆";
        CloseBuildingOptionPanel();
        //替换预生成的物件
        _preGeneratedObject = preGeneratedObject;
    }
    /// <summary>
    /// 开启创建模式，该模式下玩家右键将直接打开建造模式面板，自由选择对应的物件进行放置
    /// </summary>
    void OpenBuildOptionPanel()
    {
        Vector3 mousePos = Input.mousePosition;
        //关闭通常会话选项的同时将开启创建模式
        CloseGeneralOptionPanel();
        isBuildingModelEnabled = true;
        isAnyModelEnabled = true;
        BuildingOptionPanel.gameObject.SetActive(true);
        BuildingOptionPanel.GetComponent<Transform>().position = new Vector3(mousePos.x, mousePos.y, 8);
        _MainMenuView.TopPanel.StatusBar.text = "已进入创建模式,按ESC可退出创建模式 (ゝ∀･)⌒☆";
    }
    /// <summary>
    /// 通过鼠标来创建创建模式会话窗口
    /// </summary>
    void OpenBuildOptionPanelWithMouse()
    {
        Vector3 mousePos = Input.mousePosition;
        isAnyModelEnabled = true;
        BuildingOptionPanel.gameObject.SetActive(true);
        BuildingOptionPanel.GetComponent<Transform>().position = new Vector3(mousePos.x, mousePos.y, 8);
    }
    /// <summary>
    /// 关闭创建模式会话窗口
    /// </summary>
    void CloseBuildingOptionPanel()
    {
        BuildingOptionPanel.gameObject.SetActive(false);
    }
    /// <summary>
    /// 关闭通常会话窗口
    /// </summary>
    void CloseGeneralOptionPanel()
    {
        //如果再次点击右键这关闭窗口
        optionHasBeenCreated = false;
        GeneralOptionPanel.gameObject.SetActive(false);
    }
    /// <summary>
    /// 在右键点击时通常面板的响应
    /// </summary>
    private void OnRightClickGeneralOptionPanelBehavior()
    {
        if (isAnyModelEnabled) return;
        Vector3 mousePos = Input.mousePosition;
        if (optionHasBeenCreated)
        {
            //当不处于任何模式之下，用户右键会直接生成通常选项
            CloseGeneralOptionPanel();
        }
        else
        {
            //激活右键窗口
            optionHasBeenCreated = true;
            GeneralOptionPanel.gameObject.SetActive(true);
            GeneralOptionPanel.GetComponent<Transform>().position = new Vector3(mousePos.x, mousePos.y, 8);
        }
    }
    /// <summary>
    /// 在右键按下时建造面板的响应
    /// </summary>
    private void OnRightClickBuildingOptionPanelBehavior()
    {
        if (!isBuildingModelEnabled) return;
        if (BuildingOptionPanel.gameObject.activeSelf)
        {
            //假如，处于创建模式下，会话窗口存在，右键将关闭窗口
            CloseBuildingOptionPanel();
        }
        else
        {
            //但是如果窗口不存在，则直接创建一个
            OpenBuildOptionPanelWithMouse();
        }
    }
    #endregion
}