    jQuery(document).ready(function(){			
    	jQuery.fn.labelOver = function(overClass) {
    		return this.each(function(){
    			var label = jQuery(this);
    			var f = label.attr('for');
    			if (f) {
    				var input = jQuery('#' + f);
    				
    				this.hide = function() {
    				  label.css({ textIndent: -10000 });
    				};
    			
    				this.show = function() {
    				  if (input.val() == ''){
    					  label.css({ textIndent: 0 });
    					  input.trigger('clear');
    				  }
    				};
    	
    				// handlers
    				input.focus(this.hide);
    				input.blur(this.show);
    			  label.addClass(overClass).click(function(){ input.focus();});
    				
    				if (input.val() != '') this.hide(); 
    			}
    		});
    	};
    	
    	var url = "https://buy.garmin.com/shop/ProductJSONServlet?case=simpleProductList&jsoncallback=?";
    	var accentMap = {
    		'ē':'e',
    		'ū':'u',
    		'ü':'u',
    		'™':' ',//ignore
    		'®':' '//ignore
    	};
    	var normalize = function( term ) {
    		var ret = '';
    		for ( var i = 0; i < term.length; i++ ) {
    			ret += accentMap[ term.charAt(i) ] || term.charAt(i);
    		}
    		//reg and trade are replaced by ' ' so its possible to have 2 spaces together. Ignore those.
    		return ret.replace("  ", " ");
    	};
    	jQuery("#productsHint").labelOver("over");
        jQuery("#productsHint").hide();
    	jQuery("#pleaseWait").labelOver("over");
    	jQuery("#pleaseWait").show();			
    	jQuery("#products").attr('disabled','disabled');
    	
    	//Since the jsonpCallback value is being hardcoded, any and ALL JSON requests should be made with an SSL enabled service host to prevent JSON reply spoofing.
    	jQuery.ajaxSetup({
    		jsonpCallback:'jsonp1282086947001',	
    		timeout:30000,
    		error:function(){
    			alert("The server has encountered an unknown error.");	
    		}
    	});
    	
    	jQuery("#products").focus(function(){
    		if(this.value.length > 0){
    			jQuery( this ).autocomplete("search", this.value);
    		}
    	});
    	
    	jQuery.getJSON(url, function(data) {
    		jQuery("#pleaseWait").hide();
    		jQuery("#productsHint").show();
    		jQuery("#products").removeAttr('disabled');
    		jQuery("#products").autocomplete({
    			minLength: 0,
    			source: function( request, response ) {
    				currentSearch = request;
    				var matcher = new RegExp( jQuery.ui.autocomplete.escapeRegex( request.term ), "i" );
    				var results = jQuery.grep( data.list, function( value ) {
    						value = value.label || value.value || value;
    						return matcher.test( value ) || matcher.test( normalize( value ) );
    					}); 
    				response(results);
    			},
    			select: function(event, ui) {
    				jQuery("#products").val(ui.item.label).attr('disabled','disabled');
    				jQuery('#productsproductId').val(ui.item.pId);
    				window.location = "http://support.garmin.com/support/productSupport/productSupport.faces?productId=" + ui.item.pId;
    				return false;	
    			}
    		})			
    		.data( "autocomplete" )._renderItem = function( ul, item) {
    			var li = jQuery( "<li></li>" );
    			if((ul[0].childNodes.length) % 2 != 0){
    				li.addClass("odd");
    			}
    			//the following used to highlight the matched chars			
    			var il = item.label;
    			var matcher = new RegExp( jQuery.ui.autocomplete.escapeRegex( currentSearch.term ), "i" );
    			var match = matcher.exec( normalize( il ));
    			if(match == null){
    				match = matcher.exec( il );
    			}
    			var mi = match.index; 
    			var m = match[0];
    			var containsReg = m.indexOf(" ")>0?1:0;
    			var same = il.substr(mi, m.length+containsReg);
    			var last = il.substr(mi+m.length+containsReg, il.length);
    			var stg1 = il.substr(0,mi) + "<strong>"+ same +"</strong>" + last;
    			return li.data( "item.autocomplete", item )
    				.append( "<a>" + stg1 + "</a>" )
    				.appendTo( ul );
    		};
    	});
    });
