// http://econym.googlepages.com/geomulti.htm
// http://mapki.com/wiki/Read_This_First#Re-Geocoding

// define constructor
var eeMap = Class.create();

eeMap.prototype =
{
	initialize: function( pElemID, pInitLatLng, pInitZoom )
	{
		this.elem = $( pElemID );
		this.map = null;
		this.view = null;
		this.geocoder = null;

		this._duplicateFilter = Array();

		var handle = this._duplicateFilter;
		Object.extend(
			this._duplicateFilter,
			{
				contains: function( pGMarker )
				{
					for ( var i=0; i<handle.length; ++i )
					  	if( pGMarker.getLatLng().equals(handle[i].getLatLng()) )
					  		return handle[i] ;

					return null;
				}
			}
		);

		if( GBrowserIsCompatible() )
		{
			if ( this.elem )
			{
				// initialize default params
				pInitLatLng = (pInitLatLng == null ) ? new GLatLng(51.1, 10.393066) : pInitLatLng;
				pInitZoom = (pInitZoom == null) ? 10 : pInitZoom;

				this.map = new GMap2( this.elem );
				this.view = new GLatLngBounds(); // Initialize viewable
 					this.geocoder = new GClientGeocoder();
				// this.mapTypeControl = new GMapTypeControl();
 				this.map.addControl( new GSmallZoomControl() );
 				this.map.addControl(new GMapTypeControl())
     				this.map.setCenter( pInitLatLng, pInitZoom ); // Initialize map
			}
 				else
 					alert( 'Dieses Element ist nicht verfuegbar.' );
			}
			else
				this.elem.innerHTML = 'Ihr Browser kann keine Google Maps anzeigen.';
	},

	addAddress: function( pAddress, pZoom, pDescription, pTitle )
	{
     		// preserve context / reference to eeMaps object within the closure,
     		// i.e. while switching to the DOM-context
     		var handler = this;
     		var callback = function( pPoint )
     			{
     				if( ! pPoint )
     					alert('adresse nicht gefunden!');
     					// TODO: ajax error message to bug tracker
     					// secure, b/c live DB not affected (however spam possible)
     				else
     					handler.addMarker( pPoint.lat(), pPoint.lng(), pZoom, pDescription, pTitle );
     					// TODO: ajax address / coordinates-pair to database for caching
     					// problem: manipulates live DB with possibly wrong / corrupted information
     			};

     		this.geocoder.getLatLng( pAddress, callback );
    },

	addMarker: function( pLat, pLng, pZoom, pDescription, pTitle )
	{
     		var point = new GLatLng( pLat, pLng );
        	var marker = new GMarker( point );

        	var duplicate = this._duplicateFilter.contains(marker);
        	if( duplicate == null )
        	{
        		if( pDescription )
          		Object.extend( marker, { _tabs: [ new GInfoWindowTab(pTitle, pDescription) ] } );
          	else
          		Object.extend( marker, { _tabs: new Array() } );
        		this._duplicateFilter.push( marker );
        	}
        	else
        	{
        		if( pDescription )
        			duplicate._tabs.push( new GInfoWindowTab(pTitle, pDescription) );
        		marker = duplicate;
          		this.map.removeOverlay( duplicate );
        	}

          	this.map.addOverlay( marker );
          	this.view.extend( marker.getLatLng() );

          	if( pZoom == null || pZoom == 'auto')
         		this.map.setCenter( this.view.getCenter() , this.map.getBoundsZoomLevel(this.view) );
         	else
         		this.map.setCenter( this.view.getCenter() , Math.min(pZoom, this.map.getBoundsZoomLevel(this.view)) );

		if( pDescription != null )
		{
			// marker.bindInfoWindowHtml( pDescription );\
			marker.bindInfoWindowTabsHtml( marker._tabs );
            		marker.openInfoWindowTabsHtml( marker._tabs );
		}
    },

    getLatLngInfo: function( pAddress, pLatElem, pLngElem )
    {
     		var callback = function( pPoint )
     			{
     				if( ! pPoint )
     				{
     					$(pLatElem).value = 0.0;
     					$(pLngElem).value = 0.0;
     				}
     				else
     				{
     					$(pLatElem).value = pPoint.lat();
     					$(pLngElem).value = pPoint.lng();
     				}
     			};

     		this.geocoder.getLatLng( pAddress, callback );
    },

	resetCenter: function( pAddress )
	{
     		// preserve context / reference to eeMaps object within the closure,
     		// i.e. while switching to the DOM-context
     		var map = this.map;

		this.geocoder.getLatLng(
			pAddress,
       		function( point )
     		{
              	map.panTo( point );
       		}
		 );
	}
};