#include "scriptnode.h"
#include "engine.h"
#include "sparrowshell/sparrowshell.h"
#include <iostream>
#include <sstream>
#include <string>
#include "Version.h"
#include "SparrowInput/Version.h"
#include "SparrowRenderer/Version.h"
#include "SparrowSerializer/Version.h"
#include "guitools.h"

#define LUA_DEFINE(var) S[#var]=var
#define LUA_SET_FUN(var) m_script.set_function(#var,&ScriptNode::var,this);this->functions_name.push_back(#var);

ScriptNode::ScriptNode()
{
    LUA_SET_FUN(getDeltaTime);
    LUA_SET_FUN(print);
    LUA_SET_FUN(version);
    LUA_SET_FUN(clear);
    LUA_SET_FUN(picker);
    LUA_SET_FUN(materialEditor);
    LUA_SET_FUN(rendering);

    m_script.new_usertype<Engine>("Engine",
                                  "time",&Engine::getTime
                                  );
}

void ScriptNode::update(){
    static bool test = true;
    if(test && m_scene!= nullptr){
        m_script["engine"] = getEngine();
        test=false;
    }
}

void ScriptNode::execute(std::string to_execute){
    try{
        m_script.script(to_execute);
    }catch(sol::error error_lua){
        this->getEngine().getShell()->out(error_lua.what(),glm::vec3(1,0,0));
    }
}

std::vector<std::string> ScriptNode::possibleCompletion(std::string search){
    std::vector<std::string> result;
    for(std::string& name : functions_name)
        if(name.find(search)==0)
            result.push_back(name);
    return result;
}

void ScriptNode::print(std::string to_print){
    this->getEngine().getShell()->out(to_print.append("\n"));
}

void ScriptNode::version(){
    std::ostringstream oss;
    oss << " SparrowEngine version: "<< SparrowEngine_VERSION_MAJOR << "." << SparrowEngine_VERSION_MINOR;
    this->getEngine().getShell()->out(oss.str());
    oss.str("");
    oss << " SparrowInput version: "<< SparrowInput_VERSION_MAJOR << "." << SparrowInput_VERSION_MINOR;
    this->getEngine().getShell()->out(oss.str());
    oss.str("");
    oss << " SparrowRenderer version: "<< SparrowRenderer_VERSION_MAJOR << "." << SparrowRenderer_VERSION_MINOR;
    this->getEngine().getShell()->out(oss.str());
    oss.str("");
    oss << " SparrowSerializer version: "<< SparrowSerializer_VERSION_MAJOR << "." << SparrowSerializer_VERSION_MINOR;
    this->getEngine().getShell()->out(oss.str());
}

void ScriptNode::clear(){
    this->getEngine().getShell()->clear();
}

float ScriptNode::getDeltaTime(){
   return this->getEngine().getDeltaTime()/1000.;
}

void ScriptNode::testfunc(int i, float x=0.f,float y=0.f, float z=0.f){
    std::string s;
    s= "Pop item ";
    s+= std::to_string(i)+" at position (";
    s+=std::to_string(x);
    s+=",";
    s+=std::to_string(y);
    s+=",";
    s+=std::to_string(z);
    s+=")";
    this->getEngine().getShell()->out(s.append("\n"));
}

void ScriptNode::picker(){
    this->getEngine().getGuiTools()->togglePicker();
}

void ScriptNode::materialEditor(){
    this->getEngine().getGuiTools()->toggleMaterialEditor();
}

void ScriptNode::rendering(){
    this->getEngine().getGuiTools()->toggleRenderingPipelineGui();
}
