/*!*******************************************************************************
|	$Revision$
|	$Date: 2010-04-29 15:52:44 +0200 (Thu, 29 Apr 2010) $
|
********************************************************************************/  

/* CP.GMap
----------------------------------------------------------------------------*/

CP.set( 'GMap', {
	initialize: function( uid, options )
	{
		var _this = this,
			defaultData = {
				centerLat: 47.16730970131578,
				centerLng: 19.632568359375,
				zoom: 7,
				markers: []
			},
			defaults = {
				edit: false,
				width: 600,
				height: 400,
				language: 'hu',
				canvasClass: '.mod-gmap-canvas',
				addressInputClass: '.mod-gmap-address',
				serializedIdSuffix: '-config',
				data: {}
			};

		$.extend( this, defaults, options || {} );
		this.data = $.extend( {}, defaultData, this.data );

		this.uid = uid;
		this.dom = $( '#' + uid );
		
		this.target = this.dom.find( this.canvasClass );
		if( this.target.size() == 0 )
			this.target = this.dom;
			
		if( this.target.width() == 0 || this.target.height() == 0 )
		{
			this.target.css({
				width: this.width,
				height: this.height
			});
		}
		
		if( !this.dom.size() )
			return false;
		
		this.map = null;
		this.markerCount = 0;
		this.markers = {};
		
		this.geocoder = null;
		
		if( this.edit )
			this.initEditMode();
		
		this.google = window.google || null;

		if( this.google === null )
			_log( 'Google loader not found, GMap exits...' );
		else
		{
			this.google.load("maps", "2", {
				callback: function(){
					_this.initMap();
				},
				language: this.language
			});
		}
		
		return this;
	},
	initMap: function()
	{
		var _this = this;
		
		if( GBrowserIsCompatible() )
		{
			var d = this.data,
				markerCount = d.markers.length;
			
			this.map = new GMap2( this.target.get(0) );
			this.map.setUIToDefault();
			this.map.setCenter( new GLatLng( d.centerLat, d.centerLng ), d.zoom );
			
			$.each( d.markers, function( i, m ){
				var autoPopup = ( i == 0 && markerCount == 1 );
				_this.addMarker( new GLatLng( m.lat, m.lng ), m, false, autoPopup );
			});
		}
	},
	initEditMode: function()
	{
		var _this = this,
			blockForm = this.dom.parents( 'form:first' );

		if( blockForm.size() )
		{
			blockForm.bind( 'submit', function(){
				$( '#' + _this.uid + _this.serializedIdSuffix ).val( _this.serialize() );
			});
		}
		
		this.addressInput = this.dom.find( this.addressInputClass ).onEnter(function(e){
			e.preventDefault();
			_this.findAddress();
		});
		
		this.dom.find( '.map-cmd-add' ).click(function(){ _this.addCenter(); });
		this.dom.find( '.map-cmd-autofit' ).click(function(){ _this.autoFit(); });
		this.dom.find( '.map-cmd-deleteall' ).click(function(){ _this.deleteAllMarkers(); });
	},
	findAddress: function()
	{
		var _this = this,
			address = this.addressInput.val();
			
		if( address == '' )
			return false;
		
		if( this.geocoder === null )
			this.geocoder = new GClientGeocoder();

		this.geocoder.getLocations( address, function( response ){
			switch( response.Status.code )
			{
				case G_GEO_SUCCESS:
					if( response.Placemark.length )
					{
						var place = response.Placemark[0];
						var point = new GLatLng( place.Point.coordinates[1], place.Point.coordinates[0]);

						var marker = _this.addMarker( point, {html: '<b>' + place.address + '</b>' }, false, true );
						_this.addressInput.val('');
					}
					break;
				default:
					alert( __( 'Unable to find the address' ) );
			}
		});
		
		return true;
	},
	addMarker: function( latLng, extraData, autoFit, autoPopup )
	{
		var _this = this,
			marker = new GMarker( latLng, {draggable: this.edit} ),
			index = this.markerCount++,
			data = extraData || {html: ''};
	
		GEvent.addListener( marker, 'dragstart', function(){
			_this.map.closeInfoWindow();
		});
	
		GEvent.addListener( marker, 'click', function(){
			marker.openInfoWindow( _this._buildInfoWindow( index ) );
		});
		
		GEvent.addListener( marker, 'dragend', function(){
			marker.openInfoWindow( _this._buildInfoWindow( index ) );
		});
	
		this.map.addOverlay(marker);
		
		// store the marker
		this.markers[index] = {
			marker: marker,
			html: data.html
		};
		
		// auto-fit
		if( autoFit )
			this.autoFit();
			
		if( autoPopup )
			GEvent.trigger( marker, 'click' );
		
		return marker;
	},
	addCenter: function()
	{
		this.addMarker( this.map.getCenter() );
	},
	deleteAllMarkers: function()
	{
		var _this = this;

		new CP.UiDialog.Confirm(
			__( 'Confirm action' ),
			__( 'Delete all markers?' ),
			{
				onOk: function(){
					$.each( _this.markers, function( index, item ){
						_this._deleteMarker( index );
					});
				}
			}
		).open();
	},
	deleteMarker: function( index )
	{
		var _this = this;

		new CP.UiDialog.Confirm(
			__( 'Confirm action' ),
			__( 'Delete marker?' ),
			{
				onOk: function(){
					_this._deleteMarker( index );
				}
			}
		).open();
	},
	_deleteMarker: function( index )
	{
		var m = this.markers[index] || null;
		
		if( m )
		{
			GEvent.clearInstanceListeners( m.marker );
			this.map.removeOverlay( m.marker );
			delete this.markers[index];
			
			return true;
		}
		
		return false;
	},
	autoFit: function()
	{
		var bounds = new GLatLngBounds();
		
		$.each( this.markers, function( index, item ){
			bounds.extend( item.marker.getLatLng() );
		});
		
		this.map.setCenter( bounds.getCenter(), this.map.getBoundsZoomLevel( bounds ) );
	},
	serialize: function()
	{
		var center = this.map.getCenter(),
			data = {
				centerLat: center.y,
				centerLng: center.x,
				zoom: this.map.getZoom(),
				markers: []
			};
			
		$.each( this.markers, function( index, item ){
			var latLng = item.marker.getLatLng();
			data.markers.push({
				lat: latLng.y,
				lng: latLng.x,
				html: item.html
			});
		});
			
		return JSON.stringify( data );
	},
	_editText: function( index )
	{
		var _this = this,
			marker = this.markers[index],
			prompt = new CP.UiDialog.Prompt(
				__( 'Marker' ),
				__( 'Marker description' ),
				{
					onOk: function(){
						var html = this.getField( 'html' ).val();
						marker.html = html;
						marker.marker.openInfoWindow( _this._buildInfoWindow( index ) );
					},
					fields: {
						'html': {
							label: __( 'Description' ),
							type: 'textarea',
							value: marker.html
						}
					}
				}
			).open();
	},
	_buildInfoWindow: function( index )
	{
		var _this = this,
			marker = this.markers[index],
			content = $( '<div class="mod-gmap-infowin"></div>' );
		
		if( this.edit )
		{
			var controls = $( '<div class="mod-gmap-infowin-controls"></div>' );

			$( '<a href="javascript:void(0);">' + __( 'Edit text' ) + '</a>' ).click(function(){
				_this._editText( index );
			}).appendTo( controls );
			
			$( '<span> | </span>' ).appendTo( controls );

			$( '<a href="javascript:void(0);">' + __( 'Delete marker' ) + '</a>' ).click(function(){
				_this.deleteMarker( index );
			}).appendTo( controls );

			content.append( '<div class="mod-gmap-infowin-html">' + ( marker.html ? marker.html : '' )  + '</div>' )
				.append( controls );	
		}
		else
		{
			content.append( ( marker.html ? marker.html : '' ) );
		}
		
		return content.get(0);
	}
});
CP.GMap.instanceClass = 'mod-gmap';