void ObjectScript::set_float(lua_State *state) {
            EG::Game::Object *o = static_cast<EG::Game::Object *>(object);
            int n = lua_gettop(state);
            std::string key(lua_tolstring(state, 1, NULL));
            lua_Number value = lua_tonumber(state, 2);

            bool found_attribute = false;
            EG::Game::ObjectAttributeBasicFloat *desired = NULL;
            if (o->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_FLOAT)) {
                std::vector<EG::Game::ObjectAttribute *> *attributes = o->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_FLOAT);
                std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attributes->begin();
                while (attr_iter != attributes->end()) {
                    EG::Game::ObjectAttributeBasicFloat *attr = static_cast<EG::Game::ObjectAttributeBasicFloat *>(*attr_iter);
                    if (attr->GetKey() == key) {
                        desired = attr;
                        found_attribute = true;
                        break;
                    }
                    ++attr_iter;
                }
            }

            if (found_attribute) {
                desired->SetValue(value);
            } else {
                o->AddAttribute(new EG::Game::ObjectAttributeBasicFloat(key, value));
            }
        }
        void Game::PostUpdates(void){
            console->Update(time->GetFrameTime());
            physics->Update(time->GetFrameTime());
            network->Update(time->GetFrameTime());

            if (gui->GetInitialized()){
                if (input->IsMousePressed(EG::Input::mouse_left)) {
                    gui->InjectMouseDown(AWE_MB_LEFT);
                }
                if (input->IsMouseReleased(EG::Input::mouse_left)) {
                    gui->InjectMouseUp(AWE_MB_LEFT);
                }
                glm::vec2 mp = input->GetMousePosition();
                gui->InjectMouseMove((unsigned int)(mp.x), (unsigned int)(mp.y));

                std::vector<char> text = input->GetTextEntered();
                std::vector<char>::iterator text_iter = text.begin();
                if (input->IsKeyPressed(EG::Input::back_space)) {
                    gui->InjectKeyPress('\b');
                    std::cout << "Backspace" << std::endl;
                }
                if (input->IsKeyPressed(EG::Input::del)){
                    gui->InjectKeyPress(char(127));
                }
                if (input->IsKeyPressed(EG::Input::tab)){
                    gui->InjectKeyPress('\t');
                }
                if (input->IsKeyPressed(EG::Input::left)){
                    //gui->InjectKeyPress(Awesomium::KeyCodes::AK_LEFT);
                }
                if (input->IsKeyPressed(EG::Input::right)){
                    //gui->InjectKeyPress(Awesomium::KeyCodes::AK_RIGHT);
                }
                if (input->IsKeyPressed(EG::Input::up)){
                    //gui->InjectKeyPress(Awesomium::KeyCodes::AK_UP);
                }
                if (input->IsKeyPressed(EG::Input::down)){
                    //gui->InjectKeyPress(Awesomium::KeyCodes::AK_DOWN);
                }
                while (text_iter != text.end()){
                    char c = (*text_iter);
                    int cint = int(c);
                    gui->InjectKeyPress(cint);
                    ++text_iter;
                }

                gui->Update();
            }

            input->Update();

            EG::Utility::UnsignedIntDictionaryKeysIterator object_iter = scene->GetObjectManager()->GetObjects()->GetKeysBegin();
            while (object_iter != scene->GetObjectManager()->GetObjects()->GetKeysEnd()){
                unsigned int object_id = (*object_iter);
                EG::Game::Object *object = scene->GetObjectManager()->GetObjectById(object_id);

                if (object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_EMISSION_PARTICLE_SYSTEM)){
                    std::vector<EG::Game::ObjectAttribute *> *attrs = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_EMISSION_PARTICLE_SYSTEM);
                    std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attrs->begin();
                    while (attr_iter != attrs->end()){
                        EG::Game::ObjectAttributeEmissionParticleSystem *pattr = static_cast<EG::Game::ObjectAttributeEmissionParticleSystem *>(*attr_iter);

                        EG::Graphics::ParticleSystem *psys = pattr->GetParticleSystem();
                        std::list<EG::Graphics::Particle *> *particles = psys->GetParticles();
                        std::list<EG::Graphics::Particle *>::iterator piter = particles->begin();
                        while (piter != particles->end()){
                            EG::Graphics::Particle *p = (*piter);
                            bool has_physics = false;
                            glm::mat4 motion_state;
                            if (p->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_CONTROL_RIGID_BODY)){
                                std::vector<EG::Game::ObjectAttribute *> *attrs = p->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_CONTROL_RIGID_BODY);
                                std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attrs->begin();
                                while (attr_iter != attrs->end()){
                                    EG::Game::ObjectAttributeControlRigidBody *rigid_body_attr = static_cast<EG::Game::ObjectAttributeControlRigidBody *>(*attr_iter);
                                    if (!(rigid_body_attr->GetConnected())){
                                        physics->AddRigidBody(rigid_body_attr->GetBody());
                                        rigid_body_attr->SetConnected(true);
                                    }

                                    if (!(p->Alive())){
                                        physics->RemoveRigidBody(rigid_body_attr->GetBody());
                                    }

                                    // TODO: Get Motion State From Physics
                                    EG::Dynamics::RigidBody *body = rigid_body_attr->GetBody();
                                    motion_state = body->GetMotionState();
                                    has_physics = true;

                                    ++attr_iter;
                                }
                            }

                            if (has_physics && p->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION)){
                                std::vector<EG::Game::ObjectAttribute *> *attrs = p->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION);
                                std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attrs->begin();
                                while (attr_iter != attrs->end()){
                                    EG::Game::ObjectAttributeBasicTransformation *trans_attr = static_cast<EG::Game::ObjectAttributeBasicTransformation *>(*attr_iter);
                                    glm::mat4 t = trans_attr->GetTransformation();
                                    glm::vec3 p(t[3][0], t[3][1], t[3][2]);
                                    glm::vec3 c = scene->GetCurrentCamera()->GetPosition();
                                    float distance = glm::distance(p, c);
                                    trans_attr->SetTransformation(motion_state);
                                    ++attr_iter;
                                }
                            }
                            ++piter;
                        }

                        pattr->GetParticleSystem()->Update(time->GetFrameTime());
                        ++attr_iter;
                    }
                }

                if (object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_CONTROL_ANIMATION)) {
                    EG::Dynamics::AnimationState *animations = (static_cast<EG::Game::ObjectAttributeControlAnimationState *>(object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_CONTROL_ANIMATION)->at(0)))->GetAnimationState();
                    animations->Update(time->GetFrameTime());
                }

                bool has_physics = false;
                glm::mat4 motion_state;
                if (object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_CONTROL_RIGID_BODY)){
                    std::vector<EG::Game::ObjectAttribute *> *attrs = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_CONTROL_RIGID_BODY);
                    std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attrs->begin();
                    while (attr_iter != attrs->end()){
                        EG::Game::ObjectAttributeControlRigidBody *rigid_body_attr = static_cast<EG::Game::ObjectAttributeControlRigidBody *>(*attr_iter);
                        if (!(rigid_body_attr->GetConnected())){
                            physics->AddRigidBody(rigid_body_attr->GetBody());
                            rigid_body_attr->SetConnected(true);
                        }

                        // TODO: Get Motion State From Physics
                        EG::Dynamics::RigidBody *body = rigid_body_attr->GetBody();
                        motion_state = body->GetMotionState();
                        has_physics = true;

                        ++attr_iter;
                    }
                }

                if (has_physics && object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION)){
                    std::vector<EG::Game::ObjectAttribute *> *attrs = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION);
                    std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attrs->begin();
                    while (attr_iter != attrs->end()){
                        EG::Game::ObjectAttributeBasicTransformation *trans_attr = static_cast<EG::Game::ObjectAttributeBasicTransformation *>(*attr_iter);
                        trans_attr->SetTransformation(motion_state);
                        ++attr_iter;
                    }
                }

                std::vector<EG::Game::ObjectScript *> *scripts = object->GetScripts();
                std::vector<EG::Game::ObjectScript *>::iterator script_iter = scripts->begin();
                while (script_iter != scripts->end()) {
                    EG::Game::ObjectScript *script = (*script_iter);
                    EG::Game::ObjectScript::object = object;
                    script->Run();
                    ++script_iter;
                }

                ++object_iter;
            }
        }
