/**
 * author: Antonio Ramirez http://webeaters.blogspot.com
 *
 * class: AutoComplete for Prototype 1.5.1
 *
 * version: 1.2.0 - 2007-11-11 
 * 		(based on AutoSuggest 2.1.3 - 2007-07-19)
 *
 *
 * REFERENCES AND THANKS 
 * this class is based on the work in AutoSuggest.js of
 * Timothy Groves - http://www.brandspankingnew.net
 * and adapted for use with prototype 1.5.1
 *
 */

var AutoComplete = Class.create();

var xml_ac;
function create_xml_ac(oo, _callback, forumid) {
	xml_ac = null;
	if (xml_ac != null) return;

	var options = {
		timeout: 5000,
		noresults: 'No entries found...',
		imageslocation: basehref + 'images/ac/',
		script: function (input) { return (basehref + 'lib/autocomplete.comp?fieldid='+oo.id+'&input='+input+'&forumid='+forumid); },
		callback: _callback,
		cache: false
	};
	xml_ac=new AutoComplete(oo.id,options);
	return true;
}
function create_xml_ac_tagging(oo, _callback, forumid, existing, toremove) {
	xml_ac = null;
	if (xml_ac != null) return;

	var options = {
		timeout: 5000,
		noresults: 'No entries found...',
		imageslocation: basehref + 'images/ac/',
		script: function (input) { 
				var existingValue = ''; 
				var remValue = ''; 
				if( $(existing) ) {
					existingValue = $(existing).value; 
				}
				if( $(toremove) ) {
					remValue = $(toremove).value; 
				}
				//alert(existingValue);
				return (basehref + 'lib/autocomplete.comp?fieldid='+oo.id+'&input='+input+'&forumid='+forumid+'&existing='+ existingValue + '&toremove=' + remValue); 
		},
		callback: _callback,
		cache: false
		
	};
	xml_ac=new AutoComplete(oo.id,options);
	return true;
}
function create_xml_ac_tagging_meta(oo, _callback, forumid, existingid, existingv) {
	xml_ac = null;
	if (xml_ac != null) return;

	var options = {
		timeout: 5000,
		noresults: 'No entries found...',
		imageslocation: basehref + 'images/ac/',
		script: function (input) { 
				return (basehref + 'lib/autocomplete.comp?fieldid='+oo.id+'&input='+input+'&forumid='+forumid+'&existingid='+ existingid + '&existingv=' + existingv); 
		},
		callback: _callback,
		cache: false
		
	};
	xml_ac=new AutoComplete(oo.id,options);
	return true;
}
function create_xml_ac_simple(oo, _callback, forumid) {
	var options = {
		timeout: 5000,
		noresults: 'No entries found...',
		imageslocation: basehref + 'images/ac/',
		script: function (input) { return (basehref + 'lib/autocomplete.comp?fieldid='+oo.id+'&input='+input+'&forumid='+forumid); },
		callback: _callback,
		cache: false
	};
	var tmp_xml_ac = new AutoComplete(oo.id, options);
	return true;
}




