/*! Collects all containers that are reachable from \a fc and schedules them
    for writing. For each container an approriate element is created and
    its preWrite method is called, thus recursively discovering all reachable
    containers.

    \param[in] fc FieldContainer that is inspected for reachable containers.
 */
void
OSBRootElement::preWrite(FieldContainer * const fc)
{
    OSG_OSB_LOG(("OSBRootElement::preWrite\n"));

    if(fc == NULL)
        return;

    const std::string    &typeName = fc->getType().getName();
          OSBElementBase *elem     = OSBElementFactory::the()->acquire(
        typeName, this);

    editElementList().push_back(elem);
    elem->setContainer(fc         );
    elem->setFCIdFile (fc->getId());
    elem->preWrite    (fc         );
}
/*! Reads from the stream set by a preceding call to initialiseRead. Since the
    root element is the first one created it reads the file header and
    creates the elements to read the data following the header.

    \param[in] typeName The argument is ignored.
 */
void
OSBRootElement::read(const std::string &/*typeName*/)
{
    OSG_OSB_LOG(("OSBRootElement::read\n"));

    BinaryReadHandler *rh           = getReadHandler();
    std::string        headerMarker;

    rh->getValue(headerMarker);

    if(headerMarker == OSGOSB_HEADER_ID_1)
    {
        OSG_OSB_LOG(("OSBRootElement::read: Header version: [%u]\n",
                OSGOSBHeaderVersion100));
        setHeaderVersion(OSGOSBHeaderVersion100);
    }
    else if(headerMarker == OSGOSB_HEADER_ID_2)
    {
        OSG_OSB_LOG(("OSBRootElement::read: Header version: [%u]\n",
                OSGOSBHeaderVersion200));
        setHeaderVersion(OSGOSBHeaderVersion200);
    }
//     else if(headerMarker == OSGOSB_HEADER_ID_201)
//     {
//         OSG_OSB_LOG(("OSBRootElement::read: Header version: [%u]\n",
//                 OSGOSBHeaderVersion201));
//         setHeaderVersion(OSGOSBHeaderVersion201);
//     }
    else
    {
        FWARNING(("OSBRootElement::read: Unrecognized file header, could not "
                  "load file.\n"));
        return;
    }

    std::string headerName;
    rh->getValue(headerName);
    std::string headerOptions;
    rh->getValue(headerOptions);
    UInt64 fileSize;
    rh->getValue(fileSize);

    OSG_OSB_LOG(("OSBRootElement::read: headerName: [%s]\n",
            headerName.c_str()));
    OSG_OSB_LOG(("OSBRootElement::read: headerOptions: [%s]\n",
            headerOptions.c_str()));
    OSG_OSB_LOG(("OSBRootElement::read: fileSize: [%" PRISize "]\n",
            fileSize));

    std::string     fcTypeName;
    UInt32          fcIdFile;    // id used in the file
    UInt32          fcIdSystem;  // id used in the system
    OSBElementBase *elem;

    while(true)
    {
        if(!readFieldContainerHeader(fcTypeName, fcIdFile))
            break;

        OSG_OSB_LOG(("OSBRootElement::read: fcTypeName [%s] fcIdFile: [%u]\n",
                fcTypeName.c_str(), fcIdFile));

        elem = OSBElementFactory::the()->acquire(fcTypeName, this);
        elem->setFCIdFile(fcIdFile  );
        elem->read       (fcTypeName);

        if(elem->getContainer() != NULL)
        {
            fcIdSystem = elem->getContainer()->getId();

            OSG_OSB_LOG(("OSBRootElement::read: fcIdFile: [%u] fcIdSystem: [%u]\n",
                    fcIdFile, fcIdSystem));

            editIdMap().insert(
                FieldContainerIdMap::value_type(fcIdFile, fcIdSystem));

            if(getContainer() == NULL)
            {
                setContainer(elem->getContainer());
            }

            editElementList().push_back(elem                          );
            editIdElemMap  ().insert   (std::make_pair(fcIdFile, elem));
        }
    }
}