//--------------------------------------------------
var AC_isIE;
var AC_isGecko;
var AC_isSafari;
var AC_isOther; // safest bet is to try what one would try under Gecko

// in general, the AutoComplete code prefers to make "capability tests"
// instead of browser inspection.  e.g., "if ( event.srcElement != null )"

function AC_DetectBrowser( )
{
	var ua = navigator.userAgent.toLowerCase();

	AC_isGecko = ( navigator.product == 'Gecko' );
	AC_isIE = !AC_isGecko && ( ua.indexOf ( "msie" ) != -1 );
	AC_isSafari = !AC_isGecko && !AC_isIE && ( ua.indexOf ( "safari" ) != -1 );
	AC_isOther = !AC_isGecko && !AC_isIE && !AC_isSafari;
}

AC_DetectBrowser ();


// --------------------------------------------------

var AC_useTable=true;


var AC_targetElements;
var AC_insertEmailsOnly;

var AC_allCanons = [];
var AC_allControls = [];
var AC_loadURL = [];
var AC_allMinChars = [];
var AC_allWidth = [];

var AC_allFields = [];
var AC_allValues = [];

var AC_allSelectFunction = [];

var currentControlIndex;


// --------------------------------------------------

var AC_MaxResultItems 	= 30;
var AC_MaxVisibleItems	= 12;

// --------------------------------------------------



function AC_OnLoad( control_name, list, url, minChars, width, fnct )
{
	if ( typeof window.AC_listStr == "undefined" || window.AC_listStr == null || window.AC_listStr.length == 0 )
	{
		window.AC_listDisplayStr = "";
	}
	else
	{
		window.AC_listDisplayStr = " (" + window.AC_listStr + ")";
	}

	AC_allCanons[AC_allCanons.length] = list==null?new Array():list ;
	AC_loadURL[AC_loadURL.length] = url;
	AC_allWidth[AC_allWidth.length] = width;
	AC_allMinChars[AC_allMinChars.length]=minChars==null?1:minChars;
	AC_allSelectFunction[AC_allSelectFunction.length]=fnct;

	var field = window.document.getElementById( control_name );
	AC_allControls[AC_allControls.length] = field;

	if ( field != null )
	{
		field.autocomplete = "off";
		field.onkeydown = AC_OnKeyDown;
		field.onkeypress = AC_OnKeyPress;
		field.onkeyup = AC_OnKeyUp;
		field.onblur = AC_OnBlur;
		field.onselect = AC_OnSelect;
		field.oncut = AC_OnCut;
		field.onpaste = AC_OnPaste;
		field.onclick = AC_OnClick;
	}

	onResize = AC_OnResize( );
	window.AC_loaded = true;
	
}


// suggestion list control and the DIV that contains it
var AC_dropDownDiv = null;
var AC_dropDownList = null;
var AC_dropDownIFrame = null;
var AC_dropDownTable = null;



function setCurControl( editCtrl )
{
	if ( typeof editCtrl == "string" )
	{
		editCtrl = document.getElementById ( editCtrl );
	}

	currentControlIndex = -1;

	for(var i=0; i<AC_allControls.length; i++)
	{ 
		if(AC_allControls[i] == editCtrl)
		{
				currentControlIndex = i;
				break;
		}
	}
}



// --------------------------------------------------  Display utility functions

// add a class to an element
function AC_AddElementClass ( element, className ) {
	// don't add duplicates
	if ( element && element.className.indexOf (className) == -1 )
		element.className += " " + className;
}


// remove a class from an element
function AC_RemoveElementClass ( element, className )
{
	if ( element == null ) return;

	var loc = element.className.indexOf (className);
	if ( loc == -1 ) return;

	// grab the preceding and following string fragments
	element.className = element.className.substring ( 0, loc ) +
				element.className.substring ( loc + className.length + 1 );
}


// check for a class on an element
function AC_ElementHasClass ( element, className )
{
	return ( element && ( element.className.indexOf (className) != -1 ));
}


// scroll a child's frame into the visible area of a parent
// currently only supports vertical coords.
function AC_ScrollToChild ( parent, indexOrElement )
{
	if ( parent == null || indexOrElement == null ) return;

	var cType = typeof indexOrElement;
	if ( cType == "number" || cType == "string" )
	{
		indexOrElement = AC_useTable?AC_dropDownTable.rows[indexOrElement]:parent.childNodes[indexOrElement];
	}

	if ( indexOrElement == null ) return;

	if ( indexOrElement.offsetTop + indexOrElement.offsetHeight > parent.scrollTop + parent.clientHeight ) {
		parent.scrollTop = indexOrElement.offsetTop + indexOrElement.offsetHeight - parent.clientHeight;
		return; // top takes priority over the bottom
	}

	if ( indexOrElement.offsetTop < parent.scrollTop )
	{
		parent.scrollTop = indexOrElement.offsetTop;
	}
}


function AC_CancelEvent ( event )
{
	event.returnValue = false;
	if ( event.preventDefault )
	{
		event.preventDefault();
	}
}

function AC_GetTarget( event )
{
	if ( event == null )
	{
		event = window.event;
	}

	if ( event == null )
	{
		return null;
	}

	if ( event.srcElement != null ) // IE
	{
		return event.srcElement;
	}

	var retVal = event.target;
	while ( retVal && retVal.nodeType != 1 ) // climb up from text nodes on Moz
	{
		retVal = retVal.parentNode;
	}

	return retVal;
}


//----------------------------------------------------------- Add new control to autocomplete


//------------------------------========================== input HANDLERS =======================------------------START


// --------------------------------------------------


var AC_TAB = 9;
var AC_DELETE = 46;      // removed the currently hilighted suggestion from the list,
	                     // no change to input text (eat the key)
var AC_BACKSPACE = 8;    // delete the character to the left of the caret
var AC_LEFT_ARROW = 37;  // make the selection, end auto-insert
var AC_RIGHT_ARROW = 39; // make the selection, end auto-insert
var AC_HOME = 36;        // go to first suggestion item
var AC_END = 35;         // go to last suggestion item
var AC_PAGE_UP = 33;     // page up in the suggestion list, if visible
var AC_PAGE_DOWN = 34;   // page down in the suggestion list, if visible
var AC_UP_ARROW = 38;    // move the drop down list selection up by one
var AC_DOWN_ARROW = 40;  // move the drop down list selection down by one
var AC_ESC = 27;         // removed list of suggestions, no change to input or hilight
var AC_ENTER = 13;       // make the selection, end auto-insert, move cursor to end of text (eat the key)
var AC_SPACE = 32;       // space bar
var AC_COMMA_KEY = 188;  // comma is the address delimiter
var AC_SEMI_COLON_KEY = 186; // semi-colon is an alternate delimiter
var AC_NBSP = 160;		// ISO 8859-1 and UNICODE non-breaking space
var AC_COMMA = 44;		// ISO 8859-1 and UNICODE comma ','
var AC_SEMI_COLON = 59;	// ISO 8859-1 and UNICODE semi-colon ';'
var AC_SHIFT_KEY = 16;
var AC_CTRL_KEY = 17;
var AC_ALT_KEY = 18;
var AC_LEFT_MS_WINDOWS_KEY = 91; 
var AC_RIGHT_MS_WINDOWS_KEY = 92;
var AC_MS_MENU_KEY = 93;

// Handle Naoki's jp IME.
//
var AC_handledEnter = false;