AutoComplete.prototype = {
  Version: '1.0.0_beta',
  REQUIRED_PROTOTYPE: '1.5.1',
 
  initialize: function (id, param)
  {
  	// check whether we have the appropiate javascript libraries
  	this.PROTOTYPE_CHECK();

	
  	// get field
	//
	this.fld = $(id);

	if (!this.fld)
	{
		throw("AutoComplete requires a field id to initialize");

	}
	
	// init variables
	//
	this.sInp 	= ""; 	// input value 
	this.nInpC 	= 0;	// input value length
	this.aSug 	= []; 	// suggestions array 
	this.iHigh 	= 0;	// level of list selection 
	
	// parameters object
	this.options = param ? param : {};
	
	// defaults	
	var k, def = {minchars:1, meth:"get", varname:"input", className:"AutoComplete", timeout:2500, delay:500, offsety:-5, shownoresults: true, noresults: "-", maxheight: 250, cache: true, maxentries: 25, onAjaxError:null, setWidth: false, minWidth: 200, maxWidth: 200, useNotifier: true, imageslocation: 'images/ac'};
	for (k in def)
	{
		if (typeof(this.options[k]) != typeof(def[k]))
			this.options[k] = def[k];
	}
	
	if (this.options.useNotifier) this.fld.addClassName('ac_field');
	// set keyup handler for field
	// and prevent AutoComplete from client
	//
	var p = this;

	// NOTE: not using addEventListener because UpArrow fired twice in Safari
	this.fld.onkeypress 	= function(ev){ return p.onKeyPress(ev); };
	this.fld.onkeyup 		= function(ev){ return p.onKeyUp(ev); };
	this.fld.onblur			= function(ev){ p.resetTimeout(); return true; }; // to implement? i did not think so but... up to you
	
	this.fld.setAttribute("AutoComplete","off");
  },
  convertVersionString: function (versionString){
      var r = versionString.split('.');
      return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
  },
  PROTOTYPE_CHECK: function() { 
    if((typeof Prototype=='undefined') || 
       (typeof Element == 'undefined') || 
       (typeof Element.Methods=='undefined') ||
       (this.convertVersionString(Prototype.Version) < 
        this.convertVersionString(this.REQUIRED_PROTOTYPE)))
       throw("AutoComplete requires the Prototype JavaScript framework >= " +
        this.REQUIRED_PROTOTYPE);
  },
  onKeyPress: function (e)
  {
  	if (!e) e = window.event;
  	
  	var key	= e.keyCode || e.wich;
  	
  	
	// set responses to keypress events in the field
	// this allows the user to use the arrow keys to scroll through the results
	// ESCAPE clears the list
	// RETURN sets the current highlighted value
	// TAB moves to next item in the list

	switch(key)
	{
		case Event.KEY_RETURN:
			this.setHighlightedValue();
			Event.stop(e);
			break;
		case Event.KEY_TAB: // if we wish to use this, we need to use it here, keyup fails
			this.changeHighlight(key);
			Event.stop(e);
			break;
		case Event.KEY_ESC:
			this.clearSuggestions();
			break;
	}
	return true;
  },
  onKeyUp: function (e)
  {
  	if (!e) e = window.event;
  	
  	var key = e.keyCode || e.wich;
  	
  	if (key == Event.KEY_UP || key == Event.KEY_DOWN) 
  	{
  		this.changeHighlight(key);
  		Event.stop(e);
  	}
  	else this.getSuggestions(this.fld.value);
  	
	return true;
  },
  getSuggestions: function(val)
  {
  	
  	// input the same? do nothing
  	if(val==this.sInp) return false;
  	
  	// kill the old list
  	if($(this.acID)) $(this.acID).remove();
  	
  	this.sInp = val;
  	
  	// input length is less than the min required to trigger a request
  	// do nothing
  	if (val.length < this.options.minchars)
  	{
  		this.aSug 	= [];
  		this.nInpC	= val.length; 
  		return false;
  	}
  	
  	
  	// here we will detect if there is a comma and the splitted value has a value to check
  	// comma stars a new search and val is converted to the new value after the comma
  	var ol	= this.nInpC; // old length
  	
  	this.nInpC	= val.length ? val.length : 0;
  	
  	// if caching enabled, and user is typing (ie. length of input is increasing)
  	// filter results out of suggestions from last request
  	var l = this.aSug.length;
  	//alert(this.options.cache);
  	if (this.nInpC > ol && l && l < this.options.maxentries && this.options.cache)
  	{
  		var arr = [];
  		for (var i=0;i<l;i++)
  		{
  			if(this.aSug[i].value.substr(0,val.length).toLowerCase() == val.toLowerCase())
  				arr.push(this.aSug[i]);
  		}
  		this.aSug = arr;
  		
  		// recreate the list
  		this.createList(this.aSug);
  	}
  	else
  	{
  		// do new request
  		var p = this;
  		//var input	= this.sInp; // send the converted new value (comma)
  		clearTimeout(this.ajID); // ajax id timer
  		this.ajID = setTimeout( function () {p.doAjaxRequest(p.sInp)}, this.options.delay);
  
  	}
  	
  	return false;
  },
  doAjaxRequest: function (input)
  {
  	// we have to check here if there is a new splitted value (, or ;)
  	// always check against the last part of the comma and then check
  	// saved input is still the value of the field
  	if (input != this.fld.value) 
  		return false;
  	
  	// create ajax request
  	// do we need to call a function to recreate the url?
  	if (typeof this.options.script == 'function')
  		var url = this.options.script(encodeURIComponent(this.sInp));
  	else
  		var url = this.options.script+this.options.varname+'='+encodeURIComponent(this.sInp);
  	
  	if(!url) return false;
  	
  	var p = this;
  	var m = this.options.meth;  // get or post?
  	if (this.options.useNotifier){this.fld.setStyle({backgroundImage:'url('+p.options.imageslocation+'autocomplete_spinner.gif)'});} 
  	
  	var options = {
  		method: m,
  		onSuccess: function (req) 
  		{
  				if (p.options.useNotifier){p.fld.setStyle({backgroundImage:'url('+p.options.imageslocation+'autocomplete_leftcap.gif)'});} 
  				p.setSuggestions(req,input);
  		},
  		onFailure: (typeof p.options.onAjaxError == 'function')? function (status) {if (p.options.useNotifier){p.fld.setStyle({backgroundImage:'url('+p.options.imageslocation+'autocomplete_leftcap.gif)'});} p.options.onAjaxError(status)} :  function (status) {if (p.options.useNotifier){p.fld.setStyle({backgroundImage:'url('+p.options.imageslocation+'autocomplete_leftcap.gif)'});} alert("AJAX error: "+status); }
  	}
  	// make new ajax request
  	new Ajax.Request(url, options);
  },
  setSuggestions: function (req, input)
  {
	  // if field input no longer matches what was passed to the request
	  // don't show the suggestions
	  // here we need to check against the splitted values if any (, or ;)
	if (input != this.fld.value)
		return false;
	
	this.aSug = [];
	
	if(this.options.json) // response in json format?
	{
		var jsondata = eval('(' + req.responseText + ')');
		
		for (var i=0; i<jsondata.results.length;i++)
		{
			this.aSug.push({'id':jsondata.results[i].id, 'value':jsondata.results[i].value, 'info':jsondata.results[i].info, 'path':jsondata.results[i].path});
		}
	}
	else	// response in xml format?
	{
		
		
		var results = req.responseXML.getElementsByTagName('results')[0].childNodes;
	
		for(var i=0;i<results.length;i++)
		{
			//alert(results[i].getAttribute('id'));
			if(results[i].hasChildNodes())
				this.aSug.push(  { 'id':results[i].getAttribute('id'), 'value':results[i].childNodes[0].nodeValue, 'info':results[i].getAttribute('info'), 'path':results[i].getAttribute('path') }  );
		}
	}
	this.acID = 'ac_'+this.fld.id;
	
	this.createList(this.aSug);
  },
  createDOMElement: function ( type, attr, cont, html )
  {
	var ne = document.createElement( type );
	
	if (!ne)
		return 0;
		
	for (var a in attr)
		ne[a] = attr[a];
	
	var t = typeof(cont);
	
	if (t == "string" && !html)
		ne.appendChild( document.createTextNode(cont) );
	else if (t == "string" && html)
		ne.innerHTML = cont;
	else if (t == "object")
		ne.appendChild( cont );

	return ne;
  },
  //--------------------------------------------------------------------------------
  createListOld:	function(arr)
  {
	// get rid of the old list if any  
  	if($(this.acID)) $(this.acID).remove();
  	
  	// clear list removal timeout
  	this.killTimeout();
  	
  	// if no results, and shownoresults is false, do nothing
  	if (arr.length == 0 && !this.options.shownoresults) return false;
  	
  	// create holding div
  	var div	= this.createDOMElement('div', {id:this.acID, className:this.options.className});
  	
  	// create div header
  	var hcorner = this.createDOMElement('div', {className: 'ac_corner'});
  	var hbar	= this.createDOMElement('div', {className: 'ac_bar'});
  	var header	= this.createDOMElement('div', {className: 'ac_header'});
  	header.appendChild(hcorner);
  	header.appendChild(hbar);
  	div.appendChild(header);
  	
	// create and populate ul
	var ul	= this.createDOMElement('ul', {id:'ac_ul'});
	var p 	= this; // pointer that we will need later on
	// no results?
	if (arr.length == 0 && this.options.shownoresults)
	{
		var li = this.createDOMElement('li', {className: 'ac_warning'}, this.options.noresults );
		ul.appendChild(li);
	}
	else
	{
		// loop through arr of suggestions creating an LI element for each of them
		for (var i=0,l = arr.length; i<l; i++)
		{
			// format output with the input enclosed in a EM elementFromPoint
			// (as HTML not DOM)
			var val 	= arr[i].value;
			var st 		= val.toLowerCase().indexOf(this.sInp.toLowerCase()); // HERE WE CHECK AGAINST THE SPLITTED VALUE IF ANY***
			var output 	= val.substring(0,st) + '<em>' + val.substring(st,st+this.sInp.length) + '</em>' + val.substring(st+this.sInp.length);
			
			var span	= this.createDOMElement('span',{},output,true); // type of, properties, output, isHTML?
			
			if(arr[i].info != '') // do we need to add extra info?
			{
				var br	= this.createDOMElement('br',{});
				span.appendChild(br);
				
				var small = this.createDOMElement('small',{}, arr[i].info);
				span.appendChild(small);
			}
			var a 	= this.createDOMElement('a',{href:'#'});
			
			var tl	= this.createDOMElement('span',{className:'tl'},'&nbsp;',true);
			var tr	= this.createDOMElement('span',{className:'tr'},'&nbsp;',true);
			
			a.appendChild(tl);
			a.appendChild(tr);
			a.appendChild(span); // add the object span into the link
			
			a.name = i+1;
			
			a.onclick 		= function (){ p.setHighlightedValue();return false; };
			a.onmouseover	= function () { p.setHighlight(this.name); }; 
			
			var li = this.createDOMElement('li',{}, a); // add the link element to a li element
			
			// finally add the newly created li element to the ul element 
			ul.appendChild(li);
		}
	}
	
	div.appendChild(ul); // add the newly created list to the div element
	
	// create div footer
	var fcorner = this.createDOMElement('div', {className: 'ac_corner'});
  	var fbar	= this.createDOMElement('div', {className: 'ac_bar'});
  	var footer	= this.createDOMElement('div', {className: 'ac_footer'});
  	footer.appendChild(fcorner);
  	footer.appendChild(fbar);
  	div.appendChild(footer);
  	
  	// get position of target textfield
	// position holding div below it
	// set width of holding div to width of field 
	// if 
	
	var pos		= Position.cumulativeOffset(this.fld);
	div.style.left 		= pos[0] - this.fld.offsetLeft + "px";
	div.style.top 		= pos[1] + this.fld.offsetHeight + "px";
		
	var w 		= (this.options.setWidth && this.fld.offsetWidth < this.options.minWidth)? this.options.minWidth : (this.options.setWidth && this.fld.offsetWidth > this.options.maxWidth)? this.options.maxWidth : this.fld.offsetWidth;
	 
	div.style.width 	= w + "px";
	
	// set mouseover functions for div
	// when mouse pointer leaves div, set a timeout to remove the list after an interval
	// when mouse enters div, kill the timeout so the list won't be removed
	//
	div.onmouseover 	= function(){ p.killTimeout() };
	div.onmouseout 		= function(){ p.resetTimeout() };
	
	// add DIV to document
	document.getElementsByTagName("body")[0].appendChild(div);
	
	// highlight first item
	this.iHigh = 1;
	this.setHighlight(1);
	
	// remove list after interval
	this.toID	= setTimeout(function () {p.clearSuggestions() },this.options.timeout);
	
  },
  //Create div new =============================================================
  createList:	function(arr)
  {
	// get rid of the old list if any  
  	if($(this.acID)) $(this.acID).remove();
  	
  	// clear list removal timeout
  	this.killTimeout();
  	
  	// if no results, and shownoresults is false, do nothing
  	if (arr.length == 0 && !this.options.shownoresults) return false;
  	
  	// create holding div
  	var div	= this.createDOMElement('div', {id:this.acID, className:this.options.className});
	div.onclick 		= function (){ $(this.id).remove(); return false; };

  	// create div header
  	//var hcorner = this.createDOMElement('div', {className: 'ac_corner'});
  	//var hbar	= this.createDOMElement('div', {className: 'ac_bar'});
  	//var header	= this.createDOMElement('div', {className: 'ac_header'});
  	//header.appendChild(hcorner);
  	//header.appendChild(hbar);
  	//div.appendChild(header);
  	
	// create and populate ul
	var ul	= this.createDOMElement('ul', {id:'ac_ul'});
	var p 	= this; // pointer that we will need later on
	// no results?
	if (arr.length == 0 && this.options.shownoresults)
	{
		var li = this.createDOMElement('li', {className: 'ac_warning'}, this.options.noresults );
		ul.appendChild(li);
	}
	else
	{
		// loop through arr of suggestions creating an LI element for each of them
		for (var i=0,l = arr.length; i<l; i++)
		{
			// format output with the input enclosed in a EM elementFromPoint
			// (as HTML not DOM)
			var val 	= arr[i].value;
			var st 		= val.toLowerCase().indexOf(this.sInp.toLowerCase()); // HERE WE CHECK AGAINST THE SPLITTED VALUE IF ANY***
			var output 	= val.substring(0,st) + '<em>' + val.substring(st,st+this.sInp.length) + '</em>' + val.substring(st+this.sInp.length);

			if(arr[i].path && arr[i].path != '/' && arr[i].path != '') // do we need to add extra info?
			{
				output = '' + output + '<font style="color: #999999; font-weight: normal; font-size: 10px;"> (' + arr[i].path + ')</font>';
			}
			

			if (arr[i].id == 'addnew') {
				output = '&nbsp;&nbsp;&nbsp;&nbsp;' + output;
			}
			
			var span	= this.createDOMElement('span',{},output,true); // type of, properties, output, isHTML?
			
			if(arr[i].info != '') // do we need to add extra info?
			{
				var br	= this.createDOMElement('br',{});
				span.appendChild(br);
				
				var small = this.createDOMElement('small',{}, arr[i].info);
				span.appendChild(small);
			}
			var a 	= this.createDOMElement('a',{href:'#'});
			
			//var tl	= this.createDOMElement('span',{className:'tl'},'&nbsp;',true);
			//var tr	= this.createDOMElement('span',{className:'tr'},'&nbsp;',true);

			if (arr[i].id == 'addnew') {
				span.className = 'autocomplete_addnewspan';
				//alert('aa' + li.className);
			}
			
			//a.appendChild(tl);
			//a.appendChild(tr);
			a.appendChild(span); // add the object span into the link
			
			a.name = i+1;
			
			a.onclick 		= function (){ p.setHighlightedValue();return false; };
			a.onmouseover	= function () { p.setHighlight(this.name); }; 
			
			var li = this.createDOMElement('li',{}, a); // add the link element to a li element
			
			// finally add the newly created li element to the ul element 
			ul.appendChild(li);
		}
	}
	
	div.appendChild(ul); // add the newly created list to the div element
	
	// create div footer
	//var fcorner = this.createDOMElement('div', {className: 'ac_corner'});
  	//var fbar	= this.createDOMElement('div', {className: 'ac_bar'});
  	//var footer	= this.createDOMElement('div', {className: 'ac_footer'});
  	//footer.appendChild(fcorner);
  	//footer.appendChild(fbar);
  	//div.appendChild(footer);
  	
  	// get position of target textfield
	// position holding div below it
	// set width of holding div to width of field 
	// if 
	
	var pos		= Position.cumulativeOffset(this.fld);
	div.style.left 		= pos[0];// - this.fld.offsetLeft + "px";
	div.style.top 		= pos[1] + this.fld.offsetHeight + "px";
		
	var w 		= (this.options.setWidth && this.fld.offsetWidth < this.options.minWidth)? this.options.minWidth : (this.options.setWidth && this.fld.offsetWidth > this.options.maxWidth)? this.options.maxWidth : this.fld.offsetWidth;
	 
	div.style.width 	= w + "px";
	
	// set mouseover functions for div
	// when mouse pointer leaves div, set a timeout to remove the list after an interval
	// when mouse enters div, kill the timeout so the list won't be removed
	//
	div.onmouseover 	= function(){ p.killTimeout() };
	div.onmouseout 		= function(){ p.resetTimeout() };
	
	// add DIV to document
	document.getElementsByTagName("body")[0].appendChild(div);
	
	// highlight first item
	this.iHigh = 1;
	this.setHighlight(1);
	
	// remove list after interval
	//this.toID	= setTimeout(function () {p.clearSuggestions() },this.options.timeout);
	
  },
  //----------------------------------------------------------------
  changeHighlight:	function(key)
  {
  	var list = $("ac_ul");
	if (!list)
		return false;
	
	var n;

	n = (key == Event.KEY_DOWN || key == Event.KEY_TAB)? this.iHigh + 1 : this.iHigh - 1; // false assumed to be Event.KEY_UP
	
	n = (n > list.childNodes.length)? list.childNodes.length : ((n < 1)? 1 : n);	
	
	this.setHighlight(n);
  },
  setHighlight:		function(n)
  {
  	var list = $('ac_ul');
  	
  	if (!list) return false;
  	
  	if (this.iHigh > 0) this.clearHighlight();
  	
  	this.iHigh = Number(n);
  	
  	list.childNodes[this.iHigh-1].className = 'ac_highlight';
  	
  	this.killTimeout();
  },
  clearHighlight:	function()
  {
  	var list = $('ac_ul');
  	
  	if(!list) return false;
  	
  	if(this.iHigh > 0)
  	{
  		list.childNodes[this.iHigh-1].className = '';
  		this.iHigh = 0;
  	}
  	
  },
  setHighlightedValue:	function()
  {
  	if (this.iHigh)
  	{
		
  		// HERE WE NEED TO IMPLEMENT THE GMAIL LIKE SPLITTED VALUE
  		if (!this.aSug[this.iHigh - 1]) return;
		if(this.fld.name != "tagselectsearch"){
  			if(this.aSug[ this.iHigh -1 ].id != 'addnew') this.sInp	= this.fld.value = this.aSug[ this.iHigh -1 ].value;
  		
  		// move cursor to end of input (safari)
  			this.fld.focus();
  			if(this.fld.selectionStart)	this.fld.setSelectionRange(this.sInp.length, this.sInp.length);
  		}
		this.fld.focus();
  		this.clearSuggestions();
  		
  		// pass selected object to callback function, if exists
  		if (typeof this.options.callback == 'function')
  			this.options.callback(this.aSug[this.iHigh-1]); // the object has the properties we want, it will depend of
		//if(this.aSug[ this.iHigh -1 ].id == 'addnew') createNewTag(1, this.fld.value);
  	}
  },
  killTimeout:	function()
  {
//  	clearTimeout(this.toID);
  },
  resetTimeout:	function()
  {
//  	this.killTimeout();
//  	var p = this;
//  	this.toID = setTimeout(function () { p.clearSuggestions();});
  },
  clearSuggestions:	function ()
  {
	
	this.killTimeout();
	$(this.acID).remove();
	//if ($(this.acID)){this.fadeOut(300,function () {$(this.acID).remove();});}
  },
  fadeOut:	function (milliseconds, callback)
  {
  	this._fadeFrom 	= 1;
  	this._fadeTo	= 0;
  	this._afterUpdateInternal = callback;
  	
  	this._fadeDuration	= milliseconds;
  	this._fadeInterval = 50;
  	this._fadeTime = 0;
  	var p = this;
  	this._fadeIntervalID = setInterval(function() {p._changeOpacity()},this._fadeInterval);
  
  },
  _changeOpacity: function() {
 
 	if (!$(this.acID)){
  		this._fadeIntervalID=clearInterval(this._fadeIntervalID);
  		return;
  	} 
  	this._fadeTime += this._fadeInterval;
  	
  	var ieop = Math.round( (this._fadeFrom + ((this._fadeTo - this._fadeFrom) * (this._fadeTime/this._fadeDuration))) * 100)
  	var op = ieop / 100;
  	
 
  	var el = $(this.acID);
  	if (el.filters) // internet explorer
	{
		try
		{
			el.filters.item("DXImageTransform.Microsoft.Alpha").opacity = ieop;
		} catch (e) { 
			// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
			el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+ieop+')';
		}
	}
	else // other browsers
	{
		el.style.opacity = op;
	}
	
	if (this._fadeTime >= this._fadeDuration)
	{
		clearInterval( this._fadeIntervalID );
		if (typeof this._afterUpdateInternal == 'function')
			this._afterUpdateInternal();
	}

  }
 
}

function tag_ajaxselect_search(who){
		var currentVal = $('tagselectsearch').value;

		if (currentVal.indexOf(",") > -1) {
			var regExp = /,[^,]+$/gi;
			currentVal = currentVal.replace(regExp, ', ' + who.value);
		} else {
			currentVal = who.value;
		}

		$('tagselectsearch').value = currentVal + ', ';		
		
		return false;
	}
function tag_ajaxselect_search_field(who, fieldname){
	var currentVal = $(fieldname).value;

	if (currentVal.indexOf(",") > -1) {
		var regExp = /,[^,]+$/gi;
		currentVal = currentVal.replace(regExp, ', ' + who.value);
	} else {
		currentVal = who.value;
	}

	$(fieldname).value = currentVal + ', ';		
	
	return false;
}
function tag_ajaxselect_search_direct(tagtitle, fieldname){
	var currentVal = $(fieldname).value;

	if (currentVal.indexOf(",") > -1) {
		var regExp = /,[^,]+$/gi;
		currentVal = currentVal.replace(regExp, ', ' + tagtitle);
	} else {
		currentVal = tagtitle;
	}

	$(fieldname).value = currentVal + ', ';		
}