#include "pw/scripting/script.hpp"

#include "runtime_lua.hpp"

#include "pw/core/debug.hpp"


namespace pw {


PW_REGISTER_DECL_LUA(core)
PW_REGISTER_DECL_LUA(system)
PW_REGISTER_DECL_LUA(io)
PW_REGISTER_DECL_LUA(scene)
PW_REGISTER_DECL_LUA(visual)

struct script::state {

	sol::state _state;
	sol::table _namespace;

	state();

	void load_all();
	void load(const std::string& name);

	int run(const std::string &s);

};

int script::state::run(const std::string &s)
{
	return _state.script(s.c_str()).get<int>();
}

void script::state::load(const std::string& name)
{
	auto f = runtime_lua::get().register_functions()[name];
	f(_state,_namespace);
}

script::state::state()
{
	// create global pw namespace
	_namespace = _state.create_named_table("pw");


	// add the script as a user type
	_namespace.new_usertype<state>("script",
                                   "load_all",&state::load_all,
								   "load",&state::load
								   );

	// add this instance as "script"
	_namespace.set("script",this);

}

void script::state::load_all() {

	// open all libraries
	_state.open_libraries();
	//
	for (auto m : runtime_lua::get().register_functions()) {
		m.second(_state,_namespace);
//        debug::d() << "loading module " << m.first;
	}
}

//
// script
//

script::script()
	: _state(make_unique<script::state>())
{
}

script::~script()
{
}

int script::eval(const std::string &s)
{
	return _state->run(s);
}

void script::initialize()
{

    PW_REGISTER_USE_LUA(core)
    PW_REGISTER_USE_LUA(system)
    PW_REGISTER_USE_LUA(io)
    PW_REGISTER_USE_LUA(scene)
    PW_REGISTER_USE_LUA(visual)

}


}




