/* -*-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 OSGEARTHUTIL_SELECT_EXTENT_TOOL_H
#define OSGEARTHUTIL_SELECT_EXTENT_TOOL_H 1

#include <osgEarth/Common>
#include <osgEarth/MapNode>
#include <osgEarth/FeatureNode>
#include <osgEarth/Style>
#include <osg/Group>
#include <osgGA/GUIEventHandler>
#include <osgViewer/View>

namespace osgEarth { namespace Contrib
{
    using namespace osgEarth;

    /**
     * Tool that lets the user draw a GeoExtent, and fire a callback
     * when it is done.
     */
    struct OSGEARTH_EXPORT SelectExtentTool : public osgGA::GUIEventHandler
    {
    public:
        typedef std::function<void(const GeoExtent&)> Callback;

        //! Construct a new tool
        SelectExtentTool(MapNode* mapNode);

        //! Whether this tool is enabled (default is true)
        void setEnabled(bool value);
        bool getEnabled() const { return _enabled; }

        //! Clear the visual bounding box
        void clear();

        //! Sets the mouse button that activates the tool
        //! (osgGA::GUIEventAdapter::MouseButtonMask)
        void setMouseButtonMask(int value);

        //! Sets the mod key mask (shift, ctrl, alt) that activates the tool
        //! (osgGA::GUIEventAdapter::ModKeyMask)
        void setModKeyMask(int value);

        //! Access the style to change the appearance of the box
        Style& getStyle();

        //! Function to call when the user finished drawing the extent
        void setCallback(const Callback& callback);

    public: // osgGA::GUIEventHandler

        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override;

    protected:

        bool _enabled;
        bool _mouseDown;
        int _mouseButtonMask;
        int _modKeyMask;

        osg::ref_ptr<osg::Group> _root;

        GeoPoint _mouseDownPoint;
        GeoExtent _extent;

        osg::ref_ptr<osgEarth::FeatureNode> _featureNode;
        osg::ref_ptr<osgEarth::Feature> _feature;

        Callback _callback;  
        osg::observer_ptr< MapNode > _mapNode;

        virtual ~SelectExtentTool();

        MapNode* getMapNode() { return _mapNode.get(); }

        void rebuild();

        void updateFeature(const GeoExtent& ex); // const GeoPoint& p1, const GeoPoint& p2);
    };
} }

#endif // OSGEARTHUTIL_SELECT_EXTENT_TOOL_H