/* osgEarth
* Copyright 2008-2014 Pelican Mapping
* MIT License
*/
#ifndef OSGEARTH_DRIVERS_MP_TERRAIN_ENGINE_GEOMETRY_POOL
#define OSGEARTH_DRIVERS_MP_TERRAIN_ENGINE_GEOMETRY_POOL 1

#include "Common"
#include "MaskGenerator"
#include "MPTerrainEngineOptions"
#include <osgEarth/MapInfo>
#include <osgEarth/TileKey>
#include <osgEarth/Threading>
#include <osg/Geometry>

namespace osgEarth { namespace Drivers { namespace MPTerrainEngine
{
    using namespace osgEarth;

    /**
     * Pooled geometry manager.
     * Concept adapted from OSG's osgTerrain::GeometryPool
     */
    class GeometryPool : public osg::Referenced
    {
    public:
        GeometryPool(
            unsigned tileSize,
            const MPTerrainEngineOptions& options);

    public:
        /**
         * Hashtable key for unique (and therefore shareable) geometries.
         */
        struct GeometryKey
        {
            GeometryKey() : lod(-1) {}

            bool operator < (const GeometryKey& rhs) const
            {
                if (lod < rhs.lod) return true;
                if (lod > rhs.lod) return false;                
                return (yMin < rhs.yMin);
            }

            int    lod;
            double yMin;
        };

        typedef std::map<GeometryKey, osg::ref_ptr<osg::Geometry> > GeometryMap;

        void getPooledGeometry(
            const TileKey&               tileKey, 
            const MapInfo&               mapInfo,
            osg::ref_ptr<osg::Geometry>& out);

        osg::Geometry* createGeometry(
            const TileKey& tileKey,
            const MapInfo& mapInfo,
            MaskGenerator* maskSet ) const;

    protected:
        virtual ~GeometryPool() { }

        mutable Threading::Mutex      _geometryMapMutex;
        GeometryMap                   _geometryMap;
        unsigned                      _tileSize;
        const MPTerrainEngineOptions& _options;
        
        void createKeyForTileKey(
            const TileKey& tileKey, 
            const MapInfo& mapInfo,
            GeometryKey&   out) const;
    };

} } } // namespace osgEarth::Drivers::MPTerrainEngine

#endif // OSGEARTH_DRIVERS_MP_TERRAIN_ENGINE_GEOMETRY_POOL
