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

#include <QApplication>
#include <QBuffer>
#include <QDateTime>
#include <QDebug>
#include <QDomDocument>
#include <QFile>
#include <QImage>
#include <QUrl>

#include <QAuthenticator>
#include <QNetworkReply>
#include <QXmlFormatter>
#include <QXmlResultItems>

#include "MvQNetworkAccessManager.h"
#include "MvQOgcRequest.h"
#include "MvQXmlQuery.h"

#include "MvQWmsClient.h"

#include "LogHandler.h"
#include "StatusMsgHandler.h"

#include "mars.h"
#include "Metview.h"

//==============================
// 
// MvQProjInfo
//
//==============================

MvQProjInfo::MvQProjInfo(const MvRequest &inReq)
{
	if(strcmp(inReq.getVerb(),"GEOVIEW") != 0)
		return;	
  
  	const char* info=inReq("_ZOOM_DEFINITION");
	if(info)
	{
		parseProj4String(info);
	}	
	else
	{		 
		parseRequest(inReq);
	}
}


void MvQProjInfo::parseProj4String(const char* info)
{
	if(!info)
		return;
			  	  
	QString str(info);
	str.remove("\"");
	str.remove("{");
	str.remove("}"); 
		
	QMap<QString,QString> param;
	foreach(QString s,str.split(","))
	{
		QStringList s1=s.split(":");
		if(s1.count()==2)
		{
			 insert(s1[0].simplified(),s1[1].simplified());
		}
	}
	
	if(value("subpage_map_projection") == "cylindrical")
	{
		if(value("subpage_map_area_definition") == "full")
		{
			insert("subpage_lower_left_latitude","-90");
			insert("subpage_lower_left_longitude","-180");
			insert("subpage_upper_right_latitude","90");
			insert("subpage_upper_right_longitude","180");  
		}
	}	
}
	
void MvQProjInfo::parseRequest(const MvRequest &inReq)	
{	
	MvRequest ctx;
		
	//Expand the request
	char *shareDir=getenv("METVIEW_DIR_SHARE");
	if(shareDir)
	{	
		string path(shareDir);
		path.append("/etc/");

		string defFileName=path+ "GeoViewDef";
		string rulesFileName=path + "GeoViewRules";

		MvLanguage langMetview ( defFileName.c_str(),
				  rulesFileName.c_str(),
				  EXPAND_DEFAULTS);

	        ctx=langMetview.expandOne (inReq);
        }
        else
	{
	  	ctx=inReq;
	}		
		
	const char* proj= (const char*)ctx("MAP_PROJECTION");
	
	if(proj && strcmp(proj,"CYLINDRICAL") == 0)
	{
		insert("subpage_map_projection","cylindrical");
		
	        const char* ad= (const char*)ctx("MAP_AREA_DEFINITION");
		QString areaDef;	
		if(ad)
		{
		  	areaDef=QString(ad);
			areaDef=areaDef.toLower();
			insert("subpage_map_area_definition",areaDef);
		}	
		else
		  	return;
		  
		if(areaDef == "corners" && ctx.countValues("AREA") == 4)
		{
			double dval;
			ctx.getValue(dval,"AREA",0);
			insert("subpage_lower_left_latitude",QString::number(dval));
			ctx.getValue(dval,"AREA",1);
			insert("subpage_lower_left_longitude",QString::number(dval));
			ctx.getValue(dval,"AREA",2);
			insert("subpage_upper_right_latitude",QString::number(dval));
			ctx.getValue(dval,"AREA",3);
			insert("subpage_upper_right_longitude",QString::number(dval));  
		}	  
		
		else if(areaDef == "full")
		{
			insert("subpage_lower_left_latitude","-90");
			insert("subpage_lower_left_longitude","-180");
			insert("subpage_upper_right_latitude","90");
			insert("subpage_upper_right_longitude","180");  
		}	
	}
}

QString MvQProjInfo::get(QString key)
{
	QMap<QString,QString>::const_iterator it=find(key);
	if(it != end())
		return it.value();
	
	else
	  	return QString();
}	

								  
//==============================
// 
// Message handler for XQuery
//
//==============================


void MvQWmsMessageHandler::handleMessage(QtMsgType type,const QString& description,const QUrl& /*identifier*/,
				      const QSourceLocation& /*sourceLocation*/)
{
	if(type == QtFatalMsg)
	{
	  	fatalMsg_ << description;
	}
}  


//==============================
// 
// Base client
//
//==============================

MvQWmsClientBase::MvQWmsClientBase()
{
	supportedMimeType_ << "image/png" << "image/jpeg" << 
			    "image/gif"; // "image/svg+xml";

	supportedCrs_ << "EPSG:4326" << "CRS:84";
	
	queryMsgHandler_= new MvQWmsMessageHandler;
}

MvQWmsClientBase::~MvQWmsClientBase()
{
	delete queryMsgHandler_;
}

QString MvQWmsClientBase::getMimeType(QByteArray ba)
{
	qDebug() << "fileType" << ba.mid(0,8).toHex();

	if(ba.mid(0,8).toHex() == "89504e470d0a1a0a")
	{
		return "image/png";
	}
	else if(ba.mid(0,4).toHex() == "ffd8ffe0")
	{
		return "image/jpeg";
	}
	else if(ba.mid(0,6) == "GIF87a" ||
		ba.mid(0,6) == "GIF89a")
	{
		return "image/gif";
	}

	return QString("text/plain");
}


QString MvQWmsClientBase::getRequestedMimeType(QString r)
{
	MvQGetMapRequest req;
	req.setRequest(r);
	return req.item("FORMAT");
}

//==============================
// 
// Download/batch client
//
//==============================

MvQWmsGetClient::MvQWmsGetClient(MvRequest& req):
	reqInfo_ (req)
{
	//Init
  	getMapRunStatus_=false;
	requestChanged_=false;

	networkGetMap_=0;
	networkLegend_=0;
	networkLogo_=0;
	getMapReply_=0;
	legendReply_=0;
	logoReply_=0;
	
	getMapFrameNum_=0;
	getMapFrameToDownload_=-1;	

	//Mode
	const char* modec = (const char*)reqInfo_("_ACTION");
	QString mode;
	if(modec) mode=QString(modec);
	
	//Nosubsets
	const char* noSubsets= (const char*)reqInfo_("LAYER_NOSUBSETS");

	//Time dimensions
	QStringList timeDimName;
	const char* tdn= (const char*)reqInfo_("TIME_DIMENSIONS");
	if(tdn)
	{
		QString s(tdn);
		timeDimName=s.split("/");
	}
	
	//Create and initialise request object
	getMapRequest_=new MvQGetMapRequest;
	getMapRequest_->setRequest(QString((const char*)reqInfo_("REQUEST")),timeDimName);
	
	//Update bbox if needed
	if((mode == "prepare" || mode == "update") && 
	  (noSubsets ==0 || strcmp(noSubsets,"0") == 0))
	{  
		requestChanged_=updateBoundingBox();
	}
	
	//In update mode if bbox was not updated we quit
	if(mode == "update" && requestChanged_ == false)
	{
		return;
	}
	
	//Legend and log path
	const char* legend= (const char*)reqInfo_("LAYER_LEGEND");
	if(legend)
		legendPath_=QString(legend);
	
	const char* logo= (const char*)reqInfo_("LAYER_LOGO");
	if(logo)
		logoPath_=QString(logo);

	
	//Network access
	networkGetMap_ = new MvQNetworkAccessManager(this);
	networkLegend_ = new MvQNetworkAccessManager(this);
	networkLogo_ = new MvQNetworkAccessManager(this);

	connect(networkGetMap_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyGetMap(QNetworkReply*)));

	connect(networkLegend_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyLegend(QNetworkReply*)));

	connect(networkLogo_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyLogo(QNetworkReply*)));

}

MvQWmsGetClient::~MvQWmsGetClient()
{
	delete getMapRequest_;
	if(networkGetMap_) delete networkGetMap_;
	if(networkLegend_) delete networkLegend_;
	if(networkLogo_) delete networkLogo_;
}

