/**
* Provides a googleMap
*
* @package Ceasy_Core
* @author Ralf Glaser
*
*
*/

function MadChickGoogleMap(mapDiv, settings, onloadCallback)  {

	var self=this;

	if (typeof(GBrowserIsCompatible)=='undefined' || !GBrowserIsCompatible()) {

		alert('Die GoogleMaps-API konnte nicht geladen werden oder Ihr Browser unterstützt die API nicht.');
		return;

	}

	this._mapDiv=mapDiv;
	this._submitHandler=false;

	this._settings=settings || {};
	this._onloadCallback=onloadCallback;

	this._initCenterLat=this._settings['initCenterLat'];
	this._initCenterLng=this._settings['initCenterLng'];
	this._initZoom=this._settings['initZoom'];
	this._mode=this._settings['mode'];
	this._wsdlUrl=this._settings['wsdlUrl'];
	this._searchFormObj=this._settings['searchFormObj'];
	this._geocodeFormObj=this._settings['geocodeFormObj'];

	if (this._searchFormObj && this._searchFormObj.elements['categoryId']) {

		this._categorySelectFirstOptionText=this._searchFormObj.elements['categoryId'][0].text;

	}

	this._searchResultObj=this._settings['searchResultObj'];
	this._geocodeResultObj=this._settings['geocodeResultObj'];
	
	try { // in some cases GMapTypes and/or GIcon are still undefined at this time in IE6
		this._mapTypes={
			'n':G_NORMAL_MAP,
			's':G_SATELLITE_MAP,
			'h':G_HYBRID_MAP
		};
		this._markerIcon = new GIcon();
	} catch (e) {
		this._mapTypes={};
	}
	this._mapTypeName=this._settings['mapType'];

	if (settings['markerIcon'] && this._markerIcon) {

		this._markerIcon.image = settings['markerIcon']['imageUrl'];
		this._markerIcon.shadow = settings['markerIcon']['shadowUrl'];
		this._markerIcon.iconSize = new GSize(settings['markerIcon']['imageWidth'], settings['markerIcon']['imageHeight']);
		this._markerIcon.shadowSize = new GSize(settings['markerIcon']['imageWidth'], settings['markerIcon']['imageHeight']);
		this._markerIcon.iconAnchor = new GPoint(settings['markerIcon']['anchorX'], settings['markerIcon']['anchorY']);
		this._markerIcon.infoWindowAnchor = new GPoint(settings['markerIcon']['infoAnchorX'], settings['markerIcon']['infoAnchorY']);

	}

	if (this._mode=='edit') {

		this._latFormField=(this._settings['latFormField'] ? this._settings['latFormField'] : false);
		this._lngFormField=(this._settings['lngFormField'] ? this._settings['lngFormField'] : false);
		this._submitButton=(this._settings['submitButton'] ? this._settings['submitButton'] : false);
		this._resetButton=(this._settings['resetButton'] ? this._settings['resetButton'] : false);
		this._abortButton=(this._settings['abortButton'] ? this._settings['abortButton'] : false);

	}

	this._scaleControl=(this._settings['noScaleControl'] ? false : true);
	this._overviewControl=(this._settings['noOverviewControl'] ? false : true);
	this._typeControl=(this._settings['noTypeControl'] ? false : true);

	this._categoryFilterName='';
	this._titleFilterName='';
	this._items=[];

	this._activeCategoryItem=false;

	this._googleMap=false;
	this._markers={};
	this._geocoder=false;

	this._initData=false;




	/*********************/
	/*    public         */
	/*********************/

	// -------------------------------------------------------------------
	this.geocode= function (address) {

		if (!this._geocoder) {

			this._geocoder = new GClientGeocoder();

		}
	
		this._geocoder.getLatLng(
			address,
			function(point) {

				if (!point) {

					alert('Für die Adresse \''+address +'\' konnten automatisch leider keine Geodaten ermittelt werden.\n\nBitte wählen Sie die Adresse manuell auf der Karte.');
					self.setCenter();

				} else {

					self.setMarker(point.lat(), point.lng());

				}

			}
		);

	};
	
	//-------------------------------------------------------------------
	this.geocodeAddress= function () {
		
		var address=this._geocodeFormObj.elements['address'].value;
		var town=this._geocodeFormObj.elements['town'].value;
		
		if (!this._geocoder) {

			this._geocoder = new GClientGeocoder();

		}
		
		this._geocoder.getLocations(address+(town ? ', '+town : ''), function (response) {
			
			if (response.Placemark && response.Placemark.length>0) {
				
				_html='';
				
				for (var i=0; i<response.Placemark.length; i++) {
					_html+='<div class="googleMapResultDiv" onclick="googleMapObj.setMarker(\''+response.Placemark[i].Point.coordinates[1]+'\', \''+response.Placemark[i].Point.coordinates[0]+'\', \''+response.Placemark[i].address+'\');">'+response.Placemark[i].address+'</div>';
				}
				
				self._geocodeResultObj.innerHTML=_html;
				
				if (response.Placemark.length==1) {
					
					self.setMarker(response.Placemark[0].Point.coordinates[1], response.Placemark[0].Point.coordinates[0], response.Placemark[0].address);
							
				}
				
			} else {
				
				self._geocodeResultObj.innerHTML='Es konnte keine passende Adresse gefunden werden.';
				
			}
			
		});
		
	};

	// -------------------------------------------------------------------
	this.performItemSearch= function (itemName, itemId) {

		for (var i=1; i<this._searchFormObj.elements['itemName'].length; i++) {

			if (this._searchFormObj.elements['itemName'][i].value==itemName) {

				this._searchFormObj.elements['itemName'].selectedIndex=i;
				break;

			}

		}

		if (i==this._searchFormObj.elements['itemName'].length) {
			
			this._searchFormObj.elements['itemName'].selectedIndex=0;
			this._searchFormObj.elements['itemName'][0].value=itemName;
			
		}

		this._searchFormObj.elements['itemId'].value=itemId;
		this.performSearch();

	};

	// -------------------------------------------------------------------
	this.performSearch= function () {

		var itemName=this._searchFormObj.elements['itemName'].value;

		var filtersData={};

		if (this._searchFormObj.elements['itemId'].value) {

			filtersData['id']=this._searchFormObj.elements['itemId'].value;
			this._searchFormObj.elements['itemId'].value='';

		} else {

			filtersData[this._titleFilterName]=this._searchFormObj.elements['title'].value;

			if (this._categoryFilterName) {

				filtersData[this._categoryFilterName]=this._searchFormObj.elements['categoryId'].value;

			}

		}

		if (this._searchFormObj.elements['districtId']) {

			filtersData['districtIds']=this._searchFormObj.elements['districtId'].value;

		}

		if (itemName) {

			this._searchResultObj.innerHTML='bitte warten...';

			if (this._activeCategoryItem!=itemName) {

				this.updateSearchCategorys(itemName, true);

			}

			var parameters= new MadChickSoapClientParameters();
			parameters.add('itemName', itemName);
			parameters.add('filtersData', filtersData);

			var soapClient=new MadChickSoapClient(this._wsdlUrl);
			var result=soapClient.request('getGeoData', parameters, false);

			result=XMLArrayizer.xmlToArray(result);

			var itemIdName=result['root']['itemIdName'];

			this.removeMarker();

			var bounds = new GLatLngBounds;

			this._searchResultObj.innerHTML='';

			this._items=[];
			this._searchResultObj.innerHTML='';

			if (parseInt(result['root']['dataSummary']['count'])>parseInt(result['root']['dataSummary']['limit'])) {

				alert('Es wurden insgesamt '+result['root']['dataSummary']['count']+' Treffer gefunden.\nAus Performance-Gründen werden aber nur die ersten '+result['root']['dataSummary']['limit']+' angezeigt.\nBitte schränken Sie die Suche weiter ein.');

			}

			for (var i=0; i<result['root']['items'].length; i++) {

				var itemId=result['root']['items'][i][itemIdName];
				this._searchResultObj.innerHTML+='<div class="googleMapResultDiv" onclick="googleMapObj.showInfoWindowOfItem('+itemId+');"><input type="checkbox" checked="checked" name="result" onclick="this.blur();" onchange="googleMapObj.swapSearchResult(this);" value="'+itemId+'" />'+result['root']['items'][i]['title']+'</div>';

				this._items[itemId]={
					'itemName':itemName,
					'itemId':itemId,
					'gLat':result['root']['items'][i]['gLat'],
					'gLng':result['root']['items'][i]['gLng'],
					'title':result['root']['items'][i]['title'],
					'kmlUrl':(result['root']['items'][i]['kmlUrl'] ? result['root']['items'][i]['kmlUrl'] : false),
					'polygons':(result['root']['items'][i]['polygons'] ? [] : false),
					'polylines':(result['root']['items'][i]['polylines'] ? [] : false),
					'marker':(result['root']['items'][i]['marker'] ? result['root']['items'][i]['marker'] : false),
					'infoHtml':false
				};

				if (result['root']['items'][i]['polygons']) {

					for (var j=0; j<result['root']['items'][i]['polygons'].length; j++) {

						this._items[itemId]['polygons'].push(result['root']['items'][i]['polygons'][j]);

					}

				}

				if (result['root']['items'][i]['polylines']) {

					for (var j=0; j<result['root']['items'][i]['polylines'].length; j++) {

						this._items[itemId]['polylines'].push(result['root']['items'][i]['polylines'][j]);

					}

				}

				var gMarker=this.setItemMarker(itemId);
				bounds.extend(gMarker.getPoint());

			}

			if (result['root']['items'].length>0) {

				var zoomLevel=this._googleMap.getBoundsZoomLevel(bounds);
				this._googleMap.setCenter(bounds.getCenter(), zoomLevel);
				
				if (result['root']['items'].length==1) {
					self.showInfoWindowOfItem(itemId);
				}

			} else {

				this._searchResultObj.innerHTML='Es wurden keine passenden Objekte gefunden';

			}
			
			this._searchFormObj.elements['itemName'][0].value=''; // reset

		} else {

			alert('Bitte wählen Sie einen Objektart aus');

		}

	};

	// -------------------------------------------------------------------
	this.updateSearchCategorys= function (itemName, doNotResetItemId) {

		if (itemName) {
		
			var parameters= new MadChickSoapClientParameters();
			parameters.add('itemName', itemName);
	
			var soapClient=new MadChickSoapClient(this._wsdlUrl);
			var result=soapClient.request('getGeoDataCategorys', parameters, false);
	
			result=XMLArrayizer.xmlToArray(result);
	
			this._categoryFilterName=result['root']['categoryFilterName'];
			this._titleFilterName=result['root']['titleFilterName'];
	
			var categorySelect=this._searchFormObj.elements['categoryId'];
	
			MadChickSelectControl.removeOptions(categorySelect);
			MadChickSelectControl.appendOption(categorySelect, this._categorySelectFirstOptionText, '');
	
			for (var i=0; i<result['root']['categorys'].length; i++) {
	
				MadChickSelectControl.appendOption(categorySelect, result['root']['categorys'][i]['text'], result['root']['categorys'][i]['value']);
	
			}
	
			this._activeCategoryItem=itemName;
	
			if (!doNotResetItemId) {
	
				this._searchFormObj.elements['itemId'].value='';
	
			}
			
		}

	};

	// -------------------------------------------------------------------
	this.setSearchCategoryId= function(categoryId) {

		for (var i=0; i<this._searchFormObj.elements['categoryId'].length; i++) {

			if (this._searchFormObj.elements['categoryId'][i].value==categoryId) {

				this._searchFormObj.elements['categoryId'].selectedIndex=i;
				break;

			}

		}

	};

	// -------------------------------------------------------------------
	this.setMapType= function (mapTypeName) {

		mapTypeName=mapTypeName || this._mapTypeName;
		this._googleMap.setMapType((this._mapTypes[mapTypeName] ? this._mapTypes[mapTypeName] : G_NORMAL_MAP));

	};

	// -------------------------------------------------------------------
	this.swapSearchResult= function (resultCheckboxObj) {

		var itemId=resultCheckboxObj.value;

		if (resultCheckboxObj.checked) {

			this.setItemMarker(itemId);
			this.showInfoWindowOfItem(itemId);

		} else {

			this.removeMarker(itemId);
		}

	};

	// -------------------------------------------------------------------
	this.setItemMarker= function (itemId) {

		return this.setMarker(this._items[itemId]['gLat'], this._items[itemId]['gLng'], this._items[itemId]['title'], itemId);

	};

	// -------------------------------------------------------------------
	this.showInfoWindowOfItem= function (itemId) {

		if (this._markers[itemId]) {

			if (this._items[itemId]['infoHtml']===false) {

				var parameters= new MadChickSoapClientParameters();
				parameters.add('itemName', this._items[itemId]['itemName']);
				parameters.add('itemId', itemId);

				var soapClient=new MadChickSoapClient(this._wsdlUrl);
				var result=soapClient.request('getGeoDataInfoHtml', parameters, false);

				result=XMLArrayizer.xmlToArray(result);

				this._items[itemId]['infoHtml']=result['root']['infoHtml'];

			}

			this._markers[itemId].openInfoWindowHtml(this._items[itemId]['infoHtml']);

		}

	};
	
	// -------------------------------------------------------------------
	this.reset= function () {

		if (this._initData) {

			if (confirm('Wollen Sie den ursprünglichen Zustand wiederherstellen?')) {

				if (this._initData['marker']) {

					this.setMarker(this._initData['lat'], this._initData['lng']);

				} else {

					this.removeMarker();
					this.setCenter(this._initData['lat'], this._initData['lng']);

				}

			}

		}

	};

	// -------------------------------------------------------------------
	this.removeMarker= function(markerIndex) {

		if (markerIndex) {

			if (this._markers[markerIndex]) {

				if (this._markers[markerIndex].additionalOverlays) {

					for (var i=0; i<this._markers[markerIndex].additionalOverlays.length; i++) {

						this._googleMap.removeOverlay(this._markers[markerIndex].additionalOverlays[i]);

					}

				}

				this._googleMap.removeOverlay(this._markers[markerIndex]);

				delete this._markers[markerIndex];

			}

		} else {

			for (var i in this._markers) {

				if (this._markers[i].additionalOverlays) {

					for (var j=0; j<this._markers[i].additionalOverlays.length; j++) {

						this._googleMap.removeOverlay(this._markers[i].additionalOverlays[j]);

					}

				}

				this._googleMap.removeOverlay(this._markers[i]);

			}

			this._markers={};

		}

		if (this._latFormField && this._lngFormField) {

			this._latFormField.value='';
			this._lngFormField.value='';

		}

	};


	// -------------------------------------------------------------------
	this.setCenter= function(lat, lng)  {

		var centerPoint=new GLatLng((lat && lat!='' ? lat : this._initCenterLat), (lng && lng!='' ? lng : this._initCenterLng));

		this._googleMap.setCenter(centerPoint, parseInt(this._initZoom));

		if (!this._initData) {

			this._initData={
				'marker':false,
				'lat':centerPoint.lat(),
				'lng':centerPoint.lng()
			};

		}

	};

	// -------------------------------------------------------------------
	this.setSubmitHandler=function (submitHandler) {

		this._submitHandler=submitHandler;

	};

	// -------------------------------------------------------------------
	this.setItemData= function(itemData, markerIndex)  {

		markerIndex=markerIndex || '0';

		this._items[markerIndex]=itemData;

		return markerIndex;

	};

	// -------------------------------------------------------------------
	this.setMarker= function(lat, lng, title, markerIndex)  {

		markerIndex=markerIndex || '0'; // important, sets default for markerIndex if markerIndex is not given

		var additionalOverlays=[];

		if (this._items[markerIndex]) {

			if (this._items[markerIndex]['kmlUrl']) {

				var kmlObj=new GGeoXml(this._items[markerIndex]['kmlUrl'], function () {

					if (!this.loadedCorrectly()) {

							alert('Die KML-Datei konnte nicht geladen werden.');

					}

				});
				this._googleMap.addOverlay(kmlObj);
				additionalOverlays.push(kmlObj);

			}

			if (this._items[markerIndex]['polygons'] && this._items[markerIndex]['polygons'].length>0) {

				var polygons=this._items[markerIndex]['polygons'];

				var polygonDefault={
					'lineColor':'#000000',
					'lineWidth':1,
					'lineOpacity':1,
					'color':'#FFFFFF',
					'opacity':0.4
				};

				for (var i=0; i<polygons.length; i++) {

					if (polygons[i]['latLngsString']) {

						var latLngs=polygons[i]['latLngsString'].split('\n');
						var polygonLatLngs=[];

						for (var j=0; j<=latLngs.length; j++) {

							var latLngString=latLngs[(j==latLngs.length ? 0 : j)].replace(/[ \r\n\t]/g, '');

							if (latLngString.match(/\d{1,3}(\.\d{1,20})?,\d{1,3}(\.\d{1,20})?/)) {

								var latLng=latLngString.split(',');
								var polygonLat=latLng[0].replace(/[^0-9.]/g, '');
								var polygonLng=latLng[1].replace(/[^0-9.]/g, '');

								if (j==0) {

									var firstPolygonLat=polygonLat;
									var firstPolygonLng=polygonLng;

								}

								polygonLatLngs.push(new GLatLng(polygonLat, polygonLng));

							}

						}

						if (firstPolygonLat!=polygonLat && firstPolygonLng!=polygonLng) { // ensures, that polygon is closed

							polygonLatLngs.push(new GLatLng(firstPolygonLat, firstPolygonLng));

						}

						var polygonObj=new GPolygon(
							polygonLatLngs,
							polygons[i]['lineColor'] || polygonDefault['lineColor'],
							polygons[i]['lineWidth'] || polygonDefault['lineWidth'],
							polygons[i]['lineOpacity'] || polygonDefault['lineOpacity'],
							polygons[i]['color'] || polygonDefault['color'],
							polygons[i]['opacity'] || polygonDefault['opacity']
						);
						GEvent.addListener(polygonObj, 'click', function() {
							self.showInfoWindowOfItem(markerIndex);
						});

						this._googleMap.addOverlay(polygonObj);

						additionalOverlays.push(polygonObj);

					}

				}

			}

		}

		var markerPoint=new GLatLng(lat, lng);
		this._googleMap.setCenter(markerPoint, parseInt(this._initZoom));
		var markerIcon=self._markerIcon;
		
		if (!markerIndex || !this._markers[markerIndex]) {

			if (this._mode=='edit') {

				this._markers[markerIndex] = new GMarker(markerPoint, {draggable: true});

				GEvent.addListener(this._markers[markerIndex], 'dragend', function() {
					self._markerPositioned(self._markers[markerIndex].getPoint());
				});

			} else {

				if (this._items[markerIndex] && this._items[markerIndex]['marker']) {

					var markerData=this._items[markerIndex]['marker'];
					var markerIcon=new GIcon();

					markerIcon.image = markerData['imageUrl'] || this._markerIcon.image;
					markerIcon.shadow = markerData['shadowUrl'] || this._markerIcon.shadow;
					markerIcon.iconSize = (markerData['imageWidth'] && markerData['imageHeight'] ? new GSize(markerData['imageWidth'], markerData['imageHeight']) : this._markerIcon.iconSize);
					markerIcon.shadowSize =(markerData['imageWidth'] && markerData['imageHeight'] ? new GSize(markerData['imageWidth'], markerData['imageHeight']) : this._markerIcon.shadowSize);
					markerIcon.iconAnchor =(markerData['anchorX'] && markerData['anchorY'] ?  new GPoint(markerData['anchorX'], markerData['anchorY']) : this._markerIcon.iconAnchor);
					markerIcon.infoWindowAnchor =(markerData['infoAnchorX'] && markerData['infoAnchorY'] ? new GPoint(markerData['infoAnchorX'], markerData['infoAnchorY']) : this._markerIcon.infoWindowAnchor);

				}
				
				this._markers[markerIndex] = new GMarker(markerPoint, {'title': title, 'icon': markerIcon});

				if (markerIndex>0) {

					GEvent.addListener(this._markers[markerIndex], 'click', function() {
						self.showInfoWindowOfItem(markerIndex);
					});

				}

			}

			if (additionalOverlays.length>0) {

				this._markers[markerIndex].additionalOverlays=additionalOverlays;

			}

			this._googleMap.addOverlay(this._markers[markerIndex]);

		} else {

			// remove all existing Markers
			this.removeMarker();
			this._markers[markerIndex]=new GMarker(markerPoint, {'title': title, 'icon': markerIcon});
			this._googleMap.addOverlay(this._markers[markerIndex]);

		}

		this._markerPositioned(markerPoint);

		if (!this._initData || !this._initData['marker']) {

			this._initData={
				'marker':true,
				'lat':markerPoint.lat(),
				'lng':markerPoint.lng()
			};

		}


		return this._markers[markerIndex];

	};

	// -------------------------------------------------------------------
	this.submit= function()  {

		if (this._submitHandler) {

			if (this._submitHandler(this._latFormField.value, this._lngFormField.value)) {

				window.close();

			} else {

				alert('Die Übertragung der Daten schlug leider fehl.');

			}

		}

	};

	// *****************************************************************
	// ******************** for internal use only **********************
	// *****************************************************************

	// -------------------------------------------------------------------
	this._formFieldChanged= function()  {

		if (self._latFormField.value!='' && self._lngFormField.value!='') {

			self.setMarker(self._latFormField.value, self._lngFormField.value);

		}


	};

	// -------------------------------------------------------------------
	this._markerPositioned= function(markerPoint)  {

		if (this._latFormField) {

			this._latFormField.value=Math.round(markerPoint.lat()*1000000)/1000000;

		}

		if (this._lngFormField) {

			this._lngFormField.value=Math.round(markerPoint.lng()*1000000)/1000000;

		}

	};

	//--- Constructor ---------------------------------------------------------------
	this._init=function()  {

		if (typeof(GBrowserIsCompatible)!='undefined') {

			if (GBrowserIsCompatible()) {

				this._googleMap=new GMap2(this._mapDiv);
				this._googleMap.addControl(new GLargeMapControl());
				if (this._scaleControl) this._googleMap.addControl(new GScaleControl());
				if (this._typeControl) this._googleMap.addControl(new GMapTypeControl());
				this._googleMap.enableScrollWheelZoom();
				this.setMapType();

				if (typeof(ContextMenuControl)!='undefined') this._googleMap.addControl(new ContextMenuControl());


				if (self._onloadCallback) {

					GEvent.addListener(this._googleMap, 'load', function() {
						setTimeout(function() {  // ensures rendering of map
							self._onloadCallback();
						}, 10);
					});

				}

				if (this._mode=='edit') {

					this._googleMap.disableDoubleClickZoom();

					GEvent.addListener(this._googleMap, 'dblclick', function(obj, clickPoint) {
						self.setMarker(clickPoint.lat(), clickPoint.lng());
					});

				} else {

					GEvent.addListener(this._googleMap, 'dblclick', function(obj, clickPoint) {
						self.setCenter(clickPoint.lat(), clickPoint.lng());
					});
				}

				this.setCenter(); // this is important! Without this map will not shown up!

				if (this._submitButton) {

					this._submitButton.onclick=function () {

						self.submit();

					};

				}

				if (this._abortButton) {

					this._abortButton.onclick=function () {

						window.close();

					};

				}

				if (this._resetButton) {

					this._resetButton.onclick=function () {

						self.reset();

					};

				}

				if (this._latFormField && this._lngFormField) {

					this._latFormField.onchange=this._formFieldChanged;
					this._lngFormField.onchange=this._formFieldChanged;

				}

			} else {

				alert('Ihr Browser wird von GoogleMaps nicht unterstützt.');

			}

		} else {

			alert('Das GoogleMaps-API konnte nicht geladen werden.');

		}

	};

	// call constructor
	this._init();

}
