using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using XLua;
//using System;

namespace SFramework
{
    [System.Serializable]
    public class Injection
    {
        public string name;
        public GameObject value;
    }

    [XLua.LuaCallCSharp]
    public class SLuaBehaviour : MonoBehaviour
    {
        public TextAsset luaScript;
        public Injection[] injections;

        //internal static XLua.LuaEnv luaEnv = new XLua.LuaEnv(); //all lua behaviour shared one luaenv only!
        internal static XLua.LuaEnv luaEnv = SLuaEnv.Instance;
        internal static float lastGCTime = 0;
        internal const float GCInterval = 1;//1 second 

        private System.Action _luaStart;
        private System.Action _luaUpdate;
        private System.Action _luaOnDestroy;

        private XLua.LuaTable _scriptEnv;

        void Awake()
        {
            _scriptEnv = luaEnv.NewTable();

            // 为每个脚本设置一个独立的环境，可一定程度上防止脚本间全局变量、函数冲突
            XLua.LuaTable meta = luaEnv.NewTable();
            meta.Set("__index", luaEnv.Global);
            _scriptEnv.SetMetaTable(meta);
            meta.Dispose();

            _scriptEnv.Set("self", this);
            foreach (var injection in injections)
            {
                _scriptEnv.Set(injection.name, injection.value);
            }

            luaEnv.DoString(luaScript.text, "LuaBehaviour", _scriptEnv);

            System.Action luaAwake = _scriptEnv.Get<System.Action>("Awake");
            _scriptEnv.Get("Start", out _luaStart);
            _scriptEnv.Get("Update", out _luaUpdate);
            _scriptEnv.Get("OnDestroy", out _luaOnDestroy);

            if (luaAwake != null)
            {
                luaAwake();
            }
        }

        // Use this for initialization
        void Start()
        {
            if (_luaStart != null)
            {
                _luaStart();
            }
        }

        // Update is called once per frame
        void Update()
        {
            if (_luaUpdate != null)
            {
                _luaUpdate();
            }
            if (Time.time - SLuaBehaviour.lastGCTime > GCInterval)
            {
                luaEnv.Tick();
                SLuaBehaviour.lastGCTime = Time.time;
            }
        }

        void OnDestroy()
        {
            if (_luaOnDestroy != null)
            {
                _luaOnDestroy();
            }
            _luaOnDestroy = null;
            _luaUpdate = null;
            _luaStart = null;
            _scriptEnv.Dispose();
            injections = null;
        }
    }

}
