Helper = {
	sumulateOptions : {
		pointerX: 0,
		pointerY: 0,
		button: 0,
		ctrlKey: false,
		altKey: false,
		shiftKey: false,
		metaKey: false,
		bubbles: true,
		cancelable: true,
		randomCount : 0
	},
	eventMatchers : {
		'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
		'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/
	},
	//
	// Function to format a number as a dolalr value
	//
	returnMoney : function (number, dollarsign) {
		var nStr = '' + Math.round(parseFloat(number) * 100) / 100;
		var x = nStr.split('.');
		var x1 = x[0];
		var x2 = x.length > 1 ? '.' + x[1]:'';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) {
			x1 = x1.replace(rgx, '$1' + ',' + '$2');
		}
		if (dollarsign) {
			return "$" + x1 + x2;
		} else {
			return x1 + x2;
		}
	},

	//
	// Keeps track of the the maps X/Y coords for mouse tricks
	//
	setMapXY : function () {
		this.mapX = jQuery("#wms_map").offset().left;
		this.mapY = jQuery("#wms_map").offset().top;
		this.mapC = (jQuery("#wms_map").outerWidth(true) / 2);
		this.mapCT = (jQuery("#wms_map").outerHeight(true) / 2);
	},

	//
	// Simulate any mouse event.  Powerful :)
	//
	simulate : function (element, eventName) {
		var options = Helper.extendSimulate(Helper.sumulateOptions, arguments[2] || {});
		var oEvent, eventType = null;

		for (var name in Helper.eventMatchers) {
			if (Helper.eventMatchers[name].test(eventName)) { eventType = name; break; }
		}

		if (!eventType)
		throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');

		if (document.createEvent) {
			oEvent = document.createEvent(eventType);
			if (eventType == 'HTMLEvents') {
				oEvent.initEvent(eventName, options.bubbles, options.cancelable);
			}
			else {
				oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
					options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
					options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
				}
				//console.log(element);
				element.dispatchEvent(oEvent);
			}
			else {
				options.clientX = options.pointerX;
				options.clientY = options.pointerY;
				var evt = document.createEventObject();
				oEvent = Helper.extendSimulate(evt, options);
				element.fireEvent('on' + eventName, oEvent);
			}
			return element;
		},
		extendSimulate : function(destination, source) {
			for (var property in source) {
				destination[property] = source[property];
			}
			return destination;
		},

		initLoader : function () {
			// Position the loader
			jQuery("#loader").css({
				top : jQuery("#wms_map").offset().top,
				left : jQuery("#wms_map").offset().left
			});

			jQuery("#loader").css({
				width: jQuery("#wms_map").width(),
				height : jQuery("#wms_map").height()
			});
		},

		showHideLoader : function (show, message) {
			if (show) {
				jQuery("#loader").css({ "display" : "block" });
			} else {
				jQuery("#loader").css({ "display" : "block" });
			}
		},

		displayErrorMessage : function (show, title, message) {
			if (show) {
				jQuery(".wms_error_title").html(title);
				jQuery(".wms_error_text").html(message);
				// jQuery("#wms_message_container").slideDown("slow");
				jQuery("#wms_message_container").modal({
					onShow : function (dialog) {
						jQuery('#simplemodal-container').css('height', 'auto');
					},
					overlayClose : true
				});
			} else {
				// jQuery("#wms_message_container").slideUp("slow");
				// Close Modal Window
				jQuery.modal.close();
			}
		},

		/*
		* display_loading() & hide_loading()
		* Basic functions whose responsibility is to show the user a search event is taking place.
		*/
		displayLoading : function() {
			jQuery("#loading_icon_container").css({
				"top" : jQuery("#wms_map").offset().top,
				"left" : jQuery("#wms_map").offset().left,
				"width" : jQuery("#wms_map").width(),
				"height" : jQuery("#wms_map").height()
			});
			jQuery("#loading_icon_container").fadeIn();
		},
		hideLoading : function() {
			jQuery("#loading_icon_container").fadeOut();
		},
		/*
		* bubbleMessage()
		* Function to dynamically bubble a message up to the user.
		* @param message (m)
		* @param loader (boolean, optional)
		* @param instant (boolean, optional)
		* @param container (string, optional, ID reference to container message should be centered in)
		*/
		bubbleMessage : function (m, loader, instant, container) {

			// Check for a message.  If none, create default.
			if (!m) {
				m = "There has been an error.";
			}

			// Populate the element with the message.
			jQuery("#loading_message").html(m);

			var con = '';

			if (typeof container === 'string') {
				con = container;
			} else if (Search.context === 'map') {
				con = 'wms_map';
			} else {
				con = 'wms_list_view';
			}

			// Get the container offset
			if (container === 'window') {
				var x = 0;
				var y = 0;
				var w = jQuery(window).width();
				var h = jQuery(window).height();
				var s = jQuery(window).scrollTop();

				// Get the width of the error container
				var e_w = jQuery("#loading_message").width() / 2;
				var e_h = jQuery("#loading_message").height() / 2;
			} else {
				var x = jQuery("#" + con).offset().left;
				var y = jQuery("#" + con).offset().top;
				var w = jQuery("#" + con).width();
				var h = jQuery("#" + con).height();
				var s = 0;

				// Get the width of the error container
				var e_w = jQuery("#loading_message").width() / 2;
				var e_h = jQuery("#loading_message").height() / 2;
			}


			// Set CSS properties for dynamic position
			jQuery("#loading_map_over").css({
				"display" : "block",
				"top" : y,
				"left" : x,
				"width" : jQuery("#wms_search").width() - 360,
				"height" : jQuery("#wms_search").height() - 40
			});

			jQuery("#loading_message").css({
				"top"  : (y + h / 2) - e_h + s,
				"left" : (x + w / 2) - e_w
			});

			if (loader) {
				jQuery("#loading_message").addClass("loading_message_loader");
			} else {
				jQuery("#loading_message").removeClass("loading_message_loader");
			}

			// Create the error message
			if (typeof container === undefined) {
				jQuery("#loading_map_over").css({ display : "block" });
			} else {
				jQuery("#loading_map_over").css({ display : "none" });
			}

			jQuery("#loading_message").addClass("shadow");

			if (instant) {
				jQuery("#loading_message").css({ display : "block" });
			} else {
				jQuery("#loading_message").fadeIn();
			}
		},
		/*
		* wms.toQueryString()
		* Takes URL param hash and converts it to a query string.
		*/
		toQueryString : function (args) {
			return decodeURIComponent(jQuery.param(args));
		},
		/*
		* wms.unserialize()
		* Takes a string in format "param1=value1&param2=value2" and returns an object { param1: 'value1', param2: 'value2' }.
		* If the "param1" ends with "[]" the param is treated as an array.
		* @todo: Support params like "param1[name]=value1" (should return { param1: { name: value1 } })
		*/
		unserialize : function (serializedString) {
			var str = decodeURI(serializedString);
			var pairs = str.split('&');
			var obj = {}, p, idx, val;
			for (var i=0, n=pairs.length; i < n; i++) {
				p = pairs[i].split('=');
				idx = p[0];

				if (idx.indexOf("[]") == (idx.length - 2)) {
					// Eh um vetor
					var ind = idx.substring(0, idx.length-2)
					if (obj[ind] === undefined) {
						obj[ind] = [];
					}
					obj[ind].push(p[1]);
				}
				else {
					obj[idx] = p[1];
				}
			}
			return obj;
		},
		/*
		* socialShare()
		* Facebook and Twitter sharing method.
		*/
		socialShare : function (service, url, addr) {
			if (service === 'facebook') {
				window.open('http://www.facebook.com/sharer.php?u=' + url,'NewFBWin','width=580,height=410,left=10,top=10,resizable=yes');
			} else if (service === 'twitter') {
				window.open('http://twitter.com/share?text=Windermere - Listing Detail - ' + addr + '&url=' + url,'TwitterWin','width=580,height=410,left=10,top=10,resizable=yes');
			}
		},

		facebookShare : function (url, clickedObj, title, image) {
			var summary = $(clickedObj).children("div").html();
			window.open('http://www.facebook.com/sharer.php?s=100&p[url]=' + escape(url) + 
			'&p[title]=' + escape(title) + '&p[images][0]=' + escape(image) + '&p[summary]=' + escape(summary),'NewFBWin','width=580,height=410,left=10,top=10,resizable=yes');
		},

		polylineBoundaryMessage : function (attach_id ,title , body, confirm) {
			jQuery(".popover below").remove();

			var html = '<div class="popover below">';
			html += '<div class="arrow"></div>';
			html += '<div class="inner">';
			html += '<h3 class="title">' + title + '</h3>';
			html += '<div class="content">';
			html += body;
			if (confirm) {
				html += '<p><a href="javascript: Map.boundaryChoice(false);">Cancel</a> &nbsp; | &nbsp; <a href="javascript: Map.boundaryChoice(true);">Confirm</a></p>';
			}
			html += '</div>';
			html += '</div>';
			html += '</div>';

			// get the attach_id offset
			var left = jQuery("#btn_geo").offset().left - 115;
			var top = jQuery("#btn_geo").offset().top + 25;

			jQuery("body").append(html);

			jQuery(".popover").css({
				top : top,
				left : left,
				display : "block"
			});

			jQuery.modal.close();
			// jQuery("#loading_map_over,#loading_message").css("display","none");
		},

		hasLocalStorage : function () {
			try {
				return 'localStorage' in window && window['localStorage'] !== null;
			} catch (e) {
				return false;
			}
		},

		checkHandler : function (obj) {
			var isHandler = true;
			if (typeof jQuery(obj).data('events') === 'object') {
				jQuery.each(jQuery(obj).data('events'), function(i, event){
					jQuery.each(event, function(i, handler){
						// do more stuff eventually
					});
				});
				isHandler =  true;
			} else {
				isHandler =  false;
			}

			return isHandler;
		},

		isNumeric : function (n) {
			return !isNaN(parseFloat(n)) && isFinite(n);
		},

		acresToSqft : function (n) {
			if (n != undefined) {
				n = n.toString().replace(/[^\d\.eE-]/g,'');
				if (n * 43560 != 0) {
					return n * 43560;
				}
			}
		},

		sqftToAcres : function (n) {
			if (n != undefined) {
				n = n.toString().replace(/[^\d\.eE-]/g,'');
				if (n / 43560 != 0) {
					return n / 43560;
				}
			}
		}
	}