std::string SaveMaterialListener::Call(std::map<std::string, std::string> args) {
    std::string object_id = EG::Utility::StringMethods::ConvertURI(args["object_id"]);
    std::string mesh_id = EG::Utility::StringMethods::ConvertURI(args["id"]);

    EG::Game::Object *object = scene->GetObjectManager()->GetObjectByName(object_id);
    if (object && object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_RENDERING_MESH)) {
        std::vector<EG::Game::ObjectAttribute *> *attrs = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_RENDERING_MESH);
        std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attrs->begin();
        EG::Graphics::RenderingMaterial *material;
        bool found = false;
        while (attr_iter != attrs->end()) {
            EG::Game::ObjectAttributeRenderingMesh *attr = static_cast<EG::Game::ObjectAttributeRenderingMesh *>((*attr_iter));
            if (attr->GetMeshId() == mesh_id) {
                found = true;
                material = attr->GetMaterial();
                break;
            }
            ++attr_iter;
        }
        if (found) {
            // Color
            std::string color_string = EG::Utility::StringMethods::SearchAndReplace(args["color"], "%2C", " ");
            float *color_floats = EG::Utility::StringMethods::ConvertStringToFloatArray(color_string);
            glm::vec4 color = glm::vec4(color_floats[0], color_floats[1], color_floats[2], color_floats[3]);
            material->SetColor(color);

            // Is Lit
            if (args["lit"] == "true") {
                material->SetLit(true);
            } else {
                material->SetLit(false);
            }

            // Is Translucent
            if (args["translucent"] == "true") {
                material->SetTranslucent(true);
            } else {
                material->SetTranslucent(false);
            }

            // Casts Shadows
            if (args["casts_shadows"] == "true") {
                material->SetCastsShadows(true);
            } else {
                material->SetCastsShadows(false);
            }

            // Specular Scalar
            float specular_scalar = EG::Utility::StringMethods::ConvertStringToFloatArray(args["specular_scalar"])[0];
            material->SetSpecular(specular_scalar);

            // Decal
            std::string decal = EG::Utility::StringMethods::ConvertURI(args["decal"]);
            if (decal == "") {
                material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_DECAL, "default_decal");
            } else {
                if (!(scene->GetTextureManager()->HasTexture(decal))) {
                    scene->GetTextureManager()->AddTexture(decal, new EG::Graphics::Texture(decal));
                }
                if (material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_DECAL) != decal) {
                    material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_DECAL, decal);
                }
            }

            // Normal
            std::string normal = EG::Utility::StringMethods::ConvertURI(args["normal"]);
            if (normal == "") {
                material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_NORMAL, "default_normal");
            } else {
                if (!(scene->GetTextureManager()->HasTexture(normal))) {
                    scene->GetTextureManager()->AddTexture(normal, new EG::Graphics::Texture(normal));
                }
                if (material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_NORMAL) != normal) {
                    material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_NORMAL, normal);
                }
            }

            // Height
            std::string height = EG::Utility::StringMethods::ConvertURI(args["height"]);
            if (height == "") {
                material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_HEIGHT, "default_height");
            } else {
                if (!(scene->GetTextureManager()->HasTexture(height))) {
                    scene->GetTextureManager()->AddTexture(height, new EG::Graphics::Texture(height));
                }
                if (material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_HEIGHT) != height) {
                    material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_HEIGHT, height);
                }
            }

            // Specular
            std::string specular = EG::Utility::StringMethods::ConvertURI(args["specular"]);
            if (specular == "") {
                material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_SPECULAR, "default_specular");
            } else {
                if (!(scene->GetTextureManager()->HasTexture(specular))) {
                    scene->GetTextureManager()->AddTexture(specular, new EG::Graphics::Texture(specular));
                }
                if (material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_SPECULAR) != specular) {
                    material->SetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_SPECULAR, specular);
                }
            }
        }
    }

    return "{\"status\": true}";
}
void Editor::PickObject(glm::vec2 mouse_position) {
    EG::Graphics::Camera *c = scene->GetCurrentCamera();
    glm::vec3 begin = c->GetPosition();
    glm::vec3 dir = EG::Math::Utility::ProjectClick(glm::vec2(graphics->GetViewportWidth(), graphics->GetViewportHeight()),
                                                    mouse_position, scene->GetCurrentCamera()->GetNearFar().y,
                                                    c->GetPosition(), c->GetViewMatrix(), c->GetProjectionMatrix());

    EG::Graphics::MeshManager *meshes = scene->GetMeshManager();
    bool object_picked = false;
    glm::mat4 multiplied_trans;
    glm::vec3 *box;
    EG::Game::Object *object;
    for (std::pair<unsigned int, EG::Game::Object *> object_pair : *(scene->GetObjectManager()->GetObjects())) {
        unsigned int object_id = object_pair.first;
        object = object_pair.second;
        if (object->GetObjectId() == selection_box->GetObjectId()) {
            continue;
        }
        glm::mat4 trans = glm::mat4(1.0f);
        if (object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION)) {
            std::vector<EG::Game::ObjectAttribute *> *tattrs = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION);
            EG::Game::ObjectAttribute *tattr = (*tattrs)[0];
            trans = (static_cast<EG::Game::ObjectAttributeBasicTransformation *>(&(tattr[0])))->GetTransformation();
        }
        if (object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_RENDERING_MESH)) {
            std::vector<EG::Game::ObjectAttribute *> *attributes = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_RENDERING_MESH);
            std::vector<EG::Game::ObjectAttribute *>::iterator attr_iter = attributes->begin();
            while (attr_iter != attributes->end()) {
                EG::Game::ObjectAttributeRenderingMesh *mattr = (static_cast<EG::Game::ObjectAttributeRenderingMesh *>(*attr_iter));
                EG::Graphics::Mesh *mesh = meshes->Get(mattr->GetMeshId());
                box = mesh->GetBoundingBox();
                multiplied_trans = trans * mattr->GetOffset();
                object_picked = EG::Math::Utility::RayAABBTest(begin, dir, box[0], box[1], multiplied_trans);
                if (object_picked) {
                    break;
                }
                ++attr_iter;
            }
        }
        if (object_picked) {
            break;
        }
    }
    if (object_picked) {
        std::stringstream out;
        out << "Object Picked: " << object->GetObjectName();
        console->Print(out.str());
        std::stringstream script;
        script << "main_view.tools.select_object(\"" << object->GetObjectName() << "\");";
        gui->ExecuteScript(script.str().c_str());
        object_selected = true;
        selected_object_id = object->GetObjectId();
        glm::vec4 box_min = glm::vec4(box[0].x, box[0].y, box[0].z, 1.0f);
        glm::vec4 box_max = glm::vec4(box[1].x, box[1].y, box[1].z, 1.0f);
        box_min = multiplied_trans * box_min;
        box_max = multiplied_trans * box_max;
        glm::vec4 box_diff = box_max - box_min;
        glm::vec4 position = ((box_max + box_min) / 2.0f) - (box_diff / 2.0f);
        glm::vec3 scaling = glm::vec3(box_diff.x, box_diff.y, box_diff.z) + glm::vec3(0.1f, 0.1f, 0.1f);
        glm::mat4 new_trans = EG::Math::Utility::GenerateTransform(glm::vec3(position.x, position.y, position.z), scaling);
        std::vector<EG::Game::ObjectAttribute *> *tattrs = selection_box->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_BASIC_TRANSFORMATION);
        EG::Game::ObjectAttribute *tattr = (*tattrs)[0];
        (static_cast<EG::Game::ObjectAttributeBasicTransformation *>(&(tattr[0])))->SetTransformation(new_trans);
    }
}
std::string ReadObjectsListener::Call(std::map<std::string, std::string> args) {

    std::stringstream out;
    out << "[";
    bool first = true;
    for (std::pair<unsigned int, EG::Game::Object *> object_pair : *(scene->GetObjectManager()->GetObjects())) {
        EG::Game::Object *object = object_pair.second;
        if (first) {
            first = false;
        } else {
            out << ",";
        }
        out << "{\"id\": \"" << object->GetObjectName() << "\", ";
        out << "\"record_id\": " << object->GetObjectId();

        if (object->HasAttributesOfType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_RENDERING_MESH)) {
            out << ", \"materials\": [";
            std::vector<EG::Game::ObjectAttribute *> *material_attributes = object->GetAttributesByType(EG::Game::ObjectAttribute::OBJECT_ATTRIBUTE_RENDERING_MESH);
            std::vector<EG::Game::ObjectAttribute *>::iterator material_iter = material_attributes->begin();
            while (material_iter != material_attributes->end()) {
                EG::Game::ObjectAttributeRenderingMesh *material_attribute = static_cast<EG::Game::ObjectAttributeRenderingMesh *>(*material_iter);
                EG::Graphics::RenderingMaterial *material = material_attribute->GetMaterial();
                // Mesh Id
                out << "{\"id\": \"" << material_attribute->GetMeshId() << "\"";

                // Color
                glm::vec4 c = material->GetColor();
                out << ",\"color\": [" << c.x << ", " << c.y << ", " << c.z << ", " << c.w << "]";

                // Specular
                out << ",\"specular\": " << material->GetSpecular();

                // Decal
                out << ",\"decal\": \"";
                if (material->HasTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_DECAL)){
                    out << scene->GetTextureManager()->GetTexture(material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_DECAL))->GetFilePath();
                }
                out << "\"";

                // Normal
                out << ",\"normal\": \"";
                if (material->HasTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_NORMAL)){
                    out << scene->GetTextureManager()->GetTexture(material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_NORMAL))->GetFilePath();
                }
                out << "\"";

                // Height
                out << ",\"height\": \"";
                if (material->HasTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_HEIGHT)){
                    out << scene->GetTextureManager()->GetTexture(material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_HEIGHT))->GetFilePath();
                }
                out << "\"";

                // Specular
                out << ",\"specular\": \"";
                if (material->HasTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_SPECULAR)){
                    out << scene->GetTextureManager()->GetTexture(material->GetTexture(EG::Graphics::RenderingMaterial::RENDERING_MATERIAL_TEXTURE_SPECULAR))->GetFilePath();
                }
                out << "\"";

                // Material Specularity
                out << ",\"specular_scalar\": " << material->GetSpecular();

                // Casts Shadows
                out << ",\"casts_shadows\": " << (material->GetCastsShadows() ? "true" : "false");

                // Lit
                out << ",\"lit\": " << (material->GetLit() ? "true" : "false");

                // Translucent
                out << ",\"translucent\": " << (material->GetTranslucent() ? "true" : "false");

                // Fin
                out << "}";
                ++material_iter;
            }
            out << "]";
        }

        out << "}";
    }
    out << "]";
    //std::cout << out.str() << std::endl;
    return out.str().c_str();
}