/**
 * TV_Map
 * 
 * Class that handles Googles maps
 * 
 * @author tku
 * @copyright Copyright (C) Techvibes Media Inc. (http://www.techvibes.com)
 */
/**
 * Returns a TV_Map instance and loads the Google API code if necessary
 * 
 * @param string|object container Element that will receive the map
 * @param string api_key Google Map API key
 * @param object options Configuration options
 * @param srting|function callback function that will be called when API code is fully loaded
 * @return TV_Map
 */
function tv_getMap(container, options, callback) {
	var map = new TV_Map(container, options, callback);
	loadGoogleApiCode(map);
	return map;
}
/**
 * Constructor
 * 
 * @param string|object container
 * @param string api_key
 * @param object options
 * @param string|function callback
 * @return void
 */
function TV_Map(container, options, callback) {
	this.map = null;
	this.container = $(container);
	this.options = this.getOptions(options);
	this.callback = callback;
	this.markers = new Array();
}
/**
 * Sets up the default configuration values
 * 
 * @param object options
 * @return object
 */
TV_Map.prototype.getOptions = function(options) {
	if (typeof(options) != 'object') {
		options = new Object();
	}
	if (options.center == undefined || options.center.x == undefined || options.center.y == undefined) {
		if (options.center == undefined) {
			options.center = new Object();
		}
		if (options.center.x == undefined) {
			options.center.x = 49.249657393;
		}
		if (options.center.y == undefined) {
			options.center.y = -123.119340403;
		}
	}
	if (options.zoom == undefined) {
		options.zoom = 10;
	}
	if (options.controls == undefined) {
		options.controls = new Object();
	}
	if (options.controls == undefined || options.controls.zoom == undefined) {
		options.controls.zoom = true;
	}
	if (options.controls == undefined || options.controls.type == undefined) {
		options.controls.type = true;
	}
	if (options.auto_render == undefined) {
		options.auto_render = false;
	}
	if (options.scroll_wheel_zoom == undefined) {
		options.scroll_wheel_zoom = true;
	}
	if (options.double_click_zoom == undefined) {
		options.double_click_zoom = true;
	}
	return options;
}
/**
 * Renders the map to the container
 * 
 * @return void
 */
TV_Map.prototype.render = function(){
	this.map = new GMap2(this.container);
	/**
	 * Set center and zoom
	 */
	this.map.setCenter(
		new GLatLng(this.options.center.x, this.options.center.y),
		this.options.zoom
	);
	/**
	 * Add controls
	 */
	if (this.options.controls && this.options.controls.zoom) {
		if (this.options.controls.zoom == 'small') {
			this.map.addControl(new GSmallMapControl());
		} else {
			this.map.addControl(new GLargeMapControl());
		}
	}
	if (this.options.controls && this.options.controls.type) {
		this.map.addControl(new GMapTypeControl());
	}
	/**
	 * Enable zoom options
	 */
	if (this.options.double_click_zoom) {
		this.map.enableDoubleClickZoom();
	}
	if (this.options.scroll_wheel_zoom) {
		this.map.enableScrollWheelZoom();
		/**
		 * mouse wheel zoom has to be handled special
		 */
		GEvent.addDomListener(this.map.getContainer(), "DOMMouseScroll", this.mouseWheelZoom.bind(this));
		this.map.getContainer().onmousewheel = this.mouseWheelZoom.bind(this);
	}
	/**
	 * Add the markers
	 */
	for (var i = 0; i < this.markers.length; i++) {
		var marker = new GMarker(new GLatLng(this.markers[i].lat, this.markers[i].lng));
		this.map.addOverlay(marker);
	}
}
/**
 * Add a new marker to the map
 * 
 * @param double lat
 * @param double lng
 * @return void
 */
TV_Map.prototype.addItem = function(lat, lng) {
	this.markers.push({
		lat: lat,
		lng: lng
	});
}
/**
 * Callback of tv_loadMapApiCodeCallback()
 * 
 * @return void
 */
TV_Map.prototype.loadApiCodeCallback = function() {
	if (typeof(this.callback) == 'function') {
		this.callback(this);
	}
	if (this.options.auto_render) {
		this.render();
	}
}
/**
 * Handles the mouse wheel to be able to zoom the map
 * 
 * @param object event
 * @return void
 */
TV_Map.prototype.mouseWheelZoom = function(event) {
	if (!event) {
		event = window.event;
	}
	if (event.preventDefault) {
		event.preventDefault()
	}
	event.returnValue = false;
}
