/***************************** 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
