/*!
  \file
  \brief Lua の補助

  \author Satofumi KAMIMURA

  $Id: LuaHandler.cpp 1235 2009-08-21 07:59:16Z satofumi $
*/

#include "LuaHandler.h"
#include "log_printf.h"
#include <sstream>
#include <string>

using namespace qrk;
using namespace std;


namespace
{
  void handleError(lua_State* L)
  {
    string error_message = lua_tostring(L, -1);

    log_printf("error: %s\n", error_message.c_str());
  }
}


struct LuaHandler::pImpl
{
  string error_message_;
  lua_State* L_;
  string path_;


  pImpl(void)
    : error_message_("Not initialized."), L_(lua_open()), path_("")
  {
    luaL_openlibs(L_);
  }


  ~pImpl(void)
  {
    // exit() 時に lua に登録したオブジェクトが生成順に関係なく削除され、
    // Segmentation falt が起きるため、閉じないことにする
    // lua_close(L_);
  }


  static pImpl* object(void)
  {
    static pImpl singleton_object;
    return &singleton_object;
  }
};


LuaHandler::LuaHandler(void) : pimpl(pImpl::object())
{
}


LuaHandler::~LuaHandler(void)
{
}


lua_State* LuaHandler::pointer(void)
{
  return pImpl::object()->L_;
}


lua_State* LuaHandler::newthread(lua_State* L)
{
  return lua_newthread(L);
}


void LuaHandler::addPath(lua_State* L, const char* additional_path)
{
  LuaHandler lua_handler;
  lua_handler.pimpl->path_ += string(additional_path) + ";";

  // パス設定の評価
  string lua_path = "package.path = \"" + lua_handler.pimpl->path_ + "\"";
  lua_handler.dostring(L, lua_path.c_str());
}


int LuaHandler::dofile(lua_State* L, const char* lua_file)
{
  int ret = luaL_dofile(L, lua_file);
  if (ret) {
    handleError(L);
  }
  return ret;
}


int LuaHandler::dostring(lua_State* L, const char* lua_string)
{
  int ret = luaL_dostring(L, lua_string);
  if (ret) {
    handleError(L);
  }
  return ret;
}


void LuaHandler::registerValue(lua_State* L, const char* name, int value)
{
  lua_pushnumber(L, value);
  lua_setglobal(L, name);
}
