#include <Inventor/SoPath.h>
#include <Inventor/actions/SoSearchAction.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoNormal.h>
#include <Inventor/SoDetail.h>

//
// The SoVertexShapeDetail::getLastPropertyNode in Inventor 1 creates
// a SearchAction but fails to delete it.  This causes
// a large memory leak (the searchAction, all of the paths it finds,
// and all of the nodes on those paths will never be deleted) and will
// cause the application to slow down because of the extra paths.
//
// To fix this, compile this file into a .o and then link
// the .o before -lInventor.  The linker will give a warning about
// multiply defined symbols; that is normal and expected.
//


////////////////////////////////////////////////////////////////////////
//
// Description:
//  Returns the node of the given type that affects the shape that
//  this detail's path leads to. The passed property node should
//  be one that does not accumulate such as, oh, gosh,
//  maybe a Normal or a Coordinate3 node, because we look
//  for the last (and hence current) one.
//
//
// Use: private

SoNode *
SoVertexShapeDetail::getLastPropertyNode(SoType typeId) const
//
////////////////////////////////////////////////////////////////////////
{
#ifdef DEBUG    
    if (path == NULL) {
	 fprintf( stderr, "SoVertexShapeDetail::getLastPropertyNode - " );
	 fprintf( stderr, "path to shape is NULL\n" );
	 return NULL;
    }
#endif

    SoNode *result;
    
    if (path->getTail()->isOfType(typeId)) {
	// path already leads to a node of given type, so just return it
	result = path->getTail();
    }
    else {
	// Apply a search action to the path, and look
	// for the _last_ node of the requested type
	
	SoSearchAction sa;
	sa.setType(typeId);
	sa.setFindAll(TRUE);
	sa.apply(path);

	SoPathList paths = sa.getPaths();
    
	if (paths.length() == 0) {
	    // nothing found
	    result = NULL;
	}
	else {
	    // return the last one found
	    result = paths[paths.length() - 1]->getTail();
	}
    }

    return result;
}
