// ----------------------------------------------------------------------------
TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
    TrackObject* parent,
    const XMLNode& xml_node,
    ModelDefinitionLoader& model_def_loader)
    : TrackObjectPresentationSceneNode(xml_node)
{
    m_render_info = NULL;
    std::string name;
    xml_node.get("name", &name);
    float custom_hue = 0.0f;
    xml_node.get("hue", &custom_hue);
    if (custom_hue > 0.0f)
        m_render_info = new RenderInfo(custom_hue, false);

    m_node = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG
    m_node->setName(("libnode_" + name).c_str());
#endif

    XMLNode* libroot;
    std::string lib_path =
        file_manager->getAsset(FileManager::LIBRARY, name) + "/";

    bool create_lod_definitions = true;

    if (!model_def_loader.containsLibraryNode(name))
    {
        World* world = World::getWorld();
        Track* track = NULL;
        if (world != NULL)
            track = world->getTrack();
        std::string local_lib_node_path;
        std::string local_script_file_path;
        if (track != NULL)
        {
            local_lib_node_path = track->getTrackFile("library/" + name + "/node.xml");
            local_script_file_path = track->getTrackFile("library/" + name + "/scripting.as");
        }
        std::string lib_node_path = lib_path + "node.xml";
        std::string lib_script_file_path = lib_path + "scripting.as";

        if (local_lib_node_path.size() > 0 && file_manager->fileExists(local_lib_node_path))
        {
            lib_path = track->getTrackFile("library/" + name);
            libroot = file_manager->createXMLTree(local_lib_node_path);
            if (track != NULL)
                World::getWorld()->getScriptEngine()->loadScript(local_script_file_path, false);
        }
        else if (file_manager->fileExists(lib_node_path))
        {
            libroot = file_manager->createXMLTree(lib_node_path);
            if (track != NULL)
                World::getWorld()->getScriptEngine()->loadScript(lib_script_file_path, false);
        }
        else
        {
            Log::error("TrackObjectPresentationLibraryNode",
                "Cannot find library '%s'", lib_node_path.c_str());
            return;
        }

        if (libroot == NULL)
        {
            Log::error("TrackObjectPresentationLibraryNode",
                       "Cannot find library '%s'", lib_node_path.c_str());
            return;
        }

        file_manager->pushTextureSearchPath(lib_path + "/");
        file_manager->pushModelSearchPath(lib_path);
        material_manager->pushTempMaterial(lib_path + "/materials.xml");
        model_def_loader.addToLibrary(name, libroot);

        // Load LOD groups
        const XMLNode *lod_xml_node = libroot->getNode("lod");
        if (lod_xml_node != NULL)
        {
            for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
            {
                const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
                for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
                {
                    model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
                }
            }
        }
    }
    else
    {
        libroot = model_def_loader.getLibraryNodes()[name];
        assert(libroot != NULL);
        // LOD definitions are already created, don't create them again
        create_lod_definitions = false;
    }

    m_node->setPosition(m_init_xyz);
    m_node->setRotation(m_init_hpr);
    m_node->setScale(m_init_scale);
    m_node->updateAbsolutePosition();

    assert(libroot != NULL);
    World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader,
        create_lod_definitions, m_node, parent, m_render_info);
    m_parent = parent;
}   // TrackObjectPresentationLibraryNode
// ----------------------------------------------------------------------------
TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
    TrackObject* parent,
    const XMLNode& xml_node,
    ModelDefinitionLoader& model_def_loader)
    : TrackObjectPresentationSceneNode(xml_node)
{
    m_parent = NULL;
    m_start_executed = false;
    m_reset_executed = false;

    std::string name;
    xml_node.get("name", &name);
    m_name = name;

    m_node = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG
    m_node->setName(("libnode_" + name).c_str());
#endif

    XMLNode* libroot;
    std::string lib_path =
        file_manager->getAsset(FileManager::LIBRARY, name) + "/";

    bool create_lod_definitions = true;

    if (!model_def_loader.containsLibraryNode(name))
    {
        Track* track = Track::getCurrentTrack();
        std::string local_lib_node_path;
        std::string local_script_file_path;
        if (track != NULL)
        {
            local_lib_node_path = track->getTrackFile("library/" + name + "/node.xml");
            local_script_file_path = track->getTrackFile("library/" + name + "/scripting.as");
        }
        std::string lib_node_path = lib_path + "node.xml";
        std::string lib_script_file_path = lib_path + "scripting.as";

        if (local_lib_node_path.size() > 0 && file_manager->fileExists(local_lib_node_path))
        {
            lib_path = track->getTrackFile("library/" + name);
            libroot = file_manager->createXMLTree(local_lib_node_path);
            if (track != NULL)
            {
                Scripting::ScriptEngine::getInstance()->loadScript(local_script_file_path, false);
            }
        }
        else if (file_manager->fileExists(lib_node_path))
        {
            libroot = file_manager->createXMLTree(lib_node_path);
            if (track != NULL)
            {
                Scripting::ScriptEngine::getInstance()->loadScript(lib_script_file_path, false);
            }
        }
        else
        {
            Log::error("TrackObjectPresentationLibraryNode",
                "Cannot find library '%s'", lib_node_path.c_str());
            return;
        }

        if (libroot == NULL)
        {
            Log::error("TrackObjectPresentationLibraryNode",
                       "Cannot find library '%s'", lib_node_path.c_str());
            return;
        }

        std::string unique_id = StringUtils::insertValues("library/%s", name.c_str());
        file_manager->pushTextureSearchPath(lib_path + "/", unique_id);
        file_manager->pushModelSearchPath(lib_path);
        material_manager->pushTempMaterial(lib_path + "/materials.xml");
#ifndef SERVER_ONLY
        if (CVS->isGLSL())
        {
            SP::SPShaderManager::get()->loadSPShaders(lib_path);
        }
#endif
        model_def_loader.addToLibrary(name, libroot);

        // Load LOD groups
        const XMLNode *lod_xml_node = libroot->getNode("lod");
        if (lod_xml_node != NULL)
        {
            for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
            {
                const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
                for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
                {
                    model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
                }
            }
        }
    }
    else
    {
        libroot = model_def_loader.getLibraryNodes()[name];
        assert(libroot != NULL);
        // LOD definitions are already created, don't create them again
        create_lod_definitions = false;
    }

    m_node->setPosition(m_init_xyz);
    m_node->setRotation(m_init_hpr);
    m_node->setScale(m_init_scale);
    m_node->updateAbsolutePosition();

    assert(libroot != NULL);
    Track::getCurrentTrack()->loadObjects(libroot, lib_path, model_def_loader,
                                          create_lod_definitions, m_node,
                                          parent);
    m_parent = parent;
}   // TrackObjectPresentationLibraryNode
TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
    const XMLNode& xml_node,
    ModelDefinitionLoader& model_def_loader) :
