function suggest_box () {
	var oField=null;
	var oButton=null;
	var oDropDown=null;

	var oValueField=null;

	var aValues=null;
	var aMatches=null;
	
	var oTopScreenObject=null;
	var tSelectedClass=null;
	var tUnSelectedClass=null;
}

function suggest_box ( vField, vButton, vDropDown, vValueField, vTopScreenObject, tSelectedClass, tUnSelectedClass ) {
	var oField=GetElementByID(vField);
	var oButton=GetElementByID(vButton);
	var oDropDown=GetElementByID(vDropDown);

	var oValueField=GetElementByID(vValueField);
	
	var aValues=new Array();
	var aMatches=new Array();

	var oTopScreenObject=GetElementByID(vTopScreenObject);

	this.clear_matches=function () { aMatches=new Array(); };
	
	this.clear_values=function () { aValues=new Array(); this.clear_matches(); };
	
	this.add_value=function ( tValue, tDescr ) {
		var i=aValues.length;
		if ( typeof tDescr == "undefined" )
			tDescr=tValue;
		aValues[i]=new Array();
		aValues[i][0]=tValue;
		aValues[i][1]=tDescr;
	};
	
	this.get_matches=function () {
		var i, j;
		if ( oField.value == '' ) {
			this.clear_matches();
			for ( i=0; i < aValues.length; i ++ ) {
				aMatches[i]=new Array();
				aMatches[i][0]=aValues[i][0];
				aMatches[i][1]=aValues[i][1];
			}
		} else {
			this.clear_matches();
			for ( i=0, j=0; i < aValues.length; i ++ ) {
				if ( aValues[i][1].indexOf(oField.value) != -1 ) {
					aMatches[j]=new Array();
					aMatches[j][0]=aValues[i][0];
					aMatches[j][1]=aValues[i][1];
					j ++;
				}
			}
		}
	};
	
	this.get_exact_match=function () {
		var i, bMatch=false;
		for ( i=0; i < aMatches.length; i ++ ) {
			if ( oField.value == aMatches[i][1] ) {
				oValueField.value=aMatches[i][0];
				bMatch=true;
				break;
			}
		}
		if ( !bMatch )
			oValueField.value='CUSTOM';
	};
	
	this.get_selected_row=function () {
		var i, oRow, nReturn=-1;
		for ( i=0; i < aMatches.length; i ++ ) {
			if (( oRow=GetElementByID(oDropDown.id+'_'+i)) ) {
				if ( oRow.className == tSelectedClass ) {
					nReturn=i;
					break;
				}
			} else
				break;
		}
		return ( nReturn );
	};
	
	this.select_row=function ( nRow ) {
		var i, oRow, tClass;
		if ( nRow < 0 )
			nRow=aMatches.length-1;
		else if ( nRow > aMatches.length-1 )
			nRow=0;
		for ( i=0; i < aMatches.length; i ++ ) {
			if ( i == nRow )
				tClass=tSelectedClass;
			else
				tClass=tUnSelectedClass;
			oRow=GetElementByID(oDropDown.id + '_' + i);
			if ( oRow.className != tClass )
				oRow.className=tClass;
		}
	};
	
	this.hide_list=function () {
		oDropDown.style.display='none';
	};
	
	this.show_list=function () {
		if ( oDropDown.innerHTML == '' || oDropDown.innerHTML == '<em>No matches.</em>' ) {
			this.get_matches();
			this.refresh_list();
		}
		oDropDown.style.display='';
	};
	
	this.toggle_list=function () {
		if ( oDropDown.style.display == '' )
			this.hide_list();
		else {
			this.clear_matches();
			for ( i=0; i < aValues.length; i ++ ) {
				aMatches[i]=new Array();
				aMatches[i][0]=aValues[i][0];
				aMatches[i][1]=aValues[i][1];
			}
			this.refresh_list();
			this.show_list();
		}
		oField.focus();
	};

	this.refresh_list=function ( bCompare ) {
		var i, oRow, that=this;
		if ( aMatches.length == 0 )
			oDropDown.innerHTML='<em>No matches.</em>';
		else {
			var bEqual=false;
			if ( bCompare ) {
				bEqual=true;
				for ( i=0; i < aMatches.length; i ++ ) {
					oRow=GetElementByID(oDropDown.id+'_'+i);
					if ( !oRow || oRow.innerHTML != aMatches[i][1] ) {
						bEqual=false;
						break;
					}
				}
			}
			if ( !bEqual ) {
				oDropDown.innerHTML='';
				for ( i=0; i < aMatches.length; i ++ ) {
					oRow=document.createElement('div');
					oRow.id=oDropDown.id + '_' + i;
					oRow.className=tUnSelectedClass;
					Event.add(oRow,"click",function () { 
						var i=that.get_selected_row();
						if ( oValueField )
							oValueField.value=aMatches[i][0];
						oField.value=aMatches[i][1];
						oField.focus();
						that.hide_list();
					});
					Event.add(oRow,"mouseout",function () { 
						this.className=tUnSelectedClass; 
					});
					Event.add(oRow,"mouseover",function () { 
						this.className=tSelectedClass; 
						this.style.cursor='hand';
						this.style.cursor='pointer';
					});
					oRow.innerHTML=aMatches[i][1];
					oDropDown.appendChild(oRow);
				}
			}
		}
	};

	this.key_up=function ( event ) {
		var nRow, nKeyCode=event.keyCode;
	
		if ( nKeyCode == 27 ) {
			this.hide_list();
			return;
		}
		
		if ( nKeyCode == 13 ) {
			this.get_matches();
			nRow=this.get_selected_row();
			if ( nRow > -1 ) {
				if ( oValueField )
					oValueField.value=aMatches[nRow][0];
				oField.value=aMatches[nRow][1];
				oField.focus();
				this.hide_list();
			} else
				this.show_list();
			return;
		}
		
		if ( nKeyCode == 38 ) {		// up arrow
			this.get_matches();
			nRow=this.get_selected_row();
			if ( nRow == -1 ) {
				this.refresh_list();
				this.select_row(aMatches.length-1);
			} else
				this.select_row(nRow-1);
			this.show_list();
			return;
		}
		
		if ( nKeyCode == 40 ) {		// down arrow
			this.get_matches();
			nRow=this.get_selected_row();
			if ( nRow == -1 ) {
				this.refresh_list();
				this.select_row(0);
			} else {
				this.refresh_list(true);
				this.select_row(nRow+1);
			}
			this.show_list();
			return;
		}

		if ( nKeyCode == 8 || nKeyCode == 46 ) {
			this.get_matches();
			this.refresh_list();
			this.show_list();
			this.get_exact_match();
			return;
		}
		
		if ( nKeyCode < 32 || ( nKeyCode >= 33 && nKeyCode <= 46 ) || ( nKeyCode >= 112 && nKeyCode <= 123 ))
			return;
		
		this.get_matches();
		this.refresh_list();
		this.show_list();
		this.get_exact_match();
	};

	oDropDown.style.display='none';
	oDropDown.style.top='-1000px';
	oDropDown.style.left='-1000px';
	oDropDown.style.overflow='auto';
	oDropDown.style.top=oField.offsetTop+oField.offsetHeight+'px';
	oDropDown.style.left=oField.offsetLeft+'px';
	oDropDown.style.width=oField.offsetWidth*1.5+'px';
	
	
	var oTraverse=oField;
	var nOffsetTop=oField.offsetHeight, nOffsetLeft=0;

	while ( oTraverse ) {
		nOffsetTop=nOffsetTop+oTraverse.offsetTop;
		nOffsetLeft=nOffsetLeft+oTraverse.offsetLeft;
		oTraverse=oTraverse.offsetParent;
		if ( oTraverse == oTopScreenObject )
			break;
	}

	oDropDown.style.top=nOffsetTop+'px';
	oDropDown.style.left=nOffsetLeft+'px';
}
