/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef MvQWcsClient_H
#define MvQWcsClient_H

#include <QFile>
#include <QMap>
#include <QObject>
#include <QStringList>

#include "MvRequest.h"

#include "MvQOgcParam.h"


class QAuthenticator;
class QDomElement;
class QNetworkReply;

class MvQNetworkAccessManager;
class MvQGetCoverageRequest;

class MvQWcsClientBase : public QObject
{
public:
    virtual ~MvQWcsClientBase(){};
    QStringList supportedMimeType() { return supportedMimeType_; }
    QStringList supportedCrs() { return supportedCrs_; }

protected:
    MvQWcsClientBase();

    QStringList supportedMimeType_;
    QStringList supportedCrs_;

    QString getMimeType(QByteArray);
    QString getRequestedMimeType(QString);
};


class MvQWcsGetClient : public MvQWcsClientBase
{
    Q_OBJECT

public:
    MvQWcsGetClient(MvRequest&);
    ~MvQWcsGetClient();

    MvQGetCoverageRequest* getCovRequest() { return getCovRequest_; }
    void setGetCovRequest(QString);

    QString outFile() { return outFile_; }

    void runGetCov();
    bool getCovRunStatus() { return getCovRunStatus_; }

public slots:
    void slotReplyGetCov(QNetworkReply*);

protected:
    void downloadGetCov();

    MvQGetCoverageRequest* getCovRequest_;

    MvQNetworkAccessManager* networkGetCov_;
    QNetworkReply* getCovReply_;

    MvRequest reqInfo_;
    QString iconFile_;
    QString outFile_;
    bool getCovRunStatus_;
};


class MvQWcsUiClient : public MvQWcsClientBase
{
    Q_OBJECT

public:
    MvQWcsUiClient(string&, MvRequest&);
    ~MvQWcsUiClient();

    enum ClientMode
    {
        BasicMode,
        AdvancedMode
    };

    QString url() { return url_; }
    void setUrl(const QString&, const QString version = "Default");
    QString version() { return version_; }
    void setVersion(const QString&);
    MvQGetCoverageRequest* getCovRequest() { return getCovRequest_; }
    void setGetCovRequest(QString);

    QString getCapDoc() { return capability_; }
    QString describeCovDoc() { return describeCov_; }

    QStringList outFiles() { return outFiles_; }

    ClientMode clientMode() { return clientMode_; }
    void setClientMode(ClientMode);

    QStringList formatDisplayValues() const;
    QString formatCurrentDisplayValue() const;

    QStringList transparentDisplayValues() const;
    QString transparentCurrentDisplayValue() const;
    void setTransparentCurrentDisplayValue(QString);

    void setWidth(QString);
    QString width() const;
    void setHeight(QString);
    QString height() const;

    QStringList crsDisplayValues() const;
    QString crsCurrentDisplayValue() const;
    void setCrsCurrentDisplayValue(QString);

    QStringList styleDisplayValues() const;
    QStringList styleDescriptions() const;
    int styleCurrentIndex() const;
    void setStyleCurrentIndex(int);

    void setLayerFromDpy(MvQOgcNode*);
    QStringList layerDisplayValues() const;
    QStringList layerDescriptions() const;
    const QList<MvQOgcDimension*>& dimension() { return dimension_; }
    QStringList dimensionNameToDpy() const;
    QStringList dimensionToDpy(QString) const;
    void setDimensionFromDpy(QString, QString);
    void setDimensionFromDpy(QString, QStringList);
    void setBoundingBoxFromDpy(QString, QString, QString, QString);
    const MvQOgcBoundingBox* boundingBox() { return requestBbox_; }
    MvQOgcBoundingBox lastBoundingBox() const;
    MvQOgcBoundingBox* currentBoundingBox() const;

    QString extraGetCapPar() { return extraGetCapPar_; }
    QString extraGetCovPar() { return extraGetCovPar_; }
    void setExtraGetCapPar(QString);
    void setExtraGetCovPar(QString);

    MvQOgcTree* layer() { return layer_; }
    int layerCurrentIndex();
    QString layerName() { return layer_->currentValue(); }
    QString layerTitle() { return layer_->currentDisplayValue(); }
    QString layerAbstract() { return layer_->currentDescription(); }

