<!--

function MM_reloadPage(init) {  //reloads the window if Nav4 resized
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}
MM_reloadPage(true);


/******************************************
* Contractible Headers Script- ? Dynamic Drive (www.dynamicdrive.com)
* Visit http://www.dynamicdrive.com/ for full source code
* This notice must stay intact for use
******************************************/

var ns6=document.getElementById&&!document.all?1:0


var ie7 = document.all && !window.opera;


var head="display:''"
var folder=''

function expandit(curobj){
folder=ns6?curobj.nextSibling.nextSibling.style:document.all[curobj.sourceIndex+1].style
if (folder.display=="none")
folder.display=""
else
folder.display="none"
}

function confirmDelete(deleteURL, backURL)
{
	var c = confirm("Do you really want to delete this report?");
	if (c == true)
	{
		window.location=deleteURL;
	}
	else
	{
		window.location=backURL;
	}
}


function openAWindow( pageToLoad, winName, width, height, center) {
/* Opens a new window on the users desktop.
   Arguments:
    pageToLoad - The URL of a page to load in the browser window.
                 This can be a relative URL or fully qualified.
    winName - 	 Name of the new window.
    width - 	 The horizontal size of the new window.
    height - 	 The vertical size of the new window.
    center -     toggle centering on 4.0 browsers.
                  1=centered window 0=no centering

    Values in the "args" section below can all be toggled in the
    same fashion as the center toggle.  Just modify the appropriate
    value in the args section to be either 0 or 1.

    A call to this function might look like this:
    <a href="javascript:openAWindow('ice.asp','ice',375,250,1)">Ice</a>

   Created by Glenn Davis of Project Cool, Inc. for general use.  If
   you use this routine please leave all comments in place so that
   others may benefit as well.
*/

    xposition=0; yposition=0;
    if ((parseInt(navigator.appVersion) >= 4 ) && (center)){
        xposition = (screen.width - width) / 2;
        yposition = (screen.height - height) / 2;
    }
    args = "width=" + width + ","
    + "height=" + height + ","
    + "location=0,"
    + "menubar=0,"
    + "resizable=0,"
    + "scrollbars=1,"
    + "status=0,"
    + "titlebar=0,"
    + "toolbar=0,"
    + "hotkeys=0,"
    + "screenx=" + xposition + ","  //NN Only
    + "screeny=" + yposition + ","  //NN Only
    + "left=" + xposition + ","     //IE Only
    + "top=" + yposition;           //IE Only

    window.open( pageToLoad,winName,args );
}


function check(field, on)
{
  var i;
  if(typeof field.length != "undefined"){
  
	  for (i=0;i<field.length;i++)
	  {
	    var rowClass = 'row2';
	  	if (i%2 == 0)
	  		rowClass = 'row1';
	  	
	    field[i].checked=on;

	    highlight( field[i], field[i].value, rowClass );
	  }
	}
	else{ //there is checkbutton group with only 1 checkbutton in it.
	    field.checked=on;
	    highlight( field, field.value, 'row1' );	
	}
	  
}

function highlight( object, targetID, offstyle )
{   
	var docObj = document.getElementById( targetID );
	if( object.checked )
  { docObj.className = 'highlighted'; }
	else
	{ docObj.className = offstyle; }
}



// Cross Browser DOM
// copyright Stephen Chapman, 4th Jan 2005
// you may copy this code but please keep the copyright notice as well
var aDOM = 0, ieDOM = 0, nsDOM = 0; 
var stdDOM = document.getElementById;
if (stdDOM) 
	aDOM = 1; 
else 
{
	ieDOM = document.all; 
	if (ieDOM) 
		aDOM = 1; 
	else 
	{
		var nsDOM = ((navigator.appName.indexOf('Netscape') != -1) && (parseInt(navigator.appVersion) ==4)); 
		if (nsDOM) 
			aDOM = 1;
	}
}


function xDOM(objectId, wS) 
{
	if (stdDOM) return wS ? document.getElementById(objectId).style: document.getElementById(objectId);
	
	if (ieDOM) return wS ? document.all[objectId].style: document.all[objectId];
	
	if (nsDOM) return document.layers[objectId];
}