bool MvQWmsGetClient::updateBoundingBox()
{
	//Get current view area in the plot

	MvRequest ctxIn=reqInfo_("_CONTEXT");
	if(!ctxIn || strcmp(ctxIn.getVerb(),"GEOVIEW") != 0)
		return false;
		
	//ctxIn.print(); 
	MvQProjInfo projInfo(ctxIn);
	//ctxIn.print(); 
			
	QList<float> areaL;
	
	//Cylindrical
	if(projInfo.get("subpage_map_projection") == "cylindrical")
	{
		if(projInfo.get("subpage_map_area_definition") == "corners"||
		   projInfo.get("subpage_map_area_definition") == "full")
		{
			areaL << projInfo.get("subpage_lower_left_latitude").toDouble();
			areaL << projInfo.get("subpage_lower_left_longitude").toDouble();
			areaL << projInfo.get("subpage_upper_right_latitude").toDouble();
			areaL << projInfo.get("subpage_upper_right_longitude").toDouble();
		}
	}
	

#if 0
	MvRequest ctx;
	MvRequest ctxIn=reqInfo_("_CONTEXT");
	
	ctxIn.print();
	
	char *shareDir=getenv("METVIEW_DIR_SHARE");
	if(shareDir)
	{	
		string path(shareDir);
		path.append("/etc/");

		string defFileName=path+ "GeoViewDef";
		string rulesFileName=path + "GeoViewRules";

		MvLanguage langMetview ( defFileName.c_str(),
				  rulesFileName.c_str(),
				  EXPAND_DEFAULTS);

	        ctx=langMetview.expandOne (ctxIn);
        }
        else
	{
	  	ctx=ctxIn;
	}	

	ctx.print();

	const char* proj= (const char*)ctx("MAP_PROJECTION");
	
	int cnt = ctx.countValues("AREA");
	double dval; 
	QList<float> areaL;
	for(int i=0; i< cnt; i++)
	{
		ctx.getValue(dval,"AREA",i);
	 	areaL << dval;
	}

	//Check if we have the view area definition
	if(!proj || areaL.count() != 4)
	{
		return false;
	}	
#endif
	//Max bounding box for the given CRS/SRS
	const char* bbChar= (const char*)reqInfo_("MAX_BOUNDING_BOX");
	QRectF maxBox;
	if(bbChar)
	{
	  	QString s(bbChar);
		QStringList lst=s.split("/");
		if(lst.count() == 4)
		{
		 	maxBox=QRectF(lst[0].toFloat(),lst[1].toFloat(),
				    lst[2].toFloat()-lst[0].toFloat(),
				    lst[3].toFloat()-lst[1].toFloat());				    
		}
	}
	
	if(maxBox.isEmpty())
	{
	  	return false;
	}	
	  
	//Current bounding box from the request
	QRectF currentBox;
	QStringList lst=getMapRequest_->item("BBOX").split(",");	  	
	qDebug() << lst;
	if(lst.count() == 4)
	{
		 currentBox=QRectF(lst[0].toFloat(),lst[1].toFloat(),
				    lst[2].toFloat()-lst[0].toFloat(),
				    lst[3].toFloat()-lst[1].toFloat());				    
	}
		
	if(currentBox.isEmpty())
	{
	  	return false;
	}		  
	  
		 
	  
	qDebug() << "area" << areaL << maxBox << currentBox; 
	qDebug() << "request" << getMapRequest_->request()  << getMapRequest_->crs();
	  
	//We reached this point only if both view area and
	//bounding box were found!!!!
	  
	if(projInfo.get("subpage_map_projection") == "cylindrical")
	{
		//areaL: s,w,n,e
		//bbox: mix, miny, max, maxy
		//qDebug() << "area" << areaL;	
				
		QRectF areaBox;
		
		//For 1.3.0 in epsg:4326 x is lat and y is lon !!!!!
		if(getMapRequest_->request().contains("CRS=",Qt::CaseInsensitive) &&
		   getMapRequest_->crs() == "EPSG:4326")
		{					
			areaBox=QRectF(areaL[0],areaL[1],areaL[2]-areaL[0],areaL[3]-areaL[1]);
		}
		else if(getMapRequest_->crs() == "EPSG:4326" || getMapRequest_->crs() == "CRS:84")			
		{						
			areaBox=QRectF(areaL[1],areaL[0],areaL[3]-areaL[1],areaL[2]-areaL[0]);
		}

		qDebug() << "CONTAINS" << areaBox << maxBox <<  currentBox ;

		if(areaBox.isEmpty())
		{  
			return false;
		}		
		
		qDebug() << "CONTAINS" << areaBox << maxBox <<  currentBox ;

		if(areaBox.intersects(maxBox))
		{  		
			// maxAreaBox = the intersection of the viewable area 
			//and the max bounding box for the srs/c
			QRectF maxAreaBox=areaBox.intersected(maxBox);

			qDebug() << "Intersects" << areaBox << maxBox <<  currentBox << maxAreaBox;

			//Find out the relation of the maxAreaBox and the current bounding 
			//box in the request
			QRectF resBox;
			if(maxAreaBox != currentBox)
			{
				resBox=maxAreaBox;
			}  
			
			if(!resBox.isEmpty())
			{  
				getMapRequest_->setItem("BBOX",
				QString::number(resBox.x()) + "," + 
				QString::number(resBox.y()) + "," + 
				QString::number(resBox.x()+resBox.width()) + "," + 
				QString::number(resBox.y()+resBox.height()));
				
				return true;
			}	
		}		
		
	}
	
	return false;
}

void MvQWmsGetClient::runGetMap()
{	
	outFiles_.clear();

	qDebug() << "request" << getMapRequest_->request();
 
	QStringList lst=getMapRequest_->requestFrame();
	getMapFrameNum_=lst.count();
	getMapFrameToDownload_=0;	

	getMapRunStatus_=false;
	downloadGetMapFrame();
}

void MvQWmsGetClient::downloadGetMapFrame()
{
	//qDebug() << "request" << getMapFrameToDownload_ << getMapRequest_->requestFrame(getMapFrameToDownload_);
	
	QNetworkRequest  netReq(QUrl::fromPercentEncoding(getMapRequest_->requestFrame(getMapFrameToDownload_).toUtf8()));
	//netReq.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg("egows").arg("egows").toAscii()).toBase64());
	
	getMapReply_ = networkGetMap_->get(netReq);
}

void MvQWmsGetClient::downloadLegend()
{
	if(!legendPath_.isEmpty())	
	{
		//qDebug() << "legend" << QUrl::fromPercentEncoding(legendPath_.toAscii());
	  
		QNetworkRequest netReq(QUrl::fromPercentEncoding(legendPath_.toUtf8()));
		//netReq.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg("egows").arg("egows").toAscii()).toBase64());	
	  	legendReply_=networkLegend_->get(netReq);
	}
	else
	{
		//QApplication::exit();
		downloadLogo();
	}
}

void MvQWmsGetClient::downloadLogo()
{
	if(!logoPath_.isEmpty())	
	{
		logoReply_=networkLogo_->get(QNetworkRequest(QUrl::fromPercentEncoding(logoPath_.toUtf8())));
	}
	else
	{
		QApplication::exit();
	}
}



void MvQWmsGetClient::slotReplyGetMap(QNetworkReply* reply)
{
	QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

	if(reply->error() != QNetworkReply::NoError)
	{				
		getMapFrameNum_=0;
		getMapFrameToDownload_=-1;
		
		QString ems="GetMap request failed!\nError: ";
		ems+=reply->errorString();
		marslog(LOG_EROR,"GetMap request failed!\nError: %s ",reply->errorString().toStdString().c_str());			
		QApplication::exit();
		return;
	}
	else
	{			
		// temporary file
		QString outFile;		
		outFile=marstmp();
		
		getMapRequest_->setOutFile(getMapFrameToDownload_,outFile);

		QByteArray ba=reply->readAll();	

		if(mimeType.isEmpty())
			mimeType=getMimeType(ba);

		//If exception is returned or mime type is 
		//different to what was requested
		if(mimeType.contains("application/vnd.ogc.se_xml") ||
		   mimeType.contains("text/xml") ||
		   !mimeType.contains(getRequestedMimeType(url.toString())))		
		{
			QString eMsg;
			//readException(ba,eMsg);

			getMapFrameNum_=0;
			getMapFrameToDownload_=-1;
			
			//marslog(LOG_EROR,"GetMap request failed!\nError: %s ",eMsg.toStdString().c_str());
			marslog(LOG_EROR,"GetMap request failed! ");
			QApplication::exit();
			return;
		}

		QFile out(outFile);
		out.open(QIODevice::WriteOnly);
		out.write(ba);
		out.close();

		getMapFrameToDownload_++;
			
		if(getMapFrameToDownload_ < getMapFrameNum_)
		{
			downloadGetMapFrame();
		}
		else
		{
			getMapFrameNum_=0;
			getMapFrameToDownload_=-1;
				
			getMapRunStatus_=true;
			downloadLegend();
			//QApplication::exit();
		}
	}

	reply->deleteLater();
	getMapReply_=0;
}

void MvQWmsGetClient::slotReplyLegend(QNetworkReply* reply)
{
	QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

	if(reply->error() != QNetworkReply::NoError)
	{
		QString ems="Legend download failed!\nError: ";
		ems+=reply->errorString();
		marslog(LOG_EROR,"Legend download failed!\nError: %s ",reply->errorString().toStdString().c_str());
		//log->error(reply->errorString().toStdString() + "\n");			
		downloadLogo();
		//QApplication::exit();
		return;	
	}
	else
	{	
		QByteArray ba=reply->readAll();

		//If exception is returned ot mime type is 
		//different ot what was requested
		if(mimeType.contains("application/vnd.ogc.se_xml") ||
		   mimeType.contains("text/xml") ||
		   mimeType.contains("text/plain") ) //||
		//   mimeType != getRequestedMimeType(url.toString()))		
		{
			QApplication::exit();
			return;
		}
		else
		{
			QString outFile=QString::fromStdString(marstmp());

			QFile out(outFile);
			out.open(QIODevice::WriteOnly);
			out.write(ba);
			out.close();

			legendImagePath_=outFile;

			//QApplication::exit();
			downloadLogo();
		}
	}

	reply->deleteLater();
	legendReply_=0;
}


