/*
var XmlHttp = false;

if ( window.XMLHttpRequest ) 
{
	XmlHttp = new XMLHttpRequest();

} else if ( window.ActiveXObject )
{
	XmlHttp = new ActiveXObject( 'Microsoft.XMLHTTP' );
}
*/

// ---

function GSInstance( aReference, aControlID, aValueControlID ) {
	this.reference = aReference;
	this.controlID = aControlID;
	this.valueControlID = aValueControlID;
}

var Instances = new Array( 0 );


function getGSIndexByReference( ref ) {
	for ( var i = 0; i < Instances.length; i++ ) {
		if ( Instances[i].reference == ref ) {
			return i;
		}
	}
	return 0;
}

function getGSReferenceByIndex( index ) {
	return Instances[index].reference;
}


// ---

function GSClass( aControlID, aLink, aContentID, aValueControlID ) {

	this.m_ControlID      = aControlID;
	this.m_ValueControlID = aValueControlID;
	this.m_Link           = aLink;
	this.m_ContentID      = aContentID;
	this.m_SearchText     = "";
	//

	this.m_Data     = new Array();
	this.m_Values   = new Array();
	this.m_NumberOfRecords = 0;

	this.m_IsContentVisible = false;
	this.m_IsCursorEnabled  = false;
	this.m_CursorIndex      = 0;

	//

	this.MoveCursorUp   = GSMoveCursorUp;
	this.MoveCursorDown = GSMoveCursorDown;

	// methods

	this.ShowContent    = GSShowContent;
	this.WriteContent   = GSWriteContent;
	this.InitValues     = GSInitValues;
	this.Attach         = GSAttach;
	this.Clear          = GSClear;

	this.doMyKeyUp    = GSOnKeyUp;
	this.doMyKeyDown  = GSOnKeyDown;
	this.doMyBlur     = GSOnBlur;
	this.doMyFocus    = GSOnFocus;

	// onload
	this.Clear();
	this.Attach();

	// register ourselves in the instances array for the static functions
	Instances.splice( Instances.length, 0, new GSInstance( this, this.m_ControlID, this.m_ValueControlID ) );
}


function GSClear() {
	this.ShowContent( false );

	this.m_IsCursorEnabled  = false;
	this.m_CursorIndex      = 0;
	this.m_SearchText       = "";
}


function GSSelectIndex( selIndex, gsIndex ) {

	var gs = getGSReferenceByIndex( gsIndex );
	gs.m_CursorIndex = selIndex;
	gs.m_IsCursorEnabled = true;

	var anObject = GetObjectByID( gs.m_ControlID );

	var o = document.getElementById( gs.m_ValueControlID );
	if ( o ) {
		o.value = gs.m_Values[gs.m_CursorIndex];
		anObject.value = gs.m_Data[gs.m_CursorIndex ];
	}

	gs.WriteContent();
}


function GSMoveCursorUp() {
	this.m_CursorIndex --;
	if ( this.m_CursorIndex < 0 ) {
		this.m_IsCursorEnabled = false;
		this.m_CursorIndex     = 0;
	}

	var o = document.getElementById( this.m_ValueControlID );
	if ( o ) {
		o.value = this.m_Values[this.m_CursorIndex];
	}

	this.WriteContent();
}



function GSMoveCursorDown() {
	if ( !this.m_IsCursorEnabled ) {
		this.m_IsCursorEnabled = true;
		this.m_CursorIndex = 0;
	} else {
		this.m_CursorIndex ++;
		if ( this.m_CursorIndex >= this.m_NumberOfRecords ) {
			this.m_CursorIndex = this.m_NumberOfRecords - 1;
		}
	}

	var o = document.getElementById( this.m_ValueControlID );
	if ( o ) {
		o.value = this.m_Values[this.m_CursorIndex];
	}

	this.WriteContent();
}


function GSOnKeyUp( e ) {

	var theKey = 0;
	anObject = GetObjectByID( this.m_ControlID );
	if ( !e ) var e = window.event;
	theKey = e["keyCode"];

	if ( theKey == 40 ) return;
	if ( theKey == 38 ) return;
	if ( theKey == 27 ) return;

	if ( anObject.value.length < 1 ) {
		this.ShowContent( false );

	} else {

		if ( !this.m_IsContentVisible ) {
			this.WriteContent();
			this.ShowContent( true );
		}

		if ( this.m_SearchText != anObject.value ) {
			this.m_SearchText = anObject.value;
			var theLink = this.m_Link + this.m_SearchText + "&anticache=" + Math.random();

			this.m_CursorIndex = 0;

			this.InitValues( GetFileContent( theLink ) );
			this.WriteContent();

			if ( !this.m_IsContentVisible ) this.ShowContent( true );
		}
	} // end of if anobject.value.length < 1

}


