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

#include <osg/Geometry>
#include <osgCompute/Buffer>
#include <osgCuda/Export>

namespace osgCuda
{
    /**
    */
    class LIBRARY_EXPORT GeometryStream : public osgCompute::BufferStream
    {
    public:
        void*					 _hostPtr;
        bool                     _hostPtrAllocated;
        bool                     _syncHost;
        void*					 _devPtr;
        bool                     _syncDevice;
        GLuint                   _bo;
        bool                     _boRegistered;

        GeometryStream();
        virtual ~GeometryStream();


    private:
        // not allowed to call copy-constructor or copy-operator
        GeometryStream( const GeometryStream& ) {}
        GeometryStream& operator=( const GeometryStream& ) { return *this; }
    };

    /**
    */
    class LIBRARY_EXPORT Geometry : public osgCompute::Buffer, public osg::Geometry
    {
    public:
        Geometry();

        META_Buffer( osgCuda, Geometry )

        virtual bool init();

        virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
        virtual void releaseGLObjects(osg::State* state=0) const;

        virtual bool setMemory( const osgCompute::Context& context, int value, unsigned int mapping, unsigned int offset = 0, unsigned int count = UINT_MAX ) const;
        virtual void* map( const osgCompute::Context& context, unsigned int mapping ) const;
        virtual void unmap( const osgCompute::Context& context ) const;

        virtual void clear();

    protected:
        virtual ~Geometry();
        void clearLocal();

        virtual void* mapStream( GeometryStream& stream, unsigned int mapping ) const;
        virtual void unmapStream( GeometryStream& stream ) const;

        bool setupStream( unsigned int mapping, GeometryStream& stream ) const;
        bool allocStream( unsigned int mapping, GeometryStream& stream ) const;
        bool syncStream( unsigned int mapping, GeometryStream& stream ) const;

        virtual void clear( const osgCompute::Context& context ) const;
        virtual osgCompute::BufferStream* newStream( const osgCompute::Context& context ) const;

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

    
}


#endif //OSGCUDA_GEOMETRY