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();
}