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

#include <osgCompute/Memory>
#include <osgCuda/Export>

namespace osgCompute
{
    class InteropObject;
    class InteropMemory;

    enum InteropUsage
    {
        CUDA_TARGET           = 0x01,
        GL_TARGET             = 0x10,
        GL_SOURCE_COMPUTE_SOURCE = 0x00,
        GL_SOURCE_COMPUTE_TARGET = 0x01,
        GL_TARGET_COMPUTE_SOURCE = 0x10,
        GL_TARGET_COMPUTE_TARGET = 0x11,
    };

    /**
    Interface for all scene based objects 
    */
    class LIBRARY_EXPORT InteropObject
    {
    public:
        InteropObject() { clearLocal(); }

        virtual InteropMemory* getInteropMemory() = 0;
        virtual const InteropMemory* getInteropMemory() const= 0;
        virtual InteropMemory* getOrCreateInteropMemory() = 0;

        virtual void addIdentifier( const std::string& identifier ) = 0;
        virtual void removeIdentifier( const std::string& identifier ) = 0;
		virtual bool isIdentifiedBy( const std::string& identifier ) const = 0;
		virtual IdentifierSet& getIdentifiers() = 0;
		virtual const IdentifierSet& getIdentifiers() const = 0;

        virtual void setUsage( unsigned int usage );
        virtual unsigned int getUsage() const;

        virtual void clear();

        virtual void freeProxy() = 0;

    protected:
        virtual ~InteropObject() { clearLocal(); }
        void clearLocal();

        unsigned int _usage;

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

    /**
    */
    class LIBRARY_EXPORT InteropMemory : public osgCompute::Memory
    {
    public:
        InteropMemory() {}

		virtual InteropObject* getInteropObject() = 0;
		virtual const InteropObject* getInteropObject() const = 0;

    protected:
        virtual ~InteropMemory() {}

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

#endif //OSGCUDA_INTEROPERABILITY_H