function fixIE()
{
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) 
  {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
    var newWidth = myWidth - 260;
    var newHeight = myHeight - 240;
    document.getElementById('items').style.height = parseInt(newHeight) + 'px';
    xDOM('expenseitemtable').width = parseInt(newWidth) + 'px';
  } 
  else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) 
  {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
    
	  myItems = xDOM('expenseitemtable', true);
	  var newWidth = myWidth - 260;
	  var newHeight = myHeight - 210;
	  document.getElementById('items').style.height = parseInt(newHeight) + 'px';
	  document.getElementById('items').style.width = parseInt(newWidth) + 'px';
	  myItems.width = parseInt(newWidth-20) + 'px';
	  
  } 
  else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) 
  {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
    
      myItems = xDOM('expenseitemtable', true);
	  var newWidth = myWidth - 260;
	  var newHeight = myHeight - 210;
	  document.getElementById('items').style.height = parseInt(newHeight) + 'px';
	  myItems.width = parseInt(newWidth) + 'px';
  }
}
	

function doSettings(action){

	document.settingsForm.settingsAction.value=action;
	document.settingsForm.settingsAction.submit();
}
//-->


/*function cleanFields(){

 document.expenseListForm.submitprint.value="";
 document.expenseListForm.submitpdf.value="";
 document.expenseListForm.submitexport.value="";
 document.expenseListForm.submitdelete.value="";
 document.expenseListForm.submitarchive.value="";
 document.expenseListForm.target='_self';
 document.expenseListForm.action="Expense.do";
}*/

function testChecked(field, ac,localized_error_message){

 var res=0;
 var i;
 document.expenseListForm.submitprint.value="";
 document.expenseListForm.submitpdf.value="";
 document.expenseListForm.submitexport.value="";
 document.expenseListForm.submitdelete.value="";
 document.expenseListForm.submitarchive.value="";
 
  if(typeof field.length != "undefined"){
  
	  for (i=0;i<field.length;i++){
	
	    if(field[i].checked){
	    	res = res +1;
	    }
	  }
	}
	else{
	  	 if(field.checked){
	    	res = res+1;
	     }
	}
	
	document.expenseListForm.action="Expense.do";
	if(res>0){

	    if(ac == "print"){
			document.expenseListForm.submitprint.value="true";
			document.expenseListForm.target='_blank';
			document.expenseListForm.submit();
			document.expenseListForm.submitprint.value="";
			document.expenseListForm.target='_self';
		}
	    else if(ac == "pdf"){
			document.expenseListForm.submitpdf.value="true";
			document.expenseListForm.target='_blank';
			document.expenseListForm.submit();
			document.expenseListForm.submitpdf.value="";
			document.expenseListForm.target='_self';
		}
	    else if(ac == "delete"){
			document.expenseListForm.submitdelete.value="true";
			document.expenseListForm.submit();
			document.expenseListForm.submitdelete.value="";
		}
	    else if(ac == "archive"){
			document.expenseListForm.submitarchive.value="true";
			document.expenseListForm.submit();
			document.expenseListForm.submitarchive.value="";
		}
		else if(ac == "export"){
			document.expenseListForm.submitexport.value="true";
			document.expenseListForm.target='_blank';
			document.expenseListForm.action="chooseExport.jsp";
			document.expenseListForm.submit();
			document.expenseListForm.submitexport.value="";
			document.expenseListForm.target='_self';
			document.expenseListForm.action="Expense.do";
		}
		

	}
	else
	{
		errorbox(localized_error_message);
	}
}

function errorbox(msg)
{
	errorwindow=window.open("","","width=250,height=125")
	errorwindow.document.write('<center>' + msg + '<form><input type="button" value="Close" onClick="window.close()"></form></center>')
	errorwindow.document.close()
	errorwindow.document.bgColor="white"
	return true
}

function goHome(){
	document.searchForm.action="index.jsp";
	document.searchForm.submit();
}

function goArchived(){
	document.searchForm.action="submitview.jsp?archivedBack=true";
	document.searchForm.submit();
}	
function setViewing(gUser, user){

	if(gUser == user){
		document.changeLanguageForm.action="index.jsp";
	}
	else{
		document.changeLanguageForm.action="View.do";
	}
	document.changeLanguageForm.submit();
}
function changeApp(ac){
	document.chooseAppForm.action=ac;
	document.chooseAppForm.submit();
}
function setCountryCode(code){
	if(code.length > 2){	
		document.registerationForm.elements['phone1'].value = code.substring(2);
	}
}
function addEditAccount(acc,parent){
	
	if(acc =='EditAccounts'){
		document.expenseForm.target='_blank';
	    document.expenseForm.action="editAccounts.jsp?parent="+parent;
		document.expenseForm.submit();
	}
}
function addEditCategory(acc,parent){
	
	if(acc =='EditCategories'){
		document.expenseForm.target='_blank';
	    document.expenseForm.action="editCategories.jsp?parent="+parent;
		document.expenseForm.submit();
	}
}
function addEditCurrencies(acc,parent){
	
	if(acc =='EditCurrencies'){
		document.expenseForm.target='_blank';
	    document.expenseForm.action="editCurrencies.jsp?parent="+parent;
		document.expenseForm.submit();
	}
}
function addEditPayments(acc,parent){
	
	if(acc =='EditPaymentMethods'){
		document.expenseForm.target='_blank';
	    document.expenseForm.action="editPayments.jsp?parent="+parent;
		document.expenseForm.submit();
	}
}