function GSOnKeyDown( e ) {

	var theKey = 0;
	anObject = GetObjectByID( this.m_ControlID );
	if ( !e ) var e = window.event;
	theKey = e["keyCode"];

	// down
	if ( theKey == 40 && this.m_IsContentVisible ) {
		this.MoveCursorDown();
		anObject.value = this.m_Data[ this.m_CursorIndex ];
	}

	// up
	if ( theKey == 38 && this.m_IsContentVisible ) {
		this.MoveCursorUp();	
		anObject.value = this.m_Data[ this.m_CursorIndex ];
	}

	// escape pressed ?
	if ( theKey == 27 && this.m_IsContentVisible ) {
		anObject.value = "";
		this.Clear();
	}
}



function GSOnBlur() {
	SetObjectVisibility( this.m_ContentID, false );
}


function GSOnFocus() {
	if ( this.m_IsContentVisible ) {
		SetObjectVisibility( this.m_ContentID, true );
	}
}



function GSAttach() {
	var theObject = GetObjectByID( this.m_ControlID );

	// position teh content div under the control

	x = GetObjectLeft( this.m_ControlID );
	y = GetObjectTop( this.m_ControlID );
	height = GetObjectHeight( this.m_ControlID );

	SetObjectPosition( this.m_ContentID, x, y + height );

	// hook the control events we need. events need to be attached to "this" before hooking the control

	theObject.onkeydown = GSOnKeyDownStatic;
	theObject.onkeyup   = GSOnKeyUpStatic;
	theObject.onblur    = GSOnBlurStatic;
	theObject.onfocus   = GSOnFocusStatic;
}



function GSInitValues( aString ) {

	if ( !aString || aString == "" ) {
		this.m_Data = new Array();
		this.m_NumberOfRecords = 0;
		this.ShowContent( false );
	} else {

		var dataStrings = String( aString ).split( "#" );
		if ( dataStrings.length > 1 ) {
			this.m_Values = String( dataStrings[1] ).split( "|" );
			this.m_Data   = String( dataStrings[0] ).split( "|" );
		} else {
			this.m_Data = String( aString ).split( "|" );
		}
		this.m_NumberOfRecords = this.m_Data.length;
		this.WriteContent();
		this.ShowContent( true );
	}
}



function GSShowContent( aState ) {
	this.m_IsContentVisible = aState;
	SetObjectVisibility( this.m_ContentID, aState );
}



function GSWriteContent() {

	var theObject = GetObjectByID( this.m_ContentID );
	var theContent = new String();
	theContent = "<table cellspacing=\"0\" cellpadding=\"0\" class=\"suggest\">";

	var gsIndex = getGSIndexByReference( this );

	for ( var i = 0; i < this.m_NumberOfRecords; i++ ) {
		var theTDClass = ( this.m_IsCursorEnabled && i == this.m_CursorIndex ) ? "over" : "";
		theContent += "<tr><td onmouseover=\"GSSelectIndex( " + i + ", " + gsIndex + " );\" class=\"" +  theTDClass + "\">" + this.m_Data[i] + "</td></tr>";
	}

	theContent += "</table>";
	theObject.innerHTML = theContent;
}


/*
function GetFileContent( url )
{
	alert(url);
	XmlHttp.open( "GET", url, false ); // sync request
	XmlHttp.send( null );
	return ( XmlHttp.responseText );
}
*/

function GSOnKeyDownStatic( e ) {
	// look for our instance and route the event
	for ( var i = 0; i < Instances.length; i++ ) {
		if ( Instances[i].controlID == this.id ) {
			Instances[i].reference.doMyKeyDown( e );
			break;
		}
	}
}


function GSOnKeyUpStatic( e ) {
	// look for our instance and route the event
	for ( var i = 0; i < Instances.length; i++ ) {
		if ( Instances[i].controlID == this.id ) {
			Instances[i].reference.doMyKeyUp( e );
			break;
		}
	}
}


function GSOnBlurStatic() {
	// look for our instance and route the event
	for ( var i = 0; i < Instances.length; i++ ) {
		if ( Instances[i].controlID == this.id ) {
			Instances[i].reference.doMyBlur();
			break;
		}
	}
}

function GSOnFocusStatic() {
	// look for our instance and route the event
	for ( var i = 0; i < Instances.length; i++ ) {
		if ( Instances[i].controlID == this.id ) {
			Instances[i].reference.doMyFocus();
			break;
		}
	}
}