/* osgEarth
 * Copyright 2025 Pelican Mapping
 * MIT License
 */
#pragma once

#include <osgEarth/Common>
#include <osgEarth/Feature>
#include <osgEarth/Filter>

namespace osgEarth { namespace Util
{
    /**
     * This filter will simplify geometries.
     */
    class OSGEARTH_EXPORT SimplifyFilter : public FeatureFilter
    {
    public:
        struct OSGEARTH_EXPORT Options : public ConfigOptions
        {
            Options(const ConfigOptions& co = {}) : ConfigOptions(co) {
                fromConfig(_conf);
            }

            OE_OPTION(double, tolerance, 0.0);
            OE_OPTION(bool, toleranceIsPercentage, false);
            OE_OPTION(bool, preserveTopology, true);
            OE_OPTION(bool, preserveAllFeatures, false);

            void fromConfig(const Config& conf) {
                conf.get("tolerance", tolerance(), toleranceIsPercentage());
                conf.get("preserve_topology", preserveTopology());
                conf.get("preserve_all_features", preserveAllFeatures());
            }

            Config getConfig() const {
                Config conf = ConfigOptions::getConfig();
                conf.key() = "simplify";
                conf.set("tolerance", tolerance(), toleranceIsPercentage());
                conf.set("preserve_topology", preserveTopology());
                conf.set("preserve_all_features", preserveAllFeatures());
                return conf;
            }
        };

    public:
        // Call this determine whether this filter is available.
        static bool isSupported();    

    public:
        SimplifyFilter() = default;
        SimplifyFilter(const Config& conf);

        void setTolerance(double value) {
            options().tolerance() = value;
            options().toleranceIsPercentage() = false;
        }

        void setToleranceAsPercentage(double value) {
            options().tolerance() = value;
            options().toleranceIsPercentage() = true;
        }

        void setPreserveTopology(bool value) {
            options().preserveTopology() = value;
        }

        void setPreserveAllFeatures(bool value) {
            options().preserveAllFeatures() = value;
        }

        virtual ~SimplifyFilter() { }

    public:
        virtual FilterContext push( FeatureList& input, FilterContext& context ); 

        Options& options() { return _options; }
        const Options& options() const { return _options; }

    protected:
        Options _options;
    };
} }