function AC_OnKeyDown( event )
{
	if ( event == null ) event = window.event;

	var editCtrl = AC_GetTarget ( event );
	if ( editCtrl == null ) return;

	setCurControl( editCtrl );

	var keyCode = event.keyCode;

	AC_handledEnter = false;

	//if ( keyCode != 18 )
	//window.document.form_main.Body.value += "DOWN="+keyCode+" " + String.fromCharCode(keyCode) + " ";

	// ALL PRINTABLE CHARACTERS MUST BE HANDLED IN KEYPRESS

	// do not consume navigation keys when Ctrl or Alt is pressed
	if ( event.ctrlKey || event.ctrlLeft || event.altKey || event.altLeft || event.metaKey )
	{
		// kill the drop down for these navigation operations
		// (would be nice to be smarter... e.g. ctrl-end when
		// already at the end doesn't require dimissal).
		switch ( keyCode )
		{
		case AC_HOME:
		case AC_END:
		case AC_PAGE_UP:
		case AC_PAGE_DOWN:
		case AC_UP_ARROW:
		case AC_DOWN_ARROW:
		case AC_RIGHT_ARROW:
			AC_RemoveDropDown();
			break;
		}

		return;
	}

	var op = null;

	switch(keyCode)
	{
	case AC_LEFT_ARROW:
	case AC_ESC:
		if ( AC_IsActive() )
		{
			AC_RemoveDropDown();
			AC_CancelEvent ( event ); // IE nukes edited text on escape; we want to simply remove the dropdown
		}
		break;

	case AC_HOME:
		op = "selectFirst";
		break;
	case AC_END:
		op = "selectLast";
		break;
	case AC_PAGE_UP:
		op = "selectPrevPage";
		break;
	case AC_PAGE_DOWN:
		op = "selectNextPage";
		break;
	case AC_UP_ARROW:
		op = "selectPrev";
		break;
		
	case AC_DOWN_ARROW:
		if ( AC_IsActive() )
		{
			AC_UpdateDropDown ( editCtrl, "selectNext" );
			AC_CancelEvent ( event );
		}
		else  
		{
			AC_NewDropDown ( editCtrl );
			if ( AC_IsActive() )
			{
				AC_CancelEvent ( event );
			}
		}
		break;

	case AC_TAB:
		// have to trap this in keyDown on IE, but we
		// need to cancel it in keyPress for Moz--
		if ( !AC_isIE ) break;
		// FALL-THRU:
	case AC_RIGHT_ARROW:
		if ( AC_IsActive() )
		{
			AC_InsertSuggestion ( editCtrl );
			AC_CancelEvent ( event );
		}
		break;

	default:
		break;
	}

	if ( AC_IsActive() && op != null )
	{
		AC_UpdateDropDown ( editCtrl, op );
		AC_CancelEvent ( event );
	}
}


function AC_OnKeyPress( event )
{
	if ( event == null ) event = window.event;

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null ) return;

	// only onKeyPress receives the UNICODE value of the key
	var keyCode = event.keyCode;
	if ( keyCode == 0 ) // as it might on Moz
	{
		keyCode = event.charCode;
	}
	
	if ( keyCode == 0 ) // unlikely to get here
	{
		keyCode = event.which;
	}
	
	AC_handledEnter = false;

	//window.document.form_main.Body.value += "PRESS="+keyCode+" "+String.fromCharCode(keyCode)+" ";
	
	// Do not skip out when modifiers are pressed (ctrl, alt, etc.).
	// Many latin characters are generated with alt, and we must process them
	// as ordinary printable key presses, because, well, they are.  Note that 
	// the keyCode value -- the printable character -- will prevent us from
	// doing something silly like inserting the current menu selection when
	// alt-comma is pressed to generate a c-cedilla.

	if ( event.charCode != null && event.charCode == 0 )
	{
		// short version: this is how you tell it's a nav key, not an ASCII char (the values overlap)

		switch ( keyCode )
		{
		case AC_ESC:
		case AC_HOME:
		case AC_END:
		case AC_PAGE_UP:
		case AC_PAGE_DOWN:
		case AC_UP_ARROW:
		case AC_DOWN_ARROW:
		case AC_RIGHT_ARROW:
			// IE cancels all these on keyDown.  need to cancel them on 'press' for Moz.

			if ( !event.ctrlKey && !event.altKey && !event.metaKey && AC_IsActive() )
			{
				AC_CancelEvent ( event );
			}

			// stop processing-- otherwise they look like %, (, etc.
			return;
		}
	}

	switch ( keyCode )
	{
	case AC_SEMI_COLON:
	case AC_COMMA:
		if (AC_IsActive() && event.shiftKey == false)
		{
			AC_InsertSuggestion ( editCtrl );
			AC_CancelEvent ( event );
		}
		break;

	case AC_ENTER:
	{
		// always cancel return/enter in TEXTAREAs
		if ( editCtrl.tagName == "TEXTAREA" )
		{
			AC_CancelEvent ( event );
		}

		AC_handledEnter = true;
		
		if ( typeof AC_HandleEnter == "function" )
		{
			if ( AC_HandleEnter( AC_GetTarget( event ) ) == true )
			{
				AC_CancelEvent( event );
				return;
			}
		}
	
		// FALL-THRU:
	}
	case AC_TAB: // we get here on Moz
		if (AC_IsActive())
		{
			AC_InsertSuggestion ( editCtrl );
			AC_CancelEvent ( event );
		}
		// TODO: on TAB, fake a select-all in address field TEXTAREAs?
		break;

  	default:
		// all other printable typing ends up here
		//AC_KickNewDropDown ( editCtrl );
		break;
	}
	
	detaliiProdus();
	
}

  
function AC_OnKeyUp( event )
{
	if ( event == null ) event = window.event;

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null ) return;

	var keyCode = event.keyCode;

	//window.document.form_main.Body.value += "UP="+keyCode+" " + String.fromCharCode(keyCode) + "\n";;

	switch( keyCode )
	{
	case AC_DELETE:
	case AC_BACKSPACE:
		// on key up so we don't interfere with auto-key, and can see the result after the press
		if (AC_IsActive() && editCtrl.value.length == 0 )
		{
			AC_RemoveDropDown();
		}
		else if ( editCtrl.value.length > 0 )
		{
			AC_KickNewDropDown( editCtrl );
		}
		else if ( editCtrl.value.length == 0 && 
			  typeof AC_useSelect != "undefined" && AC_useSelect == true )
		{
			AC_ShowAll( AC_targetElements[ 0 ] );
		}
		break;
	case AC_ESC:
	case AC_HOME:
	case AC_END:
	case AC_PAGE_UP:
	case AC_PAGE_DOWN:
	case AC_UP_ARROW:
	case AC_DOWN_ARROW:
	case AC_LEFT_ARROW:
	case AC_RIGHT_ARROW:
	case AC_TAB:
	case AC_SEMI_COLON:
	case AC_SEMI_COLON_KEY:
	case AC_COMMA:
	case AC_COMMA_KEY:
	case AC_ENTER:
		break;
	default:
 	 	var isSpecial = false;
		if (typeof event.ctrlLeft != "undefined")
		{
			isSpecial = (event.ctrlLeft == true);
		}
		if (isSpecial == false && typeof event.ctrlKey != "undefined")
		{
			isSpecial = (event.ctrlKey == true);
		}
		if (isSpecial == false && typeof event.metaKey != "undefined")
		{
			isSpecial = (event.metaKey == true);
		}
		//if (isSpecial == false && typeof event.altLeft != "undefined")
		//{
		//	isSpecial = (event.altLeft == true);
		//}
		//if (isSpecial == false && typeof event.altKey != "undefined")
		//{
		//	isSpecial = (event.altKey == true);
		//}
		//if (isSpecial == false && typeof event.shiftKey != "undefined")
		//{
		//	isSpecial = (event.shiftKey == true);
		//}
		
		if ( isSpecial == false )
		//if (isSpecial == false && !AC_IsActive() && editCtrl.value.length != 0 )
		{
			AC_KickNewDropDown( editCtrl );
		}
		break;
	}

	// Handle Naoki's jp IME.
	//
	if ( ! AC_handledEnter && keyCode == AC_ENTER )
	{
		AC_KickNewDropDown( editCtrl );
	}
	
	detaliiProdus();
	
} 


function AC_OnBlur( event, control )
{
	
	// IE
	//
	if ( event == null )
	{
		event = window.event;
	}

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null )
	{
		return;
	}

	// When the drop-down-list is clicked on, AC_Menu_onClick will get called,
	// and it will call AC_RemoveDropDown()() once the selection has been made.
	var listGetsFocus = editCtrl.getAttribute("listGetsFocus");    
	if (listGetsFocus != null)
	{        
		editCtrl.removeAttribute("listGetsFocus");
		return;
	}
	
	// Loosing edit focus means endAutoInsert
	
	//parte adaugata pentru partea de cautare produs la introducere cerere/oferta
	
	AC_RemoveDropDown();
	
	detaliiProdus();
	
}

