using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Package.Domain;
using VIZ.Package.Storage;

namespace VIZ.Package.Service
{
    /// <summary>
    /// Viz命令服务
    /// </summary>
    public class VizCommandService
    {
        /// <summary>
        /// 设置场景
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        /// <param name="layer">图层</param>
        public void SetObject(ConnModel conn, string scene, VizLayer layer)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            // 需要等待结果
            conn.EndpointManager.Request($"RENDERER*{layer} SET_OBJECT SCENE*{scene}");
        }

        /// <summary>
        /// 重新加载场景
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        public void Reload(ConnModel conn, string scene)
        {
            conn.EndpointManager.Send($"SCENE**{scene} RELOAD");
        }

        /// <summary>
        /// 播放
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        /// <param name="layer">图层</param>
        public void Start(ConnModel conn, string scene, VizLayer layer)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            if (string.IsNullOrWhiteSpace(scene))
            {
                conn.EndpointManager.Send($"RENDERER*{layer}*STAGE START");
            }
            else
            {
                conn.EndpointManager.Send($"RENDERER*{layer}*STAGE*DIRECTOR*{scene} START");
            }
        }

        /// <summary>
        /// 继续
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        /// <param name="layer">图层</param>
        public void Continue(ConnModel conn, string scene, VizLayer layer)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            if (string.IsNullOrWhiteSpace(scene))
            {
                conn.EndpointManager.Send($"RENDERER*{layer}*STAGE CONTINUE");
            }
            else
            {
                conn.EndpointManager.Send($"RENDERER*{layer}*STAGE*DIRECTOR*{scene} CONTINUE");
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        /// <param name="layer">图层</param>
        public void Stop(ConnModel conn, string scene, VizLayer layer)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            if (string.IsNullOrWhiteSpace(scene))
            {
                conn.EndpointManager.Send($"RENDERER*{layer}*STAGE STOP");
            }
            else
            {
                conn.EndpointManager.Send($"RENDERER*{layer}*STAGE*DIRECTOR*{scene} STOP");
            }
        }

        /// <summary>
        /// 显示安全框
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="show">是否显示</param>
        public void ShowTS(ConnModel conn, bool show)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            VizConfigEntity config = ApplicationDomainEx.VizConfig;

            if (config.EngineFullType == EngineFullType.VIZ_Eng3)
            {
                conn.EndpointManager.Send($"RENDERER SET_TITLE_AREA {(show ? 1 : 0)}");
            }
            else if (config.EngineFullType == EngineFullType.VIZ_Eng4)
            {
                conn.EndpointManager.Send($"{ApplicationDomainEx.VizPreviewRenderer} SET_TITLE_AREA {(show ? 1 : 0)}");
            }
        }

        /// <summary>
        /// 显示安区域
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="show">是否显示</param>
        public void ShowSA(ConnModel conn, bool show)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            VizConfigEntity config = ApplicationDomainEx.VizConfig;

            if (config.EngineFullType == EngineFullType.VIZ_Eng3)
            {
                conn.EndpointManager.Send($"RENDERER SET_SAFE_AREA {(show ? 1 : 0)}");
            }
            else if (config.EngineFullType == EngineFullType.VIZ_Eng4)
            {
                conn.EndpointManager.Send($"{ApplicationDomainEx.VizPreviewRenderer} SET_SAFE_AREA {(show ? 1 : 0)}");
            }
        }

        /// <summary>
        /// 显示边界框
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="show">是否显示</param>
        public void ShowBB(ConnModel conn, bool show)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            VizConfigEntity config = ApplicationDomainEx.VizConfig;

            if (config.EngineFullType == EngineFullType.VIZ_Eng3)
            {
                conn.EndpointManager.Send($"RENDERER SHOW_BOUNDING_BOX {(show ? 1 : 0)}");
            }
            else if (config.EngineFullType == EngineFullType.VIZ_Eng4)
            {
                conn.EndpointManager.Send($"{ApplicationDomainEx.VizPreviewRenderer} SHOW_BOUNDING_BOX {(show ? 1 : 0)}");
            }
        }

        /// <summary>
        /// 显示RGB
        /// </summary>
        /// <param name="conn">连接</param>
        public void ShowRGB(ConnModel conn)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            VizConfigEntity config = ApplicationDomainEx.VizConfig;

            if (config.EngineFullType == EngineFullType.VIZ_Eng3)
            {
                conn.EndpointManager.Send($"RENDERER SET_KEY 0,RENDERER*KEY_INTERNAL*ACTIVE SET 0");
            }
            else if (config.EngineFullType == EngineFullType.VIZ_Eng4)
            {
                conn.EndpointManager.Send($"{ApplicationDomainEx.VizPreviewRenderer} SET_KEY 0,RENDERER*KEY_INTERNAL*ACTIVE SET 0");
            }
        }

        /// <summary>
        /// 显示键
        /// </summary>
        /// <param name="conn">连接</param>
        public void ShowKey(ConnModel conn)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            VizConfigEntity config = ApplicationDomainEx.VizConfig;

            if (config.EngineFullType == EngineFullType.VIZ_Eng3)
            {
                conn.EndpointManager.Send($"RENDERER SET_KEY 1,RENDERER*KEY_INTERNAL*ACTIVE SET 0");
            }
            else if (config.EngineFullType == EngineFullType.VIZ_Eng4)
            {
                conn.EndpointManager.Send($"{ApplicationDomainEx.VizPreviewRenderer} SET_KEY 1,RENDERER*KEY_INTERNAL*ACTIVE SET 0");
            }
        }

        /// <summary>
        /// 显示预览键
        /// </summary>
        /// <param name="conn">连接</param>
        public void ShowKeyPreview(ConnModel conn)
        {
            if (conn == null)
                throw new ArgumentNullException(nameof(conn));

            VizConfigEntity config = ApplicationDomainEx.VizConfig;

            if (config.EngineFullType == EngineFullType.VIZ_Eng3)
            {
                conn.EndpointManager.Send($"RENDERER SET_KEY 0,RENDERER*KEY_INTERNAL*IMAGE RESET,RENDERER*KEY_INTERNAL*ACTIVE SET 1");
            }
            else if (config.EngineFullType == EngineFullType.VIZ_Eng4)
            {
                conn.EndpointManager.Send($"{ApplicationDomainEx.VizPreviewRenderer} SET_KEY 0,RENDERER*KEY_INTERNAL*IMAGE RESET,RENDERER*KEY_INTERNAL*ACTIVE SET 1");
            }
        }

        /// <summary>
        /// 设置更新
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="isEnabled">是否启用</param>
        public void SetEnabledUpdate(ConnModel conn, bool isEnabled)
        {
            conn.EndpointManager.Send($"RENDERER*UPDATE SET {(isEnabled ? 1 : 0)}");
        }

        /// <summary>
        /// 开始动画
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="layer">层</param>
        public void Start(ConnModel conn, VizLayer layer)
        {
            conn.EndpointManager.Send($"RENDERER*{layer}*STAGE START");
        }

        /// <summary>
        /// 继续版子
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="layer">层</param>
        public void TakeContinue(ConnModel conn, VizLayer layer)
        {
            conn.EndpointManager.Send($"RENDERER*UPDATE SET 1");
            conn.EndpointManager.Send($"RENDERER*{layer}*STAGE CONTINUE");
        }

        /// <summary>
        /// 下版子
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="layer">层</param>s
        public void TakeOut(ConnModel conn, VizLayer layer)
        {
            conn.EndpointManager.Send($"RENDERER*UPDATE SET 1");
            conn.EndpointManager.Send($"RENDERER*{layer} SET_OBJECT");
        }

        /// <summary>
        /// 获取场景名
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="layer">层</param>
        /// <returns>场景名</returns>
        public string GetSceneName(ConnModel conn, VizLayer layer)
        {
            VizScene scene = VizScene.MAIN_SCENE;

            switch (layer)
            {
                case VizLayer.FRONT_LAYER: scene = VizScene.FRONT_SCENE; break;
                case VizLayer.MAIN_LAYER: scene = VizScene.MAIN_SCENE; break;
                case VizLayer.BACK_LAYER: scene = VizScene.BACK_SCENE; break;
            }

            return this.GetSceneName(conn, scene);
        }

        /// <summary>
        /// 获取场景名
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        /// <returns>场景名</returns>
        public string GetSceneName(ConnModel conn, VizScene scene)
        {
            string sceneName = conn.EndpointManager.Request($"{scene}*NAME GET");
            return sceneName;
        }

        /// <summary>
        /// 清理页
        /// </summary>
        /// <param name="conn">连接</param>
        public void TakeClear(ConnModel conn)
        {
            conn.EndpointManager.Request("RENDERER*FRONT_LAYER SET_OBJECT");
            conn.EndpointManager.Request("RENDERER*MAIN_LAYER SET_OBJECT");
            conn.EndpointManager.Request("RENDERER*BACK_LAYER SET_OBJECT");
            conn.EndpointManager.Request("SCENE CLEANUP");
            conn.EndpointManager.Request("GEOM CLEANUP");
            conn.EndpointManager.Request("IMAGE CLEANUP");
            conn.EndpointManager.Request("FONT CLEANUP");
            conn.EndpointManager.Request("MATERIAL CLEANUP");
            conn.EndpointManager.Request("MAPS CACHE CLEANUP");
        }

        /// <summary>
        /// 初始化页
        /// </summary>
        /// <param name="conn">连接</param>
        /// <param name="scene">场景</param>
        /// <returns>初始化返回</returns>
        public string TakeInit(ConnModel conn, string scene)
        {
            return conn.EndpointManager.Request($"SCENE*{scene} LOAD");
        }
    }
}
