void
TexturePaletteManager::write( DataOutputStream& dos ) const
{
    int x( 0 ), y( 0 ), height( 0 );
    TextureIndexMap::const_iterator it = _indexMap.begin();
    while (it != _indexMap.end())
    {
        const osg::Texture2D* texture = it->first;
        int index = it->second;

        std::string fileName;
        if ( _fltOpt.getStripTextureFilePath() )
            fileName = osgDB::getSimpleFileName( texture->getImage()->getFileName() );
        else
            fileName = texture->getImage()->getFileName();

        dos.writeInt16( (int16) TEXTURE_PALETTE_OP );
        dos.writeUInt16( 216 );
        dos.writeString( fileName, 200 );
        dos.writeInt32( index );
        dos.writeInt32( x );
        dos.writeInt32( y );
        it++;

        x += texture->getImage()->s();
        if (texture->getImage()->t() > height)
            height = texture->getImage()->t();
        if (x > 1024)
        {
            x = 0;
            y += height;
            height = 0;
        }
    }
}
void
LightSourcePaletteManager::write( DataOutputStream& dos ) const
{
    using osg::Vec4f;

    static int const INFINITE_LIGHT = 0;
    static int const LOCAL_LIGHT    = 1;
    static int const SPOT_LIGHT     = 2;

    LightPalette::const_iterator it = _lightPalette.begin();
    for ( ; it != _lightPalette.end(); ++it)
    {
        LightRecord m = it->second;

        static char lightName[64];
        sprintf(lightName, "Light%02d", m.Light->getLightNum() );

        int lightType = INFINITE_LIGHT;
        Vec4f const& lightPos = m.Light->getPosition();
        if (lightPos.w() != 0)
        {
            if (m.Light->getSpotCutoff() < 180)
                lightType = SPOT_LIGHT;
            else
                lightType = LOCAL_LIGHT;
        }

        dos.writeInt16( (int16) LIGHT_SOURCE_PALETTE_OP );
        dos.writeInt16( 240 );
        dos.writeInt32( m.Index );
        dos.writeFill(2*4, '\0');                     // Reserved
        dos.writeString( lightName, 20 );
        dos.writeFill(4, '\0');                       // Reserved

        dos.writeVec4f(m.Light->getAmbient() );
        dos.writeVec4f(m.Light->getDiffuse() );
        dos.writeVec4f(m.Light->getSpecular() );
        dos.writeInt32(lightType);
        dos.writeFill(4*10, '\0');                     // Reserved
        dos.writeFloat32(m.Light->getSpotExponent() );
        dos.writeFloat32(m.Light->getSpotCutoff() );
        dos.writeFloat32(0);                           // Yaw (N/A)
        dos.writeFloat32(0);                           // Pitch (N/A)
        dos.writeFloat32(m.Light->getConstantAttenuation() );
        dos.writeFloat32(m.Light->getLinearAttenuation() );
        dos.writeFloat32(m.Light->getQuadraticAttenuation() );
        dos.writeInt32(0);                             // Modeling flag (N/A)
        dos.writeFill(4*19, '\0');                     // Reserved

    }
}
void
MaterialPaletteManager::write( DataOutputStream& dos ) const
{
    using osg::Vec4f;

    MaterialPalette::const_iterator it = _materialPalette.begin();
    for ( ; it != _materialPalette.end(); ++it)
    {
        MaterialRecord m = it->second;
        Vec4f const& ambient = m.Material->getAmbient(osg::Material::FRONT);
        Vec4f const& diffuse = m.Material->getDiffuse(osg::Material::FRONT);
        Vec4f const& specular = m.Material->getSpecular(osg::Material::FRONT);
        Vec4f const& emissive = m.Material->getEmission(osg::Material::FRONT);
        float shininess = m.Material->getShininess(osg::Material::FRONT);

        dos.writeInt16( (int16) MATERIAL_PALETTE_OP );
        dos.writeInt16( 84 );            // Length - FIXME: hard-code/FLT version?
        dos.writeInt32( m.Index );
        dos.writeString( m.Material->getName(), 12 );
        dos.writeInt32( 0 );             // Flags
        dos.writeFloat32(ambient.r() );
        dos.writeFloat32(ambient.g() );
        dos.writeFloat32(ambient.b() );
        dos.writeFloat32(diffuse.r() );
        dos.writeFloat32(diffuse.g() );
        dos.writeFloat32(diffuse.b() );
        dos.writeFloat32(specular.r() );
        dos.writeFloat32(specular.g() );
        dos.writeFloat32(specular.b() );
        dos.writeFloat32(emissive.r() );
        dos.writeFloat32(emissive.g() );
        dos.writeFloat32(emissive.b() );
        dos.writeFloat32(shininess);
        dos.writeFloat32( diffuse.a() ); // alpha
        dos.writeFloat32(1.0f);       // 'Reserved' - unused

        if (m.Material->getAmbientFrontAndBack()   == false   ||
            m.Material->getDiffuseFrontAndBack()   == false   ||
            m.Material->getSpecularFrontAndBack()  == false   ||
            m.Material->getEmissionFrontAndBack()  == false   ||
            m.Material->getShininessFrontAndBack() == false )

        {
            std::string warning( "fltexp: No support for different front and back material properties." );
            osg::notify( osg::WARN ) << warning << std::endl;
           _fltOpt.getWriteResult().warn( warning );
        }

    }
}