function AC_OnClick( event )
{
	// IE
	//
	if ( event == null )
	{
		event = window.event;
	}

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null )
	{
		return;
	}

	// A mouse click means endAutoInsert
	AC_RemoveDropDown();
	
	detaliiProdus();

}

function AC_OnSelect( event )
{
	// IE
	//
	if ( event == null )
	{
		event = window.event;
	}

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null )
	{
		return;
	}

	// Either the control has been tabbed into, Ctrl+A, or a range was selected.
	// In all cases auto-text must be disabled.
	AC_RemoveDropDown();
	
}

function AC_OnCut( event )
{
	// IE
	//
	if ( event == null )
	{
		event = window.event;
	}

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null )
	{
		return;
	}

	// Text has been deleted from this control.  auto-text must be disabled.
	AC_RemoveDropDown();
	
	detaliiProdus();
	
}

function AC_OnPaste( event )
{
	// IE
	//
	if ( event == null )
	{
		event = window.event;
	}

	var editCtrl = AC_GetTarget( event );
	if ( editCtrl == null )
	{
		return;
	}

	// Text has been inserted into this control.  auto-text must be disabled.
	AC_RemoveDropDown();
	
	detaliiProdus();
	
}

function AC_OnResize( event )
{
	AC_PlaceDropDown ();
}

//------------------------------========================== input HANDLERS =======================------------------END




//--------------------------==================== dropdown HANDLERS ===========================------------------


// --------------------------------------------------

function AC_GetCursorIndex(editCtrl)
{
	if ( editCtrl == null || (editCtrl.type != "text" && editCtrl.type != "textarea") )
	{
		//window.document.form_main.Body.value += "1 returning -1\n";
		
		return -1;
	}
	
	// empty control means the cursor is at 0
	if (editCtrl.value == null || editCtrl.value.length == 0)
	{
		//window.document.form_main.Body.value += "2 returning -1\n";
		
		return -1;
	}
	
	// -1 for unknown
	var cursorIndex = -1;

	// IE
	//
	if ( editCtrl.createTextRange )
	{
		var selection = window.document.selection.createRange( );
		var textRange = editCtrl.createTextRange( );
		
		// if the current selection is within the edit control			
		if (textRange == null || selection == null || (( selection.text != "" ) && textRange.inRange(selection) == false) )
		{
			//window.document.form_main.Body.value += "4 returning -1\n";
			
			return -1;
		}
		
		if (selection.text == "")
		{
			if (textRange.boundingLeft == selection.boundingLeft)
			{
				cursorIndex = 0;
			}
			else
			{
				// Handle inputs.
				//
				if ( editCtrl.tagName == "INPUT" )
				{
					var contents = textRange.text;
					var index = 1;
					while (index < contents.length)
					{
						textRange.findText(contents.substring(index));
						if (textRange.boundingLeft == selection.boundingLeft)
						{
							break;
						}
						
						index++;
					}
				}
				// Handle text areas.
				//
				else if ( editCtrl.tagName == "TEXTAREA" )
				{
					var index = editCtrl.value.length + 1;
					var theCaret = document.selection.createRange().duplicate();
					while ( theCaret.parentElement() == editCtrl &&
						theCaret.move("character",1) == 1 )
					{
						--index;
					}
					
					if ( index == editCtrl.value.length + 1 )
					{
						index = -1;
					}
				}
				
				cursorIndex = index;
			}
		}
		else
		{
			cursorIndex = textRange.text.indexOf(selection.text);
		}
	}
	// Moz
	//
	else if ( window.getSelection && window.document.createRange )
	{
		if ( editCtrl.selectionStart < 0 || editCtrl.selectionStart > editCtrl.length )
		{
			return cursorIndex;
		}
		
		if ( editCtrl.selectionEnd < 0 || editCtrl.selectionEnd > editCtrl.length ||
		     editCtrl.selectionEnd < editCtrl.selectionStart )
		{
			return cursorIndex;
		}
		
		cursorIndex = editCtrl.selectionStart;
	}
	// Safari
	//
	else
	{
	}
	
	//window.document.form_main.Body.value += "5 returning "+cursorIndex+"\n";
	
	return cursorIndex;
}


// --------------------------------------------------

function AC_Menu_DeselectItem ( menuElement, index )
{
	var current = AC_useTable?AC_dropDownTable.rows[index]:menuElement.childNodes[index];

	if ( current != null )
	{
		AC_RemoveElementClass ( current, "ac_menuitem_selected" );
	}
}

function AC_Menu_SelectItem ( menuElement, index, scrollToIt ) 
{
	var current = menuElement.getAttribute("selectedIndex");
	if ( current != -1 && current != null )
		AC_Menu_DeselectItem ( menuElement, current );
		
	if(!AC_useTable)
	{
		if ( index >= 0 && index < menuElement.childNodes.length )
		{
			AC_AddElementClass ( menuElement.childNodes[index], "ac_menuitem_selected" );
		}
	}
	else
	{
		if ( index >= 0 && index < AC_dropDownTable.rows.length )
		{
			AC_AddElementClass ( AC_dropDownTable.rows[index], "ac_menuitem_selected" );
		}
	}

	if ( scrollToIt )
	{
		AC_ScrollToChild ( menuElement, index );
	}
}


function AC_Menu_onClick( event )
{
	//window.document.form_main.Body.value += "AC_Menu_onClick\n";

	listCtrl = document.getElementById( "ac_select" );
	if ( listCtrl == null ) return;

	var editCtrl = window.document.getElementById(listCtrl.getAttribute("editCtrlID"));
	if ( editCtrl == null )
	{
		return;
	}

	AC_InsertSuggestion( editCtrl );
	
		
}

function AC_Menu_onMouseDown( event )
{
	//window.document.form_main.Body.value += "AC_Menu_onMouseDown\n";

	listCtrl = document.getElementById( "ac_select" );
	if ( listCtrl == null ) return;

	var editCtrl = window.document.getElementById(listCtrl.getAttribute("editCtrlID"));
	if ( editCtrl == null )
	{
		return;
	}

	editCtrl.setAttribute("listGetsFocus", "1");
	
}


function AC_MenuItem_onMouseDown ( event ) {
	if ( event == null ) event = window.event;
	var target = this; // avoids AC_GetTarget( event ) which returns various children,
					   // but note this and other handlers require JS assignment, not inline 

	if(!AC_useTable)
	{
		var current = target.parentNode.getAttribute("selectedIndex");
		if ( current != -1 && current != null )
		{
			AC_RemoveElementClass ( target.parentNode.childNodes[current], "ac_menuitem_selected" );
		}

		AC_AddElementClass (target, "ac_menuitem_selected");

		var children = target.parentNode.childNodes;

		for ( var i=0, n=children.length; i<n; ++i )
		{
			if ( children[i] == target )
			{
				target.parentNode.setAttribute("selectedIndex", i);
				break;
			}
		}
	}
	else
	{
		var current = AC_dropDownList.getAttribute("selectedIndex");
		if ( current != -1 && current != null )
		{
			AC_RemoveElementClass ( AC_dropDownTable[current], "ac_menuitem_selected" );
		}

		AC_AddElementClass (target, "ac_menuitem_selected");

		var children = AC_dropDownTable.rows;

		for ( var i=0, n=children.length; i<n; ++i )
		{
			if ( children[i] == target )
			{
				AC_dropDownList.setAttribute("selectedIndex", i);
				break;
			}
		}	
	}
}

function AC_MenuItem_onMouseOver ( event )
{
	if ( !AC_ElementHasClass ( this, "ac_menuitem_selected" ))
	{
		// selected takes priority; not all browsers support "!" styles
		// which would eliminate this check
		AC_AddElementClass ( this, "ac_menuitem_over" );
	}
}

function AC_MenuItem_onMouseOut ( event )
{
	AC_RemoveElementClass ( this, "ac_menuitem_over" );
}


