/* 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_COMPUTATIONBIN
#define OSGCOMPUTE_COMPUTATIONBIN 1

#include <osg/ref_ptr>
#include <osg/Object>
#include <osg/NodeVisitor>
#include <osgUtil/RenderBin>
#include <osgCompute/Export>
#include <osgCompute/Callback>
#include <osgCompute/Module>

namespace osg
{
    class RenderInfo;
}

namespace osgUtil
{
    class RenderLeaf;
}

namespace osgCompute
{
    class Computation;

    /**
    mist
    */
    class LIBRARY_EXPORT ComputationBin : public osgUtil::RenderBin 
    {
    public:
        ComputationBin(); 
        ComputationBin(osgUtil::RenderBin::SortMode mode);

        META_Object( osgCompute, ComputationBin )

        virtual bool init( Computation& computation );
        virtual void reset();

        virtual void drawImplementation( osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous );
        virtual unsigned int computeNumberOfDynamicRenderLeaves() const;

        virtual bool hasModule( const std::string& moduleName ) const;
        virtual bool hasModule( Module& module ) const;
        virtual bool hasModules() const;
        virtual Module* getModule( const std::string& moduleName );
        virtual const Module* getModule( const std::string& moduleName ) const;
        virtual ModuleList* getModules();
        virtual const ModuleList* getModules() const;
        virtual unsigned int getNumModules() const;

        virtual void setContext( Context& context );
        virtual Context* getContext();
        virtual const Context* getContext() const;
        virtual bool isClear() const;
        virtual Computation* getComputation();
        virtual const Computation* getComputation() const;
        virtual LaunchCallback* getLaunchCallback();
        virtual const LaunchCallback* getLaunchCallback() const;

        virtual void clear();

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

        virtual void launch();
        virtual void drawLeafs( osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous );

        // members
        Computation*                         _computation; 
        unsigned int                         _computeOrder; 
        bool                                 _clear;
        LaunchCallback*                      _launchCallback;
        ModuleList                           _modules;
        mutable osg::ref_ptr<Context>        _context;               

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

#endif //OSGCOMPUTE_COMPUTATIONBIN