function checkPopup(combo, index, page)
{
	if ( index == combo.options.length-1 || (combo.options.length > 31 && index == 0) )
	{
		openAWindow(page + '.jsp?parent=index','newWin',800,600,1);
		
		if (combo.options.length > 31)
			combo.selectedIndex = 1;
		else
			combo.selectedIndex = 0;
	}
}

function fixDays(comboName, month, year)
{
	var combo = xDOM(comboName,false);
	var sel = combo.selectedIndex;
	var max_days = daysInMonth(month, year);
	createDayOption(combo, max_days);
	
	if (sel >= max_days) sel = max_days-1;
	combo.selectedIndex = sel;
}

function createDayOption(combo, numdays)
{
	var i;
	combo.options.length = 0;
	
	for (i = 1; i <= numdays; i++)
	{
		combo.options[i-1] = new Option(i + '',i + '');
	}
}

function daysInMonth(month, year)
{
	//month = parseInt(month);
	//year = parseInt(year);

	if (month == 0 || month == 2 || month == 4 || month == 6 || month == 7 ||  month == 9 || month == 11)
	{
		return 31;
	}
	else if (month == 1)
	{
		if(year%4 == 0)
		{
			if(year%100 != 0)
			{
				return 29;
			}
			else
			{
				if(year%400 == 0)
					return 29;
				else
					return 28;
			}
		}
		return 28;
	}
	else
	{
		return 30;
	}
}

function checkReimbursable(combo, index)
{
	if (combo.options[index].id == 0)
	{
		document.expenseListForm.a_reimbursable.checked = false;
	}
	else if (combo.options[index].id == 1)
	{
		document.expenseListForm.a_reimbursable.checked = true;
	}
}

function changeAccount(title)
{
	var isMileage = (title == 1);

	document.expenseListForm.currency.style.visibility = (isMileage) ? 'hidden' : 'visible';
	
	document.expenseListForm.taxes.style.visibility = (isMileage) ? 'hidden' : 'visible';
	document.expenseListForm.amount.style.visibility = (isMileage) ? 'hidden' : 'visible';
	
	
	if ( isMileage && document.expenseListForm.subtotal.alt != "" )
		document.expenseListForm.a_subtotal.value = document.expenseListForm.text_totalmileage.value;
	else if ( !isMileage && document.expenseListForm.subtotal.alt != "" )
		document.expenseListForm.a_subtotal.value = document.expenseListForm.text_subtotal.value;
	
	
	document.expenseListForm.distanceUnit.style.visibility = (!isMileage) ? 'hidden' : 'visible';
}

function changeAddAccount(title)
{
	var isMileage = (title == 1);

	document.expenseListForm.a_currency.style.visibility = (isMileage) ? 'hidden' : 'visible';
	
	document.expenseListForm.a_taxes.style.visibility = (isMileage) ? 'hidden' : 'visible';
	document.expenseListForm.a_amount.style.visibility = (isMileage) ? 'hidden' : 'visible';
	
	
	if ( isMileage && document.expenseListForm.a_subtotal.alt != "" )
		document.expenseListForm.a_subtotal.value = document.expenseListForm.text_totalmileage.value;
	else if ( !isMileage && document.expenseListForm.a_subtotal.alt != "" )
		document.expenseListForm.a_subtotal.value = document.expenseListForm.text_subtotal.value;
	
	
	document.expenseListForm.a_distanceUnit.style.visibility = (!isMileage) ? 'hidden' : 'visible';
}



