/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QDebug>
#include <QGeoCircle>
#include <QGeoServiceProvider>
#include <QPlaceDetailsReply>
#include <QPlaceIdReply>
#include <QPlaceManager>
#include <QPlaceSearchReply>
#include <QPlaceResult>
#include <QPlaceImage>
#include <QtCore/QMetaObject>

class RequestHandler : public QObject
{
public:
    void initializeManager() {
        //! [Initialize Manager]
        //The "provider name" is used to select a particular provider
        QGeoServiceProvider *provider = new QGeoServiceProvider("provider name");
        QPlaceManager *manager = provider->placeManager();
        //! [Initialize Manager]
        Q_UNUSED(provider);
        Q_UNUSED(manager);
    }

    void simpleSearch()
    {
        //! [Simple search]
        //1) Make an appropriate request
        QPlaceSearchRequest searchRequest;
        searchRequest.setSearchTerm("ice cream");
        searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78)));

        //2) Use the manager to initiate a request and retrieve a reply object
        QPlaceSearchReply * searchReply = manager->search(searchRequest);

        //3) Connect the reply object to a slot which is invoked upon operation completion
        connect(searchReply, SIGNAL(finished()), this, SLOT(processSearchReply()));
        //! [Simple search]
    }

    void search()
    {
        //! [Search for places cpp]

        //instantiate request and set parameters
        QPlaceSearchRequest searchRequest;
        searchRequest.setSearchTerm("ice cream");
        searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78)));

        //send off a search request
        /*QPlaceSearchReply * */ searchReply = manager->search(searchRequest);

        //connect a slot to handle the reply
        connect(searchReply, SIGNAL(finished()), this, SLOT(handleSearchReply()));

        //! [Search for places cpp]
    }

    void searchPaging()
    {
        //! [Search paging]
        QPlaceSearchRequest searchRequest;
        searchRequest.setLimit(15); //specify how many results are to be retrieved.
        //! [Search paging]
    }

    void details()
    {
        QPlace place;
        //! [Details check]
        if (!place.detailsFetched()) {
            /*QPlaceDetailsReply * */ detailsReply = manager->getPlaceDetails(place.placeId());
            connect(detailsReply, SIGNAL(finished()), this, SLOT(handleDetailsReply()));
        }
        //! [Details check]
    }

    void images()
    {
        QPlace place;

        //! [Image request]
        QPlaceContentRequest request;
        request.setContentType(QPlaceContent::ImageType);
        request.setPlaceId(place.placeId());
        request.setLimit(5);
        /*QPlaceContentReply * */ contentReply = manager->getPlaceContent(request);
        connect(contentReply, SIGNAL(finished()), this, SLOT(handleImagesReply()));
        //! [Image request]
    }


    void suggestion()
    {
        //! [Suggestion request]
        QPlaceSearchRequest request;
        request.setSearchTerm("piz");
        request.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78)));
        /* QPlaceSearchSuggestion * */suggestionReply = manager->searchSuggestions(request);
        connect(suggestionReply, SIGNAL(finished()), this, SLOT(handleSuggestionReply()));
        //! [Suggestion request]
    }

    void savePlace()
    {
        //! [Save place pt1]
        QPlace  place;
        place.setName( "Fred's Ice Cream Parlor" );

        QGeoLocation location;
        location.setCoordinate(QGeoCoordinate(12.34, 56.78));

        QGeoAddress address;
        address.setStreet("111 Nother Street");
        //! [Save place pt1]

        //! [Save place pt2]
        location.setAddress(address);
        place.setLocation(location);

        /* QPlaceIdReply * */savePlaceReply = manager->savePlace(place);
        connect(savePlaceReply, SIGNAL(finished()), this, SLOT(handleSavePlaceReply()));
        //! [Save place pt2]
    }

    void removePlace()
    {
        QPlace place;
        //! [Remove place]
        /* QPlaceIdReply * */removePlaceReply = manager->removePlace(place.placeId());
        connect(removePlaceReply, SIGNAL(finished()), this, SLOT(handleRemovePlaceReply()));
        //! [Remove place]
    }

    void initializeCategories()
    {
        //! [Initialize categories]
        /* QPlaceReply * */initCatReply = manager->initializeCategories();
        connect(initCatReply, SIGNAL(finished()), this, SLOT(handleInitCatReply()));
        //! [Initialize categories]
    }

    void saveCategory()
    {
        //! [Save category]
        QPlaceCategory fastFood;

        QPlaceCategory category;
        category.setName("pizza");
        /*QPlaceIdReply */ saveCategoryReply = manager->saveCategory(category);
        connect(saveCategoryReply, SIGNAL(finished()), this, SLOT(handleSaveCategoryReply()));

        //we could have saved a category as a child by supplying a parent identifier.
        saveCategoryReply = manager->saveCategory(category, fastFood.categoryId());
        //! [Save category]
    }

    void removeCategory()
    {
        QPlaceCategory category;
        //! [Remove category]
        /* QPlaceIdReply * */removeCategoryReply = manager->removeCategory(place.placeId());
        connect(removeCategoryReply, SIGNAL(finished()), this, SLOT(handleRemoveCategoryReply()));
        //! [Remove category]
    }

    void searchRequest() {
        QPlaceCategory diner;
        QPlaceCategory restaurant;

        //! [Search request]
        QPlaceSearchRequest searchRequest;
        searchRequest.setSearchTerm("Fast food"); //search term for what we are interested in

        //set a search center
        searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(2.3, 48.87)));

        //set a distance hint as a relevancy hint.
        //closer places have greater weighting in the ranking of results.
        searchRequest.setRelevanceHint(QPlaceSearchRequest::DistanceHint);

        //use limit to adjust pagination.
        //this limits the number of place results to 5 per page.
        searchRequest.setLimit(5);

        //provide some categories to narrow down search
        QList<QPlaceCategory> categories;
        categories << diner << restaurant;
        searchRequest.setCategories(categories);
        //! [Search request]
    }

    void content() {
        QPlace place;
        //! [Content request]
        QPlaceContentRequest request;
        request.setContentType(QPlaceContent::ImageType);
        request.setPlaceId(place.placeId());
        request.setLimit(5);

        QPlaceContentReply *contentReply = manager->getPlaceContent(request);
        //..connect signals..//

        //! [Content request]
        Q_UNUSED(contentReply);
    }

    void contentConversion()
    {
        //! [Content conversion]
        QPlaceImage image;
        image.setUrl(QUrl("www.example.com"));

        QPlaceContent content = image;

        QPlaceImage image2;
        image2 = content;
        qDebug() << image2.url(); //image2.url() == "www.example.com"
        //! [Content conversion]
    }

    void icon() {
        QPlace place;
        //! [icon]
        QUrl iconSourceUrl = place.icon().url(QSize(32,32));

        //A default icon may also be requested like so
        iconSourceUrl = place.icon().url();
        //! [icon]
    }

    void saveBetweenManagers()  {
        QPlaceResult result;
        QPlaceIdReply *saveReply;
        //! [ Save to different manager]
        //result retrieved from a different manager)
        QPlace place = manager->compatiblePlace(result.place());
        saveReply = manager->savePlace(place);
        //! [ Save to different manager]
        saveReply->abort();//needed to avoid warnings
    }

    void ratings() {
        //! [Ratings]
        qDebug() << QString("This place rated ") + place.ratings().average()
                    + "out of " + place.ratings().maximum() + "stars";
        //! [Ratings]
    }

    void matchPlaces() {
        QList<QPlaceSearchResult> results;
        //! [Match places]
        QPlaceMatchRequest request;
        request.setResults(results);
        QVariantMap parameters;
        parameters.insert(QPlaceMatchRequest::AlternativeId, "x_id_here");
        request.setParameters(parameters);
        matchReply = manager->matchingPlaces(request);
        //! [Match places]
    }

