// Global do-nothing function
var nullFunction = function(){};

// Sets up Yell logger for simple cross-browser logging
if (location.host.match(/^[a-z0-9_-]+(\.btyp)?$/i) || location.search.match(/[&?](debug|log)=true/i)) {
  var debugLevel = location.search.match(/[&?]debug=true/i);
  if (window.console) {
    window.logger = {
      debug: debugLevel ? function(message){ window.console.debug(message); } : nullFunction,
      info: function(message){ window.console.log(message); },
      warn: function(message){ window.console.warn(message); }
    };
  } else if (window.opera) {
    window.logger = {
      debug: debugLevel ? function(message){ window.opera.postError('[DEBUG] ' + message); } : nullFunction,
      info: function(message){ window.opera.postError('[INFO] ' + message); },
      warn: function(message){ window.opera.postError('### WARNING ###\n' + message); }
    };
  } else {
    // Log to the status bar
    var fullStatusLog = '';
    function statusLog(message) {
      fullStatusLog += message;
      fullStatusLog = (fullStatusLog.length <= 5000) ? fullStatusLog : fullStatusLog.substr(fullStatusLog.length - 5000);
      window.status = (fullStatusLog.length <= 120) ? fullStatusLog : fullStatusLog.substr(fullStatusLog.length - 120);
    }
    window.logger = {
      debug: debugLevel ? function(message){ statusLog(' :' + message + ':'); } : nullFunction,
      info: function(message){ statusLog(' [' + message + ']'); },
      warn: function(message){ statusLog(' |[' + message + ']|'); }
    };
  }
} else {
  // Set up a dummy logger (to prevent errors)
  window.logger = {
    debug: nullFunction,
    info: nullFunction,
    warn: nullFunction
  };
}
if (!window.console) {
  // Set up a cross-browser alternative to console.log
  window.console = { log: function(message) { alert('PLEASE USE YELL LOGGER INSTEAD\n' + message); } };
}
// Set up short-cut functions for easy logging
function log(message) {
  logger.info(message);
}
function debug(message) {
  logger.debug(message);
}
function warn(message) {
  logger.warn(message);
}

// Pauses script execution
function pause(milliseconds) {
  // Use for debug only, as this causes massive CPU usage.
  if (location.host.match(/^[a-z0-9_-]+(\.btyp)?$/i) || location.search.match(/[&?](debug|log)=true/i)) {
    var startDate = new Date();
    var now;
    log('PAUSE');
    do { now = new Date(); } while (now - startDate < milliseconds);
  }
}

// JavaScript Document
function yellAddEvent(elm, evType, fn, useCapture){
	// cross-browser event handling for IE5+, NS6 and Mozilla 
	// By Scott Andrew 
	if (elm.addEventListener) { 
		elm.addEventListener(evType, fn, useCapture); 
		return true; 
	} else if (elm.attachEvent) { 
		var r = elm.attachEvent('on' + evType, fn); 
		return r; 
	} else {
		elm['on' + evType] = fn;
	}
}
function removeEvent(obj, evType, fn, useCapture){
	if (obj.removeEventListener){
		obj.removeEventListener(evType, fn, useCapture);
		return true;
	} else if (obj.detachEvent){
		var r = obj.detachEvent("on"+evType, fn);
		return r;
	} else {
		alert("Handler could not be removed");
	}
}

function getEl(e){
	var el = (window.event && window.event.srcElement) ? window.event.srcElement : (e && e.target)? e.target : null;
	if (!el){return}
	return el;
}

function gimme(id){
	if(id.indexOf('.') != -1){
		id = id.replace(/./,"");
		return getElementsByClassName(id);
	}else{
		return document.getElementById(id);
	}
}

function getElementsByClassName(classname){
    var a = [];
	var re = new RegExp('(^| )'+classname+'( |$)');
	var els = document.all?document.all:document.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
		if(re.test(els[i].className))
			a[a.length]=els[i]; //a.push(els[i]) is not ie 5 compatible
    return a;
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	return [curleft,curtop];
}

function toggledisplay(obj){
	if(gimme(obj)){
		var type = typeof obj;
		var myObj;
		
		if(type == "object"){
			myObj = obj;
		}else if(type == "string"){
			myObj = gimme(obj);
		}
			if((myObj.style.display == 'none')||(myObj.style.display == '')){
			myObj.style.display = 'block';
		}else{
			myObj.style.display = 'none';
		}	
	}
}
function togglecontent(divId, defaultContent, otherContent){
	var type = typeof divId;
	var myObj;
	if(type == "object"){
		myObj = divId;
	}else if(type == "string"){
		myObj = gimme(divId);
	}
	if(myObj.innerHTML == defaultContent){
		myObj.innerHTML = otherContent;
	}else{
		myObj.innerHTML = defaultContent;
	}
}
function cPop(obj,popup,reldiv,offSetX,offSetY){
	if(!document.getElementById(popup+'copy')){
		var newdiv = document.createElement('div');
		newdiv.setAttribute('id', popup+'copy');
		newdiv.setAttribute('class','tip popUp');
		newdiv.innerHTML = document.getElementById(popup).innerHTML;
		obj.parentNode.insertBefore(newdiv,obj.nextSibling);
		showPopUp(obj,newdiv.id,reldiv,offSetX,offSetY);
	}else{
		showPopUp(obj,popup+'copy',reldiv,offSetX,offSetY);
	}
}
function showPopUp(clickedObj, tabName, relDiv, offSetX, offSetY){
	/*clickedObj = the link to show menu,
	tabName = the id of the div to show
	relDiv = if the div you are showing is contained within a relative div, name it here
	offSetX, offSetY = if the div has to be positioned above/below the link*/
	
	hideAllPopUps();
	
	var pos = findPos(clickedObj);
	var posRel = (!relDiv) ? [0,0] : findPos(document.getElementById(relDiv));
	var moveX = (!offSetX) ? 0 : offSetX;
	var moveY = (!offSetY) ? 0 : offSetY;
	
	var tabX = pos[0] - posRel[0] + moveX  ;
	var tabY = pos[1] - posRel[1] + moveY;
	var tabObj = document.getElementById(tabName);
	tabObj.style.left = tabX +"px";
	tabObj.style.top = tabY +"px";
	tabObj.style.display = "block";
}