TrackObjectPresentationSceneNode(xml_node)
{
    std::string name;
    xml_node.get("name", &name);

    m_node = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG
    m_node->setName(("libnode_" + name).c_str());
#endif

    XMLNode* libroot;
    std::string lib_path =
        file_manager->getAsset(FileManager::LIBRARY, name) + "/";
    bool create_lod_definitions = true;

    if (!model_def_loader.containsLibraryNode(name))
    {
        std::string lib_node_path = lib_path + "node.xml";
        libroot = file_manager->createXMLTree(lib_node_path);
        if (libroot == NULL)
        {
            Log::error("TrackObjectPresentationLibraryNode", "Cannot find library '%s'", lib_node_path.c_str());
            return;
        }

        file_manager->pushTextureSearchPath(lib_path + "/");
        file_manager->pushModelSearchPath(lib_path);
        material_manager->pushTempMaterial(lib_path + "/materials.xml");
        model_def_loader.addToLibrary(name, libroot);

        // Load LOD groups
        const XMLNode *lod_xml_node = libroot->getNode("lod");
        if (lod_xml_node != NULL)
        {
            for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
            {
                const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
                for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
                {
                    model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
                }
            }
        }
    }
    else
    {
        libroot = model_def_loader.getLibraryNodes()[name];
        assert(libroot != NULL);
        create_lod_definitions = false; // LOD definitions are already created, don't create them again
    }

    m_node->setPosition(m_init_xyz);
    m_node->setRotation(m_init_hpr);
    m_node->setScale(m_init_scale);
    m_node->updateAbsolutePosition();

    assert(libroot != NULL);
    World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader,
        create_lod_definitions, m_node);
}