//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.

#ifndef OSGUTIL_DISPLAYLISTVISITOR
#define OSGUTIL_DISPLAYLISTVISITOR 1

#include <osg/NodeVisitor>
#include <osg/Geode>
#include <osg/State>

#include <osgUtil/Export>

namespace osgUtil {

/** Visitor for traversing scene graph and setting each osg::GeoSet's _useDisplayList flag, 
  * with option to immediately compile osg::Drawable OpenGL Display lists and
  * osg::StateAttribute's.
  */
class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor
{
    public:

        /** Operation modes of the.*/
        enum ModeValues
        {
            SWITCH_ON_DISPLAY_LISTS = 0x1,
            SWITCH_OFF_DISPLAY_LISTS = 0x2,
            COMPILE_DISPLAY_LISTS = 0x4,
            COMPILE_STATE_ATTRIBUTES = 0x8
        };
        
        typedef unsigned int Mode;

        /** Construct a CompileGeoSetsVisior to traverse all child,
          * with set specified display list mode.  Default mode is to
          * gset->setUseDisplayList(true).
          */
        DisplayListVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES);
        
        /** Set the operational mode of how the visitor should set up osg::GeoSet's.*/
        void setMode(Mode mode) { _mode = mode; }

        /** Get the operational mode.*/
        Mode getMode() const { return _mode; }
        

        /** Set the State to use during traversal. */
        void setState(osg::State* state)
        {
            _state = state;
        }
        
        osg::State* getState()
        {
            return _state.get();
        }
        

        /** Simply traverse using standard NodeVisitor traverse method.*/
        virtual void apply(osg::Node& node);
        
        /** For each Geode visited set the display list usage according to the 
          * _displayListMode.
          */
        virtual void apply(osg::Geode& node);

    protected:

        Mode _mode;
        
        osg::ref_ptr<osg::State> _state;

};

}

#endif