function AC_IsActive()
{
	if (AC_dropDownDiv != null)
	{
		return (AC_dropDownDiv.style.visibility == "visible");
	}	
	return false;
}


//----------------------================================ DROPDOWN CREATION ===========================------------



function AC_ShowAll( controlName )
{
	setCurControl( controlName );
	AC_FindSuggestions( "\u0007" );
	AC_NewDropDown( controlName, "compile" );
}

var crateTimer=null;

function AC_NewDropDown ( editCtrl, state )
{
	if(state == null || state == 'new')
	{
		//create drop down only after a idle time
		if(crateTimer!=null) clearTimeout(crateTimer);
		crateTimer=setTimeout("AC_NewDropDown_Real( '"+(typeof editCtrl == "string"?editCtrl:editCtrl.id)+"', "+(typeof state == "undefined"?"null":"'"+state+"'")+" );", 
			500);
	}
	else
	{
		AC_NewDropDown_Real ( editCtrl, state )
	}
}

// build a new drop-down for the current state of the edit field, and show it
function AC_NewDropDown_Real ( editCtrl, state )
{
	if ( state == null )
	{
		state = "new";
	}

	if ( typeof editCtrl == "string" )
	{
		editCtrl = document.getElementById ( editCtrl );
	}
	
	if ( typeof AC_useSelect == "undefined" || AC_useSelect == null || AC_useSelect == false )
	{
		if ( editCtrl == null || editCtrl.value.length == 0 )
		{
			return;
		}
	}

	// 5 major steps for a New operation.

	// 1. analyze the current state of the edit field, and find the text to match against
	if ( state == "new" )
	{
		var cursorIndex = AC_GetCursorIndex(editCtrl);
		if ( cursorIndex == -1 )
		{
			return;
		}

		// Get the end delimiter ahead of the cursor.
		//
		var endDelim = -1;
		var substr = editCtrl.value.substring( cursorIndex );
		var commaDelim = substr.indexOf( ',' );
		var semiColonDelim = substr.indexOf( ';' );
		if ( semiColonDelim < commaDelim && semiColonDelim != -1 )
		{
			endDelim = semiColonDelim;
		}
		else if ( commaDelim != -1 )
		{
			endDelim = commaDelim;
		}
		else if ( semiColonDelim != -1 )
		{
			endDelim = semiColonDelim;
		}

		if ( endDelim == -1 )
		{
			endDelim = editCtrl.value.length;
		}
		else
		{
			endDelim += cursorIndex;
		}

		// Must be working at the "end" of the current input.
		//
		if ( cursorIndex < endDelim )
		{
			var nonWhiteSpace = editCtrl.value.substring( cursorIndex, endDelim ).search(/\S/);
			if ( nonWhiteSpace != -1 )
			{
				return;
			}
		}

		// Get the start delimiter index behind the cursor.
		//
		var startDelim = -1;
		substr = editCtrl.value.substring( 0, cursorIndex );
		commaDelim = substr.lastIndexOf( ',' );
		semiColonDelim = substr.lastIndexOf( ';' );
		if ( semiColonDelim > commaDelim )
		{
			startDelim = semiColonDelim;
		}
		else
		{
			startDelim = commaDelim;
		}
		var currentInput = editCtrl.value.substring( startDelim + 1, cursorIndex );
		var firstChar = currentInput.search( /\S/ );
		if ( firstChar != -1 )
		{
			currentInput = currentInput.substring( firstChar );
		}

		state = "load";
	}
	
	// 1.5 Before find... must load the data...
	if( state == "load" )
	{
		if(currentInput.length < AC_allMinChars[currentControlIndex])
		{
			return;
		}
		else if( currentInput.indexOf(AC_ListLoadedForInput) != 0 )
		{
			showLoadingIcon(editCtrl, true);

			loadlistFor(editCtrl, currentInput, AC_loadURL[currentControlIndex]);
			//curatam cache-ul
			AC_substringMatches = { };
			AC_substringMatchesLinear = { };
			return;
		}
		else
		{
			showLoadingIcon(editCtrl, false);
			state="find";
		}
	}

	
	// 2. get the suggestions based on the current input
	var t1 = (new Date()).getTime();
	if ( state == "find" )
	{
		AC_FindSuggestions( currentInput );
		state = "compile";
	}


	// 3. compile suggestions into formatted list
	var t2 = (new Date()).getTime();
	if ( state == "compile" )
	{
		AC_CompileSuggestions();
		state = "render";
	}


	var t3 = (new Date()).getTime();

	if ( t3 - t1 > 400 )
	{
		//AC_Debug ( currentInput + ":" + ( AC_currentResults ? ( ((AC_currentResults[0]==-1)?"-1":AC_currentResults[0].length) + "+" + ((AC_currentResults[1]==-1)?"-1":AC_currentResults[1].length)) : "null" ) + "bailing find:" + (t2-t1) + " compile:" + (t3-t2) + "ms\n" );
		AC_KickNewDropDown ( editCtrl, "render" );
		return;
	}

	// 4. create the list with the current suggestions     
	if ( state == "render" )
	{
		if ( AC_currentSuggestions != null && AC_currentSuggestions.length > 0 )
		{
			AC_CreateDropDown ( editCtrl, AC_currentSuggestions );
		}
	}
	
	var t4 = (new Date()).getTime();

	// split out from part 4 to make the debug output cleaner
	if ( AC_currentSuggestions == null || AC_currentSuggestions.length == 0 )
	{
		if ( typeof AC_useSelect != "undefined" && AC_useSelect == true )
		{
			AC_RemoveFromSelect( );
		}
		else
		{
			AC_RemoveDropDown( editCtrl );
		}
		
		return;
	}


	// 5. place it/show it.
	//
	if ( typeof AC_useSelect == "undefined" || AC_useSelect == null || AC_useSelect == false )
	{
		AC_PlaceDropDown ( editCtrl, true );
	}
}

var AC_loading;
var AC_edt_bgColor;
function showLoadingIcon( editCtrl, show )
{

	if ( typeof editCtrl == "string" )
	{
		editCtrl = document.getElementById ( editCtrl );
	}
	
	if ( AC_loading == null )
	{
		// the select box is placed in a div so it can have z-index=1 and be hidden
		// TODO: it may be that we can ditch this outer container
		AC_loading = window.document.createElement("img");
		AC_loading.style.position = "absolute";
		AC_loading.style.zIndex = 20;
		AC_loading.style.visibility = "hidden";
		AC_loading.src = "http://farma.agoracentral.ro/common/graphics/loading.gif";
		editCtrl.parentNode.insertBefore ( AC_loading, editCtrl.nextSibling );
	}

	if(show)
	{
		AC_edt_bgColor = editCtrl.style.backgroundColor;
		editCtrl.style.backgroundColor='#b0b0b0';
		var left = window.document.body.clientLeft - editCtrl.offsetLeft; // TODO: this actually fails on Moz, but the default layout saves us
		var top = editCtrl.offsetParent.offsetHeight + window.document.body.clientTop - editCtrl.offsetTop;
		//alert(left+' '+top);
		var parent = editCtrl;
		do
		{
			left += parent.offsetLeft;
			top += parent.offsetTop;
			parent = parent.offsetParent;
		}
		while (parent != null);

		AC_loading.style.left = left;
		AC_loading.style.top = top;	
		AC_loading.style.visibility = "visible";
	}
	else
	{
		editCtrl.style.backgroundColor=AC_edt_bgColor;
		//alert(AC_loading.style.visibility);
		AC_loading.style.visibility = "hidden";
	}

}


