﻿var autoCompleteControl			= function( )
{
	var	self					= this ;
	
	self.base					= baseClass ;
	self.base( ) ;
	
	var baseInitalise			= self.initalise ;
	self.name					= "Auto Complete Control" ;
	
	self.delimter				= ";" ;
	self.valueArray				= self.delimter.split( self.delimter ) ;
	self.lastValue				= "" ;
	self.lastProcessedValue		= "" ;
	self.minimumEntryLength		= 3 ;
	self.url					= "" ;
	self.imageSource			= 'hourglas.gif' ;
	self.errorImageSource		= 'error.gif' ;
	
	self.itemName				= "Item" ;
	self.updateTimer			= null ;
	self.enableAutomaticNewCreation	= false ;

	self.isDone					= true ;
	self.useButtonEventFiring	= false ;
	self.useWebservice			= false ;
	self.useDisplayQueryImage	= true ;
	self.hasErrors				= false ;

	self.autoCompleteControl	= null ;
	self.displayControl			= null ;
	self.valueControl			= null ;
	self.imageControl			= null ;
	self.goButtonControl		= null ;
	
	self.http					= null ;
	self.isDebugMode			= false ;
	
	self.onGetSoapEnvelope		= function( value ){ return "" ; } ;
	self.onGetPostData    		= function( value ){ return "" ; } ;
	
	self.getAjaxResult			= function( searchString )
	{
		self.lastValue			= self.displayControl.value; 
		if ( searchString.length >= self.minimumEntryLength && self.lastProcessedValue != searchString && self.isDone == true && ( !self.useButtonEventFiring || ( self.useButtonEventFiring && self.goButtonControl.value == "go" ) ) )
		{
			self.lastProcessedValue		= self.displayControl.value ;
			self.isDone			= false;
			// cache buster
			var randomNumber	= parseFloat( Math.random() * 99999999 ) ;
			self.http			= getHTTPObject( ) ;
			self.http.onreadystatechange		= self.handleHttpResponse ;
			if ( self.useWebservice )
			{
				self.http.open( "POST" , self.url , true ) ;
				self.http.setRequestHeader( "MessageType" , "CALL" ) ;
				self.http.setRequestHeader( "Content-Type" , "text/xml" ) ;
				self.http.send( self.getSoapEnvelope( self.lastValue ) );
			}
			else if( self.usePostBack )
			{
				self.http.open( "POST" , self.url + "/" + self.member, true ) ;
				self.http.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
				self.http.send( self.getPostData( self.lastValue ) ) ;
			}
			else
			{
			  self.http.open( "GET" , self.url + "/" + self.member + "?" + self.getPostData( self.lastValue ), true );
			  self.http.send( null );
			}
			return true ;
		}
		else if ( searchString.length < 1 && self.minimumEntryLength == true ) 
		{
			self.valueArray		= ";".split( ";" ) ;
			self.autoCompleteControl.close( ) ;
			self.isDone			= true; 
			document.body.style.cursor = 'auto' ; 
			self.displayControl.style.cursor = 'auto'; 
		}
		else if ( self.useButtonEventFiring )
		{
			self.autoCompleteControl.close( ) ;
		}
		return false ;
	} ;
	
	self.handleHttpResponse		= function( )
	{
		if ( self.http.readyState == 4 || self.http.readyState == 'complete' )
		{
			var strResponse = self.http.responseText ;
			switch ( self.http.status )
			{
				case 404 : // Page-not-found error
					alert( 'Error: Not Found. The requested function could not be found.' ) ;
					self.isDone	= true ; 
					break ;
				case 500 : // Display results in a full window for server-side errors
					self.handleFullPageError( strResponse ) ;
					break ;
				default:
					if ( strResponse.toLowerCase().indexOf( "the service you requested is unavailable at this time" ) > -1) 
					{ 
						self.handleFullPageError( strResponse ) ;
					} 
					else if ( strResponse.toLowerCase().indexOf( "the page you were looking for could not be found" ) > -1) 
					{ 
						alert( 'Error: Not Found. The requested function could not be found.' ) ; 
						self.isDone	= true; 
					} 
					else 
					{ 
						if ( strResponse.indexOf( "<?xml" ) < 0 ) 
						{ 
							// 
						} 
						else
						{ 
						  if(self.useWebservice)
							  strResponse		= self.http.responseXML.documentElement.childNodes[ 0 ].childNodes[ 0 ].childNodes[ 0 ].childNodes[ 0 ].nodeValue ;
							else
							  strResponse		= self.http.responseXML.documentElement.childNodes[ 0 ].nodeValue ;
						} 
						self.processResponse( strResponse ) ;
					} 
					break ;
			} 
		} 
		return true ;
	} ;

	self.handleFullPageError 	= function ( errorMessage )
	{ 
		if ( self.isDebugMode == true ) 
		{ 
			self.autoCompleteControl.setOptions( self.delimter.split( self.delimter ) ) ;
			if ( self.useDisplayQueryImage )
			{
				self.imageControl.src				= self.errorImageSource ;
				document.body.style.cursor			= 'auto' ;
				self.displayControl.style.cursor	= 'auto' ;
			}
			self.hasErrors		= true; 
			var errorWin ;
			// Create new window and display error 
			try
			{
				errorWin = window.open( '' , 'errorWin' ); 
				errorWin.document.body.innerHTML = errorMessage; 
			} 
			// If pop-up gets blocked, inform user
			catch ( e ) 
			{
				alert( 'An error occurred, but the error message cannot be displayed because of your browser\'s pop-up blocker.\nPlease allow pop-ups from this Web site.' ) ;
				alert( strIn ) ; 
			} 
		} 
		else 
		{ 
			alert( 'Error: There was an error processing your request.' ) ;
		} 
		return false ;
	} ;
	
	// This should be overriden with some external 
	self.getSoapEnvelope		= function( value )
	{
		return					self.onGetSoapEnvelope( value )  ; 
	} ;
		
	self.getPostData        = function( value )
	{
	  return          self.onGetPostData( value ) ;
	} ;
	
	self.processResponse		= function( response )
	{
		if ( response.length == 0 )
		{
			self.valueArray		= self.delimter.split( self.delimter ) ;
		}
		else
		{
			self.valueArray		= response.split( self.delimter ) ;
		}
		self.isDone				= true ;
		self.updateArray( ) ; 
	} ;
	
	self.updateArray			= function( )
	{
		if ( self.hasErrors )
		{
			clearTimeout( self.updateTimer ) ;
			self.hasErrors		= false;
			self.isDone			= true;
		}
		else
		{ 
			self.autoCompleteControl.close( ) ;
			self.autoCompleteControl.setOptions( self.valueArray ) ;
			self.autoCompleteControl.open( ) ;
			if ( self.useDisplayQueryImage )
			{
				self.imageControl.style.visibility	= 'hidden' ;
				document.body.style.cursor			= 'auto' ;
				self.displayControl.style.cursor	= 'auto' ;
			}
			clearTimeout( self.updateTimer ) ;
			self.isDone			= true; 
			if ( self.lastValue != self.lastProcessedValue ) 
			{
				self.autoCompleteControl.close( ) ;
				self.autoCompleteControl.ongetoptions( ) ;
			}
		}
	} ;

	self.makeAutoComplete = function( element , elementHid , array, sNew){

//	var obj	= this;
	var myZIndex = makeAutoCompleteCount;
	var obj	= element;
	obj.options	= array.sort();
	obj.size = 10;
	var div = document.createElement('SPAN');
	div.className	= "autoCompleteFrame"
	div.style.position = 'relative';
	element.autoComplete = "off";
	element.setAttribute("autocomplete","off");

	// Hack for IE else size dosn't work
	element.style.position = 'relative';
	div.innerHTML	= '<select size="2"><option></option></select>';
	var select = div.getElementsByTagName('SELECT')[0];
	element.parentNode.insertBefore( div, element );
	div.appendChild(element);

	select.style.zIndex = myZIndex;
	element.style.zIndex = myZIndex - 1;
	div.style.zIndex = myZIndex - 2;
	var diff = 3;
	if ( browser.isIE ) //IE does bizarre things with zIndexes and positioned elements, so we need to do bizarre things to make this work in IE
	{
		div.parentNode.style.zIndex = myZIndex - diff;
		var par = element.parentNode;
		diff += 1;
		while(par.parentNode && par.className != "osAnswer")
		{
			par = par.parentNode;
			if(par.nodeName == "TR"){
				par.style.zIndex = myZIndex - diff;
				diff += 1;
			}
		}
		if(par.className = "osAnswer")
			par.style.zIndex = myZIndex - diff;
	}
	makeAutoCompleteCount = makeAutoCompleteCount - diff - 1;
	
	select.className = "autoCompleteSelect";
	select.style.position	= 'absolute';
	select.style.top = 22 +'px';
	select.style.left = 0 + 'px';
	select.style.visibility	= 'hidden';
	select.options.length	= 0;

	var option = document.createElement('OPTION');
	select.appendChild( option );		
	
	addEvent( element,	'keyup',	function(e){obj.open( e );});
	addEvent( element,	'keydown',	ElementKeyDown);
	addEvent( element,	'dblclick',	function(){obj.open(null,true);});
	addEvent( select,	'click',	SelectClick);
	addEvent( select,	'keyup',	SelectKeyUp);
	addEvent( document,	'click',	DocClick);

	obj.name = element.id;
	obj.element = element;
	obj.elementHid = elementHid;
	obj.select = select;
		
	function DocClick( e )
	{
		if ( browser && !browser.isSafari )
		{
			var el = e.target || e.srcElement ;
			var close		= true ;
			while( el.parentNode )
			{
				if( el == select || el == element )
				{
					return	true ;
				}
				el			= el.parentNode ;
			}
			obj.close( ) ;
		}
		return	true ;
	} ;

	function SelectKeyUp(e){
		if(e.keyCode == 13){
			SelectClick(e);
			return false;
		}
	};

	function ElementKeyDown(e){
		if(e.keyCode == 40 && select.options.length > 0){
			select.focus();
		}
		if(e.keyCode == 9 && select.options.length > 0){
			obj.close();
		}
	};

	function SelectClick(e){
	  if(e && e.keyCode != 13)
	    ajaxValidation = false; //if not enter key then reenable form submission.
	    
		if (select.value == "(*)~%"){
			obj.close();
			addNew(element, elementHid, element.value);
			return false;
		}
		if(select.selectedIndex >= 0 && select.options.length > 0){
			elementHid.value = select.value + ";" + select.options[select.selectedIndex].text + ";" + select.options[select.selectedIndex].components;
		}
		obj.close();
		try	{
			if( element.select ) {
				element.select( ) ;
			}
		}
		catch( ex ) { }
		element.focus();
		// Tie in validator
		if(element.validate) element.validate();
	};

	obj.ongetoptions = function(){
	};

	obj.setOptions = function( array ){
		obj.options = array;
	};
	obj.getOptions = function(){
		return obj.options;
	};
	
	obj.close = function() {
		select.options.length	= 0 ;
		select.style.visibility	= 'hidden' ;
	};

	obj.open = function(e, open){
	  //appleWebKit browsers (Safari, Google Chrome) seem to have a problem where hitting enter to select an address ignores the procedures we have to prevent the form from submitting. 
	  //the ajaxValidation value will cause the click events on the buttons to return false, killing form submission.
		if(browser && (browser.isSafari || browser.isAppleWebKit))
		  ajaxValidation = true;
		  
		// On tab focus do not process
		if(e && e.keyCode == 9) 
		  return false;

		var text = element.value.toLowerCase();
		obj.ongetoptions( ) ;
		
		var matches = obj.options;
		
		if (element.value.length > 0 && sNew) {
			matches[matches.length] = "(*)~%";
			matches[matches.length] = "Add New " + itemName;
		}
		
		try
		{
  		select.options.length = 0;
		}
		catch( e ){}
		if((open || text.length > 0) && matches.length % 3 == 0){
			for(var i=0;i<matches.length;i+=3){
				var oValue	= matches[i]; //Row ID
				var oText	= matches[i+1]; //Text
				var oComp = matches[i+2]; //Components
				if (oValue.length > 0 || oText.length > 0){
					var option = document.createElement('OPTION')
					option.innerHTML = oText;
					option.value = oValue;
					option.components = oComp;
					select.appendChild( option );
				}
				//i ++
			}
		}

		select.selectedIndex = -1;
		if(select.options.length > 0){
			select.size = select.options.length > obj.size ? obj.size : 
							(select.options.length > 1 ? select.options.length : 2);
			
			select.style.visibility = 'visible';
		}else{
			obj.close();
		}

		if(e && e.keyCode == 13){
			SelectClick();
		}
	}

	return obj;
};

	self.initalise				= function( )
	{
		// Must set the response of this into a variable or the method will itself return true and not continue.
		var isOK		= baseInitalise( ) ;
		
		self.autoCompleteControl = self.makeAutoComplete( self.displayControl , self.valueControl , self.valueArray , self.enableAutomaticNewCreation ) ;
		if ( self.autoCompleteControl )
		{
			self.autoCompleteControl.size	= "20" ;
			self.autoCompleteControl.ongetoptions	= function( ) 
			{
				if ( self.useDisplayQueryImage )
				{
					self.imageControl.src				= self.imageSource ;
					self.imageControl.style.visibility	= 'visible' ;
					document.body.style.cursor			= 'wait' ;
					self.displayControl.style.cursor	= 'wait' ;
				}
				self.getAjaxResult( self.displayControl.value ) ;
			} ;
			isOK		= true ;
		}
		else
		{
			isOK		= false ;
		}
		
		return isOK ;
	} ;

	return true ;
} ;

var makeAutoCompleteCount = 500;