public slots:
    // ![Simple search handler]
    //4) Have the slot appropriately process the results of the operation
    void processSearchReply() {
        if (searchReply->error() == QPlaceReply::NoError) {
            foreach (const QPlaceSearchResult &result, searchReply->results()) {
                if (result.type() == QPlaceSearchResult::PlaceResult)
                    qDebug() << "Title:" << result.title();
            }
        }

    //5) Discard the rely object when done.
        searchReply->deleteLater();
        searchReply = 0;
    }
    // ![Simple search handler]

    //! [Search for places handler cpp]
    void handleSearchReply() {
        if (searchReply->error() == QPlaceReply::NoError) {
            foreach (const QPlaceSearchResult &result, searchReply->results()) {
                if (result.type() == QPlaceSearchResult::PlaceResult) {
                    QPlaceResult placeResult = result;
                    qDebug() << "Name: " << placeResult.place().name();
                    qDebug() << "Coordinate " << placeResult.place().location().coordinate().toString();
                    qDebug() << "Street: " << placeResult.place().location().address().street();
                    qDebug() << "Distance: " << placeResult.distance();
                }
            }
        }
        searchReply->deleteLater();  //discard reply
        searchReply = 0;
    }
    //! [Search for places handler cpp]

    //! [Details handler cpp]
    void handleDetailsReply() {
        QPlace place;
        if (detailsReply->error() == QPlaceReply::NoError)
            place = detailsReply->place();

        detailsReply->deleteLater(); //discard reply
        detailsReply = 0;
    }
    //! [Details handler cpp]

    //! [Image handler]
    void handleImagesReply() {
        if (contentReply->error() == QPlaceReply::NoError) {
            const auto content = contentReply->content();
            for (auto iter = content.cbegin(), end = content.cend(); iter != end; ++iter) {
                qDebug() << "Index: " << iter.key();
                QPlaceImage image = iter.value();
                qDebug() << image.url();
                qDebug() << image.mimeType();
            }

            //alternatively if indexes are irrelevant
            foreach (const QPlaceImage &image, contentReply->content()) {
                qDebug() << image.url();
                qDebug() << image.mimeType();
            }

            //we can assign content to the place that it belongs to.
            //the place object serves as a container where we can retrieve
            //content that has already been fetched
            place.insertContent(contentReply->request().contentType(), contentReply->content());
            place.setTotalContentCount(contentReply->request().contentType(), contentReply->totalCount());
        }

        contentReply->deleteLater();
        contentReply = 0;
    }
    //! [Image handler]

    //! [Suggestion handler]
    void handleSuggestionReply() {
        if (suggestionReply->error() == QPlaceReply::NoError) {
            foreach (const QString &suggestion, suggestionReply->suggestions())
                qDebug() << suggestion;
        }

        suggestionReply->deleteLater(); //discard reply
        suggestionReply = 0;
    }

    //! [Suggestion handler]

    //! [Save place handler]
    void handleSavePlaceReply() {
        if (savePlaceReply->error() == QPlaceReply::NoError)
            qDebug() << savePlaceReply->id();

        savePlaceReply->deleteLater(); //discard reply
        savePlaceReply = 0;
    }
    //! [Save place handler]

    //! [Remove place handler]
    void handleRemovePlaceReply() {
        if (removePlaceReply->error() == QPlaceReply::NoError)
            qDebug() << "Removal of place identified by"
                     << removePlaceReply->id() << "was successful";

        removePlaceReply->deleteLater(); //discard reply
        removePlaceReply = 0;
    }
    //! [Remove place handler]

    //! [Initialize categories reply]
    void handleInitCatReply() {
        if (initCatReply->error() == QPlaceReply::NoError)
            qDebug() << "Categories initialized";
        else
            qDebug() << "Failed to initialize categories";

        initCatReply->deleteLater();
        initCatReply = 0;
    }
    //! [Initialize categories reply]

    void categories() {
        QPlaceCategory pizza;
        //! [Top level categories]
        QList<QPlaceCategory> topLevelCategories = manager->childCategories();
        foreach (const QPlaceCategory &category, topLevelCategories)
            qDebug() << category.name();
        //! [Top level categories]

        //! [Child categories]
        QList<QPlaceCategory> childCategories = manager->childCategories(pizza.categoryId());
        //! [Child categories]
    }

    //! [Save category handler]
    void handleSaveCategoryReply() {
        if (saveCategoryReply->error() == QPlaceReply::NoError) {
            qDebug() << "Saved category id =" << saveCategoryReply->id();
        }

        saveCategoryReply->deleteLater();
        saveCategoryReply = 0;
    }
    //! [Save category handler]

    //! [Remove category handler]
    void handleRemoveCategoryReply() {
        if (removeCategoryReply->error() == QPlaceReply::NoError)
            qDebug() << "Removal of category identified by"
                     << removeCategoryReply->id() << "was successful";

        removeCategoryReply->deleteLater(); //discard reply
        removeCategoryReply = 0;
    }
    //! [Remove category handler]

    //! [Content handler]
    void contentHandler() {
        if (contentReply->error() == QPlaceReply::NoError)  {
            place.insertContent(contentReply->request().contentType(),
                                contentReply->content());
        }
    }
    //! [Content handler]

    void phoneNumbers() {
        //! [Phone numbers]
        if (place.contactTypes().contains(QPlaceContactDetail::Phone)) {
            foreach (const QPlaceContactDetail &number, place.contactDetails(QPlaceContactDetail::Phone))
                qDebug() << number.label() << ":" << number.value();
        }
        //! [Phone numbers]
    }


    void openingHours() {
        //! [Opening hours]
        if (place.extendedAttributeTypes().contains(QPlaceAttribute::OpeningHours))
            qDebug() << place.extendedAttribute(QPlaceAttribute::OpeningHours).text();
        //! [Opening hours]
    }

    //! [Match places handler]
    void matchHandler() {
        if (matchReply->error() == QPlaceReply::NoError) {
            foreach (const QPlace place, matchReply->places()) {
                if (place != QPlace())
                    qDebug() << "Place is a favorite with name" << place.name();
                else
                    qDebug() << "Place is not a favorite";
            }
        }

        matchReply->deleteLater();
        matchReply = 0;
    }
    //! [Match places handler]

    void convertSearchResult() {
        QPlaceSearchResult result;
        //! [Convert search result]
        if (result.type() == QPlaceSearchResult::PlaceResult) {
            QPlaceResult placeResult = result;
            qDebug() << placeResult.place().name();
            qDebug() << placeResult.place().location().coordinate();
            qDebug() << placeResult.distance();
        }
        //! [Convert search result]
    }

