#if USE_UNI_LUA
using LuaAPI = UniLua.Lua;
using RealStatePtr = UniLua.ILuaState;
using LuaCSFunction = UniLua.CSharpFunctionDelegate;
#else
using LuaAPI = XLua.LuaDLL.Lua;
using RealStatePtr = System.IntPtr;
using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
#endif

using System;
using System.Collections.Generic;
using System.Reflection;
<%
require "TemplateCommon"
%>

namespace XLua.CSObjectWrap
{
    public class XLua_Gen_Initer_Register__
	{
        <%
        local split_method_perfix = 'wrapInit'
        local split_method_count = 0
        local wrap_in_split_method = 0
        local max_wrap_in_split_method = 50
        %>
        <%ForEachCsList(wraps, function(wrap)%>
        <%if wrap_in_split_method == 0 then%>static void <%=split_method_perfix%><%=split_method_count%>(LuaEnv luaenv, ObjectTranslator translator)
        {
        <%end%>
            translator.DelayWrapLoader(typeof(<%=CsFullTypeName(wrap)%>), <%=CSVariableName(wrap)%>Wrap.__Register);
        <%if wrap_in_split_method == max_wrap_in_split_method then
        wrap_in_split_method = 0
        split_method_count = split_method_count + 1
        %>
        }
        <%else
        wrap_in_split_method = wrap_in_split_method + 1
        end
        end)%>
        <% if generic_wraps then 
        for generic_def, instances in pairs(generic_wraps) do
        for _, args in ipairs(instances) do
        local generic_arg_list = "<"
        ForEachCsList(args, function(generic_arg, gai)
            if gai ~= 0 then generic_arg_list = generic_arg_list .. ", " end
            generic_arg_list = generic_arg_list .. CsFullTypeName(generic_arg)
        end)
        generic_arg_list = generic_arg_list .. ">"
        
        %>
        <%if wrap_in_split_method == 0 then%>static void <%=split_method_perfix%><%=split_method_count%>(LuaEnv luaenv, ObjectTranslator translator)
        {
        <%end%>
            translator.DelayWrapLoader(typeof(<%=generic_def.Name:gsub("`%d+", "") .. generic_arg_list%>), <%=CSVariableName(generic_def)%>Wrap<%=generic_arg_list%>.__Register);
        <%if wrap_in_split_method == max_wrap_in_split_method then
        wrap_in_split_method = 0
        split_method_count = split_method_count + 1
        %>
        }
        <%else
        wrap_in_split_method = wrap_in_split_method + 1
        end
        end
        end
        end%>
        
        <%if wrap_in_split_method ~= 0 then
        split_method_count = split_method_count + 1
        %>}<%end%>
        
        static void Init(LuaEnv luaenv, ObjectTranslator translator)
        {
            <%for i = 1, split_method_count do%>
            <%=split_method_perfix%><%=(i - 1)%>(luaenv, translator);
            <%end%>
            <%ForEachCsList(itf_bridges, function(itf_bridge)%>
            translator.AddInterfaceBridgeCreator(typeof(<%=CsFullTypeName(itf_bridge)%>), <%=CSVariableName(itf_bridge)%>Bridge.__Create);
            <%end)%>
        }
        
	    static XLua_Gen_Initer_Register__()
        {
		    XLua.LuaEnv.AddIniter(Init);
		}
		
		
	}
	
}
namespace XLua
{
	public partial class ObjectTranslator
	{
		static XLua.CSObjectWrap.XLua_Gen_Initer_Register__ s_gen_reg_dumb_obj = new XLua.CSObjectWrap.XLua_Gen_Initer_Register__();
		static XLua.CSObjectWrap.XLua_Gen_Initer_Register__ gen_reg_dumb_obj {get{return s_gen_reg_dumb_obj;}}
	}
	
	internal partial class InternalGlobals
    {
	    <%
		local type_to_methods = {}
		local seq_tbl = {}
		ForEachCsList(extension_methods, function(extension_method, idx)
		    local parameters = extension_method:GetParameters()
			local type = parameters[0].ParameterType
			if not type_to_methods[type] then
				type_to_methods[type] = {type = type}
				table.insert(seq_tbl, type_to_methods[type])
			end
			table.insert(type_to_methods[type], {method = extension_method, index = idx})
		%>
		delegate <%=CsFullTypeName(extension_method.ReturnType)%> __GEN_DELEGATE<%=idx%>(<%ForEachCsList(parameters, function(parameter, pi)
		%><%if pi ~= 0 then%>, <%end%><%if parameter.IsOut then %>out <% elseif parameter.ParameterType.IsByRef then %>ref <% end %> <%=CsFullTypeName(parameter.ParameterType)%> <%=parameter.Name%><%
		end)%>);
		<%end)%>
	    static InternalGlobals()
		{
		    extensionMethodMap = new Dictionary<Type, IEnumerable<MethodInfo>>()
			{
			    <%for _, methods_info in ipairs(seq_tbl) do%>
				{typeof(<%=CsFullTypeName(methods_info.type)%>), new List<MethodInfo>(){
				<%  for _, method_info in ipairs(methods_info) do%>
				  new __GEN_DELEGATE<%=method_info.index%>(<%=CsFullTypeName(method_info.method.DeclaringType)%>.<%=method_info.method.Name%>)
#if UNITY_WSA && !UNITY_EDITOR
                                      .GetMethodInfo(),
#else
                                      .Method,
#endif
				<%  end%>
				}},
				<%end%>
			};
			
			genTryArrayGetPtr = StaticLuaCallbacks.__tryArrayGet;
            genTryArraySetPtr = StaticLuaCallbacks.__tryArraySet;
		}
	}
}
