//
// IRIS GL display lists allocated by Texture2 nodes are never freed,
// causing memory to be lost.  This is only a major problem for
// applications that are constantly reading in new textures, either by
// deleting and recreating Texture2 nodes with different filenames, or
// by changing the filename field of the Texture2 node.
//
// This code should be called with the old filename when the Texture2
// node is deleted or changed.  It will look through the internal list
// of files the Texture2 node keeps and remove the texture from its
// list and free up the memory held by the GL.  It may also be used if
// you want to force the Texture2 node to re-read an image file
// (because it changed, for example).
//

#include 
#include 

// Get access to private stuff:
#define private public
#include 
#undef private

//
// This routine searches through the texture maps maintained by the
// Texture2 node, finds the map with the given filename, and gets rid
// of it.  Because of the way Texture2 is implemented in Inventor 1,
// "getting rid of it" is a little complicated.
//
// First, we can't just remove the map from the linked list because
// Texture2 assumes that the GL texture ID for the last map on the
// list is 2000, the second to last is 2001, etc.  If we created a gap
// in the list then the Texture2 node would re-use a GL texture ID
// that is already in use.
//
// Second, there is no IRIS GL command to delete a texture-- the best
// we can do is redefine a texture to be a 1 by 1 texture that uses
// minimal memory (freeing up whatever memory the old definition
// used).
//
// So, this routine finds the map, marks it by naming it "_UNUSED_",
// and redefines it in GL to be a 1 by 1 texture.
//
// Then, if texture at the head of the list is named "_UNUSED_", we
// really do remove it from the linked list (and the Texture2 node
// will recycle the associated GL texture ID the next time it creates
// a texture).
//
static void
deleteTexture(const char* imageName)
{
    if( (imageName == NULL) || (strcmp( imageName, "") == 0) )
        return;

    // delete old map 
    textureMap* map = SoTextureBundle::maps;
    while( map)  {
	if( map->filename == imageName)  {
	    // free up texture memory used by  map->index
	    static float props[1]; props[0] = TX_NULL;
	    texdef2d( map->index, 1, 1, 1, (unsigned long*) props, 
		      1, (float*) props);
	    map->filename = SbName("_UNUSED_");
	    break;
	}
	map = map->next;
    }
    // Now, delete all textures name "_UNUSED_" from the head of the
    // list:
    map = SoTextureBundle::maps;
    while (map && map->filename == SbName("_UNUSED_")) {
	SoTextureBundle::maps = map->next;

	delete map;
	map = SoTextureBundle::maps;
    }
}