    QString serviceTitle() { return serviceTitle_; }

    QString iconFile() { return iconFile_; }
    void setFileNameInfo(string& name) { iconFile_ = QString::fromStdString(name); }
    void setRequestInfo(MvRequest& req) { reqInfo_ = req; }

    void downloadPreview();
    void downloadLegend();

    QList<MvQOgcElem*> covOffer() { return covOffer_; }

    QMap<QString, QString> serviceMetaData() { return serviceMeta_; }

public slots:
    void slotReplyGetCap(QNetworkReply*);
    void slotReplyDescribeCov(QNetworkReply*);
    void slotReplyGetCov(QNetworkReply*);
    //void slotReplyPreview(QNetworkReply*);
    //void slotReplyLegend(QNetworkReply*);
    void slotRunGetCap();
    void slotRunDescribeCov();
    //void slotRunGetCov();
    void slotAbortDownloadProcess();
    void slotSaveInfo();

    void slotAuthentication(QNetworkReply*, QAuthenticator*);

    void slotSetFormatFromDpy(QString);

signals:
    void getCapLoaded();
    void getCovRequestChanged(QString);
    void describeCovLoaded();
    //void previewLoaded(QString);
    //void legendLoaded(QString);
    void logUpdated();
    void statusMessage(QString);

protected:
    void clearServerDependentData();
    void clearLayerDependentData();
    void clearDimension();
    void clearBoundingBox();
    void runGetCap();
    void buildGetCovRequest();
    void saveGetCovRequest(QMap<QString, QString>&);
    void downloadGetMap();

    QString readVersion();
    void readService();
    void readCoverageOfferingBrief();
    void readCoverageOfferings();
    void readContents();

    void readFormat();
    void readLayer();
    void readLayer(QDomElement&, MvQOgcNode*);
    //void readLayerAbstract();
    void readStyle();
    void readBoundingBox();
    void readCrs();
    void readDimension();
    void readGeographicBoundingBox();
    void readException(QByteArray, QString&);
    void updatRequestBoundingBox();
    QString crsQueryName();
    QString crsDisplayName();
    QString crsRequestName();

    QStringList timeDimName();

    void clearPreview();
    void clearLegend();

    void updateAfterGetCapLoaded();
    void updateAfterLayerLoaded();

    QString url_;
    QString version_;
    QString repliedVersion_;
    QString capability_;
    QString describeCov_;
    MvQGetCoverageRequest* getCovRequest_;
    MvQGetCoverageRequest* currentGetCovRequest_;
    MvQGetCoverageRequest* lastGetCovRequest_;

    //Global
    QString serviceTitle_;
    MvQOgcList* format_;
    MvQOgcList* transparent_;
    MvQOgcIntValue* width_;
    MvQOgcIntValue* height_;
    MvQOgcColourValue* bgColour_;

    //Layer
    MvQOgcTree* layer_;
    QString layerAbstract_;
    MvQOgcCrsList* crs_;
    MvQOgcStyleList* style_;

    MvQOgcBoundingBox* requestBbox_;
    MvQOgcGeoBoundingBox* geographicBbox_;
    QList<MvQOgcBoundingBox*> bbox_;
    QList<MvQOgcDimension*> dimension_;

    MvQNetworkAccessManager* networkGetCap_;
    MvQNetworkAccessManager* networkDescribeCov_;
    MvQNetworkAccessManager* networkGetCov_;

    QNetworkReply* getCapReply_;
    QNetworkReply* describeCovReply_;
    QNetworkReply* getCovReply_;
    //QNetworkReply *previewReply_;
    //QNetworkReply *legendReply_;

    MvRequest reqInfo_;
    QString iconFile_;
    QStringList outFiles_;

    ClientMode clientMode_;
    QString defaultNsDeclaration_;
    QString xlinkNsDeclaration_;
    QString previewFile_;
    QString legendFile_;

    QString extraGetCapPar_;
    QString extraGetCovPar_;

    QString httpUser_;
    QString httpPassword_;

    QMap<QString, QString> serviceMeta_;
    QList<MvQOgcElem*> covOffer_;

    QList<MvQOgcElem*> coverage_;
};

#endif
