// ----------------------------------------------------------
// v0.91
// http://www.neuropolis.org/project/lua_from_d/
// Converted from lua.h by lunakid@neuropolis.org
// Thanks to Shinichiro Hamaji for bug-fixes!
//

private import lauxlib; // added by yaneurao

const char* LUA_VERSION   = "Lua 5.0";
const char* LUA_COPYRIGHT = "Copyright (C) 1994-2003 Tecgraf, PUC-Rio";
const char* LUA_AUTHORS   = "R. Ierusalimschy, L. H. de Figueiredo & W. Celes";

/* option for multiple returns in `lua_pcall' and `lua_call' */
const int   LUA_MULTRET = -1;


/*
** pseudo-indices
*/
const int   LUA_REGISTRYINDEX = -10000;
const int   LUA_GLOBALSINDEX  = -10001;
int             lua_upvalueindex(int i) { return LUA_GLOBALSINDEX - i; }


/* error codes for `lua_load' and `lua_pcall' */
const int   LUA_ERRRUN  = 1;
const int   LUA_ERRFILE = 2;
const int   LUA_ERRSYNTAX   = 3;
const int   LUA_ERRMEM  = 4;
const int   LUA_ERRERR  = 5;


typedef  void* lua_State;

//I think that it should be in C linkage... [Shinichiro Hamaji]
extern (C)
{
    typedef int (*lua_CFunction) (lua_State L);
}

/*
** functions that read/write blocks when loading/dumping Lua chunks
*/
typedef char* (*lua_Chunkreader) (lua_State L, void* ud, uint* sz);
typedef int   (*lua_Chunkwriter) (lua_State L, void* p, uint sz, void* ud);

/*
** basic types
*/
const int   LUA_TNONE   = -1;

const int   LUA_TNIL    = 0;
const int   LUA_TBOOLEAN    = 1;
const int   LUA_TLIGHTUSERDATA  = 2;
const int   LUA_TNUMBER = 3;
const int   LUA_TSTRING = 4;
const int   LUA_TTABLE  = 5;
const int   LUA_TFUNCTION   = 6;
const int   LUA_TUSERDATA   = 7;
const int   LUA_TTHREAD = 8;


/* minimum Lua stack available to a C function */
const int   LUA_MINSTACK    = 20;


/* type of numbers in Lua */
version (LUA_NUMBER)
{
    typedef LUA_NUMBER lua_Number;
}
else
{
    typedef double     lua_Number;
}