void MvQWmsGetClient::slotReplyLogo(QNetworkReply* reply)
{
	QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

	if(reply->error() != QNetworkReply::NoError)
	{
		QString ems="Logo download failed!\nError: ";
		ems+=reply->errorString();
		marslog(LOG_EROR,"Logo download failed!\nError: %s ",reply->errorString().toStdString().c_str());
		//log->error(reply->errorString().toStdString() + "\n");			
		QApplication::exit();
		return;	
	}
	else
	{	
		QByteArray ba=reply->readAll();

		//If exception is returned ot mime type is 
		//different ot what was requested
		if(mimeType.contains("application/vnd.ogc.se_xml") ||
		   mimeType.contains("text/xml") ||
		   mimeType.contains("text/plain") ) //||
		//   mimeType != getRequestedMimeType(url.toString()))		
		{
			QApplication::exit();
			return;
		}
		else
		{
			QString outFile=QString::fromStdString(marstmp());

			QFile out(outFile);
			out.open(QIODevice::WriteOnly);
			out.write(ba);
			out.close();

			logoImagePath_=outFile;

			QImage img(outFile);
			if(img.width() > 100)
			{
				img.scaledToWidth(100,Qt::SmoothTransformation).save(outFile,"png");
			}

			QApplication::exit();
		}
	}

	reply->deleteLater();
	logoReply_=0;
}



//=================================
// 
// Client for the user interface
//
//=================================

MvQWmsUiClient::MvQWmsUiClient(string& iconFile, MvRequest& req):
	iconFile_(QString::fromStdString(iconFile)),
	reqInfo_ (req)
{

	char *shareDir=getenv("METVIEW_DIR_SHARE");
	if(shareDir)
	{	
		string path(shareDir);
		path.append("/etc/");

		string defFileName=path+ "WmsClientDef";
		string rulesFileName=path + "WmsClientRules";

		MvLanguage langMetview ( defFileName.c_str(),
				  rulesFileName.c_str(),
				  EXPAND_DEFAULTS);

	        reqInfo_=langMetview.expandOne (req);
        }


	reqInfo_.print();	

	getMapRequest_=new MvQGetMapRequest;
	lastGetMapRequest_=new MvQGetMapRequest;

	// Initialize elements from Metview request
	url_ = QString((const char*)reqInfo_("SERVER"));
	version_ = (const char*)reqInfo_("VERSION");

	QStringList timeDimName;

	const char* tdn= (const char*)reqInfo_("TIME_DIMENSIONS");
	if(tdn)
	{
		QString s(tdn);
		timeDimName=s.split("/");
	}

	getMapRequest_->setRequest(QString((const char*)reqInfo_("REQUEST")),timeDimName);
	
	clientMode_=AdvancedMode;
	if((const char*)reqInfo_("MODE") !=0)
	{
		QString m(reqInfo_("MODE"));
		if(m=="EXPERT")
			clientMode_=BasicMode;
		else
			clientMode_=AdvancedMode;
	}	
	
	if((const char*)reqInfo_("EXTRA_GETCAP_PAR") !=0)
	{
		extraGetCapPar_=QString(reqInfo_("EXTRA_GETCAP_PAR"));	
	}	

	if((const char*)reqInfo_("EXTRA_GETMAP_PAR") !=0)
	{
		extraGetMapPar_=QString(reqInfo_("EXTRA_GETMAP_PAR"));	
	}	

	if((const char*)reqInfo_("HTTP_USER") !=0)
	{
		httpUser_=QString(reqInfo_("HTTP_USER"));	
	}	

	if((const char*)reqInfo_("HTTP_PASSWORD") !=0)
	{
		httpPassword_=QString(reqInfo_("HTTP_PASSWORD"));	
	}	


	//qDebug() << "Init:" << url_ << version_ << getMapRequest_;
	
	//Width
	width_= new MvQOgcIntValue(1024,"WIDTH","Width:");
	QString val=getMapRequest_->item(width_->requestName());
	if(!val.isEmpty())
		width_->setValue(val.toInt());
	
	//Height
	height_= new MvQOgcIntValue(512,"HEIGHT","Height:");
	val=getMapRequest_->item(height_->requestName());
	if(!val.isEmpty())
		height_->setValue(val.toInt());

	//Format
	format_= new MvQOgcList("FORMAT","Format:");

	//Transparent
	transparent_= new MvQOgcList("TRANSPARENT","Transparent:");	
	transparent_->setValues(QStringList() << "TRUE" << "FALSE");
	transparent_->setDisplayValues(QStringList() << "True" << "False");
	val=getMapRequest_->item(transparent_->requestName());
	
	//If it is a new request we set transparency to TRUE by default
	if(val.isEmpty() && getMapRequest_->request().isEmpty())
	{
		transparent_->setCurrentValue("TRUE");
	}
	else
	{
		transparent_->setCurrentValue(val);
	}

	//BgColour
	bgColour_= new MvQOgcColourValue("#FFFFFF","BGCOLOUR","Bg colour:");

	//Layer
	layer_= new MvQOgcTree("LAYERS","Layer:");

	//CRS/SRS	
	crs_= new MvQOgcCrsList("CRS","CRS:");
			
	//Style
	style_= new MvQOgcStyleList("STYLES","Style:");

	//BoundingBox
	requestBbox_=new MvQOgcBoundingBox("BBOX","");
	geographicBbox_=0;

	//Dimension
		
	//Network access
	networkGetCap_ = new MvQNetworkAccessManager(this);
	networkPreview_ = new MvQNetworkAccessManager(this);
	networkLegend_ = new MvQNetworkAccessManager(this);
	networkLogo_ = new MvQNetworkAccessManager(this);

	getCapReply_=0;
	previewReply_=0;
	legendReply_=0;
	logoReply_=0;
	
	connect(networkGetCap_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyGetCap(QNetworkReply*)));

	connect(networkPreview_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyPreview(QNetworkReply*)));

	connect(networkLegend_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyLegend(QNetworkReply*)));

	connect(networkLogo_, SIGNAL(replyReadyToProcess(QNetworkReply*)),
         	this, SLOT(slotReplyLogo(QNetworkReply*)));

	connect(networkGetCap_, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
         	this,SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));

	connect(networkPreview_, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
         	this,SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));

	connect(networkLegend_, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
         	this,SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));

	connect(networkLogo_, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
         	this,SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));

	previewFile_=marstmp();
	legendFile_=marstmp();
	logoFile_=marstmp();

	//xml namspace
	xlinkNsDeclaration_="declare namespace xlink = \"http://www.w3.org/1999/xlink\";";
}	

MvQWmsUiClient::~MvQWmsUiClient()
{
	delete width_;
	delete height_;
	delete format_;
	delete transparent_;
	delete bgColour_;
	delete layer_;
	delete crs_;
	delete style_;
	delete requestBbox_;
	delete networkGetCap_;
	delete networkPreview_;
	delete networkLegend_;
	delete networkLogo_;

	clearDimension();
	clearBoundingBox();

	clearPreview();
	clearLegend();
}

void MvQWmsUiClient::reset(QString r)
{
	slotAbortDownloadProcess();

	if(clientMode_ == BasicMode)
	{	
		getMapRequest_->setRequest(r);

	}
	else
	{
		clearServerDependentData();

		getMapRequest_->setRequest(r);

		QString v=getMapRequest_->item("VERSION");	
		if(v.isEmpty())
		{	
			v=getMapRequest_->item("version");
		}
		url_=getMapRequest_->guessUrl();
		version_=v;
	}

	emit clientResetDone();		
}


void MvQWmsUiClient::setClientMode(ClientMode mode)
{
	if(clientMode_== mode)
		return;

	if(mode == AdvancedMode)
	{
		slotAbortDownloadProcess();

		extraGetMapPar_=getMapRequest_->item("mv_key_extrapar");

		QString v=getMapRequest_->item("VERSION");	
		if(v.isEmpty())
		{	
			v=getMapRequest_->item("version");
		}

		//qDebug() << "new url:" << getMapRequest_->guessUrl();

		if(url_ !=getMapRequest_->guessUrl() ||
                   version_ != v)
		{
			if(v.isEmpty())
				setUrl(getMapRequest_->guessUrl());
			else				
				setUrl(getMapRequest_->guessUrl(),v);
		}
	}
	
	clientMode_=mode;
	
}

void MvQWmsUiClient::clearServerDependentData(bool keepRequest)
{
	capability_.clear();
	if(!keepRequest)
	{
		getMapRequest_->clear();
	}
	format_->clear();
	layer_->clear();
	clearLayerDependentData();
	serviceMeta_.clear();
} 

void MvQWmsUiClient::clearLayerDependentData()
{
	crs_->clear();
	style_->clear();
	clearDimension();
	clearBoundingBox();
} 

void MvQWmsUiClient::clearDimension()
{
	foreach(MvQOgcDimension* item, dimension_)
	{
		delete item;
	}
	dimension_.clear();
}

void MvQWmsUiClient::clearBoundingBox()
{
	foreach(MvQOgcBoundingBox* item, bbox_)
	{
		delete item;
	}
	bbox_.clear();

	if(geographicBbox_)
	{
		delete geographicBbox_;
		geographicBbox_=0;
	}
}

