/*
 * This source file is part of KEOS (Free 3D Engine)
 * For the latest info, see http://www.keosengine.org/
 * E-mails : thierry.vouriot@keosengine.org, yeri@keosengine.org
 * 
 * This program 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 2 of the License, or (at your option) any later
 * version.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
 * http://www.gnu.org/copyleft/lesser.txt.
 *
 */

#ifndef KEOS_OGLBUFFER_H
#define KEOS_OGLBUFFER_H

#include "KeosOGLPrerequisites.h"
#include "KeosBufferBase.h"
#include "KeosOGLEnum.h"

namespace Keos
{
    //-----------------------------------------------------------------------
    /** Vertex/Index buffer OpenGL implementation. 
     */
    template <int Type>
    class COGLBuffer : public IBufferBase
    {
    public :

        /** Constructor.
         *  @param nCount Buffer size.
         *  @param nBuffer OpenGL buffer id.
         */
        COGLBuffer(ulong nCount, uint nBuffer);

        /** Destructor.
         */
        virtual ~COGLBuffer();

        /** Return the OGL Buffer id.
         */
        uint GetBuffer() const;

    private :

        /** See IBufferBase.
         */
        void* Lock(ulong nOffset, ulong nSize, ulong nFlags);

        /** See IBufferBase.
         */
        void Unlock();

        // OGL buffer id
        uint m_nBuffer; 
    };

    // Index and vertex buffer definition from COGLBuffer template
    typedef COGLBuffer<GL_ARRAY_BUFFER_ARB>         COGLVertexBuffer;
    typedef COGLBuffer<GL_ELEMENT_ARRAY_BUFFER_ARB> COGLIndexBuffer;


    //=======================================================================
    // COGLBuffer inline functions
    //=======================================================================
    
    //-----------------------------------------------------------------------  
    template <int Type>
    inline COGLBuffer<Type>::COGLBuffer(ulong nCount, uint nBuffer) :
    IBufferBase(nCount),
    m_nBuffer   (nBuffer)
    {

    }

    //-----------------------------------------------------------------------  
    template <int Type>
    inline COGLBuffer<Type>::~COGLBuffer()
    {
        if (m_nBuffer)
            COGLRenderSystem::glDeleteBuffersARB(1, &m_nBuffer);
    }

    //-----------------------------------------------------------------------  
    template <int Type>
    inline uint COGLBuffer<Type>::GetBuffer() const
    {
        return m_nBuffer;
    }

    //-----------------------------------------------------------------------  
    template <int Type>
    inline void* COGLBuffer<Type>::Lock(ulong nOffset, ulong nSize, ulong nFlags)
    {
        COGLRenderSystem::glBindBufferARB(Type, m_nBuffer);
        uchar* pBuffer = reinterpret_cast<uchar*>(COGLRenderSystem::glMapBufferARB(Type, COGLEnum::LockFlags(nFlags)));

        return pBuffer + nOffset;
    }

    //-----------------------------------------------------------------------  
    template <int Type>
    inline void COGLBuffer<Type>::Unlock()
    {
        COGLRenderSystem::glUnmapBufferARB(Type);
    }

} // namespace Keos

#endif // KEOS_OGLBUFFER_H