// create the drop-down element for the given suggestion list
function AC_CreateDropDown ( editCtrl, suggestions )
{
	if ( suggestions == null || suggestions.length == 0 )
	{
		AC_RemoveDropDown( editCtrl );
		return;
	}


	var selectedIndex = 0;

	if ( AC_dropDownDiv == null )
	{
		// the select box is placed in a div so it can have z-index=1 and be hidden
		// TODO: it may be that we can ditch this outer container
		AC_dropDownDiv = window.document.createElement("div");
		AC_dropDownDiv.style.position = "absolute";
		AC_dropDownDiv.style.zIndex = 1;
		AC_dropDownDiv.style.visibility = "hidden";
		AC_dropDownDiv.style.fontSize = "0.9em";
		AC_dropDownDiv.style.width = "auto";
		AC_dropDownDiv.style.textAlign = "left";
	}

	editCtrl.parentNode.insertBefore ( AC_dropDownDiv, editCtrl.nextSibling );


	if ( AC_dropDownList == null )
	{
		AC_dropDownList = window.document.createElement("div");
		// AC_dropDownList.size = 4;
		AC_dropDownList.className = "ac_menu";
		AC_dropDownList.id = "ac_select";
		AC_dropDownList.onclick = AC_Menu_onClick;
		AC_dropDownList.onmousedown = AC_Menu_onMouseDown;
		AC_dropDownList.unselectable = "on";

		AC_dropDownList.style.width = AC_allWidth[currentControlIndex]==null?editCtrl.offsetWidth:AC_allWidth[currentControlIndex];

		if( AC_useTable )
		{
			AC_dropDownTable = window.document.createElement("table");
			// AC_dropDownList.size = 4;
			AC_dropDownTable.className = "ac_menu";
			AC_dropDownTable.id = "ac_select";
			AC_dropDownTable.onclick = AC_Menu_onClick;
			AC_dropDownTable.onmousedown = AC_Menu_onMouseDown;
			AC_dropDownTable.unselectable = "on";
			AC_dropDownTable.style.width = "auto";
			AC_dropDownList.appendChild( AC_dropDownTable )
		}

		AC_dropDownDiv.appendChild ( AC_dropDownList );
	}


	AC_dropDownList.style.visibility = "hidden";


	// delete any children in excess of what we need
	if( AC_useTable )
	{
		for ( var i=suggestions.length, n=AC_dropDownTable.rows.length; i<n; ++i )
		{
			AC_dropDownTable.deleteRow( 0 );
		}
	}
	else
	{
		for ( var i=suggestions.length, n=AC_dropDownList.childNodes.length; i<n; ++i )
		{
			AC_dropDownList.removeChild ( AC_dropDownList.childNodes[suggestions.length] );
		}
	}

	for( var index = 0; index < suggestions.length; index++ )
	{
		var option;
		if(AC_useTable)
			option = AC_dropDownTable.rows[index];
		else
			option = AC_dropDownList.childNodes[index];
			
		if ( option == null )
		{
			if(AC_useTable)
			{
				var lastRow = AC_dropDownTable.rows.length;
				option = AC_dropDownTable.insertRow(lastRow);
			}
			else
			{
				option = window.document.createElement("div");
				AC_dropDownList.appendChild(option);
			}
			
			option.className = "ac_menuitem";
			option.onmousedown = AC_MenuItem_onMouseDown;
			option.onmouseover = AC_MenuItem_onMouseOver;
			option.onmouseout = AC_MenuItem_onMouseOut;
		}
		else
		{
			// remove hiliting for recycled items
			AC_RemoveElementClass ( option, "ac_menuitem_selected" );
		}

		option.value = suggestions[ index ][ 0 ];
//		option.text = suggestions[ index ][ 1 ];

//alert(suggestions[ index ][ 1 ]);
		// force everything onto one line:
		if(AC_useTable)
		{
				var arr = AC_allCanons[currentControlIndex][ suggestions[ index ][ 0 ] ]
				for (r = 0; arr!=null && r < arr.length; r++) 
				{   
					var cell = option.cells==null?null:option.cells[r];
					if(cell==null)
					{
						cell=option.insertCell(r);
					}
						
					if(r==0)
						cell.innerHTML = suggestions[ index ][ 1 ];//first item is the one with bolds
					else
						cell.innerHTML = arr[r];

				}
		}
		else
		{
			option.innerHTML = suggestions[ index ][ 1 ];//"<nobr>" + suggestions[ index ][ 1 ] + "</nobr>";
		}
	}


	// only update the overflow after deleting excess children--
	// else we get a scrollbar flash on moz -- KJ
	if ( suggestions.length <= AC_MaxVisibleItems )
	{
		AC_dropDownList.style.height = "auto";

		if ( AC_isGecko )
		{
			// the counterpart for this statement throws an error on IE,
			// hence the "if gecko"
			AC_dropDownList.style.overflow = "hidden";
		}
		
		AC_dropDownList.style.overflowY = "hidden";
	}
	else
	{
		// set up scrolling display - limited to the number of visible items
		// TODO: this could be smarter about limiting the actual height (say,
		// a couple hundred pixels) so that you don't get a ridiculous display
		// when the text size is set really large. also, limited to the
		// viewport would be nice.

		if(AC_useTable)
		{
			AC_dropDownList.style.height = (AC_MaxVisibleItems*12) + "px";
		}
		else
		{
			var option = AC_dropDownList.childNodes[AC_MaxVisibleItems-1];
			AC_dropDownList.style.height = ( option.offsetTop + option.offsetHeight + 2 ) + "px";
		}

		if ( AC_isGecko )
		{
			// this statement must be avoided on IE, which throws an error
			AC_dropDownList.style.overflow = "-moz-scrollbars-vertical";
		}
	
		AC_dropDownList.style.overflowY = "scroll";
		//lia
		AC_dropDownList.style.overflowX = "visible";
	}

//	AC_MakeElementTreeUnselectable ( AC_dropDownList );

	AC_dropDownList.setAttribute("selectedIndex", selectedIndex);
	AC_Menu_SelectItem (AC_dropDownList, 0);

	AC_dropDownList.style.visibility = "visible";

	AC_dropDownList.setAttribute("selectedIndex", selectedIndex);

	//window.document.form_main.Body.value += AC_dropDownList.innerHTML;

	AC_PlaceDropDown ( editCtrl, true );
}


function AC_getLastElement()
{
	return AC_useTable?AC_dropDownTable.rows.length-1:AC_dropDownList.childNodes.length - 1;
}

// apply a navigation operation (next item, etc.) to an already-open drop-down
function AC_UpdateDropDown ( editCtrl, op )
{
	if ( op == null || op == "" ||
		editCtrl == null || editCtrl.value.length == 0 ||
		AC_dropDownList == null || 
		(!AC_useTable && AC_dropDownList.childNodes.length == 0) || 
		(AC_useTable && AC_dropDownTable.rows.length==0))
	{
		AC_RemoveDropDown( editCtrl );
		return;
	}    

	var selectedIndex = AC_dropDownList.getAttribute("selectedIndex");
	if (selectedIndex == null)
	{
		selectedIndex = 0;
	}

	var newSelection = selectedIndex;

	switch ( op )
	{
	case "selectPrev": newSelection--; break;
	case "selectNext": newSelection++; break;
	case "selectNextPage": newSelection += AC_MaxVisibleItems; break;
	case "selectPrevPage": newSelection -= AC_MaxVisibleItems; break;
	case "selectFirst": newSelection = 0; break;
	case "selectLast": newSelection = AC_getLastElement(); break;
	default:
		AC_RemoveDropDown( editCtrl );
		return;
	}

	if (newSelection < 0)
	{
		newSelection = 0;
	}

	if (newSelection > AC_getLastElement())
	{
		newSelection = AC_getLastElement();
	}

	if ( newSelection != selectedIndex )
	{
		AC_Menu_SelectItem ( AC_dropDownList, newSelection, true );
		AC_dropDownList.setAttribute("selectedIndex", newSelection);
	}

	AC_PlaceDropDown ( editCtrl, true );
}