void MvQWmsUiClient::setUrl(const QString &url,const QString version)
{
	if(url_ != url)
	{
		slotAbortDownloadProcess();
		url_=url;
		version_=version;
		clearServerDependentData();
	}
}

void MvQWmsUiClient::setVersion(const QString &version)
{
	if(version_ != version)
	{
		slotAbortDownloadProcess();
		version_ = version;
		//clearServerDependentData();
	}	
}

void MvQWmsUiClient::slotRunGetCapabilities()
{	
	lastGetMapRequest_->setRequest(getMapRequest_->request());
	clearServerDependentData(true); //keeps the original request

	QString r=url_;

	r+="?SERVICE=WMS&";
	if(version_ != "Default")
	{
		r+="VERSION=" + version_ + "&";
	}
	r+="REQUEST=GetCapabilities";
	if(!extraGetCapPar_.isEmpty())
	{
		r+="&" + extraGetCapPar_;
	}

	qDebug() << "slotRunGetCapabilities --> request: " << r;
    GuiLog().task() << "Load GetCapabalitites" <<  " ..in progress";

    StatusMsgHandler::instance()->show("Load GetCapabilitites ...",true);
	
	QUrl  url=QUrl::fromPercentEncoding(r.toUtf8());
	QNetworkRequest nr(url);
	//nr.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg("egows").arg("egows").toAscii()).toBase64());
	
	getCapReply_ = networkGetCap_->get(QNetworkRequest(nr));
}


void MvQWmsUiClient::downloadPreview(QSize previewSize)
{
	MvQGetMapRequest req;
	req.setRequest(getMapRequest_->requestFrame(0));

	previewSize_=previewSize;
	
	QString w=QString::number(previewSize_.width());
	QString h=QString::number(previewSize_.height());

	MvQOgcNode *node=layer_->currentNode();
	if(node)
	{
		if(!node->attribute("fixedWidth").isEmpty() &&
		    node->attribute("fixedWidth").toInt() > 0)
		{
			w=node->attribute("fixedWidth");
		}
		if(!node->attribute("fixedHeight").isEmpty() &&
		    node->attribute("fixedHeight").toInt() > 0)
		{
			h=node->attribute("fixedHeight");
		}
	}

	req.setItem("WIDTH",w);
	req.setItem("HEIGHT",h);

    GuiLog().task() << "Load preview" << GuiLog().requestKey() << req.request().toStdString();
    //log->setStatus("In progress");
    StatusMsgHandler::instance()->show(tr("Load preview ..."),true);

	QNetworkRequest netReq(QUrl::fromPercentEncoding(req.request().toUtf8()));
	netReq.setOriginatingObject(this);	
	//netReq.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg("egows").arg("egows").toAscii()).toBase64());
	
	
	previewReply_=networkPreview_->get(netReq);
}

void MvQWmsUiClient::downloadLegend()
{
	if(!style_->currentLegend().isEmpty())	
	{
        GuiLog().task() << "Load legend" << GuiLog().requestKey() << style_->currentLegend().toStdString();
        //log->setStatus("In progress");

        StatusMsgHandler::instance()->show(tr("Load legend"),true);

		//Fix for KNMI radar
		qDebug() << "downloadLegend --> request:" << style_->currentLegend();
		QNetworkRequest netReq(QUrl::fromPercentEncoding(style_->currentLegend().toUtf8()));		
		netReq.setOriginatingObject(this);
		//netReq.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg("egows").arg("egows").toAscii()).toBase64());
		legendReply_=networkLegend_->get(netReq);			
	}
	else
	{
		emit legendLoaded(QString());
	}
}

void MvQWmsUiClient::downloadLogo()
{
	MvQOgcNode *node=layer_->currentNode();
	if(node && !node->logo().isEmpty())	
	{
        GuiLog().task() << "Load logo" << GuiLog().requestKey() << node->logo().toStdString();
        //log->setStatus("In progress");
        StatusMsgHandler::instance()->show(tr("Load logo"),true);

		//Fix for KNMI radar
		qDebug() << "downloadLogo --> request:" << node->logo();
		QNetworkRequest netReq(QUrl::fromPercentEncoding(node->logo().toUtf8()));		
		netReq.setOriginatingObject(this);
		//netReq.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg("egows").arg("egows").toAscii()).toBase64());
		logoReply_=networkLogo_->get(netReq);
	}
	else
	{
		emit logoLoaded(QString());
	}
}

void MvQWmsUiClient::setGetMapRequest(QString r)
{
	if(clientMode_==BasicMode)
	{
		getMapRequest_->editRequest(r);
		emit getMapRequestChanged(getMapRequest_->request(),getMapRequest_->requestFrame());
	}
}


void MvQWmsUiClient::slotSaveInfo()
{
	// Get info
	MvRequest r("WMSCLIENT");
     	
	r("SERVER") = url_.toStdString().c_str();
	r("VERSION") = version_.toStdString().c_str();
	r("REQUEST") = getMapRequest_->request().toStdString().c_str();
	r("TIME_DIMENSIONS") = 	timeDimName().join("/").toStdString().c_str();
	//r("NON_TIME_DIMENSIONS") =  nonTimeDimName().join("/").toStdString().c_str();

	//	reqInfo_("SERVICE") = 1;
	if(clientMode_ == BasicMode)
	{
		r("MODE") = "EXPERT";
	}
	else
	{
		r("MODE") = "INTERACTIVE";
	}

   	r("EXTRA_GETCAP_PAR") = extraGetCapPar_.toStdString().c_str();
	r("EXTRA_GETMAP_PAR") = extraGetMapPar_.toStdString().c_str();

	r("HTTP_USER") = httpUser_.toStdString().c_str();
	r("HTTP_PASSWORD") = httpPassword_.toStdString().c_str();

	r("LAYER_TITLE") = layer_->currentDisplayValue().toStdString().c_str();
	r("LAYER_DESCRIPTION") = layer_->currentDescription().toStdString().c_str();
	r("SERVICE_TITLE") =  serviceMeta_["Title"].toStdString().c_str();
	r("LAYER_LEGEND") = style_->currentLegend().toStdString().c_str();

	MvQOgcNode *node=layer_->currentNode();
	if(node)
	{
		r("LAYER_LOGO") = node->logo().toStdString().c_str();

		if(!node->attribute("noSubsets").isEmpty())
		{
			r("LAYER_NOSUBSETS") =  node->attribute("noSubsets").toStdString().c_str();
		}
		if(!node->attribute("fixedWidth").isEmpty())
		{
			r("LAYER_FIXEDWITH") = node->attribute("fixedWidth").toStdString().c_str();
		}
		if(!node->attribute("fixedHeight").isEmpty())
		{
			r("LAYER_FIXEDHEIGHT")=node->attribute("fixedHeight").toStdString().c_str();
		}
	}

	r("MAX_BOUNDING_BOX") =  getMapRequest_->item("BBOX").split(",").join("/").toStdString().c_str();

	//qDebug() << version_;
	//qDebug() << url_;

	MvRequest rout;

	r.print();

	char *shareDir=getenv("METVIEW_DIR_SHARE");
	if(shareDir)
	{	
		string path(shareDir);
		path.append("/etc/");

		string defFileName=path+ "WmsClientDef";
		string rulesFileName=path + "WmsClientRules";

		MvLanguage langMetview ( defFileName.c_str(),
				  rulesFileName.c_str(),
				  EXPAND_NO_DEFAULT);

	        rout=langMetview.expandOne (r);
		
		if(!rout)
			rout=r;  
        }
	else
	{
		rout=r;
	}

	qDebug() << "slotSaveInfo -->";	
	rout.print();

	// Save info request
	rout.save(iconFile_.toStdString().c_str());
}


void MvQWmsUiClient::slotAuthentication(QNetworkReply */*reply*/,QAuthenticator *auth)
{
	auth->setUser("egows");
	auth->setPassword("egows");

	//auth->setUser(httpUser_);
	//auth->setPassword(httpPassword_);
}

void MvQWmsUiClient::slotReplyGetCap(QNetworkReply* reply)
{
	QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

    GuiLog().task() << "Load GetCapabilities";

	if(reply->error() != QNetworkReply::NoError)
	{	
        GuiLog().error() << reply->errorString().toStdString();
        StatusMsgHandler::instance()->failed();

        emit getCapabilityLoaded();
		 //QApplication::exit();
	}
	else
	{			
		QByteArray ba=reply->readAll();		

		QString eMsg;
		if(!mimeType.contains("application/vnd.ogc.wms_xml")) // ||
		 //   mimeType.contains("text/xml"))  
		  //&& mimeType == "application/vnd.ogc.se_xml")
		{
			readException(ba,eMsg);
		}

		if(!eMsg.isEmpty())
		{			
			capability_.clear();
            GuiLog().error() << eMsg.toStdString();
			emit getCapabilityLoaded();			
            StatusMsgHandler::instance()->failed();
		}
		else
		{  
			capability_ = QString(ba);
		
			//Uncomment these lines to load a getCapabilities file from the disk
			/*QFile file("/var/tmp/dummy-user/PERFORCE/metview_4/src/OgcClient/marc_dla.xml");
    			if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
         			return;

			capability_=QString(file.readAll());*/

			repliedVersion_=readVersion();			
			readService();
			readFormat();			
			readLayer();

			updateAfterGetCapLoaded();			
			
			emit getCapabilityLoaded();			
            StatusMsgHandler::instance()->done();
		}	
	}

	reply->deleteLater();
	getCapReply_=0;
}

