/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2010 Pelican Mapping
* http://osgearth.org
*
* osgEarth 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, see <http://www.gnu.org/licenses/>
*/

#ifndef OSGEARTH_CAPABILITIES_H
#define OSGEARTH_CAPABILITIES_H 1

#include <osgEarth/Common>

namespace osgEarth
{
    /**
     * Stores information about the hardware and graphics system capbilities.
     * The osgEarth::Registry stores a singleton Capabilities object that you can 
     * use to determine what your system supports.
     */
    class OSGEARTH_EXPORT Capabilities : public osg::Referenced
    {
    public:
        /** maximum # of texture units exposed in the fixed-function pipeline */
        int getMaxFFPTextureUnits() const { return _maxFFPTextureUnits; }

        /** maximum # of texture image units exposed in a GPU fragment shader */
        int getMaxGPUTextureUnits() const { return _maxGPUTextureUnits; }

        /** maximum # of texture coordinate sets available in a GPU fragment shader */
        int getMaxGPUTextureCoordSets() const { return _maxGPUTextureCoordSets; }

        /** maximum supported size (in pixels) of a texture */
        int getMaxTextureSize() const { return _maxTextureSize; }

        /** maximum number of openGL lights */
        int getMaxLights() const { return _maxLights; }

        /** whether the GPU supports shaders */
        bool supportsGLSL(float minimumVersion =1.0f) const { 
            return _supportsGLSL && _GLSLversion >= minimumVersion; }

        /** the GLSL version */
        float getGLSLVersion() const { return _GLSLversion; }

        /** whether the GPU supports texture arrays */
        bool supportsTextureArrays() const { return _supportsTextureArrays; }

        /** whether the GPU supports OpenGL 3D textures */
        bool supportsTexture3D() const { return _supportsTexture3D; }

        /** whether the GPU supports OpenGL multi-texturing */
        bool supportsMultiTexture() const { return _supportsMultiTexture; }

        /** whether the GPU supports OpenGL stencil wrapping extensions */
        bool supportsStencilWrap() const { return _supportsStencilWrap; }

        /** whether the GPU supports OpenGL the two-sided stenciling extension */
        bool supportsTwoSidedStencil() const { return _supportsTwoSidedStencil; }

        /** whether the GPU support the texture2dLod() function */
        bool supportsTexture2DLod() const { return _supportsTexture2DLod; }

        /** whether the GPU properly supports updating an existing texture with a new mipmapped image */
        bool supportsMipmappedTextureUpdates() const { return _supportsMipmappedTextureUpdates; }

    private:
        Capabilities();

    private:
        int  _maxFFPTextureUnits;
        int  _maxGPUTextureUnits;
        int  _maxGPUTextureCoordSets;
        int  _maxTextureSize;
        int  _maxLights;
        bool _supportsGLSL;
        float _GLSLversion;
        bool _supportsTextureArrays;
        bool _supportsTexture3D;
        bool _supportsMultiTexture;
        bool _supportsStencilWrap;
        bool _supportsTwoSidedStencil;
        bool _supportsTexture2DLod;
        bool _supportsMipmappedTextureUpdates;
        std::string _vendor;
        std::string _renderer;
        std::string _version;

    public:
        friend class Registry;
    };
}

#endif // OSGEARTH_CAPABILITIES_H