// position and show the drop down relative to the given edit field
function AC_PlaceDropDown ( editCtrl, forceIt )
{
	if ( editCtrl == null && AC_dropDownList != null )
	{
		editCtrl = window.document.getElementById ( AC_dropDownList.getAttribute ( "editCtrlID" ));
	}

	if ( editCtrl == null || AC_dropDownList == null )
	{
		return;
	}

	if ( AC_dropDownDiv.style.visibility != "visible" && !forceIt )
	{
		return;
	}

	// Place the drop down directly beneath the edit control.
	// Update this regularly, as the TEXTAREA can grow and shrink.

	var left = window.document.body.clientLeft - AC_dropDownList.offsetLeft; // TODO: this actually fails on Moz, but the default layout saves us
	var top = editCtrl.offsetHeight + window.document.body.clientTop - AC_dropDownList.offsetTop;
	var parent = editCtrl;
	do
	{
		left += parent.offsetLeft;
		top += parent.offsetTop;
		parent = parent.offsetParent;
	}
	while (parent != null);

	AC_dropDownDiv.style.left = left; 
	AC_dropDownDiv.style.top = top;  
	AC_dropDownDiv.style.visibility = "visible";

        if (AC_dropDownIFrame != null) {
                AC_dropDownIFrame.style.left = AC_dropDownDiv.style.left;
                AC_dropDownIFrame.style.top = AC_dropDownDiv.style.top;
                AC_dropDownIFrame.width = AC_dropDownDiv.offsetWidth;
                AC_dropDownIFrame.height = AC_dropDownDiv.offsetHeight;
                AC_dropDownIFrame.style.zIndex = editor.form_mainControl.style.zIndex + 1;
                AC_dropDownDiv.style.zIndex = AC_dropDownIFrame.style.zIndex + 1;
                AC_dropDownIFrame.style.visibility = "visible";

        }

	// make the drop down width a function of the editCtrl width
	if (AC_dropDownList.offsetWidth < editCtrl.offsetWidth)
	{
		AC_dropDownList.style.posWidth = AC_allWidth[currentControlIndex]==null?editCtrl.offsetWidth:AC_allWidth[currentControlIndex];
	}

	AC_dropDownList.setAttribute("editCtrlID",editCtrl.id);
}


function AC_RemoveDropDown()
{
	if ( AC_dropDownDiv != null )
	{
		AC_dropDownDiv.parentNode.removeChild ( AC_dropDownDiv );
		AC_dropDownDiv.style.visibility = "hidden";
		AC_dropDownDiv = null;
	}

    if ( AC_dropDownIFrame != null )
    {
            AC_dropDownIFrame.parentNode.removeChild(AC_dropDownIFrame);
            AC_dropDownIFrame.style.visibility = "hidden";
            AC_dropDownIFrame = null;
    }

	
	AC_dropDownList = null;
}

function AC_InsertSuggestion( editCtrl )
{
	if ( AC_IsActive( ) == false )
	{
		return;
	}
	
	// Get the cursor position.
	//
	var cursorIndex = AC_GetCursorIndex(editCtrl);
	if ( cursorIndex == -1 )
	{
		return;
	}
	
	// Get the stuff before the insert.
	//
	var startDelim = -1;
	substr = editCtrl.value.substring( 0, cursorIndex );
	commaDelim = substr.lastIndexOf( ',' );
	semiColonDelim = substr.lastIndexOf( ';' );
	if ( semiColonDelim > commaDelim )
	{
		startDelim = semiColonDelim;
	}
	// It's ok if the comma one is -1.
	//
	else
	{
		startDelim = commaDelim;
	}
	
	var stuffBeforeInsert = "";
	if ( startDelim != -1 )
	{
		stuffBeforeInsert = editCtrl.value.substring( 0, startDelim + 1 ) + " ";
	}
	
	var stuffAfterInsert = editCtrl.value.substring( cursorIndex );

	// Put in the stuff before the insert;
	//
	editCtrl.value = stuffBeforeInsert;
	
	// Insert the suggestion.
	//
	var item;
	if( AC_useTable)
		item = AC_dropDownTable.rows[AC_dropDownList.getAttribute("selectedIndex")];
	else
		item = AC_dropDownList.childNodes[AC_dropDownList.getAttribute("selectedIndex")];
	
	
	//execute the script from last element
	if(AC_allSelectFunction[currentControlIndex]!=null)
	{
		eval(AC_allSelectFunction[currentControlIndex]+"(AC_allFields[currentControlIndex], AC_allValues[currentControlIndex]["+item.value+"]);");
	}
	else
	{
		editCtrl.value = AC_allCanons[currentControlIndex][item.value][0].replace(/\u00A0/g,"");
	}

	AC_RemoveDropDown();
	editCtrl.focus();
	
	detaliiProdus();
	
}


var AC_updateTimer = null;
var AC_updateEditCtrl;
var AC_updateState;

function AC_KickNewDropDown( editCtrl, state )
{
	if ( AC_updateTimer != null )
	{
		clearTimeout (AC_updateTimer);
	}

	AC_updateEditCtrl = editCtrl;
	AC_updateState = state;

	AC_updateTimer = setTimeout ( "AC_HandleNewDropDown()", 10 ); // fast typers will kill this
	// TODO: examine breaking the search and popup update into two (or more) interruptable operations
}

function AC_HandleNewDropDown()
{
	var editCtrl = AC_updateEditCtrl, state = AC_updateState;

	AC_ClearUpdate (); // clear first, as another might get created before we're done

	if ( editCtrl != null )
	{
		AC_NewDropDown ( editCtrl, state );
	}
}

function AC_ClearUpdate ()
{
	if ( AC_updateTimer != null )
	{
		clearTimeout (AC_updateTimer);
		AC_updateTimer = null;
	}

	AC_updateEditCtrl = null;
	AC_updateState = null;
}


// --------------------------------------------------

//			COMPILARE LISTA DE SUGESTII

// --------------------------------------------------




AC_RotTable = { };

AC_LatinTable = [ ];

function AC_BuildTables ()
{
	var s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", t = "abcdefghijklmnopqrstuvwxyz";

	// build the rot-13 table
	for ( var i=0; i<26; ++i )
	{
		AC_RotTable [s.charAt(i)] = s.charAt((i+13)%26);
		AC_RotTable [t.charAt(i)] = t.charAt((i+13)%26);
	}

	// build the rot-13 code offset table
// DEAD: see AC_Rot13 for how this is might be used
//  window.AC_RotTable2 = { };
//	for ( var i=97; i<110; ++i )
//		AC_RotTable2[i] = 13;
//	for ( var i=110; i<123; ++i )
//		AC_RotTable2[i] = -13;
//	for ( var i=65; i<78; ++i )
//		AC_RotTable2[i] = 13;
//	for ( var i=78; i<91; ++i )
//		AC_RotTable2[i] = -13;

	AC_LatinTable[ 192 ] = AC_LatinTable[ 193 ] = AC_LatinTable[ 194 ] = AC_LatinTable[ 195 ] = AC_LatinTable[ 196 ] = AC_LatinTable[ 197 ] = "a";
	AC_LatinTable[ 199 ] = "c";
	AC_LatinTable[ 200 ] = AC_LatinTable[ 201 ] = AC_LatinTable[ 202 ] = AC_LatinTable[ 203 ] = "e";
	AC_LatinTable[ 204 ] = AC_LatinTable[ 205 ] = AC_LatinTable[ 206 ] = AC_LatinTable[ 207 ] = "i";
	AC_LatinTable[ 209 ] = "n";
	AC_LatinTable[ 210 ] = AC_LatinTable[ 211 ] = AC_LatinTable[ 212 ] = AC_LatinTable[ 213 ] = AC_LatinTable[ 214 ] = AC_LatinTable[ 216 ] = "o";
	AC_LatinTable[ 217 ] = AC_LatinTable[ 218 ] = AC_LatinTable[ 219 ] = AC_LatinTable[ 220 ] = "u";
	AC_LatinTable[ 221 ] = "y";
	AC_LatinTable[ 224 ] = AC_LatinTable[ 225 ] = AC_LatinTable[ 226 ] = AC_LatinTable[ 227 ] = AC_LatinTable[ 228 ] = AC_LatinTable[ 229 ] = "a";
	AC_LatinTable[ 231 ] = "c";
	AC_LatinTable[ 232 ] = AC_LatinTable[ 233 ] = AC_LatinTable[ 234 ] = AC_LatinTable[ 235 ] = "e";
	AC_LatinTable[ 236 ] = AC_LatinTable[ 237 ] = AC_LatinTable[ 238 ] = AC_LatinTable[ 239 ] = "i";
	AC_LatinTable[ 241 ] = "n";
	AC_LatinTable[ 242 ] = AC_LatinTable[ 243 ] = AC_LatinTable[ 244 ] = AC_LatinTable[ 245 ] = AC_LatinTable[ 246 ] = AC_LatinTable[ 248 ] = "o";
	AC_LatinTable[ 249 ] = AC_LatinTable[ 250 ] = AC_LatinTable[ 251 ] = AC_LatinTable[ 252 ] = "u";
	AC_LatinTable[ 253 ] = AC_LatinTable[ 255 ] = "y";
	
	// TODO: what about these?
	// 198 : -- 223: -- 230:

}