function diseableForMileage(acc){


      if(acc == -1){
				document.expenseForm.currency.disabled = true;
				
				document.expenseForm.subtotal.value = "0.00";
				document.expenseForm.subtotal.disabled = true;
				document.expenseForm.taxes.value = "0.00";
				document.expenseForm.taxes.disabled = true;
				
				document.expenseForm.distanceUnit.disabled = false;
				document.expenseForm.typeofacc.value="mileageacc";
				document.expenseForm.vendor.style.backgroundColor="#EEEEEE";
				document.expenseForm.taxes.style.backgroundColor="#EEEEEE";
				document.expenseForm.subtotal.style.backgroundColor="#EEEEEE";
				document.expenseForm.currency.style.backgroundColor="#EEEEEE";
				document.expenseForm.payment.style.backgroundColor="#EEEEEE";
				document.expenseForm.distanceUnit.style.backgroundColor="#FFFFFF";

		}
		else{
				document.expenseForm.currency.disabled = false;
				
				document.expenseForm.subtotal.disabled = false;
				document.expenseForm.taxes.disabled = false;
				
				document.expenseForm.distanceUnit.disabled = true;
				document.expenseForm.typeofacc.value="notmileageacc";
				document.expenseForm.vendor.style.backgroundColor="#FFFFFF";
				document.expenseForm.taxes.style.backgroundColor="#FFFFFF";
				document.expenseForm.subtotal.style.backgroundColor="#FFFFFF";
				document.expenseForm.currency.style.backgroundColor="#FFFFFF";
				document.expenseForm.payment.style.backgroundColor="#FFFFFF";
				document.expenseForm.distanceUnit.style.backgroundColor="#EEEEEE";

		}
}

function submitenterIndex(myfield,e)
{
	var keycode;
	if (window.event) keycode = window.event.keyCode;
	else if (e) keycode = e.which;
	else return true;
	
	if (keycode == 13) //Enter keycode
	   return false;
	else
	   return true;
}

function openEditForm(tar){

	 document.expenseForm.target='_blank';
	 document.expenseForm.action=tar;
	 document.expenseForm.submit();
}
function checkAcc(numUsers, msg){
	
	if(numUsers>0){
		var agree=confirm(msg);
		if (agree)
			return true ;
		else
		return false ;
	}
	else{
		return true;
	}
	
}

function clearHint(textbox)
{
	if ( textbox.alt != "" )
	{
		textbox.value = "";
		textbox.alt = "";
		
		if (textbox.name == 'subtotal' || textbox.name == 'taxes' || textbox.name == 'amount')
			
		{
			if (textbox.name == 'subtotal')
			{
				document.expenseListForm.subtotal.value = "0.00";
				document.expenseListForm.subtotal.alt = "";
			}
			
			if (textbox.name == 'taxes')
			{
				document.expenseListForm.taxes.value = "0.00";
				document.expenseListForm.taxes.alt = "";
			}
			
			document.expenseListForm.amount.value = "0.00";
			document.expenseListForm.amount.alt = "";
			textbox.value = "";
		}
		
		if (textbox.name == 'a_subtotal' || textbox.name == 'a_taxes' || textbox.name == 'a_amount')
		{
			if (textbox.name == 'a_subtotal')
			{
				document.expenseListForm.a_subtotal.value = "0.00";
				document.expenseListForm.a_subtotal.alt = "";
			}
			else if (document.expenseListForm.a_subtotal.alt != "")
			{
				document.expenseListForm.a_subtotal.value = "";
			}
			
			if (textbox.name == 'a_taxes')
			{
				document.expenseListForm.a_taxes.value = "0.00";
				document.expenseListForm.a_taxes.alt = "";
			}
			else if (document.expenseListForm.a_taxes.alt != "")
			{
				document.expenseListForm.a_taxes.value = "";
			}
			
			document.expenseListForm.a_amount.value = "0.00";
			document.expenseListForm.a_amount.alt = "";
			textbox.value = "";			
		}
		
		
	}
	textbox.style.color = "#000";
	textbox.focus();
}


function resetHint(textbox, hint)
{
	if ( textbox.value.length == 0 )
	{
		textbox.value = hint;
		textbox.style.color = "#AAA";
		textbox.alt = "[]";
	}
	textbox.focus();
}

function isUndefined(a) {
    return typeof a == 'undefined';
} 

