using UnityEngine;
using System.Collections;


namespace CommonUnity3D.XMUnity.LoadUtil
{

    /// <summary>
    /// AssetBundle加载适配器.
    /// </summary>
    public class XMUnityABLoadAdapter
    {

        private static string mLoadRootPath = null;
        public delegate void XMUnityLoadAdapterCallBack(XMUnityAssetBundle ab);
        public delegate void LoadFinishCallBack(XMUnityABLoadAdapter adapter);

        private LoadFinishCallBack OnFinshCallBack = null;
        private XMUnityLoadAdapterCallBack OnLoadCallBack = null;
        private XMUnityLoadIml mIml;
        private string mErrorLog = null;
        private bool mHasDone = false;
        public bool HasDone { get { return mHasDone; } }
        private bool mIsDispose = false;
        private string mURL = null;
        protected bool mLoadAsync = true;
        public bool LoadAsync { set { mLoadAsync = value; } get { return mLoadAsync; } }
        XMUnityAssetBundle mXMUnityAssetBundle = null;

        private static int mVersionCount = 0;

        public static void SetLoadRootPath(string path)
        {
            mLoadRootPath = path;
        }
        public XMUnityABLoadAdapter()
        {

        }
        public virtual void Load(string url, XMUnityLoadAdapterCallBack callBack)
        {
            if (string.IsNullOrEmpty(url))
            {
                Debug.Log("XMUnityLoadAdapter Invalid args: " + url);
            }

            if (callBack != null)
            {
                OnLoadCallBack += callBack;
            }


            mURL = url;

            string loadPath = mLoadRootPath + url;

            StartLoad(loadPath);
        }
        public string GetURL()
        {
            return mURL;
        }
        public virtual void SetFinishCallBack(LoadFinishCallBack callBack)
        {
            OnFinshCallBack = callBack;
        }
        public virtual void AddCallBack(XMUnityLoadAdapterCallBack callBack)
        {
            OnLoadCallBack += callBack;
        }
        public virtual void RemoveCallBack(XMUnityLoadAdapterCallBack callBack)
        {
            OnLoadCallBack -= callBack;
        }
        protected virtual void StartLoad(string loadPath)
        {
            mIml = CreateLoadAdapter();
            mIml.LoadAsync = mLoadAsync;
            mIml.Load(loadPath);
        }
        public bool OnAdapterUpdate()
        {
            if (mHasDone)
            {
                return true;
            }

            return OnUpdateLoad();
        }
        protected virtual bool OnUpdateLoad()
        {
            if (IsLoadFinish())
            {
                OnLoadFinish();
                return true;
            }

            return false;
        }
        public virtual void OnStartLoad()
        {

        }
        public virtual void OnStopLoad()
        {

        }
        public virtual void OnLoadFinish()
        {
            if (OnFinshCallBack != null)
            {
                OnFinshCallBack.Invoke(this);
                OnFinshCallBack = null;
            }

            mHasDone = true;

            if (mIml != null)
            {
                mIml.Dispose();
            }
        }
        public XMUnityAssetBundle GetXMUnityAssetBundle()
        {
            if (mXMUnityAssetBundle == null)
            {
                AssetBundle ab = mIml.GetAssetBundle();
                if(ab != null)
                {
                    mXMUnityAssetBundle = new XMUnityAssetBundle(mURL, ab, mVersionCount++);
                }
            }
            return mXMUnityAssetBundle;
        }
        public virtual void DispatchCallBack()
        {
            if (mIml == null)
            {
                return;
            }

            if (OnLoadCallBack != null)
            {
                var mfab = GetXMUnityAssetBundle();
                OnLoadCallBack(mfab);
            }
        }
        public virtual float GetProgress()
        {
            if (mHasDone)
            {
                return 1;
            }

            if (mIml != null)
            {
                return mIml.GetProgress();
            }

            return 0;
        }
        public virtual void Dispose()
        {
            if (OnFinshCallBack != null)
            {
                Debug.Log("XMUnityABLoadAdapter dispose before finish!");
            }
            if (mIml != null)
            {
                mIml.Dispose();
                mIml = null;
            }
            mIsDispose = true;
            OnLoadCallBack = null;

        }
        public virtual AssetBundle GetAssetBundle()
        {
            if (mIml != null)
            {
                return mIml.GetAssetBundle();
            }

            return null;
        }
        protected bool IsLoadFinish()
        {
            if (mIsDispose)
            {
                return true;
            }


            if (mIml == null)
            {
                return false;
            }

            if (mIml.IsLoadError())
            {
                OnLoadError(mIml.GetErrorLog());
            }

            if (mIml.IsLoadFinish())
            {
                return true;
            }

            return false;
        }
        protected virtual void OnLoadError(string error)
        {
            mErrorLog = error;
            Debug.Log("XMUnityABLoadAdapter OnLoadError: " + mErrorLog);
        }
        private static XMUnityLoadIml CreateLoadAdapter()
        {
            //工厂类,后续有需求,再新增setFactory.
            return XMUnityLoadImlFactory.GetInstance().CreateLoadIml();
        }
    }
}