AC_BuildTables();


function AC_Rot13( inputText ) {
	return inputText;
	if ( inputText == null ) return "";

	var resultText = [];
	var c, s;
//	var from = String.fromCharCode;

	for ( var i=0, n=inputText.length; i<n; ++i )
	{
		resultText [ i ] = ( s = AC_RotTable [(c = inputText.charAt(i))] ) ? s : c;

// alternate using char codes: no faster
//		c = inputText.charCodeAt(i);
//		s = AC_RotTable2[c];
//		resultText [ i ] = from (c + ( s ? s : 0 ));
	}

	//window.document.form_main.Body.value += "rot13=" + inputText + ":" + resultText.join("") + "\n";

	return resultText.join("");
}


function AC_DeLatin( inputText ) {
	if ( inputText == null ) return "";

	var resultText = [];

	for ( var i=0, n=inputText.length; i<n; ++i )
	{
		var c = inputText.charCodeAt(i);
		var sub = AC_LatinTable [c];
		if ( sub == null ) sub = inputText.charAt(i);
		resultText [ resultText.length ] = sub;
	}

	//AC_Debug ( "delatin=" + inputText + ":" + resultText.join("") + "\n" );

	return resultText.join("");
}


function AC_DeLatinRot13( inputText ) {
	if ( inputText == null ) return "";

	var resultText = [];

	for ( var i=0, n=inputText.length; i<n; ++i )
	{
		var c = inputText.charCodeAt(i);
		var sub = AC_LatinTable [c];
		if ( sub == null ) {
			c = inputText.charAt(i);
			sub = AC_RotTable [c];
			if ( sub == null ) sub = c;
		}
		resultText [ resultText.length ] = sub;
	}

	//AC_Debug ( "delatin=" + inputText + ":" + resultText.join("") + "\n");

	return resultText.join("");
}


// generate a string which represents the next lexical substring
function AC_NextToken ( token ) {
	while ( token.length > 0 ) {
		var c = token.charCodeAt(token.length - 1);

		if ( c < 65535 )
			return token.substring ( 0, token.length - 1 ) + String.fromCharCode( c+1 );

		// lop off this character, try to increment the next one
		token = token.substring ( 0, token.length - 1 );
	}

	return null;
}


// match latin accent variations to non-accented ASCII - LOWER CASE!
// nu il folosim inca...
function AC_DeLatinString ( input ) {
	input = input.replace ( /[\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]/gi, "a" );
	input = input.replace ( /[\u00E8\u00E9\u00EA\u00EB]/gi, "e" );
	input = input.replace ( /[\u00E7]/gi, "c" );
	input = input.replace ( /[\u00F1]/gi, "n" );
	input = input.replace ( /[\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8]/gi, "o" );
	input = input.replace ( /[\u00F9\u00FA\u00FB\u00FC]/gi, "u" );
	input = input.replace ( /[\u00FD\u00FF]/gi, "y" );
	input = input.replace ( /[\u00C6]/gi, "\u00E6" ); // 

	// TODO: what about: 223= ?

	return input;
}


// base string munging for both search and menu highlighting;
// handles latin accent overlays, and knocking out RE meta-characters
function AC_InnerMatchString ( input )
{
	// defang things that look like RE metacharacters
	input = input.replace( /([\\|\[|\]|\(|\)|\.|\^|\$|\?])/g, "\\\$1");

	// match latin accent variations to each other
	input = input.replace ( /[a\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]/gi, "[a\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]" );
	input = input.replace ( /[e\u00E8\u00E9\u00EA\u00EB]/gi, "[e\u00E8\u00E9\u00EA\u00EB]" );
	input = input.replace ( /[c\u00E7]/gi, "[c\u00E7]" );
	input = input.replace ( /[n\u00F1]/gi, "[n\u00F1]" );
	input = input.replace ( /[o\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8]/gi, "[o\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8]" );
	input = input.replace ( /[u\u00F9\u00FA\u00FB\u00FC]/gi, "[u\u00F9\u00FA\u00FB\u00FC]" );
	input = input.replace ( /[y\u00FD\u00FF]/gi, "[y\u00FD\u00FF]" );

	// TODO: what about: 223= ?

	return input;
}


// expression for matching input against the search strings
function AC_OuterSearchExpr ( input )
{
	input = input.replace(/\(/, "");
	input = input.replace(/\)/, "");
	var isDoubleByte = false;
	for ( var index = 0; index < input.length; ++index )
	{
		if ( input.charCodeAt(index) > 127 )
		{
			isDoubleByte = true;
			break;
		}
	}
	
	if ( isDoubleByte == true )
	{
		var newInput = "";
		for ( var index = 0; index < input.length; ++index )
		{
			newInput += input.charAt(index) + "\u00A0{0,1}";
		}
		input = newInput;
	}
	
	// allow match to cross over words (e.g. skip over middle names)
	input = input.replace ( / /, " (\\S+ +<{0,1})*" );

	// matching starts at the beginning or after certain delimiters
	return new RegExp ( "(^|[ <\"]|\u00A0)" + input, "gi" );
}


// expression for inserting highlighting tags (bold) around the matching text in the drop down menu items;
// we can't recycle the search expression because of rot13 and other stuff that differs
function AC_OuterMenuExpr ( input )
{
	var isDoubleByte = false;
	for ( var index = 0; index < input.length; ++index )
	{
		if ( input.charCodeAt(index) > 127 )
		{
			isDoubleByte = true;
			break;
		}
	}

	if ( isDoubleByte == true )
	{
		var newInput = "";
		for ( var index = 0; index < input.length; ++index )
		{
			newInput += input.charAt(index) + "\u00A0{0,1}";
		}
		input = newInput;
	}

	// menu text includes HTML escaped email address
	input = input.replace(/</, "&lt;");

	if ( input.search ( / / ) == -1 )
	{
		// no spaces - add generic matches at the end so we can use $3, $4 in all cases
		input += ")(.*)($";
	}
	else
	{
		// allow match to cross over words (e.g. skip over middle names); we set up 4 clusters
		// so that the stuff before and after the skipped words can be highlighted independently:
		// NOTE: ? operators don't work on IE5.  We lose the menu highlighting once the user types a space.
		input = input.replace(/ /," +)((?:\\S+ +(?:<|&lt;){0,1})*?)(" );
	}

	// matching starts at the beginning or after certain delimiters
	return new RegExp ( "(^|[ <\"]|&lt;|\u00A0)(" + input + ")", "gi" );
}


// --------------------------------------------------


var AC_currentInput = null;
var AC_currentResults = null;
var AC_currentSuggestions = null;

var AC_substringMatches = { };
var AC_substringMatchesLinear = { };


// --------------------------------------------------


// takes the search results, sorts them and formats for disaplay (e.g. highlight the match text)
function AC_CompileSuggestions ()
{
	var inputText = AC_currentInput;
	var searchResults = AC_currentResults;
	if ( searchResults == null )
	{
		searchResults = AC_substringMatchesLinear[ inputText ];
	}
	
	if ( searchResults == null )
	{
		AC_currentSuggestions = null;
		return null;
	}

	var suggestions = new Array( );
	var matchExpr=null;
	try{
		var matchExpr = AC_OuterMenuExpr ( AC_InnerMatchString ( inputText ));
	}catch(e){}

	var total = 0;

	for ( var index = 0; index < searchResults.length; index++ )
	{
		if ( typeof AC_ignoreMaxResultItems == "undefined" ||
			AC_ignoreMaxResultItems == null ||
			AC_ignoreMaxResultItems == false )
		{
			if ( total >= AC_MaxResultItems )
			{
				break;
			}
		}

		var name = searchResults[index][1];
		var menuText = name;

		
		if ( matchExpr )
		{
			menuText = menuText.replace ( matchExpr, "$1<b>$2</b>$3<b>$4</b>" );
			menuText = menuText.replace(/\u00A0/g,"");
		}

		suggestions [ suggestions.length ] = [ searchResults[index][0], menuText ];

		total++;
	}
	
	AC_currentSuggestions = suggestions;
	
	if ( suggestions.length == 0 )
	{
		return null;
	}
	
	return suggestions;
}