void MvQWmsUiClient::updateAfterGetCapLoaded()
{
	QString val;

	if(lastGetMapRequest_->request().isEmpty())
	{
		return;
	}

	val=lastGetMapRequest_->item(width_->requestName());
	width_->setValue(val.toInt());

	val=lastGetMapRequest_->item(height_->requestName());
	height_->setValue(val.toInt());

	val=lastGetMapRequest_->item(transparent_->requestName());
	transparent_->setCurrentValue(val);

	val=lastGetMapRequest_->item(format_->requestName());
	format_->setCurrentValue(val);

	val=lastGetMapRequest_->item(layer_->requestName());
	layer_->setCurrentValue(val);

	updateAfterLayerLoaded();
}

void MvQWmsUiClient::updateAfterLayerLoaded()
{
	//lastGetMapRequest_->setRequest(getMapRequest_->request());

	QString val;

	MvQOgcNode *node=layer_->currentNode();
	if(node)
	{
		if(!node->attribute("fixedWidth").isEmpty())
		{
			val=node->attribute("fixedWidth");
			if(val.toInt() > 0)
				width_->setValue(val.toInt());
		}
		if(!node->attribute("fixedHeight").isEmpty())
		{
			val=node->attribute("fixedHeight");
			if(val.toInt() > 0)
				height_->setValue(val.toInt());
		}
	}

	//readLayerAbstract();
	readStyle();
	readBoundingBox(); //bounding box should be called before crs!!!!!
	readCrs();
	readGeographicBoundingBox();
	readDimension();
	readAttribution();

	val=lastGetMapRequest_->item(style_->requestName());
	style_->setCurrentValue(val);

	val=lastGetMapRequest_->item(crs_->requestName());
	crs_->setCurrentValue(val);

	updatRequestBoundingBox();
	
	foreach(MvQOgcDimension* dim,dimension_)
	{
		val=lastGetMapRequest_->item(dim->requestName());
		dim->setCurrentValues(val);
	}

	buildGetMapRequest();

	//qDebug() << lastGetMapRequest_->request() << "\n" << getMapRequest_->request();
}

void MvQWmsUiClient::slotReplyPreview(QNetworkReply* reply)
{
	QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

    GuiLog().task() << "Load preview";

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

	if(reply->error() != QNetworkReply::NoError)
	{
        GuiLog().error() << reply->errorString().toStdString();
		emit previewLoaded(QString());
        StatusMsgHandler::instance()->failed();
	}
	else
	{	
		QString outFile=previewFile_;
		QByteArray ba=reply->readAll();

		if(mimeType.isEmpty())
			mimeType=getMimeType(ba);

		//qDebug() << "preview mimeType" << mimeType;

		if(mimeType.contains("application/vnd.ogc.se_xml") ||     
		   mimeType.contains("text/xml") ||
		   !mimeType.contains(getRequestedMimeType(url.toString())))
		{
			QString eMsg;
			readException(ba,eMsg);

            GuiLog().error() << eMsg.toStdString();
			emit previewLoaded(QString());
            StatusMsgHandler::instance()->failed();
		}
		else if(mimeType.contains("text/plain")) 	
		{
			QString eMsg(ba);
		
            GuiLog().error() << eMsg.toStdString();
            emit previewLoaded(QString());
            StatusMsgHandler::instance()->failed();
		}
		else
		{
			qDebug() << "preview outfile" << outFile;

			QImage img=QImage::fromData(ba);
			if(!img.isNull())
			{
				img=img.scaledToWidth(previewSize_.width(),Qt::SmoothTransformation);
				img.save(outFile,"png");
			}
			else
			{					
				QFile out(outFile);
				out.open(QIODevice::WriteOnly);
				out.write(ba);
				out.close();
			}

			emit previewLoaded(outFile);
            StatusMsgHandler::instance()->done();
		}
	}

	reply->deleteLater();
	previewReply_=0;
}

void MvQWmsUiClient::slotReplyLegend(QNetworkReply* reply)
{
    //Here, reply is not necessary the legendReply_ because the
    //request might have been redirected!!

    qDebug() << "MvQWmsUiClient::slotReplyLegend -->";

    QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

    GuiLog().task() << "Load legend";

	if(reply->error() != QNetworkReply::NoError)
	{
        GuiLog().error() << reply->errorString().toStdString();
		emit legendLoaded(QString());
        StatusMsgHandler::instance()->failed();
	}
	else
	{	
		QString outFile=legendFile_;
		QByteArray ba=reply->readAll();

		if(mimeType.isEmpty())
			mimeType=getMimeType(ba);

		//qDebug() << "mime" << mimeType << getRequestedMimeType(url.toString());

		//If exception is returned or mime type is 
		//different to what was requested
		if(mimeType.contains("application/vnd.ogc.se_xml") ||
		   mimeType.contains("text/xml"))
		//    || mimeType != getRequestedMimeType(url.toString()))		
		{
			QString eMsg;
			readException(ba,eMsg);

            GuiLog().error() << eMsg.toStdString();
			emit legendLoaded(QString());
            StatusMsgHandler::instance()->failed();
		}
		else if(mimeType.contains("text/plain") ) 	
		{
			QString eMsg(ba);
		
            GuiLog().error() << eMsg.toStdString();
			emit legendLoaded(QString());
            StatusMsgHandler::instance()->failed();
		}
		else
		{
			//qDebug() << outFile;

			QFile out(outFile);
			out.open(QIODevice::WriteOnly);
			out.write(ba);
			out.close();

			emit legendLoaded(outFile);
            StatusMsgHandler::instance()->done();
		}
	}

	reply->deleteLater();
	legendReply_=0;
}

void MvQWmsUiClient::slotReplyLogo(QNetworkReply* reply)
{
	QNetworkRequest r=reply->request();
	QUrl url=r.url();

	//qDebug() << url.toString();

	QString mimeType=reply->header(QNetworkRequest::ContentTypeHeader).toString();

    GuiLog().task() << "Load logo";

	if(reply->error() != QNetworkReply::NoError)
	{
        GuiLog().error() << reply->errorString().toStdString();
		emit logoLoaded(QString());
        StatusMsgHandler::instance()->failed();
	}
	else
	{	
		QString outFile=logoFile_;
		QByteArray ba=reply->readAll();

		if(mimeType.isEmpty())
			mimeType=getMimeType(ba);

		//qDebug() << "mime" << mimeType << getRequestedMimeType(url.toString());

		//If exception is returned or mime type is 
		//different to what was requested
		if(mimeType.contains("application/vnd.ogc.se_xml") ||
		   mimeType.contains("text/xml"))
		//    || mimeType != getRequestedMimeType(url.toString()))		
		{
			QString eMsg;
			readException(ba,eMsg);

            GuiLog().error()  << eMsg.toStdString();
			emit logoLoaded(QString());
            StatusMsgHandler::instance()->failed();
		}
		else if(mimeType.contains("text/plain") ) 	
		{
			QString eMsg(ba);
		
            GuiLog().error()  << eMsg.toStdString();
			emit logoLoaded(QString());
            StatusMsgHandler::instance()->failed();
		}
		else
		{
			//qDebug() << outFile;

			QFile out(outFile);
			out.open(QIODevice::WriteOnly);
			out.write(ba);
			out.close();

			QImage img(outFile);
			if(img.width() > 100)
			{
				img.scaledToWidth(100,Qt::SmoothTransformation).save(outFile,"png");
			}

			emit logoLoaded(outFile);
            StatusMsgHandler::instance()->done();
		}
	}

	reply->deleteLater();
	logoReply_=0;
}


bool MvQWmsUiClient::previewDownloadActive()
{
	return previewReply_ && previewReply_->isRunning();
}

bool MvQWmsUiClient::legendDownloadActive()
{
	return legendReply_ && legendReply_->isRunning();
}

void MvQWmsUiClient::slotAbortDownloadProcess()
{
    qDebug() << "MvQWmsUiClient::slotAbortDownloadProcess -->";

    if(getCapReply_ && getCapReply_->isRunning())
	{
        GuiLog().task() << "Load GetCapabalitites";
        GuiLog().error() << "Interrupted";
        StatusMsgHandler::instance()->failed();

		getCapReply_->deleteLater();
		getCapReply_=0;
		emit getCapabilityLoaded();
	}
	else if(previewReply_ && previewReply_->isRunning())
	{
        GuiLog().task() << "Load preview";
        GuiLog().error() << "Interrupted";
        StatusMsgHandler::instance()->failed();

		previewReply_->deleteLater();
		previewReply_=0;
		clearPreview();
		emit previewLoaded(previewFile_);
	}
	else if(legendReply_ && legendReply_->isRunning())
	{
        GuiLog().task() << "Load legend";
        GuiLog().error() << "Interrupted";
        StatusMsgHandler::instance()->failed();

		legendReply_->deleteLater();
		legendReply_=0;
		clearLegend();
		emit legendLoaded(legendFile_);		
	}
	else if(logoReply_ && logoReply_->isRunning())
	{
        GuiLog().task() << "Load logo";
        GuiLog().error() << "Interrupted";
        StatusMsgHandler::instance()->failed();

		logoReply_->deleteLater();
		logoReply_=0;
		clearLogo();
		emit logoLoaded(logoFile_);
	}

}

