/* osgEarth
 * Copyright 2025 Pelican Mapping
 * MIT License
 */
#ifndef OSGEARTH_UTIL_VIEW_FITTER_H
#define OSGEARTH_UTIL_VIEW_FITTER_H

#include <osgEarth/Common>
#include <osgEarth/GeoData>
#include <osgEarth/Viewpoint>
#include <osg/Camera>

namespace osgEarth { namespace Util
{
    /**
     * Creates Viewpoints that fit a camera's view frustum to encompass
     * a set of geospatial points as tightly as possible.
     */
    class OSGEARTH_EXPORT ViewFitter
    {
    public:
        //! Construct a ViewFitter with a Map SRS and a camera.
        ViewFitter(const SpatialReference* mapSRS, const osg::Camera* camera);

        //! Creates a Viewpoint that looks straight down on the map and
        //! encompasses the provided set of points.
        //! Returns true upon success, or false if there is missing data or if
        //! the camera is orthographic.
        bool createViewpoint(const std::vector<GeoPoint>& points, Viewpoint& out) const;

        //! Creates a Viewpoint that looks straight down on the map and
        //! encompasses the provided extent.
        //! Returns true upon success, or false if there is missing data or if
        //! the camera is orthographic.
        bool createViewpoint(const GeoExtent& extent, Viewpoint& out) const;

        //! Creates a Viewpoint that looks straight down on the map and
        //! encompasses the specified node.
        //! Returns true upon success, or false if there is missing data or if
        //! the camera is orthographic.
        bool createViewpoint(const osg::Node* node, Viewpoint& out) const;

        //! Sets a buffer (in meters) to apply to the view fit. Applying a buffer will
        //! expand the view so that the points are at least "buffer" meters inside the
        //! edge of the fitted view.
        void setBuffer(double value_meters) { _buffer_m = value_meters; }
        double getBuffer() const { return _buffer_m; }

        //! Sets the reference VFOV when using an orthographic camera.
        void setReferenceVFOV(float vfov_degrees) {  _vfov = vfov_degrees; }

    protected:
        osg::ref_ptr<const osg::Camera> _camera;
        osg::ref_ptr<const SpatialReference> _mapSRS;
        float _vfov;
        double _buffer_m;
    };

} }

#endif // OSGEARTH_UTIL_VIEW_FITTER_H
