// SPDX-License-Identifier: LGPL-2.1-or-later
//
// SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
//

#ifndef MARBLE_ROUTINGINPUTWIDGET_H
#define MARBLE_ROUTINGINPUTWIDGET_H

#include "PositionProviderPluginInterface.h"

#include <QWidget>

class QAbstractItemModel;

namespace Marble
{

class RoutingInputWidgetPrivate;
class GeoDataCoordinates;
class GeoDataPlacemark;
class MarbleModel;
class MarblePlacemarkModel;

/**
 * Combines a line edit for input and a couple of buttons to let
 * the user type in a search term, find according placemarks using
 * the marble runner manager and store one of them as the current
 * selection (target position)
 */
class RoutingInputWidget : public QWidget
{
    Q_OBJECT

public:
    /** Constructor */
    explicit RoutingInputWidget(MarbleModel *model, int index, QWidget *parent = nullptr);

    /** Destructor */
    ~RoutingInputWidget() override;

    /**
     * Returns true if the user has selected a valid geo position
     * @see targetPosition
     */
    bool hasTargetPosition() const;

    /**
     * Returns the geoposition selected by the user, or a default
     * constructed geoposition if hasTargetPosition returns false
     * @see hasTargetPosition selectPlacemark
     */
    GeoDataCoordinates targetPosition() const;

    /**
     * Returns the placemark model that contains search results
     */
    MarblePlacemarkModel *searchResultModel();

    /**
     * Returns false iff the input text is empty
     */
    bool hasInput() const;

    /**
     * Change the data index in the route request model
     */
    void setIndex(int index);

    /**
     * Remove target position and user input, if any
     */
    void clear();

public Q_SLOTS:
    /**
     * Search for placemarks matching the current input text. Does nothing
     * if input is empty
     */
    void findPlacemarks();

    /** Set the target position to the given coordinates,
     * eliminating any previously set positions
     * @see selectPlacemark hasTargetPosition
     */
    void setTargetPosition(const GeoDataCoordinates &position, const QString &name = QString());

    /** Cancel a started input request from the map */
    void abortMapInputRequest();

    /** Reload the bookmarks menu */
    void reloadBookmarks();

Q_SIGNALS:
    /** All runners are finished */
    void searchFinished(RoutingInputWidget *);

    /** User requests to remove this widget */
    void removalRequest(RoutingInputWidget *);

    /** User requests to activate this widget */
    void activityRequest(RoutingInputWidget *);

    /** User requests position input from the map */
    void mapInputModeEnabled(RoutingInputWidget *, bool enabled);

    /** hasTargetPosition changed because of selecting a placemark or changing the search term */
    void targetValidityChanged(bool targetValid);

private Q_SLOTS:
    /** Runner progress */
    void setPlacemarkModel(QAbstractItemModel *);

    /** Handle click on the goto target button */
    void requestActivity();

    /** Handle click on the remove widget button */
    void requestRemoval();

    /** Handle click on the map input button */
    void setMapInputModeEnabled(bool enabled);

    /** All runners have completed */
    void finishSearch();

    /** Mark ourselves dirty (no target) */
    void setInvalid();

    /** Set the target position (dragging) */
    void updatePosition(int index, const GeoDataCoordinates &position);

    void reverseGeocoding();

    void retrieveReverseGeocodingResult(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark);

    void setHomePosition();

    void setCurrentLocation();

    void updateCurrentLocationButton(PositionProviderStatus status);

    void updateCenterButton(bool hasPosition);

    void setBookmarkPosition(QAction *bookmark);

    void openTargetSelectionDialog();

    void showMenu();

private:
    RoutingInputWidgetPrivate *const d;
};

} // namespace Marble

#endif