QString MvQWmsUiClient::readVersion()
{
	QString result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	defaultNsDeclaration_="declare default element namespace \"http://www.opengis.net/wms\";";

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//WMS_Capabilities/data(@version)");
	query.evaluateTo(&result);

	if(result.simplified().isEmpty())
	{
		query.setQuery("doc($myDoc)//WMT_MS_Capabilities/data(@version)");
		query.evaluateTo(&result);
		defaultNsDeclaration_.clear();
	}

	buffer.close();

	qDebug() << "readVersion --> version: " << result;
	
	//Remove linebreak!!

	return result.simplified();
}

void MvQWmsUiClient::readService()
{
	serviceMeta_.clear();

	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	//query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Service/data(Title)");
	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Service");
	query.evaluateTo(&result);

	//serviceTitle_=result.simplified();	

	QXmlItem item(result.next());
     	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{								
			query.setFocus(item);

			QString str;

			query.setQuery(defaultNsDeclaration_ + "./data(Title)");
			query.evaluateTo(&str);
			serviceMeta_["Title"] = str.simplified();

			query.setQuery(defaultNsDeclaration_ + "./data(Abstract)");
			query.evaluateTo(&str);
			serviceMeta_["Abstract"] = str.simplified();
		
			QStringList tags;
			tags << "ContactPerson" << "ContactOrganization" << "ContactPosition" << 
				"AddressType" << "Address" << "City" << "StateOrProvince" <<
				"PostCode" << "Country" << "ContactVoiceTelephone" <<
				"ContactFacsimileTelephone" << "ContactElectronicMailAddress";

			foreach(QString t, tags)
			{
				str.clear();
				QString q=defaultNsDeclaration_ + ".//data(" + t +")";	
				query.setQuery(q);
				query.evaluateTo(&str);
				serviceMeta_[t] = str.simplified();
			}

			break;

                 }
		item = result.next();
        }

	buffer.close();

	qDebug() << "readService -->" << serviceMeta_;
	//Remove linebreak!!
}

		
void MvQWmsUiClient::readFormat()
{
	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);

	if(repliedVersion_ > "1.0")
	{
		query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Capability/Request/GetMap/data(Format)");
	}
	else
	{
		query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Capability/Request/Map/data(Format)");
	}

	query.evaluateTo(&result);

	QStringList lst;
     	query.getAtomicValues(result,lst);
	lst.sort();
	format_->setValues(lst);
	format_->setDisplayValues(lst);
		
	buffer.close();

	qDebug() << "readFormat --> formats:" << lst;
}

void MvQWmsUiClient::readLayer()
{
	//Dom
	QDomDocument doc("mydocument");
	
 	if (!doc.setContent(capability_,true)) 
	{
     		return;
 	}

	QDomElement docElem = doc.documentElement();
	readLayer(docElem,layer_->root());

	qDebug() << "Layers ---> ";
}

void MvQWmsUiClient::readLayer(QDomElement &docElem,MvQOgcNode *parent)
{	
	QDomNode dNode = docElem.firstChild();
 	while(!dNode.isNull()) 
	{
		QDomElement dElem = dNode.toElement();
		if(!dElem.isNull())
		{
			if(dElem.tagName() =="Layer")
			{
				MvQOgcNode *layer=new MvQOgcNode;
				parent->addChild(layer);

				QDomNode title=dNode.namedItem("Title");
				if(!title.isNull())
				{	
					//qDebug() << title.toElement().text().simplified();				
					layer->setDisplayValue(title.toElement().text().simplified());
				}
				
				QDomNode name=dNode.namedItem("Name");
				if(!name.isNull())
				{
					layer->setValue(name.toElement().text().simplified());
				} 

				QDomNode desc=dNode.namedItem("Abstract");
				if(!desc.isNull())
				{
					layer->setDescription(desc.toElement().text().simplified());
				}
				else if(layer->parent())
				{
					layer->setDescription(layer->parent()->description());
				} 

				QDomNamedNodeMap att=dNode.attributes();
				for(int i=0; i < att.size(); i++)
				{
					QDomAttr da=att.item(i).toAttr();
					if(!da.isNull())
					{
						layer->addAttribute(da.name(),da.value());
					}
				}	

				readLayer(dElem,layer);
			}
			else
			{									
				readLayer(dElem,parent);
			}
		}

		dNode = dNode.nextSibling();
	}
}


void MvQWmsUiClient::readStyle()
{
	if(layer_->currentValue().isEmpty())
		return;

	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.bindVariable("myLayer", QVariant(layer_->currentValue()));
	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/Style");
	query.evaluateTo(&result);

	QXmlItem item(result.next());
     	QStringList nameLst,titleLst,abstractLst,legendLst;
	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{								
			QString name,title,abstract,legend;

			//QXmlQuery query;
			query.setFocus(item);

			//Name
			query.setQuery(defaultNsDeclaration_ + "./data(Name)");
			query.evaluateTo(&name);
			nameLst << name.simplified();

			//Title
			query.setQuery(defaultNsDeclaration_ + "./data(Title)");
			query.evaluateTo(&title);
			titleLst << title.simplified();

			//Abstract
			query.setQuery(defaultNsDeclaration_ + "./data(Abstract)");
			query.evaluateTo(&abstract);
			abstractLst << abstract.simplified();

			//Legend url
			query.setQuery(defaultNsDeclaration_ + xlinkNsDeclaration_ + "string(./LegendURL/OnlineResource/@xlink:href)");
			query.evaluateTo(&legend);
			legendLst << legend.simplified();

			style_->setValues(nameLst);
			style_->setDisplayValues(titleLst);
			style_->setDescriptions(abstractLst);
			style_->setLegends(legendLst);
                 }
		item = result.next();
        }

	buffer.close();

	qDebug() << "Style ---> ";
	qDebug() << "\t" << titleLst;
}

void MvQWmsUiClient::readCrs()
{
	if(layer_->currentValue().isEmpty())
		return;

	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.bindVariable("myLayer", QVariant(layer_->currentValue()));
	//query.bindVariable("myCrsName", QVariant(crsRequestName()));	
	if(crsRequestName() == "SRS")
	{
		query.setQuery("doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/data(SRS)");
	}
	else
	{
		query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/data(CRS)");
	}

	query.evaluateTo(&result);

	QStringList lst;
	query.getAtomicValues(result,lst);

	if(repliedVersion_ <= "1.1.0")
	{
		QStringList lstOri=lst;
		lst.clear();
		foreach(QString s,lstOri)
		{
			lst << s.split(" ");
		}
	}

	if(repliedVersion_ >= "1.3.0")
	{
		QStringList lstOri=lst;
		lst.clear();
		foreach(QString s,lstOri)
		{
			if(s == "EPSG:4326" || s == "CRS:84" )
			{
			  	lst << s;
			}	
			else
			{  
				foreach(MvQOgcBoundingBox *bb, bbox_)
				{
					if(s == bb->crs())
					{
			  			lst << s;
						break;
					}
				}
			}	
		}
	}  
	  
	lst.removeDuplicates();
	lst.sort();	

	crs_->setValues(lst);
	crs_->setRequestName(crsRequestName());
	crs_->setDisplayName(crsDisplayName());

	buffer.close();

	qDebug() << "CRS ---> ";
	qDebug() << "\t" << lst;
}	

void MvQWmsUiClient::readBoundingBox()
{
	if(layer_->currentValue().isEmpty())
		return;

	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.bindVariable("myLayer", QVariant(layer_->currentValue()));
	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/BoundingBox");
	query.evaluateTo(&result);

	QXmlItem item(result.next());
     	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{								
			QMap<QString,QString> att;
			query.getAttributes(item,att);

			MvQOgcBoundingBox *bb=new MvQOgcBoundingBox(att);

			//Remove all previously defined (in the ancestors) bboxes
			foreach(MvQOgcBoundingBox *bitem, bbox_)
			{
				if(bitem->crs() == bb->crs())
				{
					bbox_.removeOne(bitem);
					delete bitem;
					break;
					
				}
			}

			bbox_.push_back(bb);

			//qDebug() << "bb" <<  bb->crs() << bb->minX() << bb->maxX();

                 }
		item = result.next();
        }

	buffer.close();
}	



