;(function($) {
	$.fn.buildLink = function(options){
		options = jQuery.extend({
			absolut: true,
			action: 'submit',
			defaultValues: null,
			currentValues: null,
			cookieFilters: null,
			cookieDates: null,
			alternateField: null,
			lnkMainSite: null,
			listField: null,
			addOnSubmit: false,
			maxCookies: 10,
			truncate: 25,
			siteUrl: null
		},options);
		this.each(
			function(){
				new $.BuilderLink(this, options);
			}
		);
		return this;
	};
	$.fn.resetLink = function(){
		return this.trigger("reset");
	};
	$.fn.buildLinkNow = function(){
		return this.trigger("buildNow");
	};
	$.fn.setMainSiteLnk = function(){
		return this.trigger("setMainSiteLnk");
	};
	
	
	$.BuilderLink = function(form, options){
		/*----TEMP---*/
		var cookies = $.cookies.filter(new RegExp("LetMeGo_search","g"),{path: '/'+options.action});
		for ( var cook in cookies) {
			$.cookies.del(cook,{path: '/'+options.action});
		}
		/*----END TEMP---*/
		var defaultStatus = options.defaultValues;
		var currentStatus = options.currentValues;
		var $form = $(form);
		var changed = new Array();
		var constructor = function(){};
		var formId = $form.attr("id");
		$form.append('<input type="hidden" id="'+formId+'Hidden" name="'+formId+'Hidden" value="'+$form.attr("action")+'" />');
		var $hidden = $("#"+formId+"Hidden");
		formId = formId.replace(/Form/,"");
		$form.find(":input,input :hidden").bind("change",function(){
			if(this.id == 'Search') return;
			var $input = $(this);
			fieldName = $input.attr("name");
			regexp = new RegExp("\\[|\\]|data|"+formId,"g");
			fieldName = fieldName.replace(regexp,"");
			fieldName = fieldName.replace(/Georeference/,"G_");
			fieldName = fieldName.replace(/^Coordinate(\d)/,"C_$1_");
			fieldName = fieldName.replace(/latitude/,"lt");
			fieldName = fieldName.replace(/longitude/,"lg");
			if(fieldName.match(/check_.*?_hour/)){
				fieldName = fieldName.replace(/_hour/g,"");
				$input = $("input[name*='["+fieldName+"]']");
			}
			if(typeof defaultStatus[fieldName] !== 'undefined'){
				if(typeof currentStatus[fieldName] !== 'undefined')
					delete currentStatus[fieldName];
				if(this.type == 'checkbox'){
					checked = $("."+fieldName+"Input:checked");
					if(checked.length){
						currentStatus[fieldName] = new Array();
						checked.each(function(){
							currentStatus[fieldName].push($(this).val());
						});
						if(equal(currentStatus[fieldName].sort(),defaultStatus[fieldName].sort())){
							delete currentStatus[fieldName];
						};
					};
				} else {
					if(defaultStatus[fieldName] != $input.val()){
						currentStatus[fieldName] = $input.val();
						if(fieldName == 'check_in' || fieldName == 'check_out'){
							if(typeof $("select[name*='"+fieldName+"_hour']").val() != 'undefined'){
								currentStatus[fieldName] += ' '+$("select[name*='"+fieldName+"_hour']").val();
							} else {
								currentStatus[fieldName] += (fieldName == 'check_in' ? ' 03:00 PM' : ' 11:00 AM');
							}
						}
					};
				};
				if(typeof currentStatus['G_type'] == 'undefined'){
					return;
				};
				run();
			};
		});
		$form.bind("reset",function(){
			var link = "http://"+options.siteUrl+"/"+options.action+"?";
			if(options.alternateField)
				populateAlternate(link);
			return;
		});
		$form.bind("buildNow",function(){
			run();
		});
		$form.bind("setMainSiteLnk",function(){
			setMainSiteLnk();
		});
		
		function run(){
			var link = buildLink(options.absolut);
			var name = getGeoreferenceName(false,true);
			if(options.alternateField)
				populateAlternate(link);
			if(options.listField)
				populateList(link,name);
			if(options.cookieFilters)
				setCookie(link,name);
			if(options.addOnSubmit)
				addLinkToSubmit(link);
			if(options.maxCookies)
				removeExtraCookies();
			if(options.lnkMainSite)
				setMainSiteLnk();
		}
		
		function addLinkToSubmit(link){
			if(options.absolut)
				$form.attr("action",link);
			else {
				var action = $hidden.val();
				$form.attr("action",action+link);
			}
		};
		function buildLink(absolut){
			var link = "";
			var first = true;
			var type = $('#geo_reference_type').val();
			switch (type) {
				case widgetHelper.getGeoTypes().AREA:
					delete currentStatus["C_0_lg"];
					delete currentStatus["C_0_lt"];
					delete currentStatus["G_id"];
					delete currentStatus["G_radius"];
				break;
				case widgetHelper.getGeoTypes().BOUNDING_BOX:
					delete currentStatus["transportation"];
					delete currentStatus["closeness"];
					delete currentStatus["G_id"];
					delete currentStatus["G_radius"];
				break;
				case widgetHelper.getGeoTypes().GEO_CODED_STRING:
				break;
			};
			delete currentStatus["G_regionBounds"];
			delete currentStatus["G_mapBounds"];
			for ( var field in currentStatus) {
				var isArray = (typeof currentStatus[field] == 'object');
				var value = '';
				if(isArray) {
					value = currentStatus[field].join('|');
				} else {
					value = currentStatus[field];
				}
				if(field == 'check_in' || field == 'check_out'){
					value = Url.encode(value);
				}
				if(field == 'SortByType' || field == 'sort_by_keyword' || field == 'sortByArea' || field == 'alt' || field == 'tolerance' || field == 'cluster' || field == 'sort_by_area' || field == 'limit'){
					continue;
				}
				if(first) first = false;
				else link += "&";
				link += field + "=" + value + (isArray ? '|' : '');
			};
			var area = getGeoreferenceName();
			if(!area){
				return false;
			}
			var path = Url.encode(area);
			if(type == widgetHelper.getGeoTypes().GEO_CODED_STRING){
				path = options.action+"/"+path;
			}
			if(options.mapView){
				if(link != ""){
					link += "&map=y";
				}
				else{
					link += "map=y";
				}
			}
			if(absolut) {
				return "http://"+options.siteUrl+"/"+path+"?"+link;
			} else {
				return "/"+path+"?"+link;
			};
		};
		function equal(source,compareTo){
		    if (!compareTo || !compareTo.length || source.length!=compareTo.length) {
	            return false;
		    };
		    for (var i=0; i<source.length; i++) {
	            if (source[i]!==compareTo[i]) {
                    return false;
	            };
		    };
		    return true;
		};
		function getGeoreferenceName(path,truncate){
			if(typeof path == 'undefined') path = true;
			if(typeof truncate == 'undefined') truncate = false;
			var name = (path && $('#path').val() != '' ? $('#path').val() : $('#Search').val());
			if(truncate){
				name = name.substring(0,options.truncate);
			};
			return name;
		};
		function populateAlternate(link){
			if(options.alternateField == null){return;}
			if(typeof link == 'undefined'){
				link = buildLink(options.absolut);
			};
			if(link){
				$(options.alternateField).val(link);
			}
		};
		function populateList(link,name){
			if(options.listField == null){return;}
			if(typeof link == 'undefined')
				link = buildLink(options.absolut);
			var $list = $(options.listField);
			var path = getGeoreferenceName(true,false);
			var regexp = new RegExp("\/"+Url.encode(path)+"\\?","g");
			$list.removeOption(regexp);
			$(options.listField+" option:eq(0)").after('<option value="'+link+'">'+name+'</option>');
		};
		function setCookie(link,name){
			var name = Url.encode(name);
			$.cookies.del(options.cookieFilters+'['+name+']',{path: '/'+options.action});
			$.cookies.del(options.cookieDates+'['+name+']',{path: '/'+options.action});
			$.cookies.set(options.cookieFilters+'['+name+']',link,{hoursToLive: 2160,path: '/'+options.action});
			$.cookies.set(options.cookieDates+'['+name+']',(new Date()).getTime(),{hoursToLive: 2160,path: '/'+options.action});
		};
		function setMainSiteLnk(){
			var link = buildLink(false);
			$(options.lnkMainSite).attr('href',$(options.lnkMainSite+'Hidden').val()+link);
		}
		function removeExtraCookies(){
			if(options.listField == null){return;}
			if(options.maxCookies == null){return;}
			var listChildren = $(options.listField).children();
			if(listChildren.length > options.maxCookies+1){
				var name = $(options.listField+" option:last").text();
				$.cookies.del(options.cookieFilters+'['+Url.encode(name)+']',{path: '/'+options.action});
				$.cookies.del(options.cookieDates+'['+Url.encode(name)+']',{path: '/'+options.action});
				$(options.listField+" option:last").remove();
				return removeExtraCookies();
			};
			return true;
		};
		if(options.alternateField){
			$().ready(function(){
				populateAlternate();
			});
		};
		return new constructor();
	};
})(jQuery);

/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/
var Url = {
 
	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},
 
	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}
