/*
 * MapObject - The JavaScript Mapping Library.
 * http://MapObject.net
 * 
 * Copyright (c) 2006-2007, Mashup Technologies, LLC
 * All rights reserved.
 * http://www.MashupTechnologies.com
 * 
 * The JavaScript code distributed with Google Maps Samples (the "Software") is licensed under the
 * Lesser GNU (LGPL) open source license version 3.
 * 
 * http://www.gnu.org/licenses/lgpl.html
 * 
 * This software 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.
 * 
 */

// Create MapObject namespace
Ext.namespace('MapObject.widget');


/**
* Panel widget designed to register address search handlers and run geocoding method registered for a given 
( mapProxy object.
* @namespace MapObject.widget
* @class GeoCoderPanel
* @param {} mapProxy Instance of MapObject.widget.AbstractMap.
* @param {String} inputEl Input element id. Input element servers as an address entry.
* @param {String} actionEl Id of action element (button, link).
*/
MapObject.widget.GeoCodingPanel = function(inputEl, actionEl, geocoder, mapProxy, opt) {
	this.addEvents({
		/**
		* @event beforegeocoding
		* Fires before gecoding is done.
		*/
		beforegeocoding : true,

		/**
		* @event aftergeocoding
		* Fires after gecoding
		* @param {String} Lat Latitute.
		* @param {String} Lng Longitude.
		* @param {Integer} Zoom Zoom level.
		*/
		aftergeocoding : true
	});

    MapObject.widget.GeoCodingPanel.superclass.constructor.call(this);

	this.init(inputEl, actionEl, geocoder, mapProxy, opt); 
}


Ext.extend(MapObject.widget.GeoCodingPanel, Ext.util.Observable, {

	// MapObject.widget.AbstractMap
	mapProxy: null,

	inputEl: null,
	actionEl: null,

	/* 
	* Configuration options 
	*/
	opt: {
		showCenterIcon: true,
		EOF: null
	},


	/**
	* Geocoder
	* @private
	* @type {???} 
	*/
	geocoder: null,

	/**
	* Icon used to create a center marker
	* @puvlick
	* @type GIcon 
	*/
	centerIcon: G_DEFAULT_ICON,

	/**
	* Center marker
	* @private
	* @type {GMarker} 
	*/
	centerMarker: null,

	init: function(inputEl, actionEl, geocoder, mapProxy, opt) {
		
		this.mapProxy = mapProxy;
		this.geocoder = geocoder;
		this.opt = opt || this.opt;

		// set up our HTML elements
		this.inputEl = document.getElementById(inputEl);
		this.actionEl = document.getElementById(actionEl);

		// Attach event to the address input field
		Ext.EventManager.addListener(this.inputEl, "keydown", function(e) {
			//enter key 
			if (e.getCharCode() == e.ENTER) { 
				// Perform geocoding
				this.geocode();
			}
		}, this);

		// Attach event to the geocode/address search button
		Ext.EventManager.addListener(this.actionEl, "click", this.geocode, this);

		
		// Register callback to recenter map
		this.geocoder.on("aftergeocoding", this.aftergeocoding, this);
		
	},

	/*
	*  aftergeocoding callback method.
	*/
	aftergeocoding: function(lat, lng, zoom) {
		if (this.mapProxy !== null && (typeof this.mapProxy.setCenter == 'function')) {

			// Check max available zoom level
			zoom = (zoom > this.mapProxy.mapObject.getCurrentMapType().getMaximumResolution()) ? this.mapProxy.mapObject.getCurrentMapType().getMaximumResolution() : zoom;

			// Set center
			this.mapProxy.setCenter(lat, lng, zoom, this.mapProxy.mapObject.getCurrentMapType());

			// Show center pushpin
			if (this.opt && this.opt.showCenterIcon) {
				// Remove previous marker
				if(this.centerMarker !== null)
				{
					this.mapProxy.removeOverlay(this.centerMarker);	
				}
				// Set center marker
				this.centerMarker = this.mapProxy.addOverlay(lat, lng, {
					'title': this.inputEl.value,
					'icon': this.centerIcon
				});	
			}
		}
	},

	// Get the address string for geocoding
	getAddress: function() {
		return this.inputEl.value;
	},

	// Perform geocoding of a text entered into input 
	geocode: function() {
		if (this.fireEvent("beforegeocoding") !== false) {

			// Perform geocoding
			this.geocoder.geocode(this.getAddress());

			this.fireEvent("aftergeocoding");
		}
	}

});