function submitHints()
{
	if ( !isUndefined(document.expenseListForm.subtotal))
	{
		//then we are editing an expense
		if ( document.expenseListForm.subtotal.alt.length != 0 )
		{
			document.expenseListForm.subtotal.value = "0.00";
		}
		
		if ( document.expenseListForm.taxes.alt.length != 0 )
		{
			document.expenseListForm.taxes.value = "0.00";
		}
		
		if ( document.expenseListForm.amount.alt.length != 0 )
		{
			document.expenseListForm.amount.value = "0.00";
		}
		
		if ( document.expenseListForm.note.alt.length != 0 )
		{
			document.expenseListForm.note.value = "";
		}
		
		if ( document.expenseListForm.vendor.alt.length != 0 )
		{
			document.expenseListForm.vendor.value = "";
		}
		
		if ( document.expenseListForm.attendee.alt.length != 0 )
		{
			document.expenseListForm.attendee.value = "";
		}
	}
	else
	{
		//we are adding
		if ( document.expenseListForm.a_subtotal.alt.length != 0 )
		{
			document.expenseListForm.a_subtotal.value = "0.00";
		}
		
		if ( document.expenseListForm.a_taxes.alt.length != 0 )
		{
			document.expenseListForm.a_taxes.value = "0.00";
		}
		
		if ( document.expenseListForm.a_amount.alt.length != 0 )
		{
			document.expenseListForm.a_amount.value = "0.00";
		}
		
		if ( document.expenseListForm.a_note.alt.length != 0 )
		{
			document.expenseListForm.a_note.value = "";
		}
		
		if ( document.expenseListForm.a_vendor.alt.length != 0 )
		{
			document.expenseListForm.a_vendor.value = "";
		}
		
		if ( document.expenseListForm.a_attendee.alt.length != 0 )
		{
			document.expenseListForm.a_attendee.value = "";
		}
		
	}
}
		




/***********************************************
* Link Floatie script- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/
var floatiewidth="250px" //default width of floatie in px
var floatieheight="80px" //default height of floatie in px. Set to "" to let floatie content dictate height.
var floatiebgcolor="lightyellow" //default bgcolor of floatie
var fadespeed=50 //speed of fade (5 or above). Smaller=faster.

var baseopacity=0
function slowhigh(which2){
imgobj=which2
browserdetect=which2.filters? "ie" : typeof which2.style.MozOpacity=="string"? "mozilla" : ""
instantset(baseopacity)
highlighting=setInterval("gradualfade(imgobj)",fadespeed)
}

function instantset(degree){
cleartimer()
if (browserdetect=="mozilla")
imgobj.style.MozOpacity=degree/100
else if (browserdetect=="ie")
imgobj.filters.alpha.opacity=degree
}

function cleartimer(){
if (window.highlighting) clearInterval(highlighting)
}

function gradualfade(cur2){
if (browserdetect=="mozilla" && cur2.style.MozOpacity<1)
cur2.style.MozOpacity=Math.min(parseFloat(cur2.style.MozOpacity)+0.1, 0.99)
else if (browserdetect=="ie" && cur2.filters.alpha.opacity<100)
cur2.filters.alpha.opacity+=10
else if (window.highlighting)
clearInterval(highlighting)
}

function ietruebody(){
return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}

function paramexists(what){
return(typeof what!="undefined" && what!="")
}

function showfloatie(thetext, e, optbgColor, optWidth, optHeight){
var dsocx=(window.pageXOffset)? pageXOffset: ietruebody().scrollLeft;
var dsocy=(window.pageYOffset)? pageYOffset : ietruebody().scrollTop;
var floatobj=document.getElementById("dhtmlfloatie")
floatobj.style.left="-900px"
floatobj.style.display="block"
floatobj.style.backgroundColor=paramexists(optbgColor)? optbgColor : floatiebgcolor
floatobj.style.width=paramexists(optWidth)? optWidth+"px" : floatiewidth
floatobj.style.height=paramexists(optHeight)? optHeight+"px" : floatieheight!=""? floatieheight : ""
floatobj.innerHTML=thetext
var floatWidth=floatobj.offsetWidth>0? floatobj.offsetWidth : floatobj.style.width
var floatHeight=floatobj.offsetHeight>0? floatobj.offsetHeight : floatobj.style.width
var winWidth=document.all&&!window.opera? ietruebody().clientWidth : window.innerWidth-20
var winHeight=document.all&&!window.opera? ietruebody().clientHeight : window.innerHeight
e=window.event? window.event : e
floatobj.style.left=dsocx+winWidth-floatWidth-5+"px"
if (e.clientX>winWidth-floatWidth && e.clientY+20>winHeight-floatHeight)
floatobj.style.top=dsocy+5+"px"
else
floatobj.style.top=dsocy+winHeight-floatHeight-5+"px"
slowhigh(floatobj)
}

function hidefloatie(){
var floatobj=document.getElementById("dhtmlfloatie")
floatobj.style.display="none"
}

/*Auto Suggest functions **********************************/


//global
var currentActiveSuggestion;
var autosuggest_busy = false;


/**
 * Provides suggestions for past entries
 * @class
 * @scope public
 */
function StateSuggestions(historyArray) {
    this.states = historyArray;
}

/**
 * Request suggestions for the given autosuggest control. 
 * @scope protected
 * @param oAutoSuggestControl The autosuggest control to provide suggestions for.
 */
StateSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
                                                          bTypeAhead /*:boolean*/) {
   
    var aSuggestions = [];
    var sTextboxValue = oAutoSuggestControl.textbox.value;
    
    if (sTextboxValue.length > 0){
    
        //search for matching states
        for (var i=0; i < this.states.length; i++) { 
            if (this.states[i].toLowerCase().indexOf(sTextboxValue.toLowerCase()) == 0) {
                aSuggestions.push(this.states[i]);
            } 
        }
    }

    //provide suggestions to the control
    //if (aSuggestions.length == 1)
    //	oAutoSuggestControl.autosuggest(aSuggestions, true);
    //else
    	oAutoSuggestControl.autosuggest(aSuggestions, false);
    	
};


/**
 * An autosuggest textbox control.
 * @class
 * @scope public
 */
function AutoSuggestControl(oTextbox /*:HTMLInputElement*/, 
                            oProvider /*:SuggestionProvider*/) {
    
    /**
     * The currently selected suggestions.
     * @scope private
     */   
    this.cur /*:int*/ = -1;

    /**
     * The dropdown list layer.
     * @scope private
     */
    this.layer = null;
    
    /**
     * Suggestion provider for the autosuggest feature.
     * @scope private.
     */
    this.provider /*:SuggestionProvider*/ = oProvider;
    
    /**
     * The textbox to capture.
     * @scope private
     */
    this.textbox /*:HTMLInputElement*/ = oTextbox;
    
    //initialize the control
    this.init();
    
}

/**
 * Autosuggests one or more suggestions for what the user has typed.
 * If no suggestions are passed in, then no autosuggest occurs.
 * @scope private
 * @param aSuggestions An array of suggestion strings.
 * @param bTypeAhead If the control should provide a type ahead suggestion.
 */
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/,
                                                     bTypeAhead /*:boolean*/) {

    //make sure there's at least one suggestion
    if (aSuggestions.length > 0) {
        
        //Ryan - this method doesn't work well with fast typing
        if (bTypeAhead) {
           this.typeAhead(aSuggestions[0]);
        }
        
        this.showSuggestions(aSuggestions);
    } else {
        this.hideSuggestions();
    }
};

/**
 * Creates the dropdown layer to display multiple suggestions.
 * @scope private
 */
AutoSuggestControl.prototype.createDropDown = function () {

    var oThis = this;

    //create the layer and assign styles
    this.layer = document.createElement("div");
    this.layer.className = "suggestions";
    this.layer.style.visibility = "hidden";
    this.layer.style.width = this.textbox.offsetWidth;
    
    //when the user clicks on the a suggestion, get the text (innerHTML)
    //and place it into a textbox
    this.layer.onmousedown = 
    this.layer.onmouseup = 
    this.layer.onmouseover = function (oEvent) {
        oEvent = oEvent || window.event;
        oTarget = oEvent.target || oEvent.srcElement;

        if (oEvent.type == "mousedown") {
            oThis.textbox.value = oTarget.firstChild.nodeValue;
            oThis.hideSuggestions();
        } else if (oEvent.type == "mouseover") {
            oThis.highlightSuggestion(oTarget);
        } else {
            oThis.textbox.focus();
        }
    };
    
    
    document.body.appendChild(this.layer);
};

function isObject(a)
{
     return (typeof a == 'object' && !!a);
}

/**
 * Gets the left coordinate of the textbox.
 * @scope private
 * @return The left coordinate of the textbox in pixels.
 */
AutoSuggestControl.prototype.getLeft = function () /*:int*/ {

    var oNode = this.textbox;
    var iLeft = 0;
    
    while(isObject(oNode) && oNode.tagName != "BODY") {
        iLeft += oNode.offsetLeft;
        oNode = oNode.offsetParent;        
    }
    
    if (ie7)
    	return iLeft - 30;
    else
    	return iLeft;
};

/**
 * Gets the top coordinate of the textbox.
 * @scope private
 * @return The top coordinate of the textbox in pixels.
 */
AutoSuggestControl.prototype.getTop = function () /*:int*/ {

    var oNode = this.textbox;
    var iTop = 0;
    
    while(isObject(oNode) && oNode.tagName != "BODY") {
        iTop += oNode.offsetTop;
        oNode = oNode.offsetParent;
    }

    return iTop;
};

/**
 * Handles three keydown events.
 * @scope private
 * @param oEvent The event object for the keydown event.
 */
