/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2008-2012 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.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* 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_BIOME_LAYER_H
#define OSGEARTH_PROCEDURAL_BIOME_LAYER_H

#include "Export"
#include "Biome"
#include "BiomeManager"
#include <osgEarth/ImageLayer>
#include <osgEarth/LayerReference>
#include <osgEarth/FeatureSource>

namespace osgEarth
{
    namespace Procedural
    {
        using namespace osgEarth;

        class OSGEARTHPROCEDURAL_EXPORT BiomeLayer : public ImageLayer, public osg::Observer
        {
        public:
            class OSGEARTHPROCEDURAL_EXPORT Options : public ImageLayer::Options
            {
            public:
                META_LayerOptions(osgEarth, Options, ImageLayer::Options);
                OE_OPTION_LAYER(FeatureSource, controlVectors);
                OE_OPTION_SHAREDPTR(BiomeCatalog, biomeCatalog);
                OE_OPTION(float, blendRadius);
                OE_OPTION(std::string, biomeidField);
                virtual Config getConfig() const;
            private:
                void fromConfig(const Config& conf);
            };

        public:
            META_Layer(osgEarthProcedural, BiomeLayer, Options, ImageLayer, Biomes);
                
            //! Get the biome corresponding to the input "id"
            const Biome* getBiome(int id) const;

            //! The catalog holding all biome information
            std::shared_ptr<const BiomeCatalog> getBiomeCatalog() const;

            //! Manager that paged biome data in and out
            BiomeManager& getBiomeManager() { return _biomeMan; }

            virtual void addedToMap(const Map*) override;

        protected:

            virtual void init() override;

            virtual Status openImplementation() override;

            virtual Status closeImplementation() override;

            virtual GeoImage createImageImplementation(
                const TileKey& key, 
                ProgressCallback* progress) const override;

        protected:

            FeatureSource* getControlSet() const;

            virtual ~BiomeLayer() { }

            // control features for biome selection
            FeatureList _features;

            // spatial index for _features
            void* _index;

            // handles memory residency of biome asset data
            BiomeManager _biomeMan;

            using Tracker = std::unordered_map<osg::Object*, TileKey>;
            mutable Mutexed<Tracker> _tracker;
            void objectDeleted(void*) override;
        };

    }
} // namespace osgEarth::Procedural

#endif // OSGEARTH_PROCEDURAL_BIOME_LAYER_H