void MvQWmsUiClient::readGeographicBoundingBox()
{
	if(layer_->currentValue().isEmpty())
		return;

	QStringList str;
	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.bindVariable("myLayer", QVariant(layer_->currentValue()));

	if(repliedVersion_ >= "1.3.0")
	{
		query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/EX_GeographicBoundingBox");
		query.evaluateTo(&result);

		QMap<QString,QString> att;

		QXmlItem item(result.next());
     		while (!item.isNull()) 
		{
         		if (item.isNode()) 
			{								
				QString val;

				//QXmlQuery query;
				query.setFocus(item);
		
				query.setQuery(defaultNsDeclaration_ + "./data(westBoundLongitude)");
				query.evaluateTo(&val);
				att["westBoundLongitude"]=val.simplified();
			
				query.setQuery(defaultNsDeclaration_ + "./data(eastBoundLongitude)");
				query.evaluateTo(&val);
				att["eastBoundLongitude"]=val.simplified();

				query.setQuery(defaultNsDeclaration_ + "./data(southBoundLatitude)");
				query.evaluateTo(&val);
				att["southBoundLatitude"]=val.simplified();

				query.setQuery(defaultNsDeclaration_ + "./data(northBoundLatitude)");
				query.evaluateTo(&val);
				att["northBoundLatitude"]=val.simplified();

				qDebug() << att;

				if(geographicBbox_)
				{	
					delete geographicBbox_;
				}
				geographicBbox_=new MvQOgcGeoBoundingBox(att); //new MvQXmlElementNode(query,item);
				break;
                	 }

			item = result.next();
		}
        }
	else
	{
		query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/LatLonBoundingBox");

		query.evaluateTo(&result);

		QXmlItem item(result.next());
     		while (!item.isNull()) 
		{
         		if (item.isNode()) 
			{		
				QMap<QString,QString> att;
				query.getAttributes(item,att);

				qDebug() << att;

				if(geographicBbox_)
				{	
					delete geographicBbox_;
				}
				geographicBbox_=new MvQOgcGeoBoundingBox(att); //new MvQXmlElementNode(query,item);
				break;
                	 }
			item = result.next();
		}
         }

}

void MvQWmsUiClient::readDimension()
{
	if(layer_->currentValue().isEmpty())
		return;

	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.bindVariable("myLayer", QVariant(layer_->currentValue()));
	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/Dimension");
	query.evaluateTo(&result);

	QXmlItem item(result.next());
     	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{		
			QMap<QString,QString> att;
			QString value;

			query.getAttributes(item,att);
			query.getAtomicValue(item,value);

			MvQOgcDimension *dim=new MvQOgcDimension(att,value);

			for(int i=0; i < dimension_.count();i++)
			{
				if(dim->name().compare(dimension_[i]->name(),Qt::CaseInsensitive) == 0)
				{
					MvQOgcDimension *item=dimension_[i];
					dimension_.removeAt(i);
					delete item;
					break;
				}
			} 

			if(dim->name().compare("time",Qt::CaseInsensitive) == 0)
			{
				dim->setRequestName("TIME");
				dim->setDisplayName("Time:");
			}
			else if(dim->name().compare("elevation",Qt::CaseInsensitive) == 0)
			{
				dim->setRequestName("ELEVATION");
				dim->setDisplayName("Elevation:");
			}
			else
			{
				QString dname=dim->name();
				dname=dname.toUpper();
				dname="DIM_" + dname;
				dim->setRequestName(dname);
				dname+=" :";
				dim->setDisplayName(dname);
			}
			
			dimension_.push_back(dim);
                 }
		item = result.next();
         }

	if(repliedVersion_ >= "1.3.0")
	 	return;

	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/Extent");
	query.evaluateTo(&result);

	item=result.next();
     	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{		
			QMap<QString,QString> att;
			QString value;

			query.getAttributes(item,att);
			query.getAtomicValue(item,value);

			//MvQXmlElementNode *elem=new MvQXmlElementNode(query,item);
			foreach(MvQOgcDimension* dim, dimension_)
			{
				if(dim->name() == att["name"])
				{
					dim->setAttributes(att);
					dim->setValues(value);
					break;
				}
			}
                 }
		item = result.next();
         }
}

void MvQWmsUiClient::readAttribution()
{
	if(layer_->currentValue().isEmpty())
		return;

	MvQOgcNode *layerNode=layer_->currentNode();
	if(!layerNode)
		return;	

	QXmlResultItems result;

	QByteArray ba=capability_.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);

	MvQXmlQuery query;
     	query.bindVariable("myDoc", &buffer);
	query.bindVariable("myLayer", QVariant(layer_->currentValue()));
	query.setQuery(defaultNsDeclaration_ + "doc($myDoc)//Layer[normalize-space(Name) = $myLayer]/ancestor-or-self::*/Attribution");
	query.evaluateTo(&result);

	QXmlItem item(result.next());
	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{								
			QString logo;

			//QXmlQuery query;
			query.setFocus(item);

			//Logo url
			query.setQuery(defaultNsDeclaration_ + xlinkNsDeclaration_ + "string(./LogoURL/OnlineResource/@xlink:href)");
			query.evaluateTo(&logo);			
			layerNode->setLogo(logo.simplified());
                 }
		item = result.next();
        }

	buffer.close();

	qDebug() << "Attribution ---> ";
	qDebug() << "\t" << layerNode->logo();
}

void MvQWmsUiClient::readException(QByteArray ba,QString &msg)
{
	//if(xmlMsg.isEmpty())
	//	return;

	QXmlResultItems result;

	qDebug() << "Exception" << ba;

	//QByteArray ba=xmlMsg.toUtf8();
	QBuffer buffer(&ba) ; // This is a QIODevice.
    	buffer.open(QIODevice::ReadOnly);
	
	QString ns;
	if(repliedVersion_ >= "1.3.0")
		ns="declare default element namespace \"http://www.opengis.net/ogc\";";
	
	MvQXmlQuery query;
	query.setMessageHandler(queryMsgHandler_);
     	query.bindVariable("myDoc", &buffer);
	query.setQuery(ns + "doc($myDoc)//ServiceExceptionReport/ServiceException");			  
	query.evaluateTo(&result);

	QXmlItem item(result.next());
	if(item.isNull())
	{
		query.setQuery("doc($myDoc)//ServiceExceptionReport/ServiceException");			  
		query.evaluateTo(&result);
		item=result.next();
	}
	
     	while (!item.isNull()) 
	{
         	if (item.isNode()) 
		{								
			msg += "Exception: ";

			QMap<QString,QString> att;
			QString value;
	
			query.getAttributes(item,att);
			query.getAtomicValue(item,value);
			msg +=att["code"].simplified() + "\n";
			
			if(!value.isEmpty())
			{
				msg += value;
				msg +='\n';
			}

                 }
		item = result.next();
        }

	//If XML parsing failed
	if(queryMsgHandler_->fatalFound())
	{
		msg += "Exception: parsing of exception document failed!!\n";
		foreach(QString s, queryMsgHandler_->fatalMessages())
		{
		  	msg+=s + '\n';
			
		}	
	}

	queryMsgHandler_->clear();
	buffer.close();	

}

void MvQWmsUiClient::buildGetMapRequest()
{	
	if(layer_->currentValue().isEmpty()) 
		return;

	getMapRequest_->clear();

	QString s;
	QString str=url_;
	str+="?SERVICE=WMS";
	
	//Version
	/*if(version_ != "Default")
	{
		str+="&VERSION=";
		str+=version_;
	}*/

	str+="&VERSION=";
	str+=repliedVersion_;

	//Request
	str+="&REQUEST=GetMap";
	
	//Layers	
	str+="&" + layer_->requestName() + "=" +  layer_->currentValue();

	//Style	
	str+="&" + style_->requestName() + "="  + style_->currentValue();
	
	//srs or crs
	str+="&" + crs_->requestName() + "=" +  crs_->currentValue();
	
	//bbox	
	str+="&BBOX=" + 
		requestBbox_->minX() + "," +
		requestBbox_->minY() + "," +
		requestBbox_->maxX() + "," +
		requestBbox_->maxY();

	//width
	str+="&WIDTH=" + QString::number(width_->value());
	str+="&HEIGHT=" + QString::number(height_->value());
	
	//Format	
	str+="&" + format_->requestName() + "=" +  format_->currentValue();

	//Transparent	
	str+="&" + transparent_->requestName() + "=" +  transparent_->currentValue();

	//Dimensions
	foreach(MvQOgcDimension *dim,dimension_)
	{	   
		str+="&";
	   	str+=dim->requestName();
	   	str+="=";
	   	str+=dim->currentValues();
	}   
	
	qDebug() << str;

	if(!extraGetMapPar_.isEmpty())
	{
		str+="&" + extraGetMapPar_;
	}

	getMapRequest_->setRequest(str,timeDimName());

	currentGetMapRequest_=getMapRequest_;

	//qDebug() << getMapRequest_->requestFrame();

	//str+="&stream=false";

	//getMapRequest_=str;

	//saveGetMapRequest(currentGetMapRequest_);

	emit getMapRequestChanged(getMapRequest_->request(),getMapRequest_->requestFrame());
}


//===========================================
//
// Get/Set methods
//
//===========================================

//Format
QStringList MvQWmsUiClient::formatDisplayValues() const
{
	return format_->displayValues();
}

QString MvQWmsUiClient::formatCurrentDisplayValue() const
{
	return format_->currentDisplayValue();
}

void  MvQWmsUiClient::slotSetFormatFromDpy(QString value)
{
	if(format_->currentDisplayValue() != value)
	{
		format_->setCurrentDisplayValue(value);
		buildGetMapRequest();
	}
}

//Transparent
QStringList MvQWmsUiClient::transparentDisplayValues() const
{
	return transparent_->displayValues();
}

QString MvQWmsUiClient::transparentCurrentDisplayValue() const
{
	return transparent_->currentDisplayValue();
}