AutoSuggestControl.prototype.handleKeyDown = function (oEvent /*:Event*/) {
	
    switch(oEvent.keyCode) {
        case 38: //up arrow
            this.previousSuggestion();
            break;
        case 40: //down arrow 
            this.nextSuggestion();
            break;
        case 13: //enter
            this.hideSuggestions();
            break;
    }


};

/**
 * Handles keyup events.
 * @scope private
 * @param oEvent The event object for the keyup event.
 */
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
	

    var iKeyCode = oEvent.keyCode;
    


    //for backspace (8) and delete (46), shows suggestions without typeahead
    if (iKeyCode == 8 || iKeyCode == 46) {
        this.provider.requestSuggestions(this, false);
        
    //make sure not to interfere with non-character keys
    } 
    
    //tab key to autocomplete using typeahead
    //else if (iKeyCode == 9) {
    //    this.provider.requestSuggestions(this, true);
    //}
    
    else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
        //ignore
    } else {
        //request suggestions from the suggestion provider with typeahead
        this.provider.requestSuggestions(this, false);
    }

};

/**
 * Hides the suggestion dropdown.
 * @scope private
 */
AutoSuggestControl.prototype.hideSuggestions = function () {
    this.layer.style.visibility = "hidden";
};

/**
 * Highlights the given node in the suggestions dropdown.
 * @scope private
 * @param oSuggestionNode The node representing a suggestion in the dropdown.
 */
AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
    
    for (var i=0; i < this.layer.childNodes.length; i++) {
        var oNode = this.layer.childNodes[i];
        if (oNode == oSuggestionNode) {
            oNode.className = "current"
        } else if (oNode.className == "current") {
            oNode.className = "";
        }
    }
};

/**
 * Initializes the textbox with event handlers for
 * auto suggest functionality.
 * @scope private
 */
AutoSuggestControl.prototype.init = function () {

    //save a reference to this object
    var oThis = this;
    
    //assign the onkeyup event handler
    this.textbox.onkeyup = function (oEvent) {
    
        //check for the proper location of the event object
        if (!oEvent) {
            oEvent = window.event;
        }    
        
        //call the handleKeyUp() method with the event object
        oThis.handleKeyUp(oEvent);
    };
    
    //assign onkeydown event handler
    this.textbox.onkeydown = function (oEvent) {
    
        //check for the proper location of the event object
        if (!oEvent) {
            oEvent = window.event;
        }    
        
        //call the handleKeyDown() method with the event object
        oThis.handleKeyDown(oEvent);
    };
    
    //assign onblur event handler (hides suggestions)    
    this.textbox.onblur = function () {
        oThis.hideSuggestions();
    };
    
    //create the suggestions dropdown
    this.createDropDown();
};

/**
 * Highlights the next suggestion in the dropdown and
 * places the suggestion into the textbox.
 * @scope private
 */
AutoSuggestControl.prototype.nextSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
        var oNode = cSuggestionNodes[++this.cur];
        this.highlightSuggestion(oNode);
        this.textbox.value = oNode.firstChild.nodeValue; 
    }
};

/**
 * Highlights the previous suggestion in the dropdown and
 * places the suggestion into the textbox.
 * @scope private
 */
AutoSuggestControl.prototype.previousSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0 && this.cur > 0) {
        var oNode = cSuggestionNodes[--this.cur];
        this.highlightSuggestion(oNode);
        this.textbox.value = oNode.firstChild.nodeValue;   
    }
};

/**
 * Selects a range of text in the textbox.
 * @scope public
 * @param iStart The start index (base 0) of the selection.
 * @param iLength The number of characters to select.
 */
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*:int*/) {


    //use text ranges for Internet Explorer
    if (this.textbox.createTextRange) {
        var oRange = this.textbox.createTextRange(); 
        oRange.moveStart("character", iStart); 
        oRange.moveEnd("character", iLength - this.textbox.value.length);      
        oRange.select();
        
    //use setSelectionRange() for Mozilla
    } else if (this.textbox.setSelectionRange) {
        this.textbox.setSelectionRange(iStart, iLength);
    }     

    //set focus back to the textbox
    this.textbox.focus();

    
}; 

/**
 * Builds the suggestion layer contents, moves it into position,
 * and displays the layer.
 * @scope private
 * @param aSuggestions An array of suggestions for the control.
 */
AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/) {
    
    var oDiv = null;
    this.layer.innerHTML = "";  //clear contents of the layer
    
    for (var i=0; i < aSuggestions.length; i++) {
        oDiv = document.createElement("div");
        oDiv.appendChild(document.createTextNode(aSuggestions[i]));
        this.layer.appendChild(oDiv);
    }
    
    this.layer.style.left = this.getLeft() + "px";
    this.layer.style.top = (this.getTop()+this.textbox.offsetHeight) + "px";
    this.layer.style.visibility = "visible";

};

