/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2020 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_PROCEDURAL_VEGETATION_FEATURE_GEN
#define OSGEARTH_PROCEDURAL_VEGETATION_FEATURE_GEN 1

#include <osgEarthProcedural/Export>
#include <osgEarthProcedural/VegetationLayer>
#include <osgEarthProcedural/LifeMapLayer>
#include <osgEarthProcedural/BiomeLayer>

#include <osgEarth/Map>
#include <osgEarth/TerrainTileModelFactory>
#include <osgEarth/FeatureCursor>
#include <osg/Texture>

using namespace osgEarth;

namespace osgEarth { namespace Procedural
{
    /**
     * Creates features representing the location and configuration
     * of vegetation objects.
     */
    class OSGEARTHPROCEDURAL_EXPORT VegetationFeatureGenerator
    {
    public:
        //! Construct a generator.
        VegetationFeatureGenerator();

        //! Sets the map in which to find layers (required)
        void setMap(const Map* map);

        //! Sets the vegetation layer from which to generate features (required)
        void setLayer(VegetationLayer* layer);

        //! Adds a property name to store as a feature attribute
        void addAssetPropertyName(const std::string& name);

        //! Returns the status of the generator - call this to 
        //! see if there are any setup errors before calling getFeatures.
        const Status& getStatus() const;

        //! Populate the output with veg positions corresponding to the tile key.
        //! The key's LOD should match the VegetationLayer's LOD; otherwise no features
        //! will result.
        Status getFeatures(const TileKey& key, FeatureList& output) const;

        //! Populate the output with veg positions within the extent.
        Status getFeatures(const GeoExtent& extent, FeatureList& output) const;
        
    private:
        Status _status;
        osg::ref_ptr<const Map> _map;
        osg::ref_ptr<VegetationLayer> _veglayer;
        std::vector<std::string> _propNames;
        typedef std::unordered_map<const ModelAsset*, osg::BoundingBoxf> SizeCache;
        mutable Threading::Mutexed<SizeCache> _sizeCache;

        void initialize();
    };

} } // namespace osgEarth::Procedural

#endif // OSGEARTH_PROCEDURAL_VEGETATION_FEATURE_GEN