void  MvQWmsUiClient::setTransparentCurrentDisplayValue(QString value)
{
	if(transparent_->currentDisplayValue() != value)
	{
		transparent_->setCurrentDisplayValue(value);
		buildGetMapRequest();
	}
}

//Width
QString MvQWmsUiClient::width() const
{
	return QString::number(width_->value());
}

void  MvQWmsUiClient::setWidth(QString value)
{
	if(width_->value() != value.toInt())
	{
		width_->setValue(value.toInt());
		buildGetMapRequest();
	}
}

//Height
QString MvQWmsUiClient::height() const
{
	return QString::number(height_->value());
}

void  MvQWmsUiClient::setHeight(QString value)
{
	if(height_->value() != value.toInt())
	{
		height_->setValue(value.toInt());
		buildGetMapRequest();
	}
}

//Extra par
void  MvQWmsUiClient::setExtraGetCapPar(QString value)
{
	if(extraGetCapPar_ != value)
	{
		extraGetCapPar_=value;  
	}
}

void  MvQWmsUiClient::setExtraGetMapPar(QString value)
{
	if(extraGetMapPar_ != value)
	{
		extraGetMapPar_=value;  
		buildGetMapRequest();
	}
}

//Style
QStringList MvQWmsUiClient::styleDisplayValues() const
{
	return style_->displayValues();
}

QStringList MvQWmsUiClient::styleDescriptions() const
{
	return style_->descriptions();	
}

int MvQWmsUiClient::styleCurrentIndex() const
{
	return style_->currentIndex();
}

void MvQWmsUiClient::setStyleCurrentIndex(int index)
{
	if(style_->currentIndex() != index)
	{
		style_->setCurrentIndex(index);
		buildGetMapRequest();
	}
}


//CRS
QStringList MvQWmsUiClient::crsDisplayValues() const
{
	return crs_->displayValues();
}

QString MvQWmsUiClient::crsCurrentDisplayValue() const
{
	return crs_->currentDisplayValue();
}

void  MvQWmsUiClient::setCrsCurrentDisplayValue(QString value)
{
	if(crs_->currentDisplayValue() != value)
	{
		slotAbortDownloadProcess();
		crs_->setCurrentDisplayValue(value);
		updatRequestBoundingBox();
		buildGetMapRequest();
	}
}

//Layer
int MvQWmsUiClient::layerCurrentIndex()
{
	return 0;
	//return layer_->values().indexOf(layer_->currentValue());
}

QStringList MvQWmsUiClient::layerDisplayValues() const
{
	return QStringList();
	//return layer_->displayValues();
}

QStringList MvQWmsUiClient::layerDescriptions() const
{
	return QStringList();
	//qDebug() << layer_->descriptions();
	//return layer_->descriptions();	
}

void MvQWmsUiClient::setLayerFromDpy(MvQOgcNode* node)
{
	slotAbortDownloadProcess();

	clearLayerDependentData();

	layer_->setCurrentNode(node);

	lastGetMapRequest_->setRequest(getMapRequest_->request());

	updateAfterLayerLoaded();	
}


//BBOX
void MvQWmsUiClient::setBoundingBoxFromDpy(QString minX,QString maxX, QString minY, QString maxY)
{
	slotAbortDownloadProcess();
	requestBbox_->setArea(minX,maxX,minY,maxY);
	buildGetMapRequest();	
}	

MvQOgcBoundingBox MvQWmsUiClient::lastBoundingBox() const
{
	QString lastValue=lastGetMapRequest_->item("BBOX");
	QStringList lst=lastValue.split(",");
	MvQOgcBoundingBox bb;
	if(lst.count() == 4)
	{
		bb.setArea(lst[0],lst[2],lst[1],lst[3]);
	}
	return bb;
}

MvQOgcBoundingBox* MvQWmsUiClient::currentBoundingBox() const
{
	qDebug() << crs_->currentValue();

	for(int i=bbox_.count()-1; i >=0; i--)
	{
		if(bbox_[i]->crs() == crs_->currentValue())
		{
			return bbox_[i]; 
		}
	}
	
	return 0;
}

//Dimensions
QStringList MvQWmsUiClient::dimensionNameToDpy() const
{
	QStringList lst;
	/*foreach(MvQOgcDimensionList *dim,dimension_)
	{
	    lst << dim->displayName();
	}*/

	return lst;
}

QStringList MvQWmsUiClient::dimensionToDpy(QString /*dimDpyName*/) const
{
	/*foreach(MvQOgcDimensionList *dim,dimension_)
	{
	    if(dim->displayName() == dimDpyName)
	    {
		return dim->displayValues();
	    }
	}*/

	return QStringList();
}

void MvQWmsUiClient::setDimensionFromDpy(QString dimDpyName, QString val)
{
	slotAbortDownloadProcess();

	foreach(MvQOgcDimension *dim,dimension_)
	{
	    if(dim->displayName() == dimDpyName)
	    {
		//dim->setCurrentDisplayValue(val);
		dim->setCurrentValues(val);
		buildGetMapRequest();
		return;
	    }
	}
}	

void MvQWmsUiClient::setDimensionFromDpy(QString /*dimDpyName*/, QStringList /*val*/)
{
	/*foreach(MvQOgcDimensionList *dim,dimension_)
	{
	    if(dim->displayName() == dimDpyName)
	    {
		//dim->setCurrentDisplayValues(val);
		setCurrentValues(val);
		buildGetMapRequest();
		return;
	    }
	}*/
}	

QString MvQWmsUiClient::crsQueryName()
{
	if(repliedVersion_ < QString("1.3.0"))
	{
		return QString("SRS");
	}
	else
	{
		return QString("CRS");
	}
}

QString MvQWmsUiClient::crsRequestName()
{
	if(repliedVersion_ < QString("1.3.0"))
	{
		return QString("SRS");
	}
	else
	{
		return QString("CRS");
	}
}

QString MvQWmsUiClient::crsDisplayName()
{
	if(repliedVersion_ < QString("1.3.0"))
	{
		return QString("SRS:");
	}
	else
	{
		return QString("CRS:");
	}
}

QStringList  MvQWmsUiClient::timeDimName()
{
	QStringList timeDimName;

	foreach(MvQOgcDimension *dim,dimension_)
	{
		if(dim->isTime())
		{
			timeDimName << dim->requestName();
		}
	}
	return timeDimName;
}

void MvQWmsUiClient::clearPreview()
{
	//if(previewFile_ != emptyFileNameString_)
	//{
		QFile f(previewFile_);

		if(!f.remove())
		{
			//qDebug() << "MvQZoomStackLevel::clearPreview() ---> Preview file" << imgFileName_ << "could not be deleted!";
		}
		//previewFile_ = emptyFileNameString_;
	//}
}

void MvQWmsUiClient::clearLegend()
{
	//if(previewFile_ != emptyFileNameString_)
	//{
		QFile f(legendFile_);

		if(!f.remove())
		{
			//qDebug() << "MvQZoomStackLevel::clearPreview() ---> Preview file" << imgFileName_ << "could not be deleted!";
		}
		//previewFile_ = emptyFileNameString_;
	//}
}

void MvQWmsUiClient::clearLogo()
{
	QFile f(logoFile_);

	if(!f.remove())
	{
	}
}


void MvQWmsUiClient::updatRequestBoundingBox()
{
	requestBbox_->clear();
	bool foundBb=false;

	//Check if bbox is available for the current crs. 
	//It is mandatory from 1.3.0 !!!
	foreach(MvQOgcBoundingBox* bb,bbox_)
	{
		if(bb->crs() == crs_->currentValue())
		{
			foundBb=true;
			requestBbox_->setArea(bb->minX(),bb->maxX(),bb->minY(),bb->maxY());
			break;
		}
	}

	if(!foundBb && geographicBbox_ !=0)
	{  
		//For 1.3.0 epsg:4326 lat is x and lon is y!!!!!
		if(repliedVersion_ >= "1.3.0")
		{
		  	if(crs_->currentValue() == "EPSG:4326")		  
			{
		  		requestBbox_->setArea(geographicBbox_->minY(),
					geographicBbox_->maxY(),
					geographicBbox_->minX(),
					geographicBbox_->maxX());
			
				foundBb=true;
			}
			else if(crs_->currentValue() == "CRS:84" )
			{
				requestBbox_->setArea(geographicBbox_->minX(),
					geographicBbox_->maxX(),
					geographicBbox_->minY(),
					geographicBbox_->maxY()); 	
			
				foundBb=true;
			}
		}
		else
		{  
			//Else for older versions lat-lon we try to use the geographic bounding box 		
			requestBbox_->setArea(geographicBbox_->minX(),
					geographicBbox_->maxX(),
					geographicBbox_->minY(),
					geographicBbox_->maxY());
					
			foundBb=true;
		}	
	}

	//For special non-geographical projections where no crs is defined (e.g. cross-section)
	if(!foundBb && crs_->currentValue().isEmpty() && geographicBbox_ !=0)
	{
		requestBbox_->setArea(geographicBbox_->minX(),
					geographicBbox_->maxX(),
					geographicBbox_->minY(),
					geographicBbox_->maxY());
	}
} 


