/* osgCompute - Copyright (C) 2008-2009 SVT Group
*                                                                     
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*                                                                     
* 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
* GNU Lesse General Public License for more details.
*
* The full license is in LICENSE file included with this distribution.
*/

#ifndef OSGCOMPUTE_VISITOR
#define OSGCOMPUTE_VISITOR 1

#include <osg/NodeVisitor>
#include <osgCompute/Export>
#include <osgCompute/Context>

namespace osgCompute
{
    class Computation;

    /**
    */
    class LIBRARY_EXPORT ResourceVisitor : public osg::NodeVisitor
    {
    public:
        ResourceVisitor();

        META_NodeVisitor( osgCompute, ResourceVisitor )

            virtual bool init();
        virtual void setupForTraversal();
        virtual void updateComputation();

        virtual void apply( osg::Node& node );
        virtual void apply( osg::Geode& node );
        virtual void apply( Computation& computation );
        virtual void apply( osg::Group& group );
        virtual Computation* getComputation();
        virtual const Computation* getComputation() const;

        virtual void addResource( Resource& resource );
        virtual void removeResource( Resource& resource );
        virtual bool hasResource( Resource& resource );
        virtual ResourceSet& getResources();
        virtual const ResourceSet& getResources() const;

        virtual bool isClear() const;

        virtual void reset();
        virtual void clear();
    protected:
        friend class Computation;
        virtual ~ResourceVisitor() { clearLocal(); }
        void clearLocal();

        virtual void setComputation( Computation* computation );

        Computation*                       _computation;

        ResourceSet*                       _ptrResources;
        ResourceSet*                       _ptrOldResources;
        ResourceSet                        _resourcesA;
        ResourceSet                        _resourcesB;

        bool                               _clear;

    private:
        // copy constructor and operator should not be called
        ResourceVisitor( const ResourceVisitor&, const osg::CopyOp& ) {}
        ResourceVisitor& operator=( const ResourceVisitor& copy ) { return (*this); }
    };

    /**
    */
    class LIBRARY_EXPORT ContextVisitor : public osg::NodeVisitor
    {
    public:
        ContextVisitor();

        META_NodeVisitor( osgCompute, ContextVisitor )

        virtual bool init();
        virtual void reset();

        virtual void apply( osg::Group& group );
        virtual void apply( Computation& computation );

        virtual Context* getContext();
        virtual const Context* getContext() const;
        virtual bool isClear() const;

        virtual void clear();
    protected:
        friend class Computation;
        virtual ~ContextVisitor() { clearLocal(); }
        void clearLocal();

        virtual void setContext( Context* context );

        osg::ref_ptr<osgCompute::Context>   _context;
        bool                                _clear;

    private:
        // copy constructor and operator should not be called
        ContextVisitor( const ContextVisitor&, const osg::CopyOp& ) {}
        ContextVisitor& operator=( const ContextVisitor& copy ) { return (*this); }
    };
}

#endif //OSGCOMPUTE_VISITOR
