﻿using System;
using JLGames.RocketDriver.Actions.Utils;
using UnityEngine;
using Object = UnityEngine.Object;

namespace JLGames.RocketDriver.Actions.Loaderx
{
    public static class Loader
    {
        /// <summary>
        /// Initialize the default loader
        /// 初始化默认加载器
        /// </summary>
        /// <param name="settingsName"></param>
        public static void InitLoader(string settingsName = LoaderManager.DefaultName)
        {
            LoaderManager.InitLoader(LoaderManager.DefaultName, settingsName);
        }

        /// <summary>
        /// Initialize version information
        /// Version information is not allowed to be cached
        /// 初始化版本信息
        /// 版本信息获取不允许进行缓存
        /// </summary>
        /// <param name="onVersionLoaded"></param>
        public static void InitVersion(LoaderDelegate.OnAssetLoaded<AssetBundleManifest> onVersionLoaded)
        {
            DebugUtil.Log("InitVersion:", LoaderManager.Mono);
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.InitVersion(onVersionLoaded));
        }

        /// <summary>
        /// Asynchronous download bundle
        /// 异步下载资源包
        /// </summary>
        /// <param name="bundleName">资源包名称</param>
        /// <param name="onBundleLoaded">回调</param>
        /// <param name="autoRelease">是否自动释放资源包</param>
        /// <param name="unloadAllLoadedObjects">是否全部释放实例化的资源</param>
        /// <returns></returns>
        public static void LoadBundleAsync(string bundleName, LoaderDelegate.OnBundleLoaded onBundleLoaded,
            bool autoRelease = true, bool unloadAllLoadedObjects = false)
        {
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.LoadBundleAsync(bundleName, onBundleLoaded,
                autoRelease, unloadAllLoadedObjects));
        }

        /// <summary>
        /// Asynchronous download bundle
        /// 异步下载资源包
        /// Including download dependent bundles
        /// 包括下载依赖的资源包
        /// The last element of assets in the onMultiAssetLoaded callback is the current resource bundle
        /// onMultiAssetLoaded回调中assets最后一个元素为当前资源包
        /// </summary>
        /// <param name="bundleName"></param>
        /// <param name="onBundleLoaded"></param>
        /// <param name="autoRelease"></param>
        /// <param name="unloadAllLoadedObjects"></param>
        /// <returns></returns>
        public static void LoadBundleWithDependenciesAsync(string bundleName,
            LoaderDelegate.OnBundleLoaded onBundleLoaded,
            bool autoRelease = true, bool unloadAllLoadedObjects = false)
        {
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.LoadBundleWithDependenciesAsync(bundleName, onBundleLoaded,
                autoRelease, unloadAllLoadedObjects));
        }

        /// <summary>
        /// Asynchronous batch download bundles
        /// 异步批量下载资源包
        /// </summary>
        /// <param name="bundleName"></param>
        /// <param name="onMultiBundleLoaded"></param>
        /// <param name="autoRelease"></param>
        /// <param name="unloadAllLoadedObjects"></param>
        /// <returns></returns>
        public static void LoadMultiBundleAsync(string[] bundleName,
            LoaderDelegate.OnMultiBundleLoaded onMultiBundleLoaded,
            bool autoRelease = true, bool unloadAllLoadedObjects = false)
        {
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.LoadMultiBundleAsync(bundleName, onMultiBundleLoaded, autoRelease,
                unloadAllLoadedObjects));
        }

        /// <summary>
        /// Load asset from bundle synchronously with relative path
        /// 使用相对路径从Bundle中加载资源
        /// </summary>
        /// <param name="assetPath">资源路径</param>
        /// <param name="bundle">资源包</param>
        /// <typeparam name="T">资源类型</typeparam>
        /// <returns></returns>
        public static T LoadAssetSync<T>(string assetPath, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadAssetSync<T>(assetPath, bundle);
        }

        /// <summary>
        /// Load asset from bundle synchronously with full path
        /// 使用完整路径从Bundle中加载资源
        /// The full path：refers to the relative path after removing ProjectBasePath
        /// 完整路径：指的是去除ProjectBasePath后的相对路径
        /// </summary>
        /// <param name="absPath">完整资源路径,忽略设置的ProjectBasePath</param>
        /// <param name="bundle">资源包</param>
        /// <typeparam name="T">资源类型</typeparam>
        /// <returns></returns>
        public static T LoadAssetSyncFull<T>(string absPath, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadAssetSyncFull<T>(absPath, bundle);
        }

        /// <summary>
        /// Synchronized load resources from bundle in batches
        /// 同步批量从资源包中加载资源
        /// </summary>
        /// <param name="assetPaths">资源路径</param>
        /// <param name="bundle">资源包</param>
        /// <typeparam name="T">资源类型</typeparam>
        /// <returns></returns>
        public static T[] LoadAssetsSync<T>(string[] assetPaths, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadAssetsSync<T>(assetPaths, bundle);
        }

        /// <summary>
        /// Synchronized load resources from bundle in batches
        /// 同步批量从资源包中加载资源
        /// </summary>
        /// <param name="absPaths">完整资源路径,忽略设置的ProjectBasePath</param>
        /// <param name="bundle">资源包</param>
        /// <typeparam name="T">资源类型</typeparam>
        /// <returns></returns>
        public static T[] LoadAssetsSyncFull<T>(string[] absPaths, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadAssetsSyncFull<T>(absPaths, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="bundle"></param>
        /// <returns></returns>
        public static Object[] LoadSubAssetsSync(string path, AssetBundle bundle)
        {
            return LoaderManager.DefaultLoader.LoadSubAssetsSync(path, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="type"></param>
        /// <param name="bundle"></param>
        /// <returns></returns>
        public static Object[] LoadSubAssetsSync(string path, Type type, AssetBundle bundle)
        {
            return LoaderManager.DefaultLoader.LoadSubAssetsSync(path, type, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="bundle"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T[] LoadSubAssetsSync<T>(string path, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadSubAssetsSync<T>(path, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="subNames"></param>
        /// <param name="bundle"></param>
        /// <returns></returns>
        public static Object[] LoadSubAssetsSync(string path, string[] subNames, AssetBundle bundle)
        {
            return LoaderManager.DefaultLoader.LoadSubAssetsSync(path, subNames, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="subNames"></param>
        /// <param name="bundle"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T[] LoadSubAssetsSync<T>(string path, string[] subNames, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadSubAssetsSync<T>(path, subNames, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="subName"></param>
        /// <param name="bundle"></param>
        /// <returns></returns>
        public static Object LoadSubAssetSync(string path, string subName, AssetBundle bundle)
        {
            return LoaderManager.DefaultLoader.LoadSubAssetSync(path, subName, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="subName"></param>
        /// <param name="type"></param>
        /// <param name="bundle"></param>
        /// <returns></returns>
        public static Object LoadSubAssetSync(string path, string subName, Type type, AssetBundle bundle)
        {
            return LoaderManager.DefaultLoader.LoadSubAssetSync(path, subName, type, bundle);
        }

        /// <summary>
        /// Load sub-resources (sprites, prefabs, etc.)
        /// 加载子资源(子图、预置等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="subName"></param>
        /// <param name="bundle"></param>
        /// <returns></returns>
        public static T LoadSubAssetSync<T>(string path, string subName, AssetBundle bundle) where T : Object
        {
            return LoaderManager.DefaultLoader.LoadSubAssetSync<T>(path, subName, bundle);
        }

        /// <summary>
        /// Asynchronously load resources from bundle
        /// 异步从资源包中加载资源
        /// </summary>
        /// <param name="assetFullPath">资源路径</param>
        /// <param name="bundle">资源包</param>
        /// <param name="onAssetLoaded">回调</param>
        /// <typeparam name="T">资源类型</typeparam>
        /// <returns></returns>
        public static void LoadAssetAsync<T>(string assetFullPath, AssetBundle bundle,
            LoaderDelegate.OnAssetLoaded<T> onAssetLoaded) where T : Object
        {
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.LoadAssetAsync(assetFullPath, bundle, onAssetLoaded));
        }

        /// <summary>
        /// Load resources asynchronously
        /// Asynchronous includes
        ///     1. Bundle download
        ///     2. Resource loading
        /// 异步加载资源
        /// 异步包括：
        ///     1.Bundle下载
        ///     2.资源加载
        /// </summary>
        /// <param name="bundleName">资源包名称</param>
        /// <param name="assetFullPath">资源路径</param>
        /// <param name="onLoaded">回调</param>
        /// <param name="autoRelease">是否自动释放资源包</param>
        /// <param name="unloadAllLoadedObjects">是否全部释放实例化的资源</param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static void LoadAssetAsync<T>(string bundleName, string assetFullPath,
            LoaderDelegate.OnAssetWithBundleLoaded<T> onLoaded,
            bool autoRelease = true, bool unloadAllLoadedObjects = false) where T : Object
        {
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.LoadAssetAsync(bundleName, assetFullPath, onLoaded, autoRelease,
                unloadAllLoadedObjects));
        }

        /// <summary>
        /// Batch asynchronously load resources from bundle
        /// 异步从资源包中批量加载资源
        /// </summary>
        /// <param name="assetFullPath">路径数组</param>
        /// <param name="ab">资源包</param>
        /// <param name="onMultiAssetLoaded">回调</param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static void LoadMulitAssetAsync<T>(string[] assetFullPath, AssetBundle ab,
            LoaderDelegate.OnMultiAssetLoaded<T> onMultiAssetLoaded)
            where T : Object
        {
            LoaderManager.Mono.StartCoroutine(LoaderManager.DefaultLoader.LoadMulitAssetAsync(assetFullPath, ab, onMultiAssetLoaded));
        }

        /// <summary>
        /// 打印高度Bundle引用情况
        /// </summary>
        public static void DebugBundleRef()
        {
#if UNITY_EDITOR
            BundleRefSet.DebugBundleRef();
#endif
        }

#if UNITY_EDITOR
        /// <summary>
        /// 创建ABLoader
        /// </summary>
        /// <returns></returns>
        public static ILoader CreatAbLoader()
        {
            return new AbLoader();
        }

        /// <summary>
        /// 创建ResLoader
        /// </summary>
        /// <returns></returns>
        public static ILoader CreatResLoader()
        {
            return new ResLoader();
        }

        /// <summary>
        /// 创建EditorLoader
        /// </summary>
        /// <returns></returns>
        public static ILoader CreatEditorLoader()
        {
            return new EditorLoader();
        }

#endif
    }
}