/**
 * Inserts a suggestion into the textbox, highlighting the 
 * suggested part of the text.
 * @scope private
 * @param sSuggestion The suggestion for the textbox.
 */
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {

    //check for support of typeahead functionality
    if (this.textbox.createTextRange || this.textbox.setSelectionRange){
        var iLen = this.textbox.value.length; 
        this.textbox.value = sSuggestion; 
        this.selectRange(iLen, sSuggestion.length);
    }
};


/* end Auto Suggest functions *******************************/




/*
Ajax stuff
*/

function createRequestObject() {
    var ro;
    var browser = navigator.appName;
    if(browser == "Microsoft Internet Explorer"){
        ro = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        ro = new XMLHttpRequest();
    }
    return ro;
}

var http = createRequestObject();
var isEditing = false;


/** Editing Ajax **/ 
function sndReq(id, i, etype) 
{
    http.open('get', 'ajax_editrow.jsp?editid='+id + '&index='+i+ '&type=' + etype);
    http.onreadystatechange = handleResponse;
    http.send(null);
}

function handleResponse() //Note that row.innerHTML is read-only, unless we made the row.
{ 
    if(http.readyState == 4)
    {
        var response = http.responseText;
        var update = new Array();

        if( response.indexOf('|') != -1 && !isEditing ) 
        {
            update = response.split('|');
            
            var index = parseInt( trim( update[1] ) );
            var realindex = index+2;
            
            //disable the add row
            var addrow = document.getElementById('expenseitemtable').rows[1];
            addrow.style.backgroundColor = '#eee';
            document.getElementById('a_add').disabled = true;
            document.getElementById('a_subtotal').disabled = true;
            document.getElementById('a_taxes').disabled = true;
            document.getElementById('a_amount').disabled = true;
            document.getElementById('a_vendor').disabled = true;
            document.getElementById('a_attendee').disabled = true;
            document.getElementById('a_note').disabled = true;
            document.expenseListForm.a_currency.disabled = true;
            document.expenseListForm.a_payment.disabled = true;
            document.expenseListForm.a_category.disabled = true;
            document.expenseListForm.a_account.disabled = true;
            document.expenseListForm.a_month.disabled = true;
            document.expenseListForm.a_date.disabled = true;
            document.expenseListForm.a_year.disabled = true;
            document.expenseListForm.a_reimbursable.disabled = true;
           
            
            //change the non-editable row
            var expenserows = document.getElementById('expenseitemtable').rows;
            
            var i = 0;
            for (i = 2; i < expenserows.length-4; i++)
            {
            	if (i == realindex)
            	{
		            var x = expenserows[realindex];
		            x.style.backgroundColor = '#ff0';
		            
		            if (x.cells.length == 7)
		            {
		
						x.deleteCell(6);
						x.deleteCell(5);
						
						x.cells[0].innerHTML = trim(update[2]);
						x.cells[0].colSpan="3";
						
						x.cells[1].innerHTML = trim(update[3]);
						x.cells[2].innerHTML = trim(update[4]);
						x.cells[3].innerHTML = trim(update[5]);
						x.cells[4].innerHTML = trim(update[6]);
					}
					else
					{
						x.cells[0].innerHTML = trim(update[2]);
						x.cells[0].colSpan="3";
						
						x.cells[1].innerHTML = trim(update[3]);
						x.cells[2].innerHTML = trim(update[4]);
						x.cells[3].innerHTML = trim(update[5]);
						x.cells[3].colSpan="3";
						x.cells[4].innerHTML = trim(update[6]);
						x.cells[4].colSpan="2";
						
						x.deleteCell(9);
						x.deleteCell(8);
						x.deleteCell(7);
						x.deleteCell(6);
						x.deleteCell(5);
					}
				}
				else
				{
					expenserows[i].cells[0].innerHTML = "<input type='checkbox' disabled ='true'>";
					expenserows[i].cells[1].innerHTML = "<img src='images/editgrey.gif' border='0' width='16' height='16' align='absmiddle'>";
				}
			}
			
            isEditing = true;
            changeAccount( parseInt(trim(update[0])) );
        }
    }
}

// Removes leading whitespaces
function LTrim( value ) {
	
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
	
}

// Removes ending whitespaces
function RTrim( value ) {
	
	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");
	
}

// Removes leading and ending whitespaces
function trim( value ) {
	return LTrim(RTrim(value));
}

