using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;

public class ResourceMgr
{
    private static ResourceMgr mInstance;
    public static ResourceMgr instance
    {
        get
        {
            if (null == mInstance)
                mInstance = new ResourceMgr();
            return mInstance;
        }
    }

    // assetbundle管理仓库
    private Dictionary<string, AssetBundle> mBundles = new Dictionary<string, AssetBundle>();
    // assets管理仓库
    private Dictionary<string, UnityEngine.Object> mAssets = new Dictionary<string, UnityEngine.Object>();

    public string updatePath
    {
        get
        {
            return Application.persistentDataPath + "/update";
        }
    }

    /// <summary>
    /// 预加载基础的bundle资源
    /// </summary>
    public void PreloadBaseBundle()
    {
        LoadAssetBundle("baseres.bundle");
    }

    /// <summary>
    /// 预加载lua的bundle资源
    /// </summary>
    public void PreloadLuaBundles()
    {
        if (File.Exists(updatePath + "/lua_update.bundle"))
            LoadAssetBundle("lua_update.bundle");
        LoadAssetBundle("lua.bundle");
    }

    public T LoadAsset<T>(int resId) where T : UnityEngine.Object
    {
        var resCfg = ResourceCfg.instance.GetResCfg(resId);
        return LoadAsset<T>(resCfg.editor_path);
    }

    public T LoadAsset<T>(string resPath) where T : UnityEngine.Object
    {
        if (mAssets.ContainsKey(resPath))
            return mAssets[resPath] as T;

        T obj = null;
#if UNITY_EDITOR
        obj = AssetDatabase.LoadAssetAtPath<T>("Assets/GameRes/" + resPath);
#else
        var abName = resPath.Substring(0, resPath.IndexOf("/")).ToLower() + ".bundle";
        var fname = Path.GetFileName(resPath);
        AssetBundle ab = null;
        if (File.Exists(updatePath + "/" + fname))
        {
            // 热更的资源，是一个独立的assetbundle文件，已fname为文件名
            ab = LoadAssetBundle(fname);
        }
        else
        {
            ab = LoadAssetBundle(abName);
        }
        if (null != ab)
        {
            var assetName = fname.Substring(0, fname.IndexOf("."));
            obj = ab.LoadAsset<T>(assetName);
        }
#endif
        if (null != obj)
            mAssets[resPath] = obj;
        return obj;
    }

    /// <summary>
    /// 读取配置文件
    /// </summary>
    /// <param name="cfgFileName"></param>
    /// <returns></returns>
    public string LoadCfgFile(string cfgFileName)
    {
        TextAsset asset = null;
#if UNITY_EDITOR
        asset = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/GameRes/Config/" + cfgFileName);
#else
        var bundle = LoadAssetBundle("normal_cfg.bundle");
        if (null != bundle)
            asset = bundle.LoadAsset<TextAsset>(cfgFileName);
#endif
        if (null != asset)
        {
            return asset.text;
        }
        else
        {
            GameLogger.LogError("ResourceMgr.LoadCfgFile Error, asset = null, cfgFileName = " + cfgFileName);
            return null;
        }
    }

    /// <summary>
    /// 读取AssetBundle
    /// </summary>
    /// <param name="abName">名称</param>
    /// <returns></returns>
    private AssetBundle LoadAssetBundle(string abName)
    {
        if (mBundles.ContainsKey(abName))
            return mBundles[abName];

        AssetBundle bundle = null;
        if (File.Exists(updatePath + "/" + abName))
        {
            // 优先从update目录（热更新目录）中查找资源
            bundle = AssetBundle.LoadFromFile(updatePath + "/" + abName);
        }
        else
        {
            bundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/res/" + abName);
        }

        if (null != bundle)
        {
            mBundles[abName] = bundle;
        }
        return bundle;
    }

    /// <summary>
    /// 获取AssetBundle
    /// </summary>
    /// <param name="abName"></param>
    /// <returns></returns>
    public AssetBundle GetAssetBundle(string abName)
    {
        if (mBundles.ContainsKey(abName))
        {
            return mBundles[abName];
        }
        Debug.LogError("GetAssetBundle Error, not contains: " + abName);
        return null;
    }
}
