/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/

#ifndef OSGPRODUCER_OSGSCENEHANDLER
#define OSGPRODUCER_OSGSCENEHANDLER 1

#include <osgProducer/Export>

#include <Producer/Camera>
#include <osgUtil/SceneView>
#include <osg/Matrix>

namespace osgProducer {

class OSGPRODUCER_EXPORT OsgSceneHandler : public Producer::Camera::SceneHandler, public osgUtil::SceneView
{
    public :
    
        OsgSceneHandler(osg::DisplaySettings *ds = NULL);

        /// override the init method to force it be run one at a time.
        virtual void init();
        
        
        class Callback : public osg::Referenced
        {
        public:
               virtual ~Callback() {}
               virtual void operator()(OsgSceneHandler&, const Producer::Camera &) = 0;             
        };
        
        virtual void clear(Producer::Camera& camera)
        {
            if (_clearCallback.valid()) (*_clearCallback)(*this,camera);
            else clearImplementation(camera);
        }

        virtual void clearImplementation(Producer::Camera& camera);

        void setClearCallback(Callback* callback) { _clearCallback = callback; }
        Callback* getClearCallback() { return _clearCallback.get(); }
        const Callback* getClearCallback() const { return _clearCallback.get(); }


        virtual void cull(Producer::Camera& camera)
        {
            if (_cullCallback.valid()) (*_cullCallback)(*this,camera);
            else cullImplementation(camera);
        }

        virtual void cullImplementation(Producer::Camera& camera);

        void setCullCallback(Callback* callback) { _cullCallback = callback; }
        Callback* getCullCallback() { return _cullCallback.get(); }
        const Callback* getCullCallback() const { return _cullCallback.get(); }


        virtual void draw(Producer::Camera& camera)
        {
            if (_drawCallback.valid()) (*_drawCallback)(*this,camera);
            else drawImplementation(camera);
        }
        
        virtual void drawImplementation(Producer::Camera& camera);

        void setDrawCallback(Callback* callback) { _drawCallback = callback; }
        Callback* getDrawCallback() { return _drawCallback.get(); }
        const Callback* getDrawCallback() const { return _drawCallback.get(); }



        void setContextID( int id );

    protected:
    
        virtual ~OsgSceneHandler() {}
    
        osg::ref_ptr<Callback> _clearCallback;
        osg::ref_ptr<Callback> _cullCallback;
        osg::ref_ptr<Callback> _drawCallback;
};

}

#endif