// --------------------------------------------------


function AC_FindSuggestions( inputText )
{
	
	if ( inputText != null )
	{
		inputText = inputText.toLowerCase();//AC_DeLatinString ( inputText.toLowerCase() );
	}

	if ( AC_currentInput != inputText )
	{
		AC_currentInput = inputText;
		AC_currentResults = null;
		AC_currentSuggestions = null;
	}

	AC_currentSuggestions = AC_FindMyLinear( inputText );
}

//the maches are an array of [ index in res list, mached name ]
function AC_FindMyLinearTokens ( inputText, fromList )
{
	var results = [ ], token;

	var showAll = false;
	if ( inputText == "\u0007" )
	{
		showAll = true;
	}

	var inputExpr = AC_OuterSearchExpr ( AC_InnerMatchString ( inputText ) );

	if(fromList!=null)
	{
		for ( var i=0, n=fromList.length; i < n; i++ )
		{
			token = AC_allCanons[currentControlIndex][ fromList[i][0] ];
			if ( showAll == true || token[0].search( inputExpr ) != -1 )
			{
				results[ results.length ] = [ fromList[i][0], token[0] ];
			}
		}
	}
	else //if it's null means we search in all list
	{
		for ( var i=0, n=AC_allCanons[currentControlIndex].length; i < n; i++ )
		{
			token = AC_allCanons[currentControlIndex][i];
			if ( showAll == true || token[0].search( inputExpr ) != -1 )
			{
				results[ results.length ] = [ i, token[0] ];
			}
		}
	}

	return results;
}

function AC_FindMyLinear ( inputText )
{
	if ( AC_substringMatchesLinear[ inputText ] == null )
	{
		var matches=null;

		if ( inputText.length > 1  )
		{
			var prefix = inputText.substring ( 0, inputText.length-1 );

			var prefixMatches = AC_substringMatchesLinear[ prefix ];
			if ( prefixMatches == null )
			{
				AC_FindMyLinear( prefix ); // fast typing can cause this - recur
			}

			prefixMatches = AC_substringMatchesLinear[ prefix ];

			if ( prefixMatches != null )
			{
				if ( prefixMatches.length == 0 )
				{
					matches = prefixMatches; // recycle empty result arrays
				}
				else
				{
					matches = AC_FindMyLinearTokens ( inputText, prefixMatches );
				}
			}
		}
		
		if ( matches == null )
		{
			matches = AC_FindMyLinearTokens( inputText, null );
		}
		
		AC_substringMatchesLinear[ inputText ] = matches;
	}

	AC_currentResults = AC_substringMatchesLinear[ inputText ];
}


// --------------------------------------------------

var AC_debugDiv = null;

function AC_Debug () {
	var text = AC_Debug.arguments[0];

	for ( var i=1, n=AC_Debug.arguments.length; i<n; ++i ) {
		text += " " + AC_Debug.arguments[i];
	}

	// comment out this line to disable debug output:
	//window.document.getElementById("debug").value += text;
	alert(text);
}


//---------------------------------// AJAX stuff
   var http_request = false;
   
   function makeRequest(url) {
		//alert(url);
      http_request = false;
      //AC_Debug("Loading data from ", url); 
      if (window.XMLHttpRequest) { // Mozilla, Safari,...
         http_request = new XMLHttpRequest();
         if (http_request.overrideMimeType) {
            http_request.overrideMimeType('text/xml');
         }
      } else if (window.ActiveXObject) { // IE
         try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
         } catch (e) {
            try {
               http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
         }
      }
      if (!http_request) {
         alert('Your browser does not support AJAX. This page cannot work properly.');
         return false;
      }
      http_request.onreadystatechange = alertContents;
      http_request.open('GET', url, true);
      http_request.send(null);
   }

   function alertContents() {
      if (http_request.readyState == 4) {
         if (http_request.status == 200) {

            var xmldoc = http_request.responseXML;
            //AC_Debug(http_request.getResponseHeader("content-type")); 
            //AC_Debug(http_request.responseXML.parseError.errorCode);
           //AC_Debug(http_request.responseXML.parseError.reson);
            var root = xmldoc.getElementsByTagName('root').item(0);
            //AC_Debug(xmldoc.xml);
            
            var header = root.getElementsByTagName('header').item(0);

			var TDrr=null;
            if(header)
            {
				TDrr=new Array();
				var cnt=0;
				for (x = 0; x < header.childNodes.length; x++) 
				{
					var sibl2 = header.childNodes.item(x);
					if (sibl2.childNodes.length > 0) 
					{
						sibl3 = sibl2.childNodes.item(0);
						AC_currentList2LoadHeaders[cnt] = sibl3.data;   
					}
					TDrr[cnt] = sibl2.attributes.getNamedItem("list").value=="yes"?true:false;
					cnt++;
				}
				
				//AC_Debug(AC_currentList2LoadHeaders);
				//AC_Debug(TDrr);
            }
            
            var irow=0;

			var node = root.getElementsByTagName('data').item(0)
			for (i = 0; i < node.childNodes.length; i++) 
			{
				var sibl = node.childNodes.item(i);
				var len = parseInt(sibl.childNodes.length / 2);
				var arr_fields = new Array(len);
				var arr_display = new Array(len);
				var cnt = 0, dcnt=0;
				for (x = 0; x < sibl.childNodes.length; x++) {
					var sibl2 = sibl.childNodes.item(x);
					var sibl3;
					if (sibl2.childNodes.length > 0) 
					{
						sibl3 = sibl2.childNodes.item(0);
						arr_fields[cnt] = sibl3.data;   
						if(TDrr==null || TDrr[cnt]==true)
						{
							arr_display[dcnt] = sibl3.data;
							dcnt++;
						}
						cnt++;
					}
				}
				
				AC_currentList2Load[irow]= arr_display;
				AC_currentList2LoadValues[irow]= arr_fields;
				irow++;
			}

            AC_ListLoadedForInput = AC_ListToBeLoadedForInput;
            AC_NewDropDown_Real(AC_ListLoadingForControl, 'new');
         } else {
			//comment alert by lia
            //alert('There was a problem with the data load.' );
         }
      }
   }
   
   var AC_currentList2Load = null;
   var AC_currentList2LoadValues = null;
   var AC_currentList2LoadHeaders = null;
   
   var AC_ListLoadedForInput = null;
   var AC_ListToBeLoadedForInput = null;
   var AC_ListLoadingForControl = null;
  
   function loadlistFor(editc, currentInput, url)
   {
   		AC_allCanons[currentControlIndex] = new Array();
		AC_allFields[currentControlIndex] = new Array();
		AC_allValues[currentControlIndex] = new Array();

		AC_currentList2Load = AC_allCanons[currentControlIndex];
		AC_currentList2LoadValues = AC_allValues[currentControlIndex];
		AC_currentList2LoadHeaders = AC_allFields[currentControlIndex];
		
		AC_ListLoadedForInput = null;
		AC_ListToBeLoadedForInput = currentInput;
		AC_ListLoadingForControl = editc;
		setTimeout("makeRequest('"+url+currentInput+"')",1);
   }

   function addrow(tbl, arr) 
   {
		var lastRow = tbl.rows.length;
		var row = tbl.insertRow(lastRow);
		for (r = 0; r < arr.length; r++) {   
			var cell = row.insertCell(r);
			cell.innerHTML = arr[r];
		}
		return row;
   }