function hideAllPopUps(){
	
	var allPopUps = getElementsByClassName('popUp');
	//alert("allPopUps: "+allPopUps.length);
	for (i=0;i<allPopUps.length;i++){
		allPopUps[i].style.display = "none";
	}
}
function setCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function getCookie(name) {

	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function addAdvertHistory(advert) {
	$.ajax({
		method: "get",
		url: "/ucs/ManageHistory.do?addadvert="+advert+'&ajax=true',
		success: function(){}
		});
	
}

$(function(){
	$('.nat a').click(function(){
		natID = $(this).closest('.nat').attr('id');
		if(natID != ""){
			coName = $('#'+natID+' .coName').html();
			coAddress = $('#'+natID+' .mini-address').html();
			alphaUrl = $('#'+natID+' .expandLink').attr('href');
			classification = jQuery.trim($('#'+natID+' .classification').text());
			telNo = jQuery.trim($('#'+natID+' .small strong:first').text());
			newCookie =escape(coName+" -:- "+coAddress+" -:- "+alphaUrl+" -:- "+classification+" -:- "+telNo); 
			addAdvertHistory(newCookie);
		}

	});
});

function deleteAdvert(id) {
	//first, remove the cookie
	//this needs more work - can't just delete the cookie without renumbering the others
	deleteCookie(id);
	
	//then remove advert from screen
	//this does not seem to work, don't know why not
	document.getElementById('savedAdverts').removeChild(id);
}

function deleteCookie(name) {
	setCookie(name,"",-1);
}
function loadEstara(iframeID, estaraUrl){
	var cffDiv = iframeID.replace(/estaraFrame/,"makeCall");
	if(gimme(cffDiv).style.display =="block"){
		gimme(iframeID).src=estaraUrl;
	}else{
		gimme(iframeID).src="/yell/loading.html";
	}
}


var w = 0;

function getBrowserWidth(){
	
	if (window.innerWidth){
		w = window.innerWidth;
	}else if (document.documentElement && document.documentElement.clientWidth != 0){
		w = document.documentElement.clientWidth;
	}else if (document.body){
		w = document.body.clientWidth;
	}		
	return w;
}

//Maps variable function
function changeM(){
	if (document.getElementById('useMultimap').checked) {
		document.forms[0].M.value = '1';
	}else {
		document.forms[0].M.value = '0';
	}
}	


function toggle800(){
	getBrowserWidth();
	if(document.getElementById('searchBoxForm')){
		if(w<931){
			document.getElementById('searchBoxForm').className="narrowRes";
		}else{
			document.getElementById('searchBoxForm').className="";
		}
	}
	
}
yellAddEvent(window, 'load', toggle800);	
yellAddEvent(window, 'resize', toggle800);	



function updateEGs(){

	$('form.searchBoxForm').submit(function(){
		return validate3Search(this.id);
		
	});
	$('form.searchBoxForm input[type=text]').keypress(function(){
		hideErrors();
	});
	
	formFields = [$('#keywordsInput'),$('#companyName'),$('#location')];
	$(formFields).each(function(){
		$(this).parent().next().hide();
		setEG($(this),$(this).parent().next());
		$(this).focus(function(){
			checkEG($(this),$(this).parent().next());
		});
		$(this).blur(function(){
			setEG($(this),$(this).parent().next());
		});
	});

}
function setEG(formField,eg){
	if(formField.val()==""){
		formField.val(eg.html());
		formField.addClass('exampleInput');
	}
}
function checkEG(formField,eg){
	if(formField.val()==eg.html()){
		formField.val("").focus();
		formField.removeClass('exampleInput');
	}
}



//Search Validation functionality


//Variables
var pass,coNamePass,locPass;
//Arrays for catching false search input
var companyNameWords=new Array("ltd","the","plc","co","in","at","and");
var locationWords=new Array("tba","c","h","d","a","p","r","t","u","k","f","o","y","i","v");
var specialChars=new Array("`","#","?","]");

function hideErrors(){
	$('.vError').remove();
}

function specialCharsCatcher(fieldid){
	for(i=0;i<specialChars.length;i++){
				scRegexp = eval("/\\"+specialChars[i]+"/g");
				updatedField = $('#'+fieldid).val();
				updatedField = updatedField.replace(scRegexp, "");
				$('#'+fieldid).val(updatedField);
	}
}

function stopwordsCatcher(field, farray){
	var stopwordArray = eval(farray).slice();
	for(k=0;k<stopwordArray.length;k++){
		if(field.value.toLowerCase() == stopwordArray[k]){
			vErrorBuilder(field,'stopword',stopwordArray[k]);
			pass = false;
			return false;
		}
	}
}
function vErrorBuilder(vfield,vErrtype,vChar){
	var vposField = $("#"+vfield.id);
	var vpost = vposField.position().top + 25;
	var vposl = vposField.position().left;
	
	
	Err_Open = '<div class="vError" style="position:absolute; top:'+vpost+'px; left:'+vposl+'px; "><div class="upArrow"/>';
	Err_Close = '</div>';
	
	if(vErrtype == 'blank'){
		if(vfield.id == 'keywordsInput' || vfield.id == 'keywordsInput_bottom'){
			$('#'+vfield.id).after(Err_Open+'Please enter a product or a service.'+Err_Close);
		}
		if(vfield.id == 'companyName' || vfield.id == 'companyName_bottom'){
			$('#'+vfield.id).after(Err_Open+'<strong>AND/OR</strong> enter a company name.'+Err_Close);
		}
	}else if(vErrtype == 'stopword'){
		$('#'+vfield.id).after(Err_Open+'Sorry, but we will need a bit more than "'+vChar+'" to find you great results.'+Err_Close);
	}else if(vErrtype == 'mapsearch'){
		vfieldJs = "submitMapSearch('"+vfield.id+"');"
		$('#'+vfield.id).after(Err_Open+'<strong>OR </strong><a id="locErrorLink" href="#" onclick="'+vfieldJs+'">view a map of '+vfield.value+'</a>.'+Err_Close);
	}
}


function validate3Search(form){
	
	formFields = [$('#keywordsInput'),$('#companyName'),$('#location')];
	$(formFields).each(function(){
		
		checkEG($(this),$(this).parent().next());
	});
	//Resets validation
	vqs = '';vkwrd = '';vcname = '';vloc = '';pass = true; mapsearch = false;
	hideErrors();

	validatefields = $('#'+form+' input[type=text]');

	//Loops through the submitted elements
	for(a=0;a<validatefields.length;a++){
		specialCharsCatcher(validatefields[a].id);
		if(validatefields[a].id == 'keywordsInput' || validatefields[a].id == 'keywordsInput_bottom'){vkwrd = validatefields[a];}
		if(validatefields[a].id == 'companyName' || validatefields[a].id == 'companyName_bottom'){vcname = validatefields[a];}
		if(validatefields[a].id == 'location' || validatefields[a].id == 'location_bottom'){vloc = validatefields[a];}
	}
	
	//Trim any whitespace from start and end of search term	
	vkwrd.value = jQuery.trim(vkwrd.value);
	vcname.value = jQuery.trim(vcname.value);
	vloc.value = jQuery.trim(vloc.value);
	
	//Check if maps search or not
	if($('#'+form+' #useMultimap:checked').length >=1 || (!vkwrd.value && !vcname.value && vloc.value)){
		mapsearch = true;
	};

	//Checks for empty fields
	if(vkwrd.value == '' && vcname.value == ''){
		if(vloc.value == ''){
			vErrorBuilder(vkwrd,'blank');
			vErrorBuilder(vcname,'blank');
			pass = false;
		}else{
			pass = false;
			if(stopwordsCatcher(vloc, 'locationWords')!= false){
				submitMapSearch(vloc.id);
			}
		}
	}else{
	//Validation if found text in search
		if(vcname.value != ''){
			stopwordsCatcher(vcname, 'companyNameWords');
		}
		if(vloc.value != ''){
			stopwordsCatcher(vloc, 'locationWords');
		}
	}
	//Returns true or false to the submitting form

	if(pass){return true;}else{return false;}
}



function submitMapSearch(vfield){
	mapLocation = $('#'+vfield)[0].value;
	window.location = "/maps/MapAction.do?location="+mapLocation+"&panel=poi&submit=Show+map&intCam=intViewAMapOf"
}




function changeSSMs(){
	if(placesMMIsSupportedBrowser()) {
		var hiddenInputs = document.getElementsByName('ssm');
		for(i=0;i<hiddenInputs.length;i++){
			hiddenInputs[i].value="0";
		}
	}
}

//  Multimap provided function
function placesMMIsSupportedBrowser(){if(document.attachEvent||document.addEventListener){if(typeof(document.doctype)=='\157\142\152\145\143\164'||typeof(document.media)=='\163\164\162\151\156\147'){if(document.getElementById){return true;}}}return false;};


//Start of homepage address book functionality
function updateSavedData(ajaxURL,returnTarget){
	$.ajax({
		method: "get",
		url: ajaxURL,
		success: function(html){
			$("#"+returnTarget).hide('fast',function(){
				$("#"+returnTarget).remove();
				if($('#saved-wrapper li').size()==0){
					$('#saved-wrapper').hide('fast',function(){
						$('#saved-wrapper').remove()
						$('body').hide().show(); //Fix for IE8 redraw error
					});
				}
				if($('#searchHistory li').size()==0){
					$('#searchHistory').hide('fast',function(){
						$('#searchHistory').remove()
						$('body').hide().show(); //Fix for IE8 redraw error
					});
				}
				if($('#advert-history li').size()==0){
					$('#advert-history').hide('fast',function(){
						$('#advert-history').remove()
						$('body').hide().show(); //Fix for IE8 redraw error
					});
				}
				$('body').hide().show(); //Fix for IE8 redraw error
			});
		}
	});
}
$(function(){
	$('.halfWidth li .delete').click(function(){
		ajaxURL = $(this).attr('href')+'&ajax=true';
		returnTarget = $(this).parent().attr('id');
		updateSavedData(ajaxURL,returnTarget);
		return false;
	});		
	$('.halfWidth h2 .delete').hover(
		function () { $(this).parent().parent().addClass('red'); }, 
		function () { $(this).parent().parent().removeClass('red');	}
	).click(function(){
		ajaxURL = $(this).attr('href')+'&ajax=true';
		returnTarget = $(this).parent().parent().attr('id');
		updateSavedData(ajaxURL,returnTarget);
		return false;
	});		
});

function initPromo(){
	$('#topics-list li').hide();
	var randomNum = Math.floor(Math.random() * $('#topics-list li').length);
	$('#topics-list li:eq('+randomNum+')').show();
	$('#topics-thumbs').show();
	$('#topics-thumbs li:eq('+randomNum+')').hide();
	$('#topics-thumbs li:visible:last').css({'padding-right':'0'});
	$('#topics-list').after($('#blog-promo h2'));
}

//End of homepage address book functionality

/*
 * Autocomplete - jQuery plugin 1.0.2
 *
 * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
 *
 */
(function($) {
	
$.fn.extend({
	autocomplete: function(urlOrData, options) {
		var isUrl = typeof urlOrData == "string";
		options = $.extend({}, $.Autocompleter.defaults, {
			url: isUrl ? urlOrData : null,
			data: isUrl ? null : urlOrData,
			delay: isUrl ? $.Autocompleter.defaults.delay : 10,
			max: options && !options.scroll ? 10 : 150
		}, options);
		
		// if highlight is set to false, replace it with a do-nothing function
		options.highlight = options.highlight || function(value) { return value; };
		
		// if the formatMatch option is not specified, then use formatItem for backwards compatibility
		options.formatMatch = options.formatMatch || options.formatItem;
		
		return this.each(function() {
			new $.Autocompleter(this, options);
		});
	},
	result: function(handler) {
		return this.bind("result", handler);
	},
	search: function(handler) {
		return this.trigger("search", [handler]);
	},
	flushCache: function() {
		return this.trigger("flushCache");
	},
	setOptions: function(options){
		return this.trigger("setOptions", [options]);
	},
	unautocomplete: function() {
		return this.trigger("unautocomplete");
	}
});

$.Autocompleter = function(input, options) {

	var KEY = {
		LEFT: 37,
		UP: 38,
		RIGHT: 39,
		DOWN: 40,
		DEL: 46,
		TAB: 9,
		RETURN: 13,
		ESC: 27,
		COMMA: 188,
		PAGEUP: 33,
		PAGEDOWN: 34,
		BACKSPACE: 8
	};

	// Create $ object for input element
	var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);

	var timeout;
	var previousValue = "";
	var cache = $.Autocompleter.Cache(options);
	var hasFocus = 0;
	var lastKeyPressCode;
	var config = {
		mouseDownOnSelect: false
	};
	var select = $.Autocompleter.Select(options, input, selectCurrent, config);
	
	var blockSubmit;
	
	// prevent form submit in opera when selecting with return key
	$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
		if (blockSubmit) {
			blockSubmit = false;
			return false;
		}
	});
	
	// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
	$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
		// track last key pressed
		lastKeyPressCode = event.keyCode;
		switch(event.keyCode) {
		
			case KEY.UP:
				event.preventDefault();
				if ( select.visible() ) {
					select.prev();
				} else {
					onChange(0, true);
				}
				break;
				
			case KEY.DOWN:
				event.preventDefault();
				if ( select.visible() ) {
					select.next();
				} else {
					onChange(0, true);
				}
				break;
				
			case KEY.PAGEUP:
				event.preventDefault();
				if ( select.visible() ) {
					select.pageUp();
				} else {
					onChange(0, true);
				}
				break;
				
			case KEY.PAGEDOWN:
				event.preventDefault();
				if ( select.visible() ) {
					select.pageDown();
				} else {
					onChange(0, true);
				}
				break;
			
			// matches also semicolon
			case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
			case KEY.TAB:
			case KEY.RETURN:
			case KEY.LEFT:
			case KEY.RIGHT:
				if( selectCurrent() ) {
					// stop default to prevent a form submit, Opera needs special handling
					event.preventDefault();
					blockSubmit = true;
					return false;
				}
				break;
				
			case KEY.ESC:
				select.hide();
				break;
				
			default:
				clearTimeout(timeout);
				timeout = setTimeout(onChange, options.delay);
				break;
		}
	}).focus(function(){
		// track whether the field has focus, we shouldn't process any
		// results if the field no longer has focus
		hasFocus++;
		 var inputname = $input.attr("name");
			  if (inputname == "keywords"){kw = ""}
			  if (inputname == "companyName"){cn = ""}
			  if (inputname == "location"){lo = ""}
	}).blur(function() {
		hasFocus = 0;
		if (!config.mouseDownOnSelect) {
			hideResults();
		}
	}).focus(function() {
		// query again when clicking focusing in a field
	
			//onChange(0, true);
		
	}).bind("search", function() {
		// TODO why not just specifying both arguments?
		var fn = (arguments.length > 1) ? arguments[1] : null;
		function findValueCallback(q, data) {
			var result;
			if( data && data.length ) {
				for (var i=0; i < data.length; i++) {
					if( data[i].result.toLowerCase() == q.toLowerCase() ) {
						result = data[i];
						break;
					}
				}
			}
			if( typeof fn == "function" ) fn(result);
			else $input.trigger("result", result && [result.data, result.value]);
		}
		$.each(trimWords($input.val()), function(i, value) {
			request(value, findValueCallback, findValueCallback);
		});
	}).bind("flushCache", function() {
		cache.flush();
	}).bind("setOptions", function() {
		$.extend(options, arguments[1]);
		// if we've updated the data, repopulate
		if ( "data" in arguments[1] )
			cache.populate();
	}).bind("unautocomplete", function() {
		select.unbind();
		$input.unbind();
		$(input.form).unbind(".autocomplete");
	});
	
	function selectCurrent() {
		var selected = select.selected();
		if( !selected )
			return false;
		var v = selected.result;
		previousValue = v;
		
		if ( options.multiple ) {
			var words = trimWords($input.val());
			if ( words.length > 1 ) {
				v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
			}
			v += options.multipleSeparator;
		}
		$input.val(v);
		hideResultsNow();
		$input.trigger("result", [selected.data, selected.value]);	
		 var inputname = $input.attr("name");
			  if (inputname == "keywords"){kw = "kw"}
			  if (inputname == "companyName"){cn = "cn"}
			  if (inputname == "location"){lo = "lo"}
		return true;
	}
	
	function onChange(crap, skipPrevCheck) {
		if( lastKeyPressCode == KEY.DEL ) {
			select.hide();
			return;
		}
		
		var currentValue = $input.val();
		
		if ( !skipPrevCheck && currentValue == previousValue )
			return;
		
		previousValue = currentValue;
		
		currentValue = lastWord(currentValue);
		if ( currentValue.length >= options.minChars) {
			//$input.addClass(options.loadingClass);
			if (!options.matchCase)
				currentValue = currentValue.toLowerCase();
			request(currentValue, receiveData, hideResultsNow);
		} else {
			stopLoading();
			select.hide();
		}
	};
	
	function trimWords(value) {
		if ( !value ) {
			return [""];
		}
		var words = value.split( options.multipleSeparator );
		var result = [];
		$.each(words, function(i, value) {
			if ( $.trim(value) )
				result[i] = $.trim(value);
		});
		return result;
	}
	
	function lastWord(value) {
		if ( !options.multiple )
			return value;
		var words = trimWords(value);
		return words[words.length - 1];
	}
	
	// fills in the input box w/the first match (assumed to be the best match)
	// q: the term entered
	// sValue: the first matching result
	function autoFill(q, sValue){
		// autofill in the complete box w/the first match as long as the user hasn't entered in more data
		// if the last user key pressed was backspace, don't autofill
		if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
			// fill in the value (keep the case the user has typed)
			$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
			// select the portion of the value not typed by the user (so the next character will erase)
			$.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
		}
	};

	function hideResults() {
		clearTimeout(timeout);
		timeout = setTimeout(hideResultsNow, 200);
	};

	function hideResultsNow() {
		var wasVisible = select.visible();
		select.hide();
		clearTimeout(timeout);
		stopLoading();
		if (options.mustMatch) {
			// call search and run callback
			$input.search(
				function (result){
					// if no value found, clear the input box
					if( !result ) {
						if (options.multiple) {
							var words = trimWords($input.val()).slice(0, -1);
							$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
						}
						else
							$input.val( "" );
					}
				}
			);
		}
		//if (wasVisible)
			// position cursor at end of input field. Disabled -Matt
		//	$.Autocompleter.Selection(input, input.value.length, input.value.length);
	};

	function receiveData(q, data) {
		if ( data && data.length && hasFocus ) {
			stopLoading();
			select.display(data, q);
			autoFill(q, data[0].value);
			select.show();
		} else {
			hideResultsNow();
		}
	};

	function request(term, success, failure) {
		if (!options.matchCase)
			term = term.toLowerCase();
		var data = cache.load(term);
		// recieve the cached data
		if (data && data.length) {
			success(term, data);
		// if an AJAX url has been supplied, try loading the data now
		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
			
			var extraParams = {
			
			};
			$.each(options.extraParams, function(key, param) {
				extraParams[key] = typeof param == "function" ? param() : param;
			});
			
			$.ajax({
				// try to leverage ajaxQueue plugin to abort previous requests
				mode: "abort",
				// limit abortion to this input
				port: "autocomplete" + input.name,
				dataType: options.dataType,
				url: options.url,
				data: $.extend(
				extraParams,{
					value: lastWord(term)
				//	limit: options.max
				}),
				success: function(data) {
					var parsed = options.parse && options.parse(data) || parse(data);
					cache.add(term, parsed);
					success(term, parsed);
				}
			});
			
		} else {
			// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
			select.emptyList();
			failure(term);
		}
	};
	
	function parse(data) {
			return $.map(eval(data), function(row) {
				return {
					data: row,
					value: row.name,
					result: row.name
				}
			});	
	};

	function stopLoading() {
		//$input.removeClass(options.loadingClass);
	};

};

