/* -----------------------------------------------------------------------------
 * lua_fnptr.i
 *
 * SWIG Library file containing the main typemap code to support Lua modules.
 * ----------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
 *                          Basic function pointer support
 * ----------------------------------------------------------------------------- */
/*
The structure: SWIGLUA_FN provides a simple (local only) wrapping for a function.

For example if you wanted to have a C/C++ function take a lua function as a parameter.
You could declare it as:
  int my_func(int a, int b, SWIGLUA_FN fn);
note: it should be passed by value, not byref or as a pointer.

The SWIGLUA_FN holds a pointer to the lua_State, and the stack index where the function is held.
The macro SWIGLUA_FN_GET() will put a copy of the lua function at the top of the stack.
After that its fairly simple to write the rest of the code (assuming know how to use lua),
just push the parameters, call the function and return the result.

  int my_func(int a, int b, SWIGLUA_FN fn)
  {
    SWIGLUA_FN_GET(fn);
    lua_pushnumber(fn.L,a);
    lua_pushnumber(fn.L,b);
    lua_call(fn.L,2,1);    // 2 in, 1 out
    return luaL_checknumber(fn.L,-1);
  }

SWIG will automatically performs the wrapping of the arguments in and out.

However: if you wish to store the function between calls, look to the SWIGLUA_REF below.

*/
// this is for the C code only, we don't want SWIG to wrapper it for us.
%{
typedef struct{
  lua_State* L; /* the state */
  int idx;      /* the index on the stack */
}SWIGLUA_FN;

#define SWIGLUA_FN_GET(fn) {lua_pushvalue(fn.L,fn.idx);}
%}

// the actual typemap
%typemap(in,checkfn="lua_isfunction") SWIGLUA_FN
%{  $1.L=L; $1.idx=$input; %}

/* -----------------------------------------------------------------------------
 *                          Storing lua object support
 * ----------------------------------------------------------------------------- */
/*
The structure: SWIGLUA_REF provides a mechanism to store object (usually functions)
between calls to the interpreter.

For example if you wanted to have a C/C++ function take a lua function as a parameter.
Then call it later, You could declare it as:
  SWIGLUA_REF myref;
  void set_func(SWIGLUA_REF ref);
  SWIGLUA_REF get_func();
  void call_func(int val);
note: it should be passed by value, not byref or as a pointer.

The SWIGLUA_REF holds a pointer to the lua_State, and an integer reference to the object.
Because it holds a permanent ref to an object, the SWIGLUA_REF must be handled with a bit more care.
It should be initialised to {0,0}. The function swiglua_ref_set() should be used to set it.
swiglua_ref_clear() should be used to clear it when not in use, and swiglua_ref_get() to get the
data back.

Note: the typemap does not check that the object is in fact a function,
if you need that you must add it yourself.


  int my_func(int a, int b, SWIGLUA_FN fn)
  {
    SWIGLUA_FN_GET(fn);
    lua_pushnumber(fn.L,a);
    lua_pushnumber(fn.L,b);
    lua_call(fn.L,2,1);    // 2 in, 1 out
    return luaL_checknumber(fn.L,-1);
  }

SWIG will automatically performs the wrapping of the arguments in and out.

However: if you wish to store the function between calls, look to the SWIGLUA_REF below.

*/

%{
typedef struct{
  lua_State* L; /* the state */
  int ref;      /* a ref in the lua global index */
}SWIGLUA_REF;


void swiglua_ref_clear(SWIGLUA_REF* pref){
 	if (pref->L!=0 && pref->ref!=LUA_NOREF && pref->ref!=LUA_REFNIL){
		luaL_unref(pref->L,LUA_REGISTRYINDEX,pref->ref);
	}
	pref->L=0; pref->ref=0;
}

void swiglua_ref_set(SWIGLUA_REF* pref,lua_State* L,int idx){
//	swiglua_ref_clear(pref); /* just in case */
	pref->L=L;
	lua_pushvalue(L,idx);                 /* copy obj to top */
	pref->ref=luaL_ref(L,LUA_REGISTRYINDEX); /* remove obj from top & put into registry */
}

void swiglua_ref_get(SWIGLUA_REF* pref){
	if (pref->L!=0)
		lua_rawgeti(pref->L,LUA_REGISTRYINDEX,pref->ref);
}

%}

%typemap(in) SWIGLUA_REF
%{  swiglua_ref_set(&$1,L,$input); %}

%typemap(out) SWIGLUA_REF
%{  if ($1.L!=0)  {swiglua_ref_get(&$1);} else {lua_pushnil(L);}
  SWIG_arg++; %}

