/*
*
* This file is part of QMapControl,
* an open-source cross-platform map widget
*
* Copyright (C) 2007 - 2008 Kai Winter
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with QMapControl. If not, see <http://www.gnu.org/licenses/>.
*
* Contact e-mail: kaiwinter@gmx.de
* Program URL   : http://qmapcontrol.sourceforge.net/
*
*/

#ifndef MAPADAPTER_H
#define MAPADAPTER_H

#include <QObject>
#include <QSize>
#include <QPoint>
#include <QPointF>
#include <QLocale>
#include <QDebug>
#include <cmath>

namespace qmapcontrol
{
	//! Used to fit map servers into QMapControl
	/*!
	 * MapAdapters are needed to convert between world- and display coordinates.
	 * This calculations depend on the used map projection.
 	 * There are two ready-made MapAdapters:
	 *  - TileMapAdapter, which is ready to use for OpenStreetMap or Google (Mercator projection)
	 *  - WMSMapAdapter, which could be used for the most WMS-Server (some servers show errors, because of image ratio)
	 * 
	 * MapAdapters are also needed to form the HTTP-Queries to load the map tiles.
	 * The maps from WMS Servers are also divided into tiles, because those can be better cached.
	 * 
	 * @see TileMapAdapter, @see WMSMapAdapter
	 * 
	 *	@author Kai Winter <kaiwinter@gmx.de>
 	 */
	class MapAdapter : public QObject
	{
		friend class Layer;
	
		Q_OBJECT
		public:	
			virtual ~MapAdapter();
	
	//! returns the host of this MapAdapter
	/*!
			 * @return  the host of this MapAdapter
	 */
			QString	host		() const;
	
	//! returns the size of the tiles
	/*!
			 * @return the size of the tiles
	 */
			int		tilesize	() const;
	
	//! returns the min zoom value
	/*!
			 * @return the min zoom value
	 */
			int 		minZoom	() const;
	
	//! returns the max zoom value
	/*!
			 * @return the max zoom value
	 */
			int		maxZoom	() const;
	
	//! returns the current zoom
	/*!
			 * @return the current zoom
	 */
			int 		currentZoom		() const;
	
			virtual int		adaptedZoom()const;
	

	//! translates a world coordinate to display coordinate
	/*!
			 * The calculations also needs the current zoom. The current zoom is managed by the MapAdapter, so this is no problem.
			 * To divide model from view the current zoom should be moved to the layers.
			 * @param  coordinate the world coordinate
			 * @return the display coordinate (in widget coordinates)
	 */
			virtual QPoint		coordinateToDisplay(const QPointF& coordinate) const = 0;
	
	//! translates display coordinate to world coordinate
	/*!
			 * The calculations also needs the current zoom. The current zoom is managed by the MapAdapter, so this is no problem.
			 * To divide model from view the current zoom should be moved to the layers.
			 * @param  point the display coordinate
			 * @return the world coordinate
	 */
			virtual QPointF	displayToCoordinate(const QPoint& point) const = 0;

		protected:
			MapAdapter(const QString& host, const QString& serverPath, int tilesize, int minZoom = 0, int maxZoom = 0);
			virtual void zoom_in() = 0;
			virtual void zoom_out() = 0;
			virtual bool isValid(int x, int y, int z) const = 0;
			virtual QString query(int x, int y, int z) const = 0;
		
			QSize 	size;
			QString	myhost;
			QString	serverPath;
			int		mytilesize;
			int min_zoom;
			int max_zoom;
			int current_zoom;

			int param1;
			int param2;
			int param3;
			int param4;
			int param5;
			int param6;
	
			QString sub1;
			QString sub2;
			QString sub3;
			QString sub4;
			QString sub5;
			QString sub6;
	
			int order[3][2];
	
			int middle_x;
			int middle_y;
	
			qreal numberOfTiles;
			QLocale loc;
	};
}
#endif