QPlaceSearchReply *searchReply;
QPlaceManager *manager;
QPlaceDetailsReply *detailsReply;
QPlaceContentReply *contentReply;
QPlaceSearchSuggestionReply *suggestionReply;
QPlaceIdReply *savePlaceReply;
QPlaceIdReply *removePlaceReply;
QPlaceIdReply *saveCategoryReply;
QPlaceIdReply *removeCategoryReply;
QPlaceReply *initCatReply;
QPlaceMatchReply *matchReply;
QPlace place;
};

class ManagerEngine : public QObject
{
};

//! [Implement reply pt1]
class SearchReply : public QPlaceSearchReply
{
public:
    explicit SearchReply(ManagerEngine *engine)
        : QPlaceSearchReply(engine), m_engine(engine){}

    ~SearchReply();
    void setResults(const QList<QPlaceSearchResult> &results);
    void setRequest(const QPlaceSearchRequest &request);
//! [Implement reply pt1]

//! [Implement reply pt2]
    void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError,
                     const QString &errorString = QString());

    ManagerEngine *m_engine;
};
//! [Implement reply pt2]

class SearchSuggestionReply : public QPlaceSearchSuggestionReply
{
public:
    void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError,
                     const QString &errorString = QString());

    ManagerEngine *m_engine;

};

//! [Trigger done]
void SearchSuggestionReply::triggerDone(QPlaceReply::Error error,
                         const QString &errorString)
{
    if (error != QPlaceReply::NoError) {
        this->setError(error,errorString);
        QMetaObject::invokeMethod(m_engine, "error", Qt::QueuedConnection,
                                  Q_ARG(QPlaceReply *,this),
                                  Q_ARG(QPlaceReply::Error, error),
                                  Q_ARG(QString, errorString));
        QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
                                  Q_ARG(QPlaceReply::Error, error),
                                  Q_ARG(QString, errorString));
    }

    this->setFinished(true);
    QMetaObject::invokeMethod(m_engine, "finished", Qt::QueuedConnection,
                              Q_ARG(QPlaceReply *,this));
    QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
//! [Trigger done]
