/*
 * PtokaX MultiLib - Compatibility layer allowing same lib to work on PXLua based on Lua 5.1 and 5.3.

 * Copyright (C) 2012-2015  Petr Kozelka, PPK at PtokaX dot org

 * This code is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

 * See http://creativecommons.org/licenses/by-nc/4.0/ for license details.
 */

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#ifndef LauxLibH
#define LauxLibH
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <stdio.h>
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "lua.h"
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define LUAL_BUFFERSIZE	((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef struct luaL_Reg {
    const char *name;
    lua_CFunction func;
} luaL_Reg;

typedef struct luaL_Buffer51 {
    char *p;
    int lvl;
    lua_State *L;
    char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer51;

typedef struct luaL_Buffer52 {
    char *b;
    size_t size;
    size_t n;
    lua_State *L;
    char initb[LUAL_BUFFERSIZE];
} luaL_Buffer52;

#define luaL_Buffer        luaL_Buffer52
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef void (* pluaL_register)(lua_State *, const char *, const luaL_Reg *); // 5.1 only
pluaL_register luaL_register;

typedef int (* pluaL_typerror)(lua_State *, int, const char *); // 5.1 only
pluaL_typerror luaL_typerror;

typedef int (* pluaL_argerror)(lua_State *, int, const char *);
pluaL_argerror luaL_argerror;

typedef const char * (* pluaL_checklstring)(lua_State *, int, size_t *);
pluaL_checklstring luaL_checklstring;

typedef const char * (* pluaL_optlstring)(lua_State *, int, const char *, size_t *);
pluaL_optlstring luaL_optlstring;

typedef lua_Number (* pluaL_checknumber)(lua_State *, int);
pluaL_checknumber luaL_checknumber;

typedef lua_Number (* pluaL_optnumber)(lua_State *, int, lua_Number);
pluaL_optnumber luaL_optnumber;

typedef lua_Integer (* pluaL_checkinteger)(lua_State *, int);
pluaL_checkinteger luaL_checkinteger;

typedef lua_Integer (* pluaL_optinteger)(lua_State *, int, lua_Integer);
pluaL_optinteger luaL_optinteger;

typedef void (* pluaL_checkstack)(lua_State *, int, const char *);
pluaL_checkstack luaL_checkstack;

typedef void (* pluaL_checktype)(lua_State *, int, int);
pluaL_checktype luaL_checktype;

typedef int (* pluaL_newmetatable)(lua_State *, const char *);
pluaL_newmetatable luaL_newmetatable;

typedef void * (* pluaL_checkudata)(lua_State *, int, const char *);
pluaL_checkudata luaL_checkudata;

typedef int (* pluaL_error)(lua_State *, const char *, ...);
pluaL_error luaL_error;

typedef int (* pluaL_checkoption)(lua_State *, int, const char *, const char * const lst[]);
pluaL_checkoption luaL_checkoption;

typedef int (* pluaL_ref)(lua_State *, int);
pluaL_ref luaL_ref;

typedef void (* pluaL_unref)(lua_State *, int, int);
pluaL_unref luaL_unref;

typedef void (* pluaL_buffinit)(lua_State *, luaL_Buffer *);
pluaL_buffinit luaL_buffinit;

typedef char * (* pluaL_prepbuffer)(luaL_Buffer *); // 5.1 only
pluaL_prepbuffer luaL_prepbuffer;

typedef char * (* pluaL_prepbuffsize)(luaL_Buffer *, size_t); // 5.2+
pluaL_prepbuffsize luaL_prepbuffsize;

typedef void (* pluaL_addlstring)(luaL_Buffer *, const char *, size_t);
pluaL_addlstring luaL_addlstring;

typedef void (* pluaL_addstring)(luaL_Buffer *, const char *);
pluaL_addstring luaL_addstring;

typedef void (* pluaL_addvalue)(luaL_Buffer *);
pluaL_addvalue luaL_addvalue;

typedef void (* pluaL_pushresult)(luaL_Buffer *);
pluaL_pushresult luaL_pushresult;

typedef void (* pluaL_setfuncs)(lua_State *, const luaL_Reg *, int); // 5.2+
pluaL_setfuncs luaL_setfuncs;

typedef void (* pluaL_requiref)(lua_State *, const char *, lua_CFunction, int); // 5.2+
pluaL_requiref luaL_requiref;

typedef void (* pluaL_addchar)(luaL_Buffer *, const char);
pluaL_addchar luaL_addchar;

typedef void (* pluaL_addsize)(luaL_Buffer *, const size_t);
pluaL_addsize luaL_addsize;
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define luaL_newlibtable(L, l)                      lua_createtable(L, 0, sizeof(l) / sizeof((l)[0]) - 1) // 5.2+
#define luaL_newlib(L, l)                           (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0)) // 5.2+
#define luaL_argcheck(L, cond, arg, extramsg)		((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
#define luaL_checkstring(L, n)                      (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L, n, d)                     (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L, n)                         ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L, n, d)                        ((int)luaL_optinteger(L, (n), (d)))
#define luaL_optlong(L, n, d)                       ((long)luaL_optinteger(L, (n), (d)))
#define luaL_typename(L, i)                         lua_typename(L, lua_type(L, (i)))
#define luaL_getmetatable(L, n)                     (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_putchar(B, c)                          luaL_addchar(B, c) // 5.1 only
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define LUA_NOREF       (-2)
#define LUA_REFNIL      (-1)
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

static int luaL52_typerror(lua_State *L, int narg, const char *tname);
static char * luaL52_prepbuffer(luaL_Buffer *B);
static void luaL51_addchar(luaL_Buffer * B, const char c);
static void luaL52_addchar(luaL_Buffer * B, const char c);
static void luaL51_addsize(luaL_Buffer * B, const size_t s);
static void luaL52_addsize(luaL_Buffer * B, const size_t s);
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#endif