extern (C)
{
/*
** state manipulation
*/
lua_State lua_open ();
void      lua_close (lua_State L);
lua_State lua_newthread (lua_State L);

lua_CFunction   lua_atpanic (lua_State L, lua_CFunction panicf);


/*
** basic stack manipulation
*/
int   lua_gettop(lua_State L);
void  lua_settop(lua_State L, int idx);
void  lua_pushvalue (lua_State L, int idx);
void  lua_remove (lua_State L, int idx);
void  lua_insert (lua_State L, int idx);
void  lua_replace (lua_State L, int idx);
int   lua_checkstack (lua_State L, int sz);

void  lua_xmove (lua_State from, lua_State to, int n);

/*
** access functions (stack -> C)
*/

int             lua_isnumber (lua_State L, int idx);
int             lua_isstring (lua_State L, int idx);
int             lua_iscfunction (lua_State L, int idx);
int             lua_isuserdata (lua_State L, int idx);
int             lua_type (lua_State L, int idx);
char*           lua_typename (lua_State L, int tp);

int             lua_equal (lua_State L, int idx1, int idx2);
int             lua_rawequal (lua_State L, int idx1, int idx2);
int             lua_lessthan (lua_State L, int idx1, int idx2);

lua_Number      lua_tonumber (lua_State L, int idx);
int             lua_toboolean (lua_State L, int idx);
char*           lua_tostring (lua_State L, int idx);
uint            lua_strlen (lua_State L, int idx);
lua_CFunction   lua_tocfunction (lua_State L, int idx);
void*           lua_touserdata (lua_State L, int idx);
lua_State       lua_tothread (lua_State L, int idx);
void*           lua_topointer (lua_State L, int idx);


/*
** push functions (C -> stack)
*/
void  lua_pushnil (lua_State L);
void  lua_pushnumber (lua_State L, lua_Number n);
void  lua_pushlstring (lua_State L, char* s, uint l);
void  lua_pushstring (lua_State L, char* s);
char* lua_pushvfstring (lua_State L, char* fmt, void* argp);
char* lua_pushfstring (lua_State L, char* fmt, ...);
void  lua_pushcclosure (lua_State L, lua_CFunction fn, int n);
void  lua_pushboolean (lua_State L, int b);
void  lua_pushlightuserdata (lua_State L, void* p);


/*
** get functions (Lua -> stack)
*/
void  lua_gettable (lua_State L, int idx);
void  lua_rawget (lua_State L, int idx);
void  lua_rawgeti (lua_State L, int idx, int n);
void  lua_newtable (lua_State L);
void* lua_newuserdata (lua_State L, uint sz);
int   lua_getmetatable (lua_State L, int objindex);
void  lua_getfenv (lua_State L, int idx);


/*
** set functions (stack -> Lua)
*/
void  lua_settable (lua_State L, int idx);
void  lua_rawset (lua_State L, int idx);
void  lua_rawseti (lua_State L, int idx, int n);
int   lua_setmetatable (lua_State L, int objindex);
int   lua_setfenv (lua_State L, int idx);


/*
** `load' and `call' functions (load and run Lua code)
*/
void  lua_call (lua_State L, int nargs, int nresults);
int   lua_pcall (lua_State L, int nargs, int nresults, int errfunc);
int   lua_cpcall (lua_State L, lua_CFunction func, void* ud);
int   lua_load (lua_State L, lua_Chunkreader reader, void* dt,
                        char* chunkname);

int lua_dump (lua_State L, lua_Chunkwriter writer, void* data);


/*
** coroutine functions
*/
int  lua_yield (lua_State L, int nresults);
int  lua_resume (lua_State L, int narg);

/*
** garbage-collection functions
*/
int   lua_getgcthreshold (lua_State L);
int   lua_getgccount (lua_State L);
void  lua_setgcthreshold (lua_State L, int newthreshold);

/*
** miscellaneous functions
*/

char* lua_version ();

int   lua_error (lua_State L);

int   lua_next (lua_State L, int idx);

void  lua_concat (lua_State L, int n);

}

/*
** ===============================================================
** some useful macros
** ===============================================================
*/

// "Actually, lua_boxpointer (and lua_unboxpointer) are kind of
// deprecated" -- Roberto Ierusalimschy
// lua_boxpointer...
// lua_unboxpointer...

void lua_pop(lua_State L, int n) { lua_settop(L, -n - 1); }

void lua_register(lua_State L, char* name, lua_CFunction f) {
    lua_pushstring(L, name);
    lua_pushcfunction(L, f);
    lua_settable(L, LUA_GLOBALSINDEX);
}

void lua_pushcfunction(lua_State L, lua_CFunction f) {
    lua_pushcclosure(L, f, 0);
}

int lua_isfunction(lua_State L, int n) {
    return lua_type(L, n) == LUA_TFUNCTION;
}
int lua_istable(lua_State L, int n) {
    return lua_type(L, n) == LUA_TTABLE;
}
int lua_islightuserdata(lua_State L, int n) {
    return lua_type(L, n) == LUA_TLIGHTUSERDATA;
}
int lua_isnil(lua_State L, int n) {
    return lua_type(L, n) == LUA_TNIL;
}
int lua_isboolean(lua_State L, int n) {
    return lua_type(L, n) == LUA_TBOOLEAN;
}
int lua_isnone(lua_State L, int n) {
    return lua_type(L, n) == LUA_TNONE;
}
int lua_isnoneornil(lua_State L, int n) {
    return lua_type(L, n) <= 0;
}

void lua_pushliteral(lua_State L, char* s) {
    lua_pushlstring(L, s, s.size);
}



/*
** compatibility macros and functions
*/

int  lua_pushupvalues (lua_State L);

void lua_getregistry(lua_State L) { lua_pushvalue(L, LUA_REGISTRYINDEX); }

void lua_setglobal(lua_State L, char* s) {
    lua_pushstring(L, s);
    lua_insert(L, -2);
    lua_settable(L, LUA_GLOBALSINDEX);
}

void lua_getglobal(lua_State L, char* s) {
    lua_pushstring(L, s);
    lua_gettable(L, LUA_GLOBALSINDEX);
}

/* compatibility with ref system */

/* pre-defined references */
const int   LUA_NOREF   = -2;
const int   LUA_REFNIL  = -1;

int lua_ref(lua_State L, int lock) {
    if (lock) {
        return luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
          lua_pushstring(L, "unlocked references are obsolete");
          lua_error(L);
          return 0;
    }
}

void lua_unref(lua_State L, int ref) {
    luaL_unref(L, LUA_REGISTRYINDEX, ref);
}

void lua_getref(lua_State L, int ref) {
    lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
}


/*
** {======================================================================
** useful definitions for Lua kernel and libraries
** =======================================================================
*/

//!! Does this make any sense here in D?...

/* formats for Lua numbers */
//!!#ifndef LUA_NUMBER_SCAN
const char* LUA_NUMBER_SCAN = "%lf";
//!!#endif

//!!#ifndef LUA_NUMBER_FMT
const char* LUA_NUMBER_FMT  = "%.14g";
//!!#endif

/* }====================================================================== */


/*
** {======================================================================
** Debug API
** =======================================================================
*/


/*
** Event codes
*/
const int   LUA_HOOKCALL    = 0;
const int   LUA_HOOKRET = 1;
const int   LUA_HOOKLINE    = 2;
const int   LUA_HOOKCOUNT   = 3;
const int   LUA_HOOKTAILRET = 4;


/*
** Event masks
*/
const int   LUA_MASKCALL    = 1 << LUA_HOOKCALL;
const int   LUA_MASKRET = 1 << LUA_HOOKRET;
const int   LUA_MASKLINE    = 1 << LUA_HOOKLINE;
const int   LUA_MASKCOUNT   = 1 << LUA_HOOKCOUNT;

const int LUA_IDSIZE    = 60;


/* activation record */
struct lua_Debug {
  int event;
  char* name;      /* (n) */
  char* namewhat;  /* (n) `global', `local', `field', `method' */
  char* what;      /* (S) `Lua', `C', `main', `tail' */
  char* source;    /* (S) */
  int currentline; /* (l) */
  int nups;        /* (u) number of upvalues */
  int linedefined; /* (S) */
  char short_src[LUA_IDSIZE]; /* (S) */
  /* private part */
  int i_ci;        /* active function */
};


typedef void (*lua_Hook) (lua_State L, lua_Debug *ar);

int   lua_getstack (lua_State L, int level, lua_Debug* ar);
int   lua_getinfo (lua_State L, char* what, lua_Debug* ar);
char* lua_getlocal (lua_State L, lua_Debug* ar, int n);
char* lua_setlocal (lua_State L, lua_Debug* ar, int n);
char* lua_getupvalue (lua_State L, int funcindex, int n);
char* lua_setupvalue (lua_State L, int funcindex, int n);

int lua_sethook (lua_State L, lua_Hook func, int mask, int count);
lua_Hook lua_gethook (lua_State L);
int lua_gethookmask (lua_State L);
int lua_gethookcount (lua_State L);
