﻿using System;
using JLGames.RocketDriver.CSharp.Event;
using UnityEngine;

namespace JLGames.RocketDriver.Games.PanelManager
{
    public interface IPanelManager : IEventDispatcher
    {
        /// <summary>
        /// Whether to add a display at the end of the frame
        /// 是否在帧结束时添加显示
        /// </summary>
        bool ShowAfterFrame { get; }

        /// <summary>
        /// Set show monent
        /// 设置显示时机
        /// </summary>
        /// <param name="showAfterFrame"></param>
        void SetShowMoment(bool showAfterFrame);

        /// <summary>
        /// Initialization
        /// 初始化
        /// </summary>
        void Init();

        /// <summary>
        /// Get panel register instance.
        /// 信息注册表
        /// </summary>
        IPanelRegister Register { get; }

        /// <summary>
        /// Set panel register.
        /// 设置注册表
        /// </summary>
        /// <param name="register"></param>
        void SetRegister(IPanelRegister register);

        /// <summary>
        /// Asset loader adapter
        /// 资源加载器
        /// </summary>
        IPanelLoaderAdapter Loader { get; }

        /// <summary>
        /// Set asset loader adapter.
        /// 设置加载器
        /// </summary>
        /// <param name="loader"></param>
        void SetLoader(IPanelLoaderAdapter loader);

        //---------------------------------

        /// <summary>
        /// Are there any panels already open
        /// 是否有已经打开的面板
        /// </summary>
        bool HasOpenedPanel { get; }

        /// <summary>
        /// Get panel info by panel id.
        /// 获取面板定义
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        /// <returns></returns>
        IPanelInfo GetPanelInfo(string panelId);

        /// <summary>
        /// Check if the panel is open by panel id.
        /// 判断面板是否打开
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        /// <returns></returns>
        bool CheckPanelOpen(string panelId);

        /// <summary>
        /// Get the instance object of the panel that has been opened by panel id.
        /// return the last.
        /// 获取已经打开面板实例对象
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        /// <returns>返回查找到的第一个面板</returns>
        IPanelInstance GetOpenedPanel(string panelId);

        /// <summary>
        /// Get the instance object of the panel that has been opened by panel view.
        /// 获取已经打开面板实例对象
        /// </summary>
        /// <param name="view">面板显示视图</param>
        /// <returns></returns>
        IPanelInstance GetOpenedPanel(GameObject view);

        /// <summary>
        /// Get all opened panel objects
        /// 获取所有已经打开面板示例对象
        /// </summary>
        /// <returns></returns>
        IPanelInstance[] GetOpenedPanels();

        //---------------------------------

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="panelId">Panel Id<br/>面板的配置Id</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(string panelId, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="panelId">Panel Id<br/>面板的配置Id</param>
        /// <param name="params">Parameters injected into IParamsPanel<br/>展示时IParamsPanel注入的参数对象</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(string panelId, object @params, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="info">Panel Info<br/>面板的配置对象</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(IPanelInfo info, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="info">Panel Info<br/>面板的配置对象</param>
        /// <param name="params">Parameters injected into IParamsPanel<br/>展示时IParamsPanel注入的参数对象</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(IPanelInfo info, object @params, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="panelId">Panel Id<br/>面板的配置Id</param>
        /// <param name="view">Panel View<br/>面板显示视图</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(string panelId, GameObject view, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="panelId">Panel Id<br/>面板的配置Id</param>
        /// <param name="view">Panel View<br/>面板显示视图</param>
        /// <param name="params">Parameters injected into IParamsPanel<br/>展示时IParamsPanel注入的参数对象</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(string panelId, GameObject view, object @params, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="info">Panel Info<br/>面板的配置对象</param>
        /// <param name="view">Panel View<br/>面板显示视图</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(IPanelInfo info, GameObject view, string layerName = null);

        /// <summary>
        /// Show a panel.
        /// 打开面板
        /// </summary>
        /// <param name="info">Panel Info<br/>面板的配置对象</param>
        /// <param name="view">Panel View<br/>面板显示视图</param>
        /// <param name="params">Parameters injected into IParamsPanel<br/>展示时IParamsPanel注入的参数对象</param>
        /// <param name="layerName">The container layer name corresponding to the panel to be displayed<br/>展示时指定的容器名称</param>
        IPanelInstance ShowPanel(IPanelInfo info, GameObject view, object @params, string layerName = null);

        //---------------------------------

        /// <summary>
        /// Close panel by panel id
        /// 关闭面板
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        void ClosePanel(string panelId);

        /// <summary>
        /// Close the first panel by panel id
        /// 关闭面板
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        void CloseFirstPanel(string panelId);

        /// <summary>
        /// Close the last panel by panel id
        /// 关闭面板
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        void CloseLastPanel(string panelId);

        /// <summary>
        /// Close the panel by instance id
        /// 关闭面板
        /// </summary>
        /// <param name="instanceId">面板的实例Id</param>
        void CloseInstacnePanel(string instanceId);

        /// <summary>
        /// Close the panel by view instance
        /// 关闭面板
        /// </summary>
        /// <param name="view">面板显示视图</param>
        void CloseInstacnePanel(GameObject view);

        /// <summary>
        /// Close the panel by instance
        /// 关闭面板
        /// </summary>
        /// <param name="instance">面板的实例对象</param>
        void CloseInstacnePanel(IPanelInstance instance);

        /// <summary>
        /// Close all displayed panels
        /// 关闭全部显示的面板
        /// </summary>
        void ClosePanels();

        /// <summary>
        /// Close all displayed panels by panel id
        /// </summary>
        /// <param name="panelId">面板的配置Id</param>
        void ClosePanels(string panelId);

        /// <summary>
        /// Close multi displayed panels match function
        /// </summary>
        /// <param name="match"></param>
        void ClosePanels(Predicate<IPanelInstance> match);
    }
}