$.Autocompleter.defaults = {
	inputClass: "ac_input",
	resultsClass: "ac_results",
	loadingClass: "ac_loading",
	minChars: 2,
	delay: 400,
	matchCase: false,
	matchSubset: true,
	matchContains: false,
	cacheLength: 0,
	max: 10,
	mustMatch: false,
	extraParams: {},
	selectFirst: false,
	formatItem: function format(item) {return item.name;},
	formatMatch: null,
	autoFill: false,
	width: 184,
	multiple: false,
	multipleSeparator: ", ",
	highlight: function(value, term) {
		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
	},
    scroll: false,
    scrollHeight: 250
};

$.Autocompleter.Cache = function(options) {

	var data = {};
	var length = 0;
	
	function matchSubset(s, sub) {
		if (!options.matchCase) 
			s = s.toLowerCase();
		var i = s.indexOf(sub);
		if (i == -1) return false;
		return i == 0 || options.matchContains;
	};
	
	function add(q, value) {
		if (length > options.cacheLength){
			flush();
		}
		if (!data[q]){ 
			length++;
		}
		data[q] = value;
	}
	
	function populate(){
		if( !options.data ) return false;
		// track the matches
		var stMatchSets = {},
			nullData = 0;

		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
		if( !options.url ) options.cacheLength = 1;
		
		// track all options for minChars = 0
		stMatchSets[""] = [];
		
		// loop through the array and create a lookup structure
		for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
			var rawValue = options.data[i];
			// if rawValue is a string, make an array otherwise just reference the array
			rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
			
			var value = options.formatMatch(rawValue, i+1, options.data.length);
			if ( value === false )
				continue;
				
			var firstChar = value.charAt(0).toLowerCase();
			// if no lookup array for this character exists, look it up now
			if( !stMatchSets[firstChar] ) 
				stMatchSets[firstChar] = [];

			// if the match is a string
			var row = {
				value: value,
				data: rawValue,
				result: options.formatResult && options.formatResult(rawValue) || value
			};
			
			// push the current match into the set list
			stMatchSets[firstChar].push(row);

			// keep track of minChars zero items
			if ( nullData++ < options.max ) {
				stMatchSets[""].push(row);
			}
		};

		// add the data items to the cache
		$.each(stMatchSets, function(i, value) {
			// increase the cache size
			options.cacheLength++;
			// add to the cache
			add(i, value);
		});
	}
	
	// populate any existing data
	setTimeout(populate, 25);
	
	function flush(){
		data = {};
		length = 0;
	}
	
	return {
		flush: flush,
		add: add,
		populate: populate,
		load: function(q) {
			if (!options.cacheLength || !length)
				return null;
			/* 
			 * if dealing w/local data and matchContains than we must make sure
			 * to loop through all the data collections looking for matches
			 */
			if( !options.url && options.matchContains ){
				// track all matches
				var csub = [];
				// loop through all the data grids for matches
				for( var k in data ){
					// don't search through the stMatchSets[""] (minChars: 0) cache
					// this prevents duplicates
					if( k.length > 0 ){
						var c = data[k];
						$.each(c, function(i, x) {
							// if we've got a match, add it to the array
							if (matchSubset(x.value, q)) {
								csub.push(x);
							}
						});
					}
				}				
				return csub;
			} else 
			// if the exact item exists, use it
			if (data[q]){
				return data[q];
			} else
			if (options.matchSubset) {
				for (var i = q.length - 1; i >= options.minChars; i--) {
					var c = data[q.substr(0, i)];
					if (c) {
						var csub = [];
						$.each(c, function(i, x) {
							if (matchSubset(x.value, q)) {
								csub[csub.length] = x;
							}
						});
						return csub;
					}
				}
			}
			return null;
		}
	};
};


$.Autocompleter.Select = function (options, input, select, config) {
	var CLASSES = {
		ACTIVE: "ac_over"
	};
	
	var listItems,
		active = -1,
		data,
		term = "",
		needsInit = true,
		element,
		list;
	
	// Create results
	function init() {
		if (!needsInit)
			return;
		element = $("<div/>")
		.hide()
		.addClass(options.resultsClass)
		.css("position", "absolute")
		.appendTo(document.body);
	
		list = $("<ul/>").appendTo(element).mouseover( function(event) {
			if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
	            active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
			    $(target(event)).addClass(CLASSES.ACTIVE);            
	        }
		}).click(function(event) {
			$(target(event)).addClass(CLASSES.ACTIVE);
			select();
			// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
			//input.focus();
			return false;
		}).mousedown(function() {
			config.mouseDownOnSelect = true;
		}).mouseup(function() {
			config.mouseDownOnSelect = false;
		});
		
		if( options.width > 0 )
			element.css("width", options.width);
			
		needsInit = false;
		
					//Added by Matt, recalculate the position of the div if the window resizes
				$(window).resize(function(){
					var offset = $(input).offset();
					element.css({
						width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
						top: offset.top + input.offsetHeight,
						left: offset.left
					});
				});
	} 
	
	function target(event) {
		var element = event.target;
		while(element && element.tagName != "LI")
			element = element.parentNode;
		// more fun with IE, sometimes event.target is empty, just ignore it then
		if(!element)
			return [];
		return element;
	}

	function moveSelect(step) {
		listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
		movePosition(step);
        var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
        if(options.scroll) {
            var offset = 0;
            listItems.slice(0, active).each(function() {
				offset += this.offsetHeight;
			});
            if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
                list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
            } else if(offset < list.scrollTop()) {
                list.scrollTop(offset);
            }
        }
	};
	
	function movePosition(step) {
		active += step;
		if (active < 0) {
			active = listItems.size() - 1;
		} else if (active >= listItems.size()) {
			active = 0;
		}
	}
	
	function limitNumberOfItems(available) {
		return options.max && options.max < available
			? options.max
			: available;
	}
	
	function fillList() {
		list.empty();
		var max = limitNumberOfItems(data.length);
		for (var i=0; i < max; i++) {
			if (!data[i])
				continue;
			var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
			if ( formatted === false )
				continue;
			var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
			$.data(li, "ac_data", data[i]);
		}
		listItems = list.find("li");
		if ( options.selectFirst ) {
			listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
			active = 0;
		}
		// apply bgiframe if available
		if ( $.fn.bgiframe )
			list.bgiframe();
	}
	
	return {
		display: function(d, q) {
			init();
			data = d;
			term = q;
			fillList();
		},
		next: function() {
			moveSelect(1);
		},
		prev: function() {
			moveSelect(-1);
		},
		pageUp: function() {
			if (active != 0 && active - 8 < 0) {
				moveSelect( -active );
			} else {
				moveSelect(-8);
			}
		},
		pageDown: function() {
			if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
				moveSelect( listItems.size() - 1 - active );
			} else {
				moveSelect(8);
			}
		},
		hide: function() {
			element && element.hide();
			listItems && listItems.removeClass(CLASSES.ACTIVE);
			active = -1;
		},
		visible : function() {
			return element && element.is(":visible");
		},
		current: function() {
			return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
		},
		show: function() {
			var offset = $(input).offset();
			element.css({
				width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
				top: offset.top + input.offsetHeight,
				left: offset.left
			}).show();
            if(options.scroll) {
                list.scrollTop(0);
                list.css({
					maxHeight: options.scrollHeight,
					overflow: 'auto'
				});
				
                if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
					var listHeight = 0;
					listItems.each(function() {
						listHeight += this.offsetHeight;
					});
					var scrollbarsVisible = listHeight > options.scrollHeight;
                    list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
					if (!scrollbarsVisible) {
						// IE doesn't recalculate width when scrollbar disappears
						listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
					}
                }
                
            }
		},
		selected: function() {
			var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
			return selected && selected.length && $.data(selected[0], "ac_data");
		},
		emptyList: function (){
			list && list.empty();
		},
		unbind: function() {
			element && element.remove();
		}
	};
};

$.Autocompleter.Selection = function(field, start, end) {
	if( field.createTextRange ){
		var selRange = field.createTextRange();
		selRange.collapse(true);
		selRange.moveStart("character", start);
		selRange.moveEnd("character", end);
		selRange.select();
	} else if( field.setSelectionRange ){
		field.setSelectionRange(start, end);
	} else {
		if( field.selectionStart ){
			field.selectionStart = start;
			field.selectionEnd = end;
		}
	}
	field.focus();
};

})(jQuery);

/*
//bgiframe plugin - 2.1.1
//Fixes bug with autocomplete listings appearing over select items and losing z-index in IE6
*/
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(b($){$.m.E=$.m.g=b(s){h($.x.10&&/6.0/.I(D.B)){s=$.w({c:\'3\',5:\'3\',8:\'3\',d:\'3\',k:M,e:\'F:i;\'},s||{});C a=b(n){f n&&n.t==r?n+\'4\':n},p=\'<o Y="g"W="0"R="-1"e="\'+s.e+\'"\'+\'Q="P:O;N:L;z-H:-1;\'+(s.k!==i?\'G:J(K=\\\'0\\\');\':\'\')+\'c:\'+(s.c==\'3\'?\'7(((l(2.9.j.A)||0)*-1)+\\\'4\\\')\':a(s.c))+\';\'+\'5:\'+(s.5==\'3\'?\'7(((l(2.9.j.y)||0)*-1)+\\\'4\\\')\':a(s.5))+\';\'+\'8:\'+(s.8==\'3\'?\'7(2.9.S+\\\'4\\\')\':a(s.8))+\';\'+\'d:\'+(s.d==\'3\'?\'7(2.9.v+\\\'4\\\')\':a(s.d))+\';\'+\'"/>\';f 2.T(b(){h($(\'> o.g\',2).U==0)2.V(q.X(p),2.u)})}f 2}})(Z);',62,63,'||this|auto|px|left||expression|width|parentNode||function|top|height|src|return|bgiframe|if|false|currentStyle|opacity|parseInt|fn||iframe|html|document|Number||constructor|firstChild|offsetHeight|extend|browser|borderLeftWidth||borderTopWidth|userAgent|var|navigator|bgIframe|javascript|filter|index|test|Alpha|Opacity|absolute|true|position|block|display|style|tabindex|offsetWidth|each|length|insertBefore|frameborder|createElement|class|jQuery|msie'.split('|'),0,{}))


/*
//ajax queue plugin
//Added to stop autocomplete sending requests when previous requests haven't been returned
*/

/*
 * Queued Ajax requests.
 * A new Ajax request won't be started until the previous queued 
 * request has finished.
 */
jQuery.ajaxQueue = function(o){
	var _old = o.complete;
	o.complete = function(){
		if ( _old ) _old.apply( this, arguments );
		jQuery.dequeue( jQuery.ajaxQueue, "ajax" );
	};

	jQuery([ jQuery.ajaxQueue ]).queue("ajax", function(){
		jQuery.ajax( o );
	});
};

/*
 * Synced Ajax requests.
 * The Ajax request will happen as soon as you call this method, but
 * the callbacks (success/error/complete) won't fire until all previous
 * synced requests have been completed.
 */
jQuery.ajaxSync = function(o){
	var fn = jQuery.ajaxSync.fn, data = jQuery.ajaxSync.data, pos = fn.length;
	
	fn[ pos ] = {
		error: o.error,
		success: o.success,
		complete: o.complete,
		done: false
	};

	data[ pos ] = {
		error: [],
		success: [],
		complete: []
	};

	o.error = function(){ data[ pos ].error = arguments; };
	o.success = function(){ data[ pos ].success = arguments; };
	o.complete = function(){
		data[ pos ].complete = arguments;
		fn[ pos ].done = true;

		if ( pos == 0 || !fn[ pos-1 ] )
			for ( var i = pos; i < fn.length && fn[i].done; i++ ) {
				if ( fn[i].error ) fn[i].error.apply( jQuery, data[i].error );
				if ( fn[i].success ) fn[i].success.apply( jQuery, data[i].success );
				if ( fn[i].complete ) fn[i].complete.apply( jQuery, data[i].complete );

				fn[i] = null;
				data[i] = null;
			}
	};

	return jQuery.ajax(o);
};

jQuery.ajaxSync.fn = [];
jQuery.ajaxSync.data = [];


/*
//initiate autocomplete
*/

/*autocomplete global omniture variables*/
var cn = ""
var kw = ""
var lo = ""
		
$(function() {

	$("#keywordsInput").attr("autocomplete","off").autocomplete('/autocomplete/autoComplete.do', {
	extraParams: {type: 'keyword'}
	});
	
	$("#companyName").attr("autocomplete","off").autocomplete('/autocomplete/autoComplete.do', {
	extraParams: {type: 'company'}
	});	
	
	$("#location,").attr("autocomplete","off").autocomplete('/autocomplete/autoComplete.do', {
	extraParams: {type: 'location'}
	});
	
	$("#keywordsInput_bottom").attr("autocomplete","off").autocomplete('/autocomplete/autoComplete.do', {
	scroll:true,scrollHeight:100,extraParams: {type: 'keyword'}
	});
	
	$("#companyName_bottom").attr("autocomplete","off").autocomplete('/autocomplete/autoComplete.do', {
	scroll:true,scrollHeight:100,extraParams: {type: 'company'}
	});
	
	$("#location_bottom").attr("autocomplete","off").autocomplete('/autocomplete/autoComplete.do', {
	scroll:true,scrollHeight:100,extraParams: {type: 'location'}
	});
	
	
	/*
	//Autocomplete Omniture tracking
	*/
	$("form#searchBoxForm").submit(function() {
		pass = false 
		
			//If the values aren't blank, append a hidden input to the form with the vars as the value
			if (!(!kw && !cn && !lo)){
				$(this).append('<input id="autocomplete" type="hidden" name="autocomplete" value="'+kw+''+cn+''+lo+'"/>');
			}

		pass = true	
		if(pass){return true;}else{return false;}	
	});
});


/*
//Togglelist plugin
*/
$.fn.togglelist = function(options) {
var defaults = {
   number: 5,
   showtext: "More",
   showtitle: "Show more",
   hidetext: "Less",
   hidetitle: "Show less",
   showonclick: ""
};
var options = $.extend(defaults, options);

//Get the id of the list the function is being ran on
var listid = $(this).attr('id');

//The initial show html
var togglehtml = '<a id="'+listid+'toggle" class="MoreLink" title="'+ options.showtitle +'" href="#" onclick="'+options.showonclick+'">'+ options.showtext +'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button></button></a>';

//The unique id of the show/hide html
var toggleselector = '#'+listid+'toggle';

//Find the nth children of the ul, hide them and store as 'hidden'
var hidden = $(this).children().slice(eval(options.number)).hide();

//Find the hidden li parent ul (to handle there being no hidden li) and insert show html after
hidden.parents('ul').after(togglehtml);

//Toggle the hidden li when the show html is clicked
$(toggleselector).click(function () {
	$(hidden).toggle();
		//If the hidden li are visible, update the "show" html with the hide title and text
		if ($(hidden).is(':visible')) {$(toggleselector).removeAttr("onclick").attr("title", ""+ options.hidetitle +"").attr("class","CloseLink").html(''+options.hidetext+'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button></button>');}
		//Else, go back to the original show html
		else{$(toggleselector).attr("title", ""+ options.showtitle +"").attr("class","MoreLink").attr("onclick", ""+ options.showonclick +"").html(''+options.showtext+'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button></button>');}
	return false;
});
	
};