/* 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_RESOURCE
#define OSGCOMPUTE_RESOURCE 1

#include <vector>
#include <set>
#include <map>
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osgCompute/Export>
#include <osgCompute/Callback>

namespace osgCompute
{
    class Context;

    typedef std::set< const Context* >                     						ContextSet;
    typedef std::set< const Context* >::iterator           						ContextSetItr;
    typedef std::set< const Context* >::const_iterator     						ContextSetCnstItr;

    typedef std::set< std::string >                                           	HandleSet;
    typedef std::set< std::string >::iterator                                 	HandleSetItr;
    typedef std::set< std::string >::const_iterator                           	HandleSetCnstItr;

    typedef std::vector< osg::ref_ptr<Resource> >                              	ResourceList;
    typedef std::vector< osg::ref_ptr<Resource> >::iterator                    	ResourceListItr;
    typedef std::vector< osg::ref_ptr<Resource> >::const_iterator              	ResourceListCnstItr;

    typedef std::set< const Resource* >											ResourcePtrSet;
    typedef std::set< const Resource* >::iterator								ResourcePtrSetItr;
    typedef std::set< const Resource* >::const_iterator							ResourcePtrSetCnstItr;

    typedef std::set< osg::ref_ptr<Resource> >                                  ResourceSet;
    typedef std::set< osg::ref_ptr<Resource> >::iterator                        ResourceSetItr;
    typedef std::set< osg::ref_ptr<Resource> >::const_iterator                  ResourceSetCnstItr;

    typedef std::map< Resource*, osg::ref_ptr<Resource> >						ResourceMap;
    typedef std::map< Resource*, osg::ref_ptr<Resource> >::iterator				ResourceMapItr;
    typedef std::map< Resource*, osg::ref_ptr<Resource> >::const_iterator		ResourceMapCnstItr;

    /**
    */
    class LIBRARY_EXPORT Resource : public osg::Object
    {
    public:
        Resource();

        virtual bool init();

        virtual void addHandle( const std::string& handle );
        virtual void removeHandle( const std::string& handle );
        virtual bool isAddressedByHandle( const std::string& handle ) const;
        virtual HandleSet& getHandles();
        virtual const HandleSet& getHandles() const;

        virtual bool isClear() const;
        virtual void clear();

    protected:
        virtual ~Resource();

        virtual void init( const Context& context ) const;
        virtual void clear( const Context& context ) const;
        virtual void setHandles( HandleSet& handles );

        void clearLocal();

        mutable ContextSet					_contexts;
        HandleSet                           _handles;
        bool                                _clear;

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

#endif //OSGCOMPUTE_RESOURCE
