





















        

<!-- version 2014.2 -->



var dummy;


var undefined;
window.currentMenu = null;

document.onmousemove = function(evnt)
{
	autoSuggestOnMouseMove(evnt);
    quickaddDraggerOnMouseMove(evnt);
    
	    portletDraggerOnMouseMove(evnt);
        ddmOnMouseMove(evnt);
        dropdownOnMouseMove(evnt);
    
}

window.clickCount = 0;

function documentOnClickHandler(evnt) {
    ++window.clickCount;
    
    ddmOnClick(evnt);
    
    
    if( window.popup_onClickHandler )
        window.popup_onClickHandler(evnt);
}

if (document.addEventListener) {
document.addEventListener('click', documentOnClickHandler, false);
} else if (document.attachEvent) {
    document.attachEvent("onclick", documentOnClickHandler);
} else {
    document.onclick = documentOnClickHandler;
}

document.onmousedown = function(evnt)
{
    
        quickaddDraggerOnMouseDown(evnt);
        portletDraggerOnMouseDown(evnt);
        dropdownOnMouseDown(evnt);
    
	NLPopupAutoSuggest_onMouseDown(evnt);
	if (window.divsToClose && typeof(window.divsToClose) != 'undefined')
	{
        for (var i=0;i<window.divsToClose.length;i++)
            document.getElementById(window.divsToClose[i]).style.display='none';
        window.divsToClose = null;
	}
}

document.onmouseup =  function(evnt)
{
    
        quickaddDraggerOnMouseUp();
        portletDraggerOnMouseUp();
        dropdownOnMouseUp(evnt);
    

    
    if( window.NLCalendar_onMouseUp )
    {
        NLCalendar_onMouseUp(evnt);
    }

    if(window.NLMachine_onMouseUp )
    {
        NLMachine_onMouseUp(evnt);
    }

	
	if ( window.OrderedListOnMouseUp != null )
		window.OrderedListOnMouseUp( evnt );
}

document.onkeydown = function(evnt)
{
	handleHotKeys(evnt);
	NLPopupAutoSuggest_onKeyDown(evnt);
	return dropdownOnKeyDown(evnt);
}

function addDivToClose(div_id)
{
	if (typeof(window.divsToClose) != 'Array')
        window.divsToClose = new Array();
    window.divsToClose[window.divsToClose.length] = div_id;
}

function handleHotKeys(evnt)
{
	
	if(getEventKeypress(evnt)==71 && getEventAltKey(evnt))
	{
		var globalSearchFld = document.getElementById("_searchstring");
		if(globalSearchFld != null)
		{
			globalSearchFld.focus();
			globalSearchFld.select();
		}
	}
}

function getMouseX(evnt)
{
    return getEvent(evnt).clientX;
}

function getMouseY(evnt)
{
    return getEvent(evnt).clientY;
}



function moveToolTip(x, y) {
	var tooltip = getToolTip(),
		tooltipWidth = parseInt(tooltip.offsetWidth),
		bodyWidth = document.body.clientWidth,
		bodyScroll = getWindowPageXOffset();
		rightLimit = bodyWidth - tooltipWidth,
		left = x - 9;

	if (left > rightLimit) {
		left = rightLimit;
	}
	if (left < 0) {
		left = 0;
	}

	tooltip.style.left = (bodyScroll + left) + "px";
	tooltip.style.top = y + document.body.scrollTop + 5 + "px";
}


function showToolTip(title, content, redraw) {
	if ( isValEmpty(title) && isValEmpty(content) )
		return;

	var tooltipHTML ='<table border="0" width="250" cellspacing="0" cellpadding="0" bgcolor="#999999">'+
				        '<tr><td width="100%">'+
				            '<table border="0" width="100%" cellspacing="1" cellpadding="2" align="center">';
	if ( !isValEmpty(title) )
		tooltipHTML +=          '<tr><td width="100%" class="bglt"><font class="smalltextb">' + title + '</font></td></tr>';
	if ( !isValEmpty(content) )
		tooltipHTML +=          '<tr><td width="100%" bgcolor="#FFFFFF"><font class="smalltext">' + content + '</font></td></tr>';
	tooltipHTML +=	        '</table>'+
						'</td></tr>'+
					'</table>';

	var tooltip = getToolTip();
	<!-- keep tooltip still if we come back over the same UI -->
	tooltip.movetooltip = redraw || isValEmpty(tooltip.tooltipcontent) || tooltip.tooltipcontent != tooltipHTML;
	tooltip.tooltipcontent = tooltipHTML;
	<!-- do not hide tooltip anymore -->
	if ( tooltip.hidetooltiptimer != null )
		clearTimeout(tooltip.hidetooltiptimer);
	<!-- 500ms delay before showing tooltip -->
	tooltip.showtooltiptimer = setTimeout(function () {
		if (tooltip.movetooltip)
			moveToolTip(lastX + 20, lastY);
		tooltip.innerHTML = tooltip.tooltipcontent;
		tooltip.style.visibility = 'visible';
	}, 500);
}

<!-- stop the timer to hide the tooltip.  -->
function stopToolTipHide() {
	var tooltip=getToolTip();
	if (tooltip.hidetooltiptimer != null)
		clearTimeout(tooltip.hidetooltiptimer);
}

<!-- hide tooltip widget -->
function hideToolTip() {
	var tooltip = getToolTip();
	<!-- do not show tooltip anymore -->
	if ( tooltip.showtooltiptimer != null )
		clearTimeout(tooltip.showtooltiptimer);
	tooltip.tooltipcontent = '';
	<!-- 500ms delay before hiding tooltip -->
	tooltip.hidetooltiptimer = setTimeout(function () {
		tooltip.tooltipcontent = null;
		tooltip.style.visibility = 'hidden';
	}, 1000);
}

<!-- returns (optionally creates) the tooltip widget -->
function getToolTip() {
	var tooltip = document.getElementById('NLToolTip');
	if ( tooltip == null )
	{
		tooltip = document.createElement("DIV");
		tooltip.id = 'NLToolTip';
		tooltip.style.position='absolute';
		tooltip.style.width='250px';
		tooltip.style.top='0px';
		tooltip.style.left='0px';
		tooltip.style.zIndex=4;
		tooltip.style.visibility='hidden';

		document.body.appendChild(tooltip);
	}
	return tooltip;
}





window.menusAreOpen = false;

window.rolloverDelay = 0;





var m_multiButtons = new Array();


function getNLMultiButtonByName(sName)
{
    return m_multiButtons[sName];
}


function NLMultiButton(sName, pValues, sDefaultValue, sTaskId, sPrimaryMultiButtonName, bSecondary, bYellowBg, bBlueBg)
{
    var params = new Array(); 

    this.sName = sName;
    m_multiButtons[sName] = this;

    this.sTaskId = sTaskId;
    this.sPrimaryButtonName = sPrimaryMultiButtonName;
    this.bSecondary = bSecondary;
    this.bYellowBg = bYellowBg;
    this.bBlueBg = !!bBlueBg;

    this.bEnabled = true;

    var j = 0;

    
    for(i=0; i< pValues.length;i++)
    {
        if(pValues[i][0] == sDefaultValue)
        {
            this.nDefault = i;
        }
        else
        {
            params[j] = [pValues[i][0], 'javascript:NLMultiButton_doAction(\'' + sName + '\', \'' + pValues[i][1]  + '\');return false;', ''];
            j++;
        }
    }
    this.sParams  = params;
    this.pValues  = pValues;
    this.nButtons = pValues.length;

    var sType = 'submit';
    var sTrClass = bYellowBg ? "pgBntY" : "pgBntG";

    if(!!bBlueBg){
        sTrClass += " pgBntB";
    };

    
    this.sHTML = '<table cellpadding=0 cellspacing=0 border=0 class="uir-multibutton" style="cursor:hand;margin-right:6px;">' +
                    '<tr class="'+sTrClass+ '">' +
                        '<td><img src="/images/nav/ns_x.gif" class="bntLT" border=0 height="50%" width=3><img src="/images/nav/ns_x.gif" class="bntLB" border=0 height="50%" width=3></td>' +
                        '<TD id="spn_' + sName +'" nowrap class="bntBgB" valign="top" height=20>' +
                                '<input onBlur="NLMultiButton_clearMultiButtonMenus();" onKeyDown="return getNLMultiButtonByName(\'' + sName + '\').onKeyPress(event);" onClick="getNLMultiButtonByName(\'' + sName + '\').onMainButtonClick(this);return false;" id="btn_' + sName + '" type="' + sType + '" '+
                                    'class="rndbuttoninpt bntBgT'+(bSecondary ? 'small' : '')+'" style="vertical-align:middle;" value="' + sDefaultValue + '" onKeyPress="setEventCancelBubble(event);" ' +
                                    'onmousedown="this.setAttribute(\'_mousedown\',\'T\'); setButtonDown(true, '+(bSecondary ? 'true' : 'false')+', this);" '+
                                    'onmouseup="this.setAttribute(\'_mousedown\',\'F\'); setButtonDown(false, '+(bSecondary ? 'true' : 'false')+', this);" '+
                                    'onmouseout="if(this.getAttribute(\'_mousedown\')==\'T\') setButtonDown(false, '+(bSecondary ? 'true' : 'false')+', this);" '+
                                    'onmouseover="if(this.getAttribute(\'_mousedown\')==\'T\') setButtonDown(true, '+(bSecondary ? 'true' : 'false')+', this);">'+
                        '</td>' +
                        '<td nowrap valign="top" class="bntBgB multiBnt" onMouseOut="NLMultiButton_onArrowMouseOut(\'' + sName + '\')" onMouseOver="NLMultiButton_onArrowMouseOver(\'' + sName + '\')" onClick="getNLMultiButtonByName(\'' + sName + '\').onDropDownClick(this, event);">' +
				           	'<div style="padding: 2px 3px 0px 4px;" class="bntBgT">' +
                              '<img class="multiBntTri" height="12" border="0" width="8" src="/images/nav/ns_x.gif" alt="More Options">'+
	    					'</div>'+
                        '</td>' +
						'<td><img src="/images/nav/ns_x.gif" height="50%" class="bntRT" border=0 width=3><img src="/images/nav/ns_x.gif" height="50%" class="bntRB" border=0 width=3></td>'+
                    '</tr>' +
                '</table>';

    this.toString = function(){return this.sHTML;};
    this.writeInlineHTML = function(){document.write(sHTML);};
}

function NLMultiButton_clearMultiButtonMenus()
{
    for(i in menus)
        if(menus[i].tabName != null && menus[i].tabName.indexOf('mulitibutton')>=0)
            menus[i].close();
}

function NLMultiButton_getBackgroundImageHtml(sImageUrl)
{
     return "background-image:url("+sImageUrl+");";
}

NLMultiButton.prototype.onMainButtonClick = function(span)
{
    NLMultiButton_doAction(this.sName, this.pValues[this.nDefault][1]);
}

NLMultiButton.prototype.setState = function(bEnabled)
{
    if (this.bEnabled == bEnabled)
        return;

    this.bEnabled = bEnabled;

    var buttonElem = document.getElementById("btn_" + this.sName);

    buttonElem.disabled = !bEnabled;
}



function NLMultiButton_doAction(sMultiButtonName, sButtonID)
{
    

    var frmMain = document.forms['main_form'];
    var btnHidden;
    
    if(frmMain && frmMain.elements[sButtonID] != null)
    {
        btnHidden = frmMain.elements[sButtonID];
    }
    else
    {
        btnHidden = document.getElementById(sButtonID);
    }

    
    if( (btnHidden.type == "submit") && sMultiButtonName)
    {
        var multibtn = getNLMultiButtonByName(sMultiButtonName);

        if(multibtn.sTaskId && multibtn.sPrimaryButtonName && multibtn.pValues[multibtn.nDefault][1] != sButtonID)
        {
            frmMain.elements['_multibtnstate_'].value = multibtn.sTaskId + ":" + multibtn.sPrimaryButtonName + ":" + btnHidden.name;
        }
    }

    btnHidden.click();
}


function NLMultiButton_openMenu(sName)
{
    clearAllMenusExcept(sName);
    var mbtn = getNLMultiButtonByName(sName);
    if (!mbtn.bEnabled)
        return;
    var menu = mbtn.getMenu();
    menu.setOpenMenuUpwardIfNotBelow(true);
    menu.setAllowArbitraryHtmlInMenuEntries(true);
    menu.showHide(true);
}


function NLMultiButton_onArrowMouseOut(sName)
{
    clearTimeout(window.rolloverDelay);
}


function NLMultiButton_onArrowMouseOver(sName)
{
    
    window.rolloverDelay = setTimeout('NLMultiButton_openMenu(\'' + sName + '\')', 100);
}


NLMultiButton.prototype.onKeyPress = function(evt)
{
    
    if(!isIE)
        return true;

    var kc = getEventKeypress(evt);

    var menu = this.getMenu();

    if(!menu.isOpen && (kc == 40))
    {
        
        menu.open(null, false);
        this.nSelected = 0;
        menu.setCurrentCellInMenu(menu.getCellInMenuAt(this.nSelected));
    }
    else if (menu.isOpen)
    {
        if( kc == 13 )
        {
            setEventPreventDefault(evt);

            
			if(menu.getCurrentCellInMenu())
	            menu.getCurrentCellInMenu().onclick();

            return false;
        }
        else if( kc == 40 || kc == 38 )
        {
            
            this.nSelected += ((kc == 38) ? -1 : 1);

            if(this.nSelected >= (this.nButtons - 1))
            {
                this.nSelected = this.nButtons - 2;
            }
            else if( this.nSelected < 0 )
            {
                
                this.nSelected = 0;
                menu.close();

                return false;
            }

            menu.setCurrentCellInMenu(menu.getCellInMenuAt(this.nSelected));
        }
    }

    return true;
}

NLMultiButton.prototype.getMenu = function()
{
    var menu = this.menu;

    if(!menu) 
    {
        var name = this.sName;
        menu = this.menu = new NLMenu(name, this.sParams, 0, null);
        menus[name] = menu;
        menuTimers[menu.tabName] = 0;
        menu.setScaleToLauncher(true);

		
		menu.setMenuCSSClass(this.bSecondary ? 'ddmDivButtonSec' : (this.bYellowBg ? 'ddmDivButtonY' : 'ddmDivButtonG'));
        menu.setXandYoverride(4, -4);
		
        
        menu.setCloseAction("getNLMultiButtonByName('"+name+"').onMenuClose();");
        menu.setAfterOpenAction("getNLMultiButtonByName('"+name+"').onAfterMenuOpen();");

        this.imgbtn  = document.getElementById("multibtnimg_" + name);
        this.btnMain = document.getElementById("btn_" + name);
    }

    return menu;
}

NLMultiButton.prototype.onDropDownClick = function(span, evt)
{
    if (!this.bEnabled)
        return true;
    setEventCancelBubble(evt);

    var menu = this.getMenu();
    menu.showHide(true);
    return false;
}

NLMultiButton.prototype.onMenuClose = function()
{
    
    //this.imgbtn.src  = getZoomFile('/images/forms/transarrowupstate.gif');
    this.nSelected   =  -1;
}


NLMultiButton.prototype.onAfterMenuOpen = function()
{
    
    //this.imgbtn.src = getZoomFile('/images/forms/transarrowdownstate.gif');
    this.nSelected  =  0;

    
    var menu = this.getMenu();
    var pValues = this.pValues; 

    var j = 0;

    
    for(var i=0; i< pValues.length;i++)
    {
        if(i != this.nDefault)
        {
            var btnHidden = document.getElementById(pValues[j][1]);
            menu.getCellInMenuAt(j).firstChild.className = btnHidden.disabled ? 'ddmAnchorDisabled' : 'ddmAnchor';
            j++;
        }
    }
}


function NLDoMainFormButtonAction(sButtonName,doFocus)
{
    
    var multibutton = getNLMultiButtonByName('multibutton_' + sButtonName);

    if(multibutton)
    {
        if (doFocus)
            document.forms['main_form'].elements['btn_'+multibutton.sName].focus();
        
        multibutton.onMainButtonClick();
    }
    else
    {
        
        var button  = document.forms['main_form'].elements[sButtonName];
        if (button)
        {
            if (doFocus)
                button.focus();
            button.click();
        }
    }
}




function makeMenu(name, values, level, parent)
{
	if ( window.menuData == null )
		window.menuData = new Array();
	if ( window.menuLevel == null )
		window.menuLevel = new Array();
	if ( window.menuParent == null )
		window.menuParent = new Array();

	window.menuData[name] = values;
    window.menuLevel[name] = level;
    window.menuParent[name] = parent;
}

function ddmOnMouseMove(evnt)
{
    if (window.currentMenu != null)
    {
        return window.currentMenu.handleMouseMove(evnt);
    }
}

function ddmOnClick(evnt)
{
   var target = getEventTarget(evnt);

   var spn = findClassUp(target, 'ddmSpan');
   if (spn == null)
   {
       var div = findClassUp(target, 'menuDiv');
       if(div == null)
       {
           clearAllMenusExcept("ALL_MENUS_PLEASE")
       }
   }
}

var zoomPercent = ['75', '90', '', '125', '150'];
var iZoomDefault = 2;
var iZoomIndex = iZoomDefault;

function getZoomFile(val)
{
    // Insert the zoom percent between the filename and the extension.
    var iExt = val.lastIndexOf('.');
    var sFile = val.substr(0,iExt) + zoomPercent[iZoomIndex] + val.substr(iExt);

    return sFile;
}



function setMenuZoomFactor(zoomFactor)
{
    if (zoomFactor != undefined)
    {
        if (zoomFactor < 0.9)
            iZoomIndex = 0;             // 75%
        else if (zoomFactor < 1.0)
            iZoomIndex = 1;             // 90%
        else if (zoomFactor > 1.25)
            iZoomIndex = 4;             // 150%
        else if (zoomFactor > 1.0)
            iZoomIndex = 3;             // 125%
        else
            iZoomIndex = 2;             // 100%
    }
}

// Do this once to make sure the zoom factor is set for the default value, in case it isn't called.
setMenuZoomFactor(1.0);

var tdCounter = 0;
var NLMENU_STYLE_PAGE = 1;
var NLMENU_STYLE_ACTION = 2;
var NLMENU_STYLE_PORTLET = 3;
var NLMENU_STYLE_CUSTOMIZE = 4;

function NLMenu(name, values, level, parentMenu, menuStyle)
{
    this.tabName = name.substring(0, name.indexOf("_"));
    this.div = null;
	this.tableDiv = null;
    this.currentCell = null;
    this.isOpen = false;
    this.level = level;
    this.parentMenu = parentMenu;
	this.name = name;
	this.values = values;
	this.span = document.getElementById("spn_" + this.name);
	this.overrideX = 0;
    this.rightjustify = false;
	this.overrideY = 0;
	// function that allows you to do custom actions when the menu opens/closes
	this.onCloseAction = null;
	this.onOpenAction = null;
    this.bHasImageTd = false;
    this.sHelperText = null;
	if (menuStyle)
	    this.nMenuStyle = menuStyle;
	else
		this.nMenuStyle = NLMENU_STYLE_PAGE;
}

var menus = new Object();
var menuTimers = new Array();
var friendlyDelay = 0;

function resetNavMenuTimer(tabname)
{
    clearTimeout(menuTimers[tabname]);
}


function startTimer(tabname)
{
   menuTimers[tabname] = setTimeout("clearAllMenus(-100, '"+tabname+"');",500);
}


function clearAllMenus(myLevel, tabname)
{
    clearTimeout(friendlyDelay);
    for(i in menus)
    {
        if(menus[i].tabName == tabname)
        {
            if(menus[i].level > myLevel)
                menus[i].close();
        }
    }
}

function clearAllMenusExcept(tabname)
{
    for(i in menus)
    {
        if(menus[i].tabName != tabname)
        {
            
            var downarrow = document.getElementById(menus[i].tabName + "_nav_arrow");
            if(downarrow != null)
                downarrow.className = "menu_tri";
            menus[i].close();
         }
    }
}

function getAndOpenMenu(child,thismenu,useTimer)
{
    lastMenuRequestedParent = thismenu;
    var menu = getMenu(child);
    if(menu)
    {
        lastMenuRequestedParent = null;
        menu.open(thismenu,useTimer);
    }
}

function getMenuRoundedBottomTableRow()
{
    var tr, td, table, tbody, trTable, tdTable, div, img;

    tr = document.createElement("tr");
	td = document.createElement("td");
	td.height = 9;
	td.colSpan = 2;
	tr.appendChild(td);

	table = document.createElement("table");
    table.heigth = 9;
	table.width = "100%";
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.border = 0;
	td.appendChild(table);

    tbody = document.createElement("tbody");
	table.appendChild(tbody);

	trTable = document.createElement("tr");
	tbody.appendChild(trTable);

	tdTable = document.createElement("td");
	trTable.appendChild(tdTable);

	img = document.createElement("img");
	img.height = 9;
	img.width = 9;
	img.border = 0;
    img.src = "/images/icons/dashboard/portletelements/bottom_left.gif";
	tdTable.appendChild(img);

	tdTable = document.createElement("td");
	tdTable.height = 9;
	tdTable.width = "99%";
	tdTable.vAlign = "bottom";
	trTable.appendChild(tdTable);

	img = document.createElement("img");
	img.height = 9;
	img.style.width = "100%";
	img.border = 0;
	img.src = "/images/icons/dashboard/portletelements/lower_gradient.gif";
	tdTable.appendChild(img);

	tdTable = document.createElement("td");
	trTable.appendChild(tdTable);

	img = document.createElement("img");
	img.height = 9;
	img.width = 9;
	img.border = 0;
	img.src = "/images/icons/dashboard/portletelements/bottom_right.gif";
    tdTable.appendChild(img);

	return tr;
}

NLMenu.prototype.setXandYoverride = function(x,y)
{
	this.overrideX = x;
	this.overrideY = y;
}

NLMenu.prototype.setHelperText= function(sHelperTxt)
{
    this.sHelperText = sHelperTxt;
}

NLMenu.prototype.setCloseAction = function(action)
{
	this.onCloseAction = new Function(action);
}

NLMenu.prototype.setOpenAction = function(action)
{
	this.onOpenAction = new Function(action);
}

NLMenu.prototype.setAfterOpenAction = function(action)
{
	this.onAfterOpen = new Function(action);
}


NLMenu.prototype.setRightJustify = function(bRightJustify)
{
    this.rightjustify = bRightJustify;
}


NLMenu.prototype.setScaleToLauncher = function(bScale)
{
    this.scaletolauncher = bScale;
}


NLMenu.prototype.setMenuBackgroundColor = function(sColor)
{
    this.sMenuBackgroundColor = sColor;
}


NLMenu.prototype.setMenuCSSClass = function(sClass)
{
    this.sOverrideClass = sClass;
}


NLMenu.prototype.setAllowArbitraryHtmlInMenuEntries = function(bAllow)
{
    this.bUseSpanForMenuEntry = bAllow;
}


NLMenu.prototype.setOpenMenuUpwardIfNotBelow = function(bOpenUpward)
{
    this.bOpenMenuUpwardsIfNotBelow = bOpenUpward;
}

function NLMenu_addHelperTextRows(tbody, sHelperText, bHasImages)
{
    var tr = document.createElement("TR");
    var td = document.createElement("TD");
    tbody.appendChild(tr);
    tr.appendChild(td);
    td.className = "text";
    td.innerHTML = sHelperText;
    if(bHasImages)
        td.colSpan = 2;
}

NLMenu.prototype.positionActionDiv = function(triggerObj, popupObj)
{
	if (! (triggerObj && popupObj))
		return;

	

	var bIsTopRowButton = true;
	if (this.span && this.span.id && (this.span.id.indexOf('secondary') > 0))
		bIsTopRowButton = false;

    var scrolledY = getWindowPageYOffset();
	var y = findAbsolutePosY(triggerObj) - scrolledY;
	if (y + triggerObj.offsetHeight + popupObj.offsetHeight > getVisibleWindowHeight() && !bIsTopRowButton)
	{	

		popupObj.style.top = 'auto';
        popupObj.style.bottom = getHeight(this.span) - 5 + "px";

		triggerObj.className += ' ac_container_bot';
	}
	else
	{
		
		popupObj.style.top = '-1px';
		popupObj.style.bottom = 'auto';

		if (this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
		{
			triggerObj.className = triggerObj.className + '_hover';
		}
		else
			triggerObj.className += ' ac_container';


	}
}

NLMenu.prototype.openActionMenu = function(childOpener, useTimer)
{
	if(this.isOpen == true)
        return;

    if (this.level > 0 && typeof childOpener != "undefined" && document.getElementById(childOpener) == null)
        return;

    if (!this.span)
		this.span = document.getElementById("spn_" + this.name);

    clearTimeout(friendlyDelay);

    var bUseSpan = true;
    if (this.onOpenAction != null)
	{
	    bUseSpan = false;
        this.onOpenAction();
	}

    this.div = document.getElementById("div_" + this.name)
	if (this.div.firstChild)
	{
		if (this.nMenuStyle == NLMENU_STYLE_ACTION || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
			this.positionActionDiv(this.span, this.div);

	    this.div.style.visibility = 'visible';
		if (this.level == 0)
			window.menusAreOpen = true;

	    this.div.style.zIndex = 50;

		this.isOpen = true;
		if(this.onAfterOpen)
			this.onAfterOpen();

	    return;
	}

    this.div.onmouseover = new Function("resetNavMenuTimer('"+this.tabName+"');");
    if(useTimer)
        this.div.onmouseout = new Function("startTimer('"+this.tabName+"');");

	var parTab = document.createElement("table");
	parTab.cellSpacing = 0;
	parTab.cellPadding = 0;
	parTab.border = 0;
	var parTbody = document.createElement("tbody");
	var	parTr = document.createElement("tr");
	var parTd = document.createElement("td");
	var parImg = document.createElement("img");
    parImg.border=0;
    parImg.src='/images/nav/ns_x.gif';
    parImg.style.height = "4px";
    parImg.style.width = "1px";
    parImg.style.display = "block";

	var tab = document.createElement("table");
    tab.className = 'ac_table'

	this.div.appendChild(parTab);
	parTab.appendChild(parTbody);
	parTbody.appendChild(parTr);
	parTr.appendChild(parTd);

	parTd.appendChild(tab);

	parTd = document.createElement("td");
	parTd.className = 'acSideShadow';
	parTd.appendChild(parImg);
	parTr.appendChild(parTd);


	// new row for the bottom shadows
	parImg = document.createElement("img");
    parImg.border=0;
    parImg.src='/images/nav/ns_x.gif';
	parImg.style.height = "4px";
	parImg.style.width = "1px";
    parImg.style.display = "block";

	parTr = document.createElement("tr");
	parTbody.appendChild(parTr);
	parTd = document.createElement("td");
	parTd.className = 'acLBotShadow';
	parTr.appendChild(parTd);
	parTd.appendChild(parImg);

	parTd = document.createElement("td");
	parTd.className = 'acRBotShadow';
	parTr.appendChild(parTd);
	parTd.appendChild(parImg);

	var tbody = document.createElement("tbody");
	tab.appendChild(tbody);
	tab.cellSpacing = 2;
	tab.cellPadding = 0;

    var allArrows = new Array();
    var arrowCounter = 0;
	var i, tr, td, hr, msg, child, url, arrowFont, arrowText, sep, anchor, img, txtClass;
    // keep track of whether or not there are ANY children in this menu so that we can position the arrows properly
    var bHasChild = false;
	var bUsesCategoryHeading = false;

	for (i=0; i < this.values.length; i++)
	{
        msg = this.values[i][0];
        url = this.values[i][1];
        child = this.values[i][2];
        img = this.values[i][3];
		txtClass = this.values[i][4];
        if(child.length > 0)
            bHasChild = true;
        if(img != null && img.length>0)
            this.bHasImageTd = true;
		else
			this.bHasImageTd = false;

        var isSeperator = msg == 'ddmSeperator';
		var isCategoryHeading = url == "ADMI_HEADING";
		if(isCategoryHeading)
			bUsesCategoryHeading = true;

		tr = document.createElement("tr");
		tbody.appendChild(tr);
		td = document.createElement("td");
		td.id = "nl" + ++tdCounter;

        anchor = document.createElement("a");
		anchor.className = 'ddmAnchor';

		if (this.nMenuStyle != NLMENU_STYLE_CUSTOMIZE)
	        anchor.onclick = new Function("return false;");

		if (isCategoryHeading)
			td.className = 'ac_text_heading';
		else
			td.className = 'ac_text';

		td.onmouseover = new Function("clearTimeout(friendlyDelay); clearAllMenus("+(this.level)+", '"+this.tabName+"');");

        if(url.length>0 && !isSeperator && !isCategoryHeading)
        {
            var url = this.values[i][1];
			var cleanurl = url;
			anchor.href = url;

			if (this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
			{
				anchor.href = cleanurl;
			}
			else
			{
				var newwindow = this.values[i][4];
				if( url.substring(0, url.indexOf(":")).toLowerCase() == 'javascript')
				{
					url = url.substring(url.indexOf(":")+1);
					if (url.charAt(0) == "/")
					{
						
						anchor.href = url;
						anchor.onclick = '';
						url = ''; 
						anchor.style.display = 'block';
					}
				}
				else
					url = "try { "+(newwindow ? "window.open(" : "window.location = ")+"'" + url + "'"+(newwindow ? ")" : "")+"; } catch (e) { if(console) console.log(e.message); }";

				td.onclick = new Function("clearAllMenusExcept('clear all'); " + url);
			}
        }

		txt = document.createElement("span");
		if (txtClass && txtClass.length > 0)
			txt.className = txtClass;
		else
			txt.className = 'ac_text_pad';

		txt.innerHTML = msg;

		if(!isSeperator)
        {
            td.appendChild(anchor);
            if(this.bHasImageTd)
            {
            	
            	if (img.charAt(0) == '<')
            	{
            		anchor.innerHTML = img;
            	}
            	else
            	{
					var imgElem = document.createElement("img");
					imgElem.border=0;
					imgElem.src=img;
					imgElem.height = 14;
					imgElem.width = 18;
					anchor.appendChild(imgElem);
					imgElem.style.verticalAlign = "bottom";
				}
            }


			if(isCategoryHeading)
			{
				txt.className = 'ac_heading_pad'
				anchor.style.fontWeight = "bold";
				anchor.style.color = "#666666";
			}

            anchor.appendChild(txt);
			tr.appendChild(td);
        }
		else if(isSeperator)
        {
			sep = document.createElement("tr");
			tbody.appendChild(sep);
			var sepTD = document.createElement("td");
			sep.appendChild(sepTD);
			sepTD.style.height = "4px";
			var sepDiv = document.createElement("div");
			sepDiv.className = 'ac_separator';
			sepTD.appendChild(sepDiv);
			var sepimg = document.createElement("img");
			sepimg.src = "/images/nav/stretch.gif";
			sepimg.style.height = "3px";
			sepDiv.appendChild(sepimg);
		}
    }

	
    if ( this.nMenuStyle == NLMENU_STYLE_ACTION  || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
	{
		var divWidth = parseInt(getRuntimeStyle(tab, "width"));
		if(divWidth < 120)
			tab.style.width = "130px";
		else
			tab.style.width = divWidth+30 + "px";
	}

	
	if (isIE)
	{
		if (this.nMenuStyle == NLMENU_STYLE_PORTLET )
		{
			this.div.style.left = "-16px";
			this.div.style.top = 0;
		}
		else if (this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
		{
			this.div.style.top = "3px";
		}
	}

	var addWidth = 0;
    var posObjectX = this.span;
	var posObjectY = this.span;

    if (this.level == 0)
        window.menusAreOpen = true;
    this.div.style.zIndex = 50;


	if (this.nMenuStyle == NLMENU_STYLE_ACTION || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
		this.positionActionDiv(this.span,  this.div);

    this.isOpen = true;
    if(this.onAfterOpen)
        this.onAfterOpen();
}

NLMenu.prototype.open = function(childOpener, useTimer)
{
	if(this.isOpen == true)
        return;

    
    if (this.level > 0 && typeof childOpener != "undefined" && document.getElementById(childOpener) == null)
        return;


    if (!this.span)
		this.span = document.getElementById("spn_" + this.name);

	
    clearTimeout(friendlyDelay);

    
    if (this.onOpenAction != null)
        this.onOpenAction();

	
    var isChild = false
    if(this.level>0)
    {
        isChild = true;
        clearAllMenus(this.level-1, this.tabName);
    }
    
    if(document.getElementById("div_" + this.name))
    {
        return;
    }

	this.div = document.createElement("div");
	this.div.className = 'menuDiv';

	if(this.sOverrideClass)
	{
        this.div.className = this.sOverrideClass;
	}
	else
	{

		var leftDiv = document.createElement("div");
		leftDiv.className = 'menuLeftDiv';
		if (isChild)
		{
			leftDiv.style.background = '';
			leftDiv.style.paddingLeft = 0;
		}

		var rightDiv = document.createElement("div");
		rightDiv.className = 'menuRightDiv';

		var bottomDiv = document.createElement("div");
		bottomDiv.className = 'menuBottomDiv';

		var tableDiv = document.createElement("div");
		tableDiv.className = 'menuTableDiv';
		this.tableDiv = tableDiv;

		leftDiv.appendChild(rightDiv);
		rightDiv.appendChild(bottomDiv);
		bottomDiv.appendChild(tableDiv);

		this.div.appendChild(leftDiv);
	}

	this.div.id = "div_" + this.name;
    this.div.onmouseover = new Function("resetNavMenuTimer('"+this.tabName+"');");
    if(useTimer)
        this.div.onmouseout = new Function("startTimer('"+this.tabName+"');");

	var tab = document.createElement("table");
    tab.className = 'menuInnerTable';
	if (this.tableDiv)
		this.tableDiv.appendChild(tab);
	else
		this.div.appendChild(tab);
	var tbody = document.createElement("tbody");
	tab.appendChild(tbody);
	tab.cellSpacing = 1;
	tab.cellPadding = 4;

	if(this.sMenuBackgroundColor)
        tab.style.backgroundColor = this.sMenuBackgroundColor;

    var allArrows = new Array();
    var arrowCounter = 0;
	var i, tr, td, hr, msg, child, url, arrowFont, arrowText, sep, anchor, img; //,  tdShadow, imgShadow, divShadow;
    // keep track of whether or not there are ANY children in this menu so that we can position the arrows properly
    var bHasChild = false;
	var bUsesCategoryHeading = false;

	for (i=0; i < this.values.length; i++)
	{
        msg = this.values[i][0];
        url = this.values[i][1];
        child = this.values[i][2];
        img = this.values[i][3];

        if(child.length > 0)
            bHasChild = true;
        if(img != null && img.length>0)
            this.bHasImageTd = true;

        var isSeperator = msg == 'ddmSeperator';
		var isCategoryHeading = url == "ADMI_HEADING";
		if(isCategoryHeading)
			bUsesCategoryHeading = true;

		tr = document.createElement("tr");
		tbody.appendChild(tr);
		td = document.createElement("td");
		if(bUsesCategoryHeading && !isCategoryHeading)
			td.style.paddingLeft = "20px";
		td.id = "nl" + ++tdCounter;
        anchor = document.createElement("a");
		anchor.className = 'ddmAnchor';
		
        anchor.onclick = new Function("return false;");


        if(child.length>0)
        {
            td.className = 'ddmTextHasChild';
            var mouseoverScript = "clearTimeout(friendlyDelay); var timeout = "+(this.level==0? 250:0)+"; friendlyDelay = setTimeout(\"getAndOpenMenu('"+child+"','"+td.id+"',"+(useTimer?"true":"false")+")\",timeout)"
            td.onmouseover = new Function(mouseoverScript);
        }
        else
        {
            td.className = 'ddmText';
            td.onmouseover = new Function("clearTimeout(friendlyDelay); clearAllMenus("+(this.level)+", '"+this.tabName+"');");
        }
        if(url.length>0 && !isSeperator && !isCategoryHeading)
        {
            var url = this.values[i][1];
			anchor.href = url;
			var newwindow = this.values[i][4];
			if( url.substring(0, url.indexOf(":")).toLowerCase() == 'javascript')
                url = url.substring(url.indexOf(":")+1);
            else
                url = "try { "+(newwindow ? "window.open(" : "window.location = ")+"'" + url + "'"+(newwindow ? ")" : "")+"; } catch (e) { if(console) console.log(e.message); }"; 
            td.onclick = new Function("clearAllMenusExcept('clear all'); " + url);
        }

        
        var txt = null;
        if(this.bUseSpanForMenuEntry)
        {
            txt = document.createElement("span");
            txt.innerHTML = msg;
        }
        else
        {
             txt = document.createTextNode(msg);
        }

       // items that have no URL AND have a child get arrows (currently we don't show arrows for items that are clickable - we
        // only show them for items that force you to go down a level in navigation)
        if( (url == null || url.length<1) && child.length>0)
		{
            tab.style.width = "165px";

            allArrows[arrowCounter] = document.createElement("span");
            allArrows[arrowCounter].className = 'menuChildIcon';
            allArrows[arrowCounter].id = this.tabName+"_arrow_"+i;
            td.appendChild(allArrows[arrowCounter]);
            arrowCounter++;
            anchor.style.paddingRight = "10px"; // text shouldn't cause the arrow to overflow
		}

		if(!isSeperator)
        {
            td.appendChild(anchor);
            if(this.bHasImageTd)
            {
				
				if (img.charAt(0) == '<')
				{
					anchor.innerHTML = img;
				}
				else
				{
					var imgElem = document.createElement("img");
					imgElem.border=0;
					imgElem.src=img;
					imgElem.height = 14;
					imgElem.width = 18;
					imgElem.style.marginRight= "5px";
					anchor.appendChild(imgElem);
				}
            }
            anchor.appendChild(txt);
			if(isCategoryHeading)
			{
				anchor.style.fontWeight = "bold";
				anchor.style.color = "#666666";
			}

			tr.appendChild(td);
        }

		if(isSeperator || isCategoryHeading)
        {

			sep = document.createElement("tr");
			tbody.appendChild(sep);
			var sepTD = document.createElement("td");
			sepTD.style.padding = "0";
			sepTD.style.margin = "0";
			sep.appendChild(sepTD);
			sepTD.style.height = "3px";
            if(this.bHasImageTd)
                sepTD.colSpan = 2;
			var sepDiv = document.createElement("div");
			sepDiv.className = 'menuSeparator';
			sepTD.appendChild(sepDiv);
		}

        if( this.sHelperText != null && i == (this.values.length-1) )
        {
            NLMenu_addHelperTextRows(tbody, this.sHelperText, this.bHasImageTd);
        }
    }

	
    var addWidth = 0;
    var posObjectX = this.span;
	var posObjectY = this.span;
    // the div must be appended to the document before it is positioned since it has no height/width
    // attributes until it's in the document
	document.body.appendChild(this.div);

	if(isChild)
    {
        posObjectX = this.div;
		if(childOpener!=null)
        {
            posObjectY = document.getElementById(childOpener);
        }
        
        if(this.level > 0)
        {
			
			var currDD = getMenu(this.tabName+'_d1');
			if(currDD != null && currDD.isOpen && currDD.div != null)
				addWidth += currDD.div.offsetWidth + currDD.div.offsetLeft;
        }
        if(this.level >1 && this.parentMenu != null)
		{
			
			var parentDD = getMenu(this.parentMenu);
			if(parentDD != null && parentDD.isOpen && parentDD.div != null)
				addWidth += parentDD.div.offsetWidth;
		}

		
        addWidth -= (this.level*4);
    }

    var divWidth = parseInt(getRuntimeStyle(tab, "width"));
    // if we have arrows, and this menu has at least one child, we set the
    // table's width to 4px larger to make room for the arrows
	if(arrowCounter>0 && bHasChild)
        tab.style.width = divWidth+5 + "px"; // + nIconWidth;

	var x = posObjectX ? posObjectX.getBoundingClientRect().left : event.x;
	var baseX = x;
    var scrollLeft = document.body.scrollLeft;


    

    if( this.rightjustify )
    {
        x += this.span.offsetWidth - this.div.offsetWidth;
    }
	
    if(isChild)
        x = addWidth+1;
	else
        x = x-10;

    if ( this.rightjustify && (x < baseX))
    {
        this.div.style.left = baseX + "px";
    }
    else if (x + this.div.offsetWidth < (getDocumentWidth()+scrollLeft) )
    {
		this.div.style.left = (x + this.overrideX) + "px";
	}
    else
    {
        
        var coveredMenuArea = (x + this.div.offsetWidth) - (getDocumentWidth()+scrollLeft);
	    this.div.style.left = (x - coveredMenuArea) + "px";
    }

	// sometimes nav menus are contained within divs that are scrollable.  In this case we have to compensate
    // for the scroll position when we put the nav menus on the page
    var scrollDiv = findClassUp(this.span,'scrollarea');
    var scrollOffset = 0;
    if(scrollDiv!=null)
    {
        scrollOffset = scrollDiv.scrollTop;
    }

    var y = posObjectY ? findAbsolutePosY(posObjectY) : event.y;

    if(posObjectY)
    {
        var scrollY = getWindowPageYOffset();
        if (y + posObjectY.offsetHeight + this.div.offsetHeight > getDocumentHeight() + scrollOffset + scrollY)
        {
            
            if(this.bOpenMenuUpwardsIfNotBelow)
            {
                
                y = findAbsolutePosY(posObjectY) - this.div.offsetHeight + 3;
            }
            else
            {
                y = getDocumentHeight() - this.div.offsetHeight + 5 + scrollOffset + scrollY;  
            }
        }
        else
        {
            y = y + posObjectY.offsetHeight;  
        }
    }

    if(isChild)
    {
        var menuTopAdjust =  22
                            
        y -= menuTopAdjust;
    }

	// if there is a scroll offset we need to compensate
	y = y + 5 + this.overrideY - scrollOffset;

	// if the top of this nav menu is off the browser, bring it down so that it is visibile.
	// We do this because nav menus typically have important links at the top.
	if(this.div.offsetHeight > (getDocumentClientHeight() - 20))
		y = 5;

    this.div.style.top = y+"px";

	
    if (this.level == 0)
        window.menusAreOpen = true;
    this.div.style.zIndex = 1500;
    var arrowTopAdjust = isIE ? 3 : 2;
    var arrowLeftAdjust = isIE ? 19 : 17;

    if (arrowCounter>0 && this.level==0)
    {
        
        for (j=0; j < allArrows.length; j++)
        {
            allArrows[j].style.left = divWidth - arrowLeftAdjust + "px";
            
            allArrows[j].style.top = allArrows[j].offsetTop - arrowTopAdjust + "px";
            
        }
    }

    if(this.scaletolauncher)
    {
       
       if( this.div.offsetWidth < this.span.offsetWidth )
       {
           this.div.style.width = this.span.offsetWidth + "px";
           tab.style.width = "100%";
       }
    }

    
    if (isIE)
        nlInsertCanvas(this.div);

    this.isOpen = true;
    if(this.onAfterOpen)
        this.onAfterOpen();
}


NLMenu.prototype.close = function()
{
	if (!this.isOpen)
		return;
    
    if (this.level==0)
        window.menusAreOpen = false;

	if (this.nMenuStyle == NLMENU_STYLE_ACTION || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
	{
		if (this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
			this.span.className = this.span.className.replace('_hover', '');
		else
			this.span.className = "uir-action-button";

		this.div.style.visibility = 'hidden';
		this.isOpen = false;
		if (this.currentCell != null && this.currentCell.className!= 'ddmTextSeperator' && this.currentCell.className!= 'ac_text_heading')
			this.currentCell.className = 'ac_text';

		return;
	}
	else if (this.nMenuStyle == NLMENU_STYLE_PORTLET)
	{
		this.div.style.visibility = 'hidden';
		this.isOpen = false;

		if (this.currentCell != null && this.currentCell.className!= 'ddmTextSeperator' && this.currentCell.className!= 'ac_text_heading')
			this.currentCell.className = 'ac_text';

		if (this.onCloseAction != null)
			this.onCloseAction();

		return;
	}

    
    nlRemoveCanvas(this.div);

    document.body.removeChild(this.div);
	this.currentCell = null;
	this.div = null;
	this.isOpen = false;
	if (this.onCloseAction != null)
		this.onCloseAction();
}


NLMenu.prototype.getCellInMenuAt = function(nIndex)
{
    return this.div.firstChild.rows[nIndex].cells[0];
}


NLMenu.prototype.getCurrentCellInMenu = function()
{
    return this.currentCell;
}

NLMenu.prototype.setCurrentCellInMenu = function(cell)
{
	if (!this.isOpen)
		return;

	// if there was previously a cell highlighted, remove the highlight
	if (this.currentCell != null && this.currentCell.className!= 'ddmTextSeperator' && this.currentCell.className != 'ac_text_heading')
	{
	    if (this.nMenuStyle == NLMENU_STYLE_ACTION || this.nMenuStyle== NLMENU_STYLE_PORTLET || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
			this.currentCell.className = 'ac_text';
		else
			this.currentCell.className ='ddmText';
	}

	// if the cell being passed in is non-null, highlight it
	if (cell != null  && cell.className!= 'ddmTextSeperator' && cell.className != 'ac_text_heading')
	{
		if (this.nMenuStyle == NLMENU_STYLE_ACTION || this.nMenuStyle== NLMENU_STYLE_PORTLET || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
			cell.className = 'ac_text_sel';
		else
			cell.className = 'ddmTextOver';
	}

	this.currentCell = cell == null ? this.div.firstChild.rows[0].cells[0] : cell;
}


NLMenu.prototype.getIndex = function(str)
{
	for (i=0; i < this.values.length; i += 2)
	{
		if (this.values[i] == str)
			return i/2;
	}
	return 0;
}


NLMenu.prototype.showHide = function(useTimer)
{
	
    clearAllMenusExcept(this.tabName);
	this.becomeCurrent();
	if (this.nMenuStyle == NLMENU_STYLE_ACTION || this.nMenuStyle == NLMENU_STYLE_PORTLET || this.nMenuStyle == NLMENU_STYLE_CUSTOMIZE)
	    this.openActionMenu(null, useTimer);
	else
	    this.open(null, useTimer);
    return true;
}


NLMenu.prototype.handleMouseMove = function(evnt)
{
	if (!this.isOpen)
		return;

	var target = getEventTarget(evnt);

	while (target != null)
	{
		if ((target.className != null) &&
			( (target.className == 'ddmText')
			|| (target.className == 'ddmTextHasChild')
			|| (target.className == 'ddmTextSeperator' )
			|| (target.className == 'ac_text_heading' )
			|| (target.className == 'ac_text')))
		{
			this.setCurrentCellInMenu(target);
			break;
		}
		target = target.parentNode;
	}
}


NLMenu.prototype.becomeCurrent = function()
{
    if (window.currentMenu != this)
    {
		window.currentMenu = this;
    }
}


function loadDelayedScriptReference(kSectionId, sMenuName)
{
	var scriptRef = document.getElementById("nmdscript" + kSectionId);
	if(scriptRef != null && (scriptRef.src==null || scriptRef.src.length==0))
	{
		lastMenuRequested = sMenuName;
		var realUrl = scriptRef._actualsrc;
		scriptRef.src = realUrl;
        return true; // may get menu items from server
    }
    return false; //no menu
}

function loadDelayedNMD(kSectionId, sMenuName)
{
	lastMenuRequested = sMenuName;
	var nmdscript= document.createElement('script');
	nmdscript.setAttribute('type','text/javascript');
    var srcString,idAttr;

    // Recent Records
    if ('cneg21_d1' == sMenuName)
    {
        srcString = "/core/elements/compound/NLRecentMenu.nl?t="+getStickyTag('RECENTRECORDS');
        idAttr = 'nmdscript-21';
    }
	else if ('cneg6_d1' == sMenuName)
	{
		srcString = "/core/elements/compound/NLShortcutMenu.nl?t="+getStickyTag('RECENTRECORDS');
		idAttr = 'nmdscript-6';
	}
    // Recent Reports
    else if (sMenuName.indexOf('_recentreports') > 0)
    {
        var minus = sMenuName.indexOf('neg')==1?"-":"";
        var num = sMenuName.substring(minus=="-"?4:1,sMenuName.indexOf('_'));
        srcString = "/core/elements/compound/NLRecentReports.nl__t="+getStickyTag('RECENTREPORTS')+"&sections="+minus+num+".nlqs";
        idAttr = 'nmdscriptcneg9_recentreports';
    }
    // Roles
    else if ('cRR_d1' == sMenuName)
    {
      srcString = "/core/elements/compound/NLRoleMenu.nl?t="+getStickyTag('ROLEMENU');
      idAttr='nmdscript-RR';
    }
    // Nav Menus
    else
    {
      srcString = "/app/center/NLNavMenuData.nl__t="+getStickyTag('NAVMENUS')+"&sections="+kSectionId+".nlqs";
      idAttr = "nmdscript"+kSectionId;
    }

    nmdscript.setAttribute('src', srcString);
    nmdscript.setAttribute('id',idAttr);

    document.getElementsByTagName("head")[0].appendChild(nmdscript);
	return true;
}

function getMenu(name, menuStyle)
{
	// if the menu objects (div) has already been created, just grab it and return it.
	var returnMe = menus[name];

	// we haven't constructed the menu object yet, so do so
    if (returnMe == null)
	{
		if(!menuDataExists(name))
		{
			
			loadDelayedNMD(name,name);
			return null;
		}
		returnMe = new NLMenu(name, window.menuData[name], window.menuLevel[name], window.menuParent[name], menuStyle);
		menus[name] = returnMe;

        
        if(returnMe.level == 0)
        {
            var timer = 0;
            menuTimers[returnMe.tabName] = timer;
        }
	}
	return returnMe;
}

function menuDataExists(name)
{
   if (!isOffline() && (window.menuData==null || window.menuData[name] == null || window.menuData[name].length<1))
       return false;
   else
       return true;
}

function deleteMenu(name)
{
   var object = menus[name];
   if (object != null)
   {
       menus[name] = null;
   }
}

var lastMenuRequested = null;
var lastMenuRequestedParent = null;

function openLastMenuRequested()
{
	try {
		var name = lastMenuRequested;
		lastMenuRequested = null;
		if(name == null || !menuDataExists(name))
		{
			return false;
		}
		var parent = lastMenuRequestedParent;
		if(parent != null)
		{ 
			lastMenuRequestedParent = null;
			if( document.getElementById(parent) != null )
			{
				return getMenu(name).open(parent, false);
			}
		}
		else
		{
			return getMenu(name).showHide(true);
		}
	} catch (e) { if(console) console.log(e.message); }
}


function showMenu(span_id, useTimer, sectionId, nDeferCount, menuStyle)
{

	try {
        
        if(!window.loadcomplete) 
        {
            if(isNaN(nDeferCount)) nDeferCount = 0;
            nDeferCount++;
            
            setTimeout(function(){showMenu(span_id, useTimer, sectionId, nDeferCount, menuStyle);}, 1000 * nDeferCount + 1);
            return false;
        }

		var spn = document.getElementById(span_id);
        if (spn != null)
        {
            var name = spn.id.substring(4, spn.id.length);

			// if we haven't loaded the actual data (javascript) for this section, do so now
            // and then let the script file open the menu
			if ((!window.menuData || window.menuData[name] == null) && sectionId != null)
			{
				return loadDelayedNMD(sectionId, name);
			}

            
            if(!menuDataExists(name))
                return false;
            lastMenuRequested = null;
            return getMenu(name, menuStyle).showHide(useTimer);
        }
    } catch (e) { if(console) console.log(e.message); }
    
}

function setNLMenuBackground(span_id, bSet)
{
	var spn = document.getElementById(span_id);
	if (spn != null)
	{
	    var parent = spn.parentNode;
		var prev   = spn.parentNode.previousSibling;
		var next   = spn.parentNode.nextSibling;

		if (bSet)
		{
			parent.className = parent.className.replace('bgofftab', 'bghovertab');
			if (prev && prev.className)
			{
				prev.className = prev.className.replace('bgofftab', 'bghovertab');
				prev.className = prev.className.replace('bgtabrborder', 'bgtabrborder_s');
			}
			if (next && next.className)
				next.className = next.className.replace('bgtabrborder', 'bgtabrborder_s');
		}
		else
		{
			parent.className = parent.className.replace('bghovertab', 'bgofftab');
			if (prev && prev.className)
			{
				prev.className = prev.className.replace('bghovertab', 'bgofftab');
				prev.className = prev.className.replace('bgtabrborder_s', 'bgtabrborder');
			}
			if (next && next.className)
				next.className = next.className.replace('bgtabrborder_s', 'bgtabrborder');
		}
	}
}

function setPortletMenuBackground(span_id, bSet)
{
	var spn = document.getElementById(span_id);
	if (spn != null)
	{
		if (bSet)
			spn.firstChild.className = spn.firstChild.className.replace('portletIconMenu', 'portletIconMenuSel');
		else
			spn.firstChild.className = spn.firstChild.className.replace('portletIconMenuSel', 'portletIconMenu');
	}
}


var currentDropdown = null; 
var dropdownCounter = 0;
window.dropdownloadtime = 0;

function initializeDropdown($dropdown)
{
	var startTime = new Date(),
		name = $dropdown.data("name"),
		options = $dropdown.data("options"),
		selected = $dropdown.data("default-option"),
		settings = $dropdown.data("settings"),
		values = ["", ""],
		maxLengthValue = "",
		index,
		option,
		dd,
        longestValues = ["","",""];

	dropdownCounter++;
	var nameC = name + dropdownCounter;

	// TODO: Fragile!!!
	$dropdown.nextAll("input").eq(0).attr("id", "inpt_" + nameC);
	$dropdown.nextAll("input").eq(1).attr("id", "hddn_" + nameC);
	$dropdown.nextAll("input").eq(2).attr("id", "indx_" + nameC);
	$dropdown.nextAll(".ddarrowSpan").children("img").attr("id", "inpt_" + nameC + "_arrow");

	if (options.length > 0) {
		values = [];
		for (index = 0; index < options.length; index++) {
			option = options[index];
            var escapedText = option.text.indexOf("&") > -1 ? unEscapeHtml(option.text) : option.text;
			values.push(escapedText);
			values.push(option.value);
			if (escapedText.length >= longestValues[0].length) {
                // get array of longest values sorted ascended by length
                longestValues[0] = escapedText;
                longestValues.sort(function(a,b){if(a.length == b.length) return 0; return a.length > b.length ? 1 : -1});
			}
		}

        maxLengthValue = getLongestRenderedString(longestValues);
	}

	dd = new NLDropdown(name, nameC, values, selected, $dropdown.get(0).ownerDocument, settings.flags, settings.width, settings.minWidth, maxLengthValue);
	if (settings.mandatory) {
		dd.setRequired(true);
	}

	$dropdown.attr("data-initialized", "T");
	window.dropdownloadtime += (new Date().getTime() - startTime.getTime());

	return dd;
}

/**
 *  Method renders all values into div element and returns value of longest string.
 *  All passed values are added to widthCache.
 */
function getLongestRenderedString(longestValuesArray)
{
	var maxLength = 0;
	var longestValue = "";

	var groupDiv = document.createElement("div");
	groupDiv.style.display="none";
	groupDiv.style.position="absolute";

	for (var i = 0; i < longestValuesArray.length; i++) {
		var txt = longestValuesArray[i];
		if (widthCache[txt]) {
			if (widthCache[txt] > maxLength) {
				maxLength = widthCache[txt];
				longestValue = txt;
			}
			continue;
		}
		var div = getTextWidthDiv();
		div.innerHTML = ((txt == " ") ? "&nbsp;" : txt);
		groupDiv.appendChild(div);
	}

	groupDiv.style.display="";
	document.body.appendChild(groupDiv);

	NS.jQuery(groupDiv).find("div").each(function() {
		var elemWidth = this.offsetWidth;
		var elemValue = this.textContent;
		widthCache[elemValue] = elemWidth;
		if ( elemWidth > maxLength) {
			maxLength = elemWidth;
			longestValue = elemValue;
		}
	});
	document.body.removeChild(groupDiv);

	return longestValue;
}

function initializeMultiDropdown($dropdown)
{
	var name = $dropdown.data("name"),
		options = $dropdown.data("options"),
		selected = $dropdown.data("selected"),
		settings = $dropdown.data("settings"),
		$input = $dropdown.next("input"),// TODO: Fragile!!!!
		values = ["", ""],
		defaultValues = [],
		defaultValuesString,
		index,
		option,
		dd;

	dropdownCounter++;
	var nameC = name + dropdownCounter;

	$input.attr("id", "hddn_" + nameC).attr("nlmultidropdown", nameC);

	if (options.length > 0) {
		values = [];
		for (index = 0; index < options.length; index++) {
			option = options[index];
			values.push(option.text.indexOf("&") > -1 ? unEscapeHtml(option.text) : option.text);
			values.push(option.value);
		}
	}

	for (index = 0; index < selected.length; index++) {
		defaultValues.push(options[selected[index]].value);
	}
	defaultValuesString = defaultValues.join(String.fromCharCode(5));

	dd = new NLMultiDropdown(name, nameC, values, defaultValuesString, settings.flags, settings.width, settings.height, $dropdown.get(0).ownerDocument);
	if (settings.mandatory) {
		dd.setRequired(true);
	}

	$dropdown.attr("data-initialized", "T");

	return dd;
}

function initializeDropdowns($root)
{
	$root.find(".ns-dropdown[data-initialized='F']").each(function () {
		initializeDropdown(jQuery(this));
	});
	$root.find(".ns-multi-dropdown[data-initialized='F'][data-lazy='F']").each(function () {
		initializeMultiDropdown(jQuery(this));
	});
}


function unEscapeHtml(str)
{
	if (str == null)
		return null;
	if (str.length == 0)
		return "";
	var escaperNode = document.createElement("a");
	escaperNode.innerHTML = str + "\n"; 
	var child = escaperNode.firstChild;

	// Padmaja B. - Bug 56340 - Strings enclosed in HTML tags were causing javascript errors.
    if(child != null && child.nodeName != "#text")
        child = child.firstChild;

	if (child != null)
    {
        // get rid of trailing space that comes from "\n" above
		var result = child.data;
        if (result.charAt(result.length-1) == ' ')
            result = result.substr(0,result.length-1);
        return result;
    }
	else
		return "";
}


function dropdownOnMouseDown(evnt)
{
    
    if(!window.loadcomplete || !NS.form.isValid())
    {
        return true;
    }

	var target = getEventTarget(evnt);
	if ( isNLMultiDropDown(target) )
	{
        var nlmdd = target.getAttribute("nlmultidropdown");
        

        getMultiDropdownFromNameC(nlmdd).handleMouseDown(evnt);
	}
	var inpt =  null;
	var bArrowButton = false;
	if (target && (target.className == 'i_dropdownarrow'))
	{
		inpt = document.getElementById(target.id.replace('_arrow', ''));
		bArrowButton = true;
	}

	if (inpt == null)
        inpt = findClassUp(target, 'dropdownInput textbox');

    
	
	if (inpt != null)
	{
	    if (bArrowButton)
	    {
		    try
			{
				setTimeout(function(){getDropdown(inpt).inpt.focus(); getDropdown(inpt).inpt.select();}, 1);
				getDropdown(inpt).inpt.focus();
			}
			catch (er) {  }
	    }
        return getDropdown(inpt).handleMouseDown(evnt);
	}
}

function dropdownOnMouseUp(evnt)
{
	var target = getEventTarget(evnt);

    
    
    if (target.tagName != null && target.tagName.toLowerCase() == "html")
    {
        return;
    }

	if ( currentMultiDropdown != null && currentMultiDropdown.onMouseMoveIdx != -1 )
	{
		currentMultiDropdown.onMouseMoveIdx = -1;
		currentMultiDropdown = null;
	}
	else if ( currentDropdown != null )
	{
		var inpt = findClassUp(target, 'dropdownInput textbox');
		if (inpt == null && currentDropdown.seenMouseMove)  
		{
            
            if(target.className == 'dropdownDiv')
                return;

            if (typeof currentDropdown != 'undefined' && currentDropdown != null) {
			    var div = findClassUp(target, 'dropdownSelected');
                if (div != null) {
                    currentDropdown.setAndClose(div.nlrow);
                }

                if (typeof currentDropdown != 'undefined' && currentDropdown != null) {
                    currentDropdown.close();
                }

                currentDropdown = null;
            }
		}
	}
}


var lastX = 0;
var lastY = 0;

function dropdownOnMouseMove(evnt)
{

	if (isIE)
		evnt = event;

	var positionY = evnt.clientY;
	
	if (evnt.clientX == lastX && positionY == lastY)
		return;
	lastX = evnt.clientX;
	lastY = positionY;

	var target = getEventTarget(evnt);
	if ( currentMultiDropdown != null )
		currentMultiDropdown.handleMouseMove(evnt);
	if ( currentDropdown != null )
		currentDropdown.handleMouseMove(evnt);
}

function dropdownOnKeyDown(evnt)
{
	var target = getEventTarget(evnt);
	var inpt = findClassUp(target, 'dropdownInput textbox');

	if ( isNLMultiDropDown(target) )
	{
		var nlmdd = target.getAttribute("nlmultidropdown");
        
		return getMultiDropdownFromNameC( nlmdd ).handleKeydown(evnt);
	}
	else
	{
		return true;
	}
}

function getButtonId(evnt)
{
	if(isIE)
		return event.button;
	else if(isNS)
		return evnt.button;
	else
        return null;
}

function dumpObj(obj)
{
	
	for(var prop in obj)
	{
		var str = prop + ": " + obj[prop];
		document.body.appendChild(document.createTextNode(str));
		document.body.appendChild(document.createElement("BR"));
	}
}

NLDropdown.prototype.handleOnFocus = function NLDropdown_handleOnFocus(event)
{
    if (this.hddn.onfocus) this.hddn.onfocus(event);
    this.inpt.select();
    this.doOnChangeWhenBlur = false;
}

NLDropdown.prototype.handleOnBlur = function NLDropdown_handleOnBlur(event)
{
    if (this.hddn.onblur) this.hddn.onblur(event);
    if (this.doOnChangeWhenBlur && this.hddn.onchange)
    {
        this.hddn.onchange();
    }
}

NLDropdown.prototype.setMandatoryBackgroundColor = function NLDropdown_setMandatoryBackgroundColor(sColor)
{
	this.sMandatoryBgColor = sColor;
}

NLDropdown.prototype.hasAttribute = function NLDropdown_hasAttribute(flag)
{
    return (this.flags & flag) != 0;
}

function NLDropdown(name, nameC, values, defaultIndex, renderDocument, flags, width, minimumWidth, maxLengthString)
{
	if (name == null)
		throw  "cannot create dropdown with null name";
	if (values == null)
		throw  "cannot create dropdown with null values";

	this.name = name; 
	this.nameC = nameC; 
	this.textArray = new Array(values.length / 2);
	this.valueArray = new Array(values.length / 2);
	this.valueToIndexMap = {};
	this.defaultIndex = defaultIndex;
	
	this.indexAtRenderTime = defaultIndex;

    this.isOpen = false;
	this.divWidthHasBeenSet = false;
	this.disabled = false;
	this.div = null;
	this.currentCell = null;
	this.searchString = "";
	this.typeAhead = false;
    this.cancelEventOnEnterKey = false;
	this.width = null;
    this.minimumWidth = minimumWidth || 0;
    this.flags = 0;
    this.sMandatoryBgColor = "#FFFFFF";
    this.bRequired = false;

    this.initializeElements( renderDocument );

    
    this.bInitialize = true;

	for (var i=0,j=0; i < values.length; i +=2, j++)
	{
		var txt = values[i];
		var val = values[i+1];
		this.textArray[j] = txt;
		this.valueArray[j] = val;
		this.valueToIndexMap[String(val)] = j;
	}

	this.setIndex(defaultIndex, true );

	if (window.dropdowns[nameC] == null) {
		window.dropdowns[nameC] = this;
	}
	this.setWidth(width == -1 ? null : width, minimumWidth == -1 ? null : minimumWidth, maxLengthString);
	this.flags = flags;
	this.bRequired = this.hasAttribute(128);
	this.disabled = this.hasAttribute(2048);
	this.typeAhead = this.hasAttribute(2147483648);

	// mandatory flag is checked in NLSelect.java - so that the proper BG color can be appliead

	if (this.hasAttribute(2048))
		this.setDisabled(true);
	if (this.hasAttribute(1073741824))
		this.setArrowImage('');
}


/**
 *  Initialize the new elements based on the current document reference.  This is executed the first
 *  time an NLDropdown is opened since it must reference objects in the current window.  This is
 *  necessary since NLDropdowns can be created in different windows than they are actually displayed
 *  and used in.  (mostly for dynamic content such as portlets and list machines)
 */
NLDropdown.prototype.initializeElements = function NLDropdown_initializeElements(doc)
{
	if ( doc == null ) {
        var isExtAvail = ( window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" );
        if (isExtAvail && parent.Ext.WindowMgr.getActive()!=null) {
            var tmpWindow = parent.Ext.WindowMgr.getActive();
            var tmpIFrame = (tmpWindow.body.dom.contentWindow ? tmpWindow.body.dom.contentWindow : window.frames[tmpWindow.getId()+"_frame"]);
             if ( (typeof tmpIFrame != 'undefined') && tmpIFrame != null)
                doc = tmpIFrame.document;
              else
                doc = document;
        } else {
		    doc = document;
        }
    }

    this.inpt = doc.getElementById("inpt_" + this.nameC);
    
    this.ddbtn = this.inpt;
	this.hddn = doc.getElementById("hddn_" + this.nameC);
	this.indx = doc.getElementById("indx_" + this.nameC);

    // we are always making the assumption that these fields exist within a span (created in NLSelect)
    this.span = this.inpt.parentNode;
    while('span' !== this.span.nodeName.toLocaleLowerCase()){
        this.span = this.span.parentNode;
    }

    if ( !this.isSelectable() )
		this.inpt.unselectable = 'on';
    this.elementsAreInitialized = true;
    this.bInitialize = false;
};


function getDropdownArrowSpacing()
{
    return 10;
}

NLDropdown.prototype.setWidth = function NLDropdown_setWidth(width, minimumWidth, maxOptionString)
{
    var newWidth;

	if (width != null)
	{
		this.width = width;
        newWidth = width;
	}
	
	else if(maxOptionString != null)
	{
        var offsetWidth = getTextWidth(maxOptionString);
		newWidth = Math.max((offsetWidth + getDropdownArrowSpacing()),(minimumWidth == null ? 0 : minimumWidth));
		newWidth += 26; 
	}
	else
	{
		if (this.div == null)
			this.buildDiv();
		var div = this.div;

		
        document.body.insertBefore(div, document.body.firstChild);

		if (div.offsetHeight < 200)
		{
			
			newWidth = div.offsetWidth + 5 + getDropdownArrowSpacing();
			if (newWidth < 40)
				newWidth = 40;
		}
		else
		{
			newWidth = div.offsetWidth + 15 + getDropdownArrowSpacing(); 
		}
		document.body.removeChild(div);
	}

    if (this.inptWidth !== newWidth || this.inptText !== this.getText())
    {
        this.setWidthDirect(newWidth);
        this.setText(null, true); 
    }
};

NLDropdown.prototype.scheduleSetWidth = function NLDropdown_scheduleSetWidth()
{
    // setWidth causes page relayout which is very slow -> this function makes sure that there is at
    // most one call to setWidth for the current execution thread.
    if (this.width == null && !this.dirty) { // The width is not explicitly set and we have not scheduled resizing yet
        this.dirty = true;

        var that = this;
        setTimeout(function () {
            that.setWidth();
            that.dirty = false;
        }, 0);
    }
};

NLDropdown.prototype.setWidthDirect = function NLDropdown_setWidthDirect(width)
{
    width = Math.max(this.minimumWidth, Math.min(width, 300));
	this.inpt.style.width = width + 'px';
    this.inptWidth = width;
};

NLDropdown.prototype.buildDiv = function NLDropdown_buildDiv()
{
	var div = document.createElement("div");
	this.div = div;
	div.className = 'dropdownDiv';
	div.unselectable = this.inpt.unselectable;
	div.style.zIndex = 1001; 
	this.divWidthHasBeenSet = false;

	var divArray = new Array(this.textArray.length);
	this.divArray = divArray;
	var i, div2;
	for (i=0; i < this.textArray.length; i++)
	{
		var msg = this.textArray[i];
		if (msg == null || msg.length == 0)
			msg = "&nbsp;";
		div2 = document.createElement("div");
		divArray[i] = div2;

		if(msg != "&nbsp;")
			msg = msg.escapeHTML();

		div2.innerHTML = msg;
		div2.unselectable = div.unselectable;
		div2.id = "nl" + ++tdCounter;
		div2.nlrow = i;
		div2.className = 'dropdownNotSelected';
		div.appendChild(div2);
	}

    var that = this;
    div.onkeydown = function (evt) {
        that.handleKeyDown(evt);
    };
	div.onkeypress = function (evt) {
        that.handleKeypress(evt);
    };
    div.onmousedown = function () {
        return false;
    };
};


NLDropdown.prototype.adjustDivForScrollbar = function NLDropdown_adjustDivForScrollbar(div, iMaxDistance)
{
    if (isIE)
    {
        div.style.width = div.offsetWidth + 18 + 'px';
    }
    else if (isNS)
    {
        div.style.width = div.offsetWidth - 12 + 'px';
    }
};


NLDropdown.prototype.sizeDiv = function NLDropdown_sizeDiv()
{
	var div = this.div;
    var resizeAmt;
	

	if(!this.divWidthHasBeenSet)
	{
		var divWidth = div.offsetWidth;
		var inptWidth = this.inpt.offsetWidth; 
        resizeAmt = inptWidth - divWidth;
		div.style.overflow = 'hidden';

		if (divWidth < inptWidth)
		{
			div.style.width = inptWidth + 'px';  
		}
		else
		{
			div.style.width = divWidth + 4 + 'px';
		}
	}

	// Calculate how much viewing area there actually is above and below the input field (NLDropdown).
	// Based on this we decide how large to make the div, and then later we position it in that spot
	var inputYPos = findPosY(this.inpt);
	var iDistanceFromDDtoTop =  inputYPos - document.body.scrollTop;
	var iDistanceFromDDtoBottom = getDocumentHeight() - ( (inputYPos - document.body.scrollTop) + this.inpt.offsetHeight) ;
	var iMaxDistance = Math.max(iDistanceFromDDtoTop,iDistanceFromDDtoBottom);

	
	if (div.offsetHeight < Math.min(200,iMaxDistance))
	{	
		if (isNS)
		{
            var divOffsetHeight = div.offsetHeight;
			div.style.height = divOffsetHeight + 'px';
            
            
            if (div.offsetHeight > divOffsetHeight)
                div.style.height = ((divOffsetHeight*2 < div.offsetHeight) ? 0 : (divOffsetHeight*2 - div.offsetHeight)) + 'px';
		}
	}
	else
	{	
		var newHeight = Math.min(iMaxDistance,200);
		div.style.height = newHeight - 2 + 'px';
		div.style.overflow = 'auto';

		if(!this.divWidthHasBeenSet)
		{
            this.adjustDivForScrollbar(div, iMaxDistance, resizeAmt);
		}
	}
	this.divWidthHasBeenSet = true;
};


NLDropdown.prototype.getForm = function NLDropdown_getForm()
{
    
    var form = null;
    try{
        form = this.elementsAreInitialized ? this.hddn.form : null;
    }catch (e) {
        
        this.elementsAreInitialized = false;
        this.bInitialize = true;
    }
    return form;
};

NLDropdown.prototype.open = function NLDropdown_open()
{
    // the first time we open up a dropdown, we have to set up some basics
    if(this.bInitialize)
        this.initializeElements();

	if (this.disabled || this.textArray.length == 0)
		return;

	if (this.div == null)
		this.buildDiv();
    this.div.style.visibility = "hidden";
    
    var isExtAvail = ( window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" );
    var tmpWindow = (isExtAvail ? parent.Ext.WindowMgr.getActive() : null);
    var tmpIFrame = (tmpWindow!=null ? (tmpWindow.body.dom.contentWindow ? tmpWindow.body.dom.contentWindow : window.frames[tmpWindow.getId()+"_frame"]) : null);


    
    var isPopupDiv = false;
    if (tmpWindow != null && tmpIFrame == null && tmpWindow.body.dom != null &&
        tmpWindow.body.dom.id.indexOf("popup") > 0){
        isPopupDiv = true;
        var selElem = this.inpt.parentNode.insertBefore(this.div, this.inpt.nextSibling);

    }
    else {
        var mydoc = (tmpIFrame!=null ? (tmpIFrame.document) : document);
        mydoc.body.insertBefore(this.div, mydoc.body.firstChild);
    }

	this.sizeDiv();

    // extreme editable fields must exist within relatively positioned SPANs so we need
    // a slightly different positioning algorithm
	if (this.hasAttribute(256))
		this.positionRelativeDiv();
	else if (!isPopupDiv){

		this.positionDiv(this.inpt, this.div);
     }

	this.isOpen = true;
	this.seenMouseMove = false;
	this.setCurrentCellInMenu(null);  
    if (isIE && this.currentCell != null)
		this.div.scrollTop = this.currentCell.offsetTop;

    if ( !this.hasAttribute(256) )
    {
        if (isIE)
            nlInsertCanvas( this.div );
    }
    this.div.style.visibility = "visible";
};

NLDropdown.prototype.positionRelativeDiv = function NLDropdown_positionRelativeDiv()
{
    this.span.style.zIndex = 1;
    this.span.insertBefore(this.div,this.span.firstChild);

    var x = findPosX(this.span);
    var y = findPosY(this.span);

	// we never have to shift the div on the x-axis in extreme lists because the input element is contained within the span in the cell
    this.div.style.left = 0;   

    
    if ((y + this.inpt.offsetHeight + this.div.offsetHeight)-document.body.scrollTop > getDocumentHeight())
        this.div.style.top = 3 - this.div.offsetHeight + "px";   
    else
        this.div.style.top = this.inpt.offsetHeight - 1 + "px";  
};

NLDropdown.prototype.positionDiv = function NLDropdown_positionDiv(triggerObj, popupObj)
{
	
    var scrolledX = getWindowPageXOffset();
    var scrolledY = getWindowPageYOffset();

	var x = findAbsolutePosX(triggerObj);
    var pOW = popupObj.offsetWidth;
    var dbSL = document.body.scrollLeft;
    var gDCW = getDocumentClientWidth();
	if (x - scrolledX + pOW - dbSL <= gDCW)
		popupObj.style.left = x + 'px';
	else
		popupObj.style.left = gDCW - pOW + dbSL + 'px';

	var y = findAbsolutePosY(triggerObj);
    var pOH = popupObj.offsetHeight;
    var tOH = triggerObj.offsetHeight;
    var gDCH = getDocumentClientHeight();
    
	if (y - scrolledY + tOH + pOH > gDCH)
	{	
		popupObj.style.top = Math.max(y - pOH,0) + 'px';
	}
	else
	{	
		if (isIE)
			popupObj.style.top = y + tOH - 1 + 'px';
		else if (isNS)
			popupObj.style.top = y + tOH - 2 + 'px';
	}
};

NLDropdown.prototype.close = function NLDropdown_close()
{
	if (!this.isOpen)
		return;
	if (this.indexOnDeck != null)
	{
		this.setIndex(this.indexOnDeck);
		this.indexOnDeck = null;
	}
	if (this.currentCell != null)
	{
		this.currentCell.className = 'dropdownNotSelected';
		this.currentCell = null;
	}
    
    this.span.style.zIndex = "";
    if ( !this.hasAttribute(256) )
    	nlRemoveCanvas( this.div );

    this.div.parentNode.removeChild(this.div);
    this.isOpen = false;
};


NLDropdown.prototype.isSelectable = function NLDropdown_isSelectable()
{
    return this.span.unselectable == 'on' ? false : true;
};

NLDropdown.prototype.setFocus = function NLDropdown_setFocus()
{
    try {
		this.inpt.focus();
        if ( this.isSelectable() )
    		this.inpt.select();
    } catch (e) { if(console) console.log(e.message); }
	
};

function getDropdownPadding()
{
    return 17;
}

NLDropdown.prototype.setText = function NLDropdown_setText(newVal, dontFocus)
{
	if (newVal == null)
		newVal = this.getText();
    this.inptText = newVal;
	this.inpt.title = newVal;
	if (newVal == null || newVal == "")
		newVal = " ";

    newVal = elideTxt(newVal, this.inptWidth - getDropdownPadding());
	this.inpt.value= newVal;
	if (!dontFocus || this == currentDropdown) 
	{
	    try {
		this.inpt.focus();
		if (!this.isOpen && this.isSelectable())
				this.inpt.select();
	    } catch (e) { if(console) console.log(e.message); }
		
	}
};

NLDropdown.prototype.getText = function NLDropdown_getText(index)
{
	if (index == null)
		index = this.getIndex();
	if ((index == null) || (index < 0) || (index > this.textArray.length))
		return "";
	return this.textArray[index];
};

NLDropdown.prototype.getValue = function()
{
	var returnMe = this.hddn.value;
	return returnMe;
};

NLDropdown.prototype.getTexts = function()
{
	return this.textArray;
};

NLDropdown.prototype.getValues = function()
{
	return this.valueArray;
};

NLDropdown.prototype.setAndClose = function NLDropdown_setAndClose(idx)
{
	
	this.indexOnDeck = null;
	
	this.close();
	this.setIndex(idx);
};

function getNext(n)
{
	var returnMe = n.firstChild;
	if (returnMe == null)
	{
		returnMe = n.nextSibling;
		if ((returnMe == null) && (returnMe.parentNode != null))
			returnMe = n.parentNode.nextSibling;
	}
	return returnMe;
};

NLDropdown.prototype.setCurrentCellInMenu = function NLDropdown_setCurrentCellInMenu(cell)
{
	if (!this.isOpen)
		return;

	var initial = cell;
	if (cell == null)
	{
		var rowNum = this.getIndex();
		if (rowNum < 0 || rowNum > this.divArray.length || rowNum === undefined)
		{
			rowNum = 0;	
		}
		cell = this.divArray[rowNum];
	}

	if (this.currentCell != null)
		this.currentCell.className ='dropdownNotSelected';
	if (cell != null)
		cell.className = 'dropdownSelected';
	this.currentCell = cell;
}

NLDropdown.prototype.getIndex = function NLDropdown_getIndex()
{
	return Number(this.indx.value);
}

NLDropdown.prototype.setIndex = function NLDropdown_setIndex(newIdx, noFocusOrOnChange)
{

	if (newIdx == null)
		return;

    newIdx = Number(newIdx);
	if (newIdx < 0 || newIdx >= this.valueArray.length)
		return;
	var old = this.getIndex();

	this.indx.value=newIdx;
	this.hddn.value=this.valueArray[newIdx];
	this.setText(this.textArray[newIdx], noFocusOrOnChange);

	
	if (old == newIdx) {
		return;
	}
	if ((!noFocusOrOnChange) && (this.hddn.onchange != null))
	{
		var isvalid = this.hddn.onchange();
		if ( isvalid == false )
		{
			this.indx.value=old;
			this.hddn.value=this.valueArray[old];
			this.setText(this.textArray[old], noFocusOrOnChange);
			return;
		}
	}
}

NLDropdown.prototype.setValue = function NLDropdown_setValue(val, noFocusOrOnChange)
{
	var mappedIndex = this.getIndexForValue(val);
	if (mappedIndex == null)
		return;
	this.setIndex(mappedIndex, noFocusOrOnChange);
}

NLDropdown.prototype.getValueAtIndex = function NLDropdown_getValueAtIndex(idx)
{
	return this.valueArray[idx];
}
NLDropdown.prototype.getTextAtIndex = function NLDropdown_getTextAtIndex(idx)
{
	return this.textArray[idx];
}


NLDropdown.prototype.respondToArrow = function NLDropdown_respondToArrow(offset)
{
	var i;
    if (this.matchTimeout != null)
	{
		clearTimeout(this.matchTimeout);
		this.matchTimeout = null;
	}

    if (this.currentCell == null)
	{
		if (this.arrowIndex == null)
            i = this.getIndex();
        else
            i = this.arrowIndex;
    }
	else
	{
		i = this.currentCell.nlrow;
	}
	i += offset;
	if (i < 0)
		i = 0;
	if (i >= this.valueArray.length)
		i = this.valueArray.length - 1;

	if (this.isOpen)
	{
		var txt = this.textArray[i];
		this.setText(txt);
		this.setCurrentCellInMenu(this.divArray[i]);
        
        var scrollTop = this.currentCell.parentNode.scrollTop;
        var lineTop = this.currentCell.offsetTop;
        var scrollHeight = getElementContentHeight(this.currentCell.parentNode);
        var lineHeight = this.currentCell.offsetHeight;
        if (scrollTop > lineTop)
            this.currentCell.scrollIntoView(true); 
        else if (scrollTop + scrollHeight < lineTop + lineHeight)
            this.currentCell.scrollIntoView(false);  
		this.indexOnDeck = i;
	}
	else
	{
		
		var value = this.valueArray[i];
		if ((value == -1) && (offset > 0))
		{
			if (i+1 < this.valueArray.length)  // go on to the next option only if there's a next option to go on to
				this.respondToArrow(offset + 1);
		}
		else
		{
            this.arrowIndex = i;
            var that = this;
            this.matchTimeout = setTimeout(function () {
                that.arrowIndex = null;
                that.setIndex(i);
            }, 0);
		}
	}
}


NLDropdown.prototype.gotoNext = function NLDropdown_gotoNext(key)
{
	if (this.searchStringTimeout != null)
	{
		clearTimeout(this.searchStringTimeout);
		this.searchStringTimeout = null;
	}

    if (this.matchTimeout != null)
	{
		clearTimeout(this.matchTimeout);
		this.matchTimeout = null;
        this.arrowIndex == null;
    }

    var startIndex = this.getIndex();
	if (this.currentCell != null)
		startIndex = this.currentCell.nlrow;

	var ctr = startIndex;
	var i;
	var len = this.textArray.length;
	this.searchString += String.fromCharCode(key).toUpperCase();

	
	if (this.searchString.length == 1)
		++ctr;

	var matched = false;
	for (var tries = 0; tries < len; tries++)
	{
		i = ctr % len;
		var match = this.textArray[i].substr( getTypeAheadStartIndex(this.textArray[i]), this.searchString.length ).toUpperCase();
		if (match == this.searchString)
		{
			matched = true;
			break;
		}
		++ctr;
	}

	if (matched)
	{
		if (this.isOpen)
		{
			this.setText(this.textArray[i]);
			this.setCurrentCellInMenu(this.divArray[i]);
			this.div.scrollTop = this.currentCell.offsetTop;
			this.indexOnDeck = i;
		}
		else
		{
            var self = this;
            this.doOnChangeWhenBlur = true;
            this.matchTimeout = setTimeout(function (){self.setIndex(i, true)}, 0);
		}
	}

	if (this.typeAhead == true)
    {
        var that = this;
        this.searchStringTimeout = setTimeout(function () {
            that.searchString = "";
        }, 2000);
    } else {
        this.searchString = "";
    }
}


function getTypeAheadStartIndex(compareString)
{
    for(var i=0; i < compareString.length; i++)
    {
        if(compareString.charCodeAt(i) != 32 && compareString.charCodeAt(i) != 160)
            return i;
    }
    return 0;
}

NLDropdown.prototype.getTextForValue = function NLDropdown_getTextForValue(value)
{
	var idx = this.getIndexForValue(value);
	if (idx != null)
		return this.textArray[idx];
	else
		return "";
}

NLDropdown.prototype.getIndexForText = function NLDropdown_getIndexForText(text)
{
    for(var i=0; i< this.textArray.length; i++)
        if(trim(this.textArray[i]) == trim(text))
            return i;
    return -1;
}


NLDropdown.prototype.getIndexForValue = function NLDropdown_getIndexForValue(value)
{
	return this.valueToIndexMap[String(value)];
}


NLDropdown.prototype.restoreToOriginalValue = function NLDropdown_restoreToOriginalValue()
{
	this.setIndex(this.indexAtRenderTime,true);
}

NLDropdown.prototype.gotoDefault = function NLDropdown_gotoDefault()
{
	this.setIndex(this.defaultIndex,true);
}

NLDropdown.prototype.resetDropDown = function NLDropdown_resetDropDown()
{
	this.gotoDefault();
}

NLDropdown.prototype.setDefaultIndex = function NLDropdown_setDefaultIndex(newDfltIdx)
{
	if (newDfltIdx == null)
		return;
    
    if(this.bInitialize)
        this.initializeElements();
	this.defaultIndex = Number(newDfltIdx);
}

NLDropdown.prototype.handleMouseDown = function NLDropdown_handleMouseDown(evnt)
{
    this.becomeCurrent();
	if (this.isOpen)
		this.close();
	else
		this.open();
};

NLDropdown.prototype.handleKeydown = function NLDropdown_handleKeydown(evnt)
{
	if (this.disabled)
		return true;

    if(this.bInitialize)
        this.initializeElements();

	var key = getEventKeypress(evnt);

    
    switch(key)
    {
        
		case 8:  
		case 16: 
		case 17: 
		case 18: 
		case 20: 
		case 46: 
		case 93: 
			return;
    }

    this.becomeCurrent();
    switch (key)
	{
		case 9:  
  			this.handleOnBlur(evnt);
			this.close();
			currentDropdown = null;
			break;
        case 13: 
            if (this.currentCell != null)
            {
                var idx = this.currentCell.nlrow;
                this.setIndex(idx);
            }
            else
            {
                this.handleOnBlur(evnt);
                this.doOnChangeWhenBlur = false;
            }

            if (this.isOpen)
            {
                this.indexOnDeck = null;
                this.close();
                currentDropdown = null;

                if(!this.cancelEventOnEnterKey)
                {
                    setEventCancelBubble(evnt);
                    setEventPreventDefault(evnt);
                }
            }

			break;
		case 38: 
			if (getEventAltKey(evnt))
			{
				if (this.isOpen)
					this.close();
			}
			else
			{
				this.respondToArrow(-1);
                setEventCancelBubble(evnt);
                setEventPreventDefault(evnt);
			}
			break;
		case 40: 
			if (getEventAltKey(evnt))
			{
				if (!this.isOpen)
					this.open();
			}
			else
			{
				this.respondToArrow(+1);
                setEventCancelBubble(evnt);
                setEventPreventDefault(evnt);
			}
			break;
		case 37: 
		case 39: 
			return true;
		case 33: 
			this.respondToArrow(-14);  
            if (this.isOpen)
			    this.div.scrollTop = this.currentCell.offsetTop;
            setEventCancelBubble(evnt);
            setEventPreventDefault(evnt);
			break;
		case 34: 
			this.respondToArrow(+14);  
            if (this.isOpen)
			    this.div.scrollTop = this.currentCell.offsetTop;
            setEventCancelBubble(evnt);
            setEventPreventDefault(evnt);
			break;
		case 35: 
			this.respondToArrow(this.valueArray.length);
            if (this.isOpen)
			    this.div.scrollTop = this.currentCell.offsetTop;
            setEventCancelBubble(evnt);
            setEventPreventDefault(evnt);
			break;
		case 36: 
			this.respondToArrow(-this.valueArray.length);
            if (this.isOpen)
			    this.div.scrollTop = this.currentCell.offsetTop;
            setEventCancelBubble(evnt);
            setEventPreventDefault(evnt);
			break;
		default:
			break;
	}
};

NLDropdown.prototype.handleKeypress = function NLDropdown_handleKeypress(evnt)
{
	if (this.disabled)
		return true;

    if(this.bInitialize)
        this.initializeElements();

    this.becomeCurrent();
    var key = getEventKeypress(evnt);
	switch (key)
	{
		case 9:	
        
			break;
		case 13: 
            if (this.isOpen)
            {
                setEventCancelBubble(evnt);
                setEventPreventDefault(evnt);
            }
            break;
		default:
			this.gotoNext(key);
			setEventPreventDefault(evnt);
			break;
	}
};

NLDropdown.prototype.handleMouseMove = function NLDropdown_handleMouseMove(evnt)
{
	if (!this.isOpen)
		return true;
	this.seenMouseMove = true;
	var target = getEventTarget(evnt);
	while (target != null)
	{
		if ((target.className != null) && (target.className == 'dropdownNotSelected'))
		{
			this.setCurrentCellInMenu(target);
			break;
		}
		target = target.parentNode;
	}
};

NLDropdown.prototype.becomeCurrent = function NLDropdown_becomeCurrent()
{
	if ((currentDropdown != null) && (currentDropdown != this))
		currentDropdown.close();
	if (currentDropdown != this)
	{
		currentDropdown = this;
        this.indexOnDeck = null;
	}
};

NLDropdown.prototype.setDisabled = function NLDropdown_setDisabled(val)
{
	this.disabled = val;
	this.inpt.disabled = val;
	this.hddn.disabled = val;
	if (this.disabled)
	{
		this.close();

		if (this.span.className && this.span.className.indexOf('effectDisabled') < 0)
	        this.span.className = this.span.className + ' effectDisabled';
	}
	else
	{
		if (this.span.className && this.span.className.indexOf('effectStatic') < 0)
	        this.span.className = this.span.className.replace(' effectDisabled', ' effectStatic');
		else
	        this.span.className = this.span.className.replace(' effectDisabled', '');
	}
};

NLDropdown.prototype.setHidden = function NLDropdown_setHidden(val)
{
    this.span.style.display = val ? "none" : "";
};

NLDropdown.prototype.addOption = function NLDropdown_addOption(text, val, idx)
{
	if ( val == null )
		throw  "cannot create an option with null value";
	if ( text == null )
		throw  "cannot create an option with null text";
	var firstOption = (this.textArray.length == 0);

	text = String(text);
    if(text.indexOf("&") > -1)
        text = unEscapeHtml(text);
	val = String(val);
	if (typeof(idx)==='undefined' || idx>this.valueArray.length)
		idx = this.valueArray.length;
	for (var i=idx; i<this.valueArray.length; ++i)
	{
		this.valueToIndexMap[this.valueArray[i]] = i+1;
	}
	this.valueToIndexMap[val] = idx;

	this.textArray.splice(idx,0,text);
	this.valueArray.splice(idx,0,val);

	if (this.defaultIndex >= idx)
		++this.defaultIndex;
	if (this.getIndex() >= idx)
		this.setIndex(this.getIndex()+1, true);

	this.div = null;  
	if (firstOption)
	{
		this.defaultIndex = 0;
		this.setIndex(0, true);
	}

    this.scheduleSetWidth();
};

NLDropdown.prototype.cloneDropdownValues = function NLDropdown_cloneDropdownValues(masterdd)
{
    if (masterdd == null)
        return;

    this.textArray = masterdd.textArray;
    this.valueArray = masterdd.valueArray;
    this.valueToIndexMap = masterdd.valueToIndexMap;
    this.inpt.style.width = masterdd.inpt.style.width;
    this.inptWidth = masterdd.inptWidth;
    this.setText(null, true );
};

NLDropdown.prototype.deleteAllOptions = function NLDropdown_deleteAllOptions()
{
	this.close();
	this.valueArray.length = 0;
	this.textArray.length = 0;
	this.valueToIndexMap = new Array();
	this.div = null;
	this.defaultIndex = 0;
	this.setText("", true );
	this.hddn.value="";
	this.indx.value="-1";
};


NLDropdown.prototype.deleteOneOption = function NLDropdown_deleteOneOption(val, bDontSetWidth)
{
	val = String(val);
	var idx = this.valueToIndexMap[val];
	if (idx == null)
		return;
	this.close();

	for (var i=idx+1; i<this.valueArray.length; ++i)
	{
		this.valueToIndexMap[this.valueArray[i]] = i-1;
	}
	delete this.valueToIndexMap[val];

	this.valueArray.splice(idx,1);
	this.textArray.splice(idx,1);

	this.div = null;  
	if (!bDontSetWidth)
		this.scheduleSetWidth();
	if (idx == this.defaultIndex)
		this.defaultIndex = 0;
	else if (this.defaultIndex > idx)
		--this.defaultIndex;
	if (this.getIndex() > idx) { this.setIndex(this.getIndex() - 1, true); }
	if (val == this.getValue())
		this.gotoDefault();
};

NLDropdown.prototype.setOptionText = function NLDropdown_setOptionText(val, text)
{
	val = String(val);
	var i = this.valueToIndexMap[val];
	if (i == null)
		return;
	this.close();

	this.textArray[i] = text;

    if (val == this.getValue())
        this.setText(text, true);

	this.div = null;  
	this.scheduleSetWidth();
};

NLDropdown.prototype.setArrowImage = function NLDropdown_setArrowImage(val)
{
	if (!this.overrideImage)
    {
        // Change to a different image based on the zoom, but only if this is one of the images we supply alternates for.
        if (val == '/images/forms/ddarrow.gif' || val == '/images/forms/ddarrowPress.gif' || val == '/images/forms/ddarrowDisabled.gif')
            val = getZoomFile(val);

        if (val)
            this.ddbtn.style.backgroundImage = "url("+val+")";
        else
            this.ddbtn.style.backgroundImage = "";
    }
};

NLDropdown.prototype.overrideArrowImage = function NLDropdown_overrideArrowImage(val)
{
	this.ddbtn.style.backgroundImage = "url("+val+")";
	this.overrideImage = true;
};

NLDropdown.prototype.setBackgroundColor = function NLDropdown_setBackgroundColor(clr)
{
    this.inpt.style.backgroundColor = clr;
};

NLDropdown.prototype.setRequired = function NLDropdown_setRequired(val)
{
    this.bRequired = val;
    if(val)
        this.setBackgroundColor(this.sMandatoryBgColor);
	else
		this.setBackgroundColor('');

	setFieldLabelRequired(this.name, val, this.getForm());
};


NLDropdown.prototype.setDefaultOrNotRequired = function NLDropdown_setDefaultOrNotRequired(val)
{
    this.setRequired(val ? this.hasAttribute(128) : false);
}

NLDropdown.prototype.getRequired = function NLDropdown_getRequired(val)
{
    return this.bRequired;
}

NLDropdown.prototype.getInput = function NLDropdown_getInput()
{
    return this.inpt;
}

NLDropdown.prototype.getHiddenInput = function NLDropdown_getHiddenInput()
{
    return this.hddn;
}

NLDropdown.prototype.getContainer = function NLDropdown_getContainer()
{
    return this.span;
}

var dropdowns = {}; 
function getDropdownFromNameC(namec, win)
{
	if (typeof win == "undefined" || win == null)
		win = window;
	var returnMe = win.dropdowns[namec];
	if ((returnMe == null) && (win.parent != null) && (win.parent.dropdowns != null))
		returnMe = win.parent.dropdowns[namec];
	return returnMe;
}

function getDropdown(inpt, win)
{
	
	if ( inpt.tagName == 'SPAN' )
	{
	 	var inputs = inpt.getElementsByTagName('INPUT');
		for ( var i = 0; i < inputs.length; i++ )
		{
		 	if ( inputs[i].type == 'hidden' && inputs[i].id != null && inputs[i].id.indexOf('hddn_') == 0 )
			{
			 	inpt = inputs[i];
				break;
			}
		}
	}

	if (inpt.id)
		return getDropdownFromNameC(inpt.id.substring(5), win);
	
}


function getTextWidthDiv() {
	var div = document.createElement("div");
	div.className = 'dropdownDiv'
	div.style.position = 'absolute';
	div.style.padding = 0;
	div.style.margin = 0;
	div.style.border = 0;
	div.style.fontSize = "13px";
	return div;
}

var textWidthDiv = getTextWidthDiv();
var widthCache = {};


function getTextWidth(txt)
{
	var cached = widthCache[txt];
	if (cached != null)
		return cached;
	textWidthDiv.innerHTML = ((txt == " ") ? "&nbsp;" : txt);
    document.body.appendChild(textWidthDiv);
	var returnMe = textWidthDiv.offsetWidth;
	document.body.removeChild(textWidthDiv);
	widthCache[txt] = returnMe;
	return returnMe;
}

function elideTxt(txt, maxWidth)
{
	if (maxWidth <= 0)
		return txt;
	if (getTextWidth(txt) < maxWidth)
		return txt;
	txt = txt.replace(/^(\s|\u00A0)*/,"").replace(/(\s|\u00A0)*$/,"");  
	if (getTextWidth(txt) < maxWidth)
		return txt;
	var ellipsis = "...";
	var ellipsisWidth = getTextWidth(ellipsis);
	if (ellipsisWidth >= maxWidth)
		return ellipsis;

	var minChars = 0,
		maxChars = txt.length,
		numChars = Math.round((minChars + maxChars) / 2),
		left = txt.substr(0, Math.round(numChars / 2)),
		right = txt.substr(txt.length - Math.floor(numChars / 2)),
		txtWidth;

	while(minChars !== maxChars){
		txtWidth = getTextWidth(left + right) + ellipsisWidth;

		if (txtWidth <= maxWidth){
			minChars = numChars;
		} else {
			maxChars = numChars - 1;
		}

		numChars = Math.round((minChars + maxChars) / 2);
		left = txt.substr(0, Math.round(numChars / 2));
		right = txt.substr(txt.length - Math.floor(numChars / 2));
	}

	return left + ellipsis + right;
}




var multidropdowns = new Object(); 
var currentMultiDropdown = null;  
function getMultiDropdownFromNameC(namec, win)
{
	if (win == null)
		win = window;
	var returnMe = win.multidropdowns[namec];
	if ((returnMe == null) && (win.parent != null) && (win.parent.multidropdowns != null))
		returnMe = win.parent.multidropdowns[namec];
	return returnMe;
}

function getMultiDropdown(inpt, win)
{
	
	if ( inpt.tagName == 'SPAN' && isValEmpty( inpt.getAttribute("nlmultidropdown") ) )
	{
	 	var inputs = inpt.getElementsByTagName('INPUT');
		for ( var i = 0; i < inputs.length; i++ )
            if ( !isValEmpty( inputs[i].getAttribute("nlmultidropdown") ) )
                return getMultiDropdownFromNameC( inputs[i].getAttribute("nlmultidropdown") , win );
	}
	return getMultiDropdownFromNameC(inpt.getAttribute("nlmultidropdown") , win);
}
NLMultiDropdown.prototype.setMandatoryBackgroundColor = function NLMultiDropdown_setMandatoryBackgroundColor(sColor)
{
	this.sMandatoryBgColor = sColor;
}
NLMultiDropdown.prototype.setRequired = function NLMultiDropdown_setRequired(val)
{
	this.bRequired = val;
	if(val)
        this.setBackgroundColor(this.sMandatoryBgColor);
	else
		this.setBackgroundColor('');

	setFieldLabelRequired(this.name, val, this.getForm());
}
NLMultiDropdown.prototype.getRequired = function NLMultiDropdown_getRequired()
{
	return this.bRequired;
}

NLMultiDropdown.prototype.hasAttribute = function NLMultiDropdown_hasAttribute(flag)
{
    return (this.flags & flag) != 0;
}


NLMultiDropdown.prototype.getForm = function NLMultiDropdown_getForm()
{
    var form = null;
    try{
        form =  this.hiddenField.form;
    }catch (e) {

    }
    return form;
}



function NLMultiDropdown(name, nameC, values, defaultValues, flags, staticWidth, height, renderDocument)
{
	if (name == null)
		throw  "cannot create multi-select dropdown with null name";
	if (values == null)
		throw  "cannot create multi-select dropdown with null values";

	this.renderDocument = renderDocument;
	this.name = name;
    this.nameC = nameC;
	this.textArray = new Array(values.length / 2);
	this.valueArray = new Array(values.length / 2);
	this.valueToIndexMap = new Array();
	this.defaultValues = defaultValues;
	this.selectedVals = isValEmpty(this.defaultValues) ? new Array() : this.defaultValues.split(String.fromCharCode(5));
	this.sMandatoryBgColor = "#FFFFFF";
	this.bRequired = false;
	this.staticWidth = staticWidth;

	// we always add 1 row to FF/Safari because they don't properly render the vertical scroll bar if the text area isn't tall enough
	this.numRows = parseInt(height) + ( !isIE ? 1 : 0 );
	this.disabled = false;
	this.span = null;
	this.table = null;
	this.width = null;
	this.flags = 0;
	
	this.hiddenField = renderDocument.getElementById("hddn_" + this.nameC);
	
	this.parentSpan = this.getParentSpan( );
    this.parentSpan.setAttribute("nlmultidropdown", this.nameC);

    
		this.parentSpan.onselectstart = new Function("return false;");
    
	
	this.currentIdx = -1;
	
	this.previousIdx = -1;
	
	this.onMouseMoveIdx = -1;

	for (var i=0,j=0; i < values.length; i +=2, j++)
	{
		var txt = values[i];
		var val = values[i+1];
		this.textArray[j] = txt;
		this.valueArray[j] = val;
		this.valueToIndexMap[String(val)] = j;
	}
	this.setWidth();
	this.defaultBorderColor = this.table.style.borderColor;

    // Issue 243637: This is a cause of multiple firing of onChange client code
    // MouseUp event needs to be handled to update hidden field value and to fire onChange event
    attachEventHandler ("mouseup", document, function(evnt){ this.handleMouseUp(evnt);}.bind(this));

	// -- we never want to add the nlmultidropdown object twice
	if (window.multidropdowns[nameC] == null)
		window.multidropdowns[nameC] = this;
	this.flags = flags;
	if (this.hasAttribute(2048))
		this.setDisabled( true );
};


NLMultiDropdown.prototype.getParentSpan = function NLMultiDropdown_getParentSpan()
{
	var span = this.hiddenField.parentNode;
	while ( span != null )
    {
        if ( span.tagName == "SPAN" && span.id != null && span.id.indexOf( this.name ) != -1 )
            return span;
        span = span.parentNode;
    }
	return span;
};


NLMultiDropdown.prototype.buildSpan = function NLMultiDropdown_buildSpan()
{
	
    this.span = this.renderDocument.createElement( isIE ? "span" : "div");
	this.parentSpan.insertBefore(this.span,this.hiddenField);
	this.span.className = 'dropdownDiv';
	this.span.style.position='relative';
	this.span.style.display='inline-block';
	
	this.span.style.height=(parseInt(this.numRows)*15).toString() + 'px';
    
        this.span.tabIndex = 0;
    
    this.span.style.overflow = 'auto';
	this.span.setAttribute("nlmultidropdown", this.nameC);

    this.table = this.renderDocument.createElement("table");
	this.span.appendChild(this.table);
	this.table.cellSpacing = 0;
	this.table.width = "100%";
	this.table.cellPadding = 0;
	this.table.style.borderCollapse = 'collapse';
    this.table.style.textAlign = 'left';
	this.table.setAttribute("nlmultidropdown", this.nameC);

	var tbody = this.renderDocument.createElement("tbody");

    var length = this.textArray.length;
    var that = this;
	for (var i=0; i < length; i++)
	{
		var td = this.renderDocument.createElement("td");

		td.className = this.contains(i) ? 'dropdownSelected' : 'dropdownNotSelected';
		td.style.whiteSpace = "nowrap";
		td.style.borderWidth='0px';
		td.style.borderStyle='solid';
		td.style.borderColor='#FFFFFF';
		td.nlrow=i;
		td.setAttribute("nlmultidropdown", this.nameC);
		var msg = this.textArray[i];
		if ( isValEmpty(msg) )
			msg = "&nbsp;";

        if ( isIE )
        {
            td.innerHTML = msg;
            td.onclick = function () {
                that.setFocus();
            };
        }
        else
        {
            var a = this.renderDocument.createElement("a");
            td.appendChild(a);
            
            a.onclick = function () {
                that.setFocus();
            };
            
            a.innerHTML = msg;
            a.nlrow=i;
		    a.setAttribute("nlmultidropdown", this.nameC);
        }

		
		td.onkeypress = function (evt) {
            that.handleKeypress(evt);
        };

        var tr = this.renderDocument.createElement("tr");
        tbody.appendChild(tr);
        tr.appendChild(td);
    }
    this.table.appendChild(tbody);

    this.span.onkeypress = function (evt) {
        that.handleKeypress(evt);
    };

    if (NS.UI && NS.UI.Helpers && NS.UI.Helpers.uir_dropdownHelper)
    {
        NS.UI.Helpers.uir_dropdownHelper.onSpanBuilt(this);
    }
};


NLMultiDropdown.prototype.positionHelperIconsForNonIE = function NLMultiDropdown_positionHelperIconsForNonIE()
{
    try {
        if(isIE)
            return;

        var helperWidgetSpan = document.getElementById( this.name + "_helperwidgets");
        if(helperWidgetSpan)
        {
            

            var top = parseInt( Math.floor(this.span.offsetHeight/2) ) - parseInt( Math.floor(helperWidgetSpan.offsetHeight/2) ) + 4;
            var left = parseInt(this.span.offsetWidth) + 10;

            helperWidgetSpan.style.position = "relative";
            helperWidgetSpan.style.left = left + 'px' ;
            helperWidgetSpan.style.top = top + 'px';
            
//            this.span.style.top = -10 + "px";
        }
    } catch (e) { if(console) console.log(e.message); }
}



function getFocusElement(td)
{
    
    if (!td)
        return null;
    if (td.focus)
        return td;

    
    var tf = td.firstChild;
    td = null;
    
    while (tf && !td)
    {
        td = getFocusElement(tf);
        tf = tf.nextSibling;
	}

    
    return td;
}


NLMultiDropdown.prototype.setFocus = function NLMultiDropdown_setFocus()
{
    
    var tf = getFocusElement(this.span);
    try {
        tf.focus();
		
		if ( this.selectedVals.length == 0 )
			this.highLightBorder(0);

    //this.onMouseMoveIdx = -1;

    } catch (e) { if(console) console.log(e.message); }
	
}

NLMultiDropdown.prototype.setWidth = function NLMultiDropdown_setWidth()
{
	if ( this.span == null )
		this.buildSpan();

    if( this.staticWidth != null )
    {
        this.span.style.width = this.staticWidth + 'px';
    }
    else
    {
        
        var newWidth = this.table.offsetWidth;
        if (newWidth < 40)
            newWidth = 40;
        newWidth = Math.min( newWidth, 300 );
        this.table.style.width = newWidth + 'px';
        
        this.parentSpan.style.width = newWidth + 'px';
        
        this.width = newWidth;
    }
    this.positionHelperIconsForNonIE();
}

NLMultiDropdown.prototype.becomeCurrent = function NLMultiDropdown_becomeCurrent()
{
	if (currentMultiDropdown != this)
		currentMultiDropdown = this;
}

NLMultiDropdown.prototype.resetDropDown = function NLMultiDropdown_resetDropDown()
{
	this.removeAll();
	this.previousIdx = -1;
	this.currentIdx = -1;
	this.selectedVals = isValEmpty(this.defaultValues) ? new Array() : this.defaultValues.split(String.fromCharCode(5));

	var numOptions = this.selectedVals.length;
	var idx = 0;
	while ( idx < numOptions )
		this.add(this.valueToIndexMap[this.selectedVals[idx++]], true);
	if ( this.width == null )
		this.setWidth();
	this.setHiddenField();
}

NLMultiDropdown.prototype.getTextForValue = function NLMultiDropdown_getTextForValue(value)
{
	var idx = this.getIndexForValue(value);
	if (idx != null)
		return this.textArray[idx];
	else
		return "";
}

NLMultiDropdown.prototype.getIndexForValue = function NLMultiDropdown_getIndexForValue(value)
{
	return this.valueToIndexMap[String(value)];
}

NLMultiDropdown.prototype.setValue = function NLMultiDropdown_setValue(value)
{
	this.setIndex(valueToIndexMap[value]);
}

NLMultiDropdown.prototype.setIndex = function NLMultiDropdown_setIndex(idx,evnt)
{
	if (this.disabled)
		return;




	
	if ( getEventShiftKey(evnt) )
		this.handleShiftKey(Math.min(this.currentIdx,idx),Math.max(this.currentIdx,idx));
	
	else if (getEventCtrlKey(evnt) || getEventMacCommandKey(evnt))
	{
		if ( this.contains(idx) )
			this.remove(idx, true);
		else
			this.add(idx, true);
	}
	
	else
	{
		this.removeAll();
		this.add(idx, true);
	}

	this.highLightBorder(idx);
	this.previousIdx = idx;

    // Issue 243637: This is a cause of multiple firing of onChange client code
    //this.setHiddenField(true);
}

NLMultiDropdown.prototype.addIndex = function NLMultiDropdown_addIndex(idx)
{
	if (this.disabled)
		return;

    this.add(idx, true);

	this.highLightBorder(idx);
	this.previousIdx = idx;
	this.setHiddenField(true);
}

NLMultiDropdown.prototype.setValues = function NLMultiDropdown_setValues(vals, bDontFireOnChange)
{
	this.removeAll();
	this.previousIdx = -1;
	var valueArray = vals.split(String.fromCharCode(5));
	var i = 0;
	for ( i = 0; i < valueArray.length; i++ )
		this.add(this.getIndexForValue(valueArray[i]),true);
	this.setHiddenField(!bDontFireOnChange);
}

NLMultiDropdown.prototype.getValues = function NLMultiDropdown_getValues()
{
    return this.valueArray;
}


NLMultiDropdown.prototype.highLightBorder = function NLMultiDropdown_highLightBorder(idx)
{
	if ( this.previousIdx != -1 )
	{
		this.getCell(this.previousIdx).style.borderStyle='solid';
		this.getCell(this.previousIdx).style.borderColor='#FFFFFF';
	}
	this.getCell(idx).style.borderStyle='dotted';
	this.getCell(idx).style.borderColor=this.defaultBorderColor;
}

NLMultiDropdown.prototype.handleScrolling = function NLMultiDropdown_handleScrolling(idx)
{
	if ( this.span != null )
	{
		var windowTop = this.span.scrollTop;
		var windowBottom = this.span.scrollTop + this.getCell(idx).offsetHeight * Math.max(1,this.numRows-1);
        
        if ( this.getCell(idx).offsetTop > (windowBottom+this.getCell(idx).offsetHeight) || this.getCell(idx).offsetTop < (windowTop-this.getCell(idx).offsetHeight) )
            this.span.scrollTop =  this.getCell(idx).offsetTop;
		
        else if ( this.getCell(idx).offsetTop > windowBottom )
			this.span.scrollTop += this.getCell(idx).offsetHeight;
        
        else if ( this.getCell(idx).offsetTop < windowTop )
            this.span.scrollTop -= this.getCell(idx).offsetHeight;
	}
}

NLMultiDropdown.prototype.getSelectedValues = function NLMultiDropdown_getSelectedValues()
{
	return this.selectedVals.join(String.fromCharCode(5));
}

NLMultiDropdown.prototype.getSelectedText = function NLMultiDropdown_getSelectedText(delim)
{
	var val = '';
	if ( isValEmpty(delim) )
		delim = ',';
	if ( this.selectedVals.length > 0 )
	{
		for ( var i=0; i < this.selectedVals.length; i++)
			val += (i == 0 ? '' : delim) + this.getText(this.valueToIndexMap[this.selectedVals[i]]);
	}
	return val;
}


NLMultiDropdown.prototype.getSelectedTextFromValues = function NLMultiDropdown_getSelectedTextFromValues(values,delim)
{
	var val = '';
	if ( isValEmpty(delim) )
		delim = ',';
	if ( !isValEmpty(values) )
	{
		
		var tokens = values.split(String.fromCharCode(5));
		for ( var i=0; i < tokens.length; i++)
			val += (i == 0 ? '' : delim) + this.getText(this.valueToIndexMap[tokens[i]]);
	}
	return val;
}


NLMultiDropdown.prototype.setHiddenField = function NLMultiDropdown_setHiddenField(invokeOnChange)
{
	this.hiddenField.value = this.getSelectedValues();
	if ( invokeOnChange )
		this.hiddenField.onchange();
}

NLMultiDropdown.prototype.removeAll = function NLMultiDropdown_removeAll()
{
	var vals = this.selectedVals;
	for ( var i=0; i < vals.length; i++ )
	{
		var idx = this.valueToIndexMap[vals[i]];
		this.remove(idx, true);
		this.getCell(idx).style.borderStyle='solid';
		this.getCell(idx).style.borderColor='#FFFFFF';
	}
}

NLMultiDropdown.prototype.add = function NLMultiDropdown_add(idx,updateCell)
{
	if (idx == null)
		return;
	this.currentIdx = idx;
	arrayAdd(this.selectedVals, this.getValue(idx));
	if ( updateCell )
		this.getCell(idx).className= 'dropdownSelected';
}

NLMultiDropdown.prototype.remove = function NLMultiDropdown_remove(idx, updateCell)
{
	if (idx == null)
		return;
	this.selectedVals = arrayRemove(this.selectedVals, this.getValue(idx));
	if ( updateCell )
		this.getCell(idx).className= 'dropdownNotSelected';
}

NLMultiDropdown.prototype.contains = function NLMultiDropdown_contains(idx)
{
	return arrayContains(this.selectedVals,this.valueArray[idx]);
}

NLMultiDropdown.prototype.getCell = function NLMultiDropdown_getCell(idx)
{
	return this.table.rows[idx].cells[0];
}

NLMultiDropdown.prototype.getValue = function NLMultiDropdown_getValue(idx)
{
	return this.valueArray[idx];
}

NLMultiDropdown.prototype.getText = function NLMultiDropdown_getText(idx)
{
	return this.textArray[idx];
}

NLMultiDropdown.prototype.setBackgroundColor = function NLMultiDropdown_setBackgroundColor(clr)
{
	this.defaultBorderColor = clr;
    this.table.style.backgroundColor = clr;
    this.span.style.backgroundColor = clr;
}

NLMultiDropdown.prototype.handleShiftKey = function NLMultiDropdown_handleShiftKey(from_idx, to_idx)
{
	if ( from_idx > to_idx || from_idx < 0 || to_idx >= this.valueArray.length  )
		return;
	else
	{
		var i = 0;
		while ( i < this.valueArray.length )
		{
			if ( i >= from_idx && i <= to_idx )
				this.add(i, true)
			else
				this.remove(i, true);
			i++;
		}
	}
}

NLMultiDropdown.prototype.handleMoveSelection = function NLMultiDropdown_handleMoveSelection(evnt,offset)
{
	var numValues = this.valueArray.length;
	var idx = this.currentIdx;

	idx += offset;
	idx = Math.min(idx,numValues-1);
	idx = Math.max(idx, 0);

	
	if ( getEventShiftKey(evnt) )
		this.handleShiftKey(Math.min(this.previousIdx,idx),Math.max(this.previousIdx,idx));
	else
		this.removeAll();

	this.add(idx, true);
	this.highLightBorder(idx);
	if ( !getEventShiftKey(evnt) )
		this.previousIdx = idx;
	this.handleScrolling(idx);
	this.setHiddenField(true);
}

NLMultiDropdown.prototype.handleTypeAhead = function NLMultiDropdown_handleTypeAhead(key)
{
	var ctr = Math.max(this.currentIdx, 0)+1;
	var i;
	var len = this.textArray.length;
	var searchString = String.fromCharCode(key).toUpperCase();

	var matched = false;
	for (var tries = 0; tries < len; tries++)
	{
		i = ctr % len;
		var match = this.textArray[i].substr(0, searchString.length).toUpperCase();
		if (match == searchString)
		{
			matched = true;
			break;
		}
		++ctr;
	}
	if (matched)
	{
		this.removeAll();
		this.add(i, true);
       	this.highLightBorder(i);
		this.previousIdx = i;
		this.handleScrolling(i);
		this.setHiddenField(true);
	}
}

NLMultiDropdown.prototype.handleMouseMove = function NLMultiDropdown_handleMouseMove(evnt)
{
	if ( this.disabled )
		return;
	if ( this.onMouseMoveIdx == -1 )
		return;
    else if (isIE && (getEvent(evnt).button == 0))
    {
        
        this.onMouseMoveIdx = -1;
        if (currentMultiDropdown == this)
            currentMultiDropdown = null;
        return;
    }
    var target = getEventTarget(evnt);
	while (target != null)
	{

        if (target.className != null
                && !isNaN(target.nlrow)
                && target.nlrow != 'undefined'
                && target.getAttribute("nlmultidropdown") == this.nameC)
		{
			var idx = target.nlrow;
			
			var doRemoveOption = this.onMouseMoveIdx != this.previousIdx && this.contains(this.onMouseMoveIdx) &&
								 Math.abs(this.previousIdx-this.onMouseMoveIdx) > Math.abs(this.previousIdx-idx);
			if ( doRemoveOption )
				this.remove(this.onMouseMoveIdx, true);
			else
			{
			
				var from_idx = Math.min(this.previousIdx, idx);
				var to_idx = Math.max(this.previousIdx, idx);
				for ( var i = from_idx; i <= to_idx; i++ )
				{
					if ( !this.contains(i) )
						this.add(i, true);
				}
			}

			this.handleScrolling(idx);
			this.onMouseMoveIdx = idx;
			break;
		}
		target = target.parentNode;
	}
	// Issue 243637: This is a cause of multiple firing of onChange client code
	//this.setHiddenField(true);
}

NLMultiDropdown.prototype.handleMouseDown = function NLMultiDropdown_handleMouseDown(evnt)
{
	if (this.disabled)
		return;

	this.becomeCurrent();
	var target = getEventTarget(evnt);
	if ( target != null && !isNaN(target.nlrow) && target.nlrow != 'undefined' )
	{
		this.onMouseMoveIdx = target.nlrow;
		this.setIndex(target.nlrow,evnt)
		this.handleScrolling(target.nlrow);
        // Fire events only on the MultiDropdown which started the drag
        this.dragBegan = true;
	}
}
// Issue 243637: This is a cause of multiple firing of onChange client code
// How the setHiddenField method (onChange is fired there) is called only on mouseUp event
NLMultiDropdown.prototype.handleMouseUp = function NLMultiDropdown_handleMouseUp(evnt)
{
    if (!this.dragBegan)
        return;

    if (this.disabled)
        return;

    this.dragBegan = false;
    this.becomeCurrent();
    this.setHiddenField(true);
}

NLMultiDropdown.prototype.handleKeydown = function NLMultiDropdown_handleKeydown(evnt)
{
	if (this.disabled)
		return;
	this.becomeCurrent();

	var bReturnMe = false;
	var keycode = getEventKeypress(evnt);
	switch (keycode)
	{
		case 33: 
			this.handleMoveSelection(evnt, -this.numRows);
			break;
		case 34: 
			this.handleMoveSelection(evnt, +this.numRows);
			break;
		case 35: 
			this.handleMoveSelection(evnt, this.valueArray.length-this.currentIdx);
			break;
		case 36: 
			this.handleMoveSelection(evnt, -this.currentIdx);
			break;
		case 38: 
			this.handleMoveSelection(evnt, -1);
			break;
		case 40: 
			this.handleMoveSelection(evnt, +1);
			break;
		default:
			bReturnMe = true;
			break;
	}
	return bReturnMe;
}

NLMultiDropdown.prototype.handleKeypress = function NLMultiDropdown_handleKeypress(evnt)
{
    if (this.disabled)
		return true;

	this.becomeCurrent();
	var key = getEventKeypress(evnt);
    this.handleTypeAhead(key);
}

NLMultiDropdown.prototype.setDisabled = function NLMultiDropdown_setDisabled(val)
{
	this.disabled = val;
	this.hiddenField.disabled = val;
    if ( this.table != null )
    {
        this.table.disabled = val;

        
        if( !isIE )
        {
            var as = this.table.getElementsByTagName("A");
            for(var i=0; i<as.length; i++)
                as[i].style.color = val ? "#AAAAAA" : "";
        }
    }

	if ( !this.disabled && this.span == null && this.width == null ) 
	{
		this.setWidth();
		this.setBackgroundColor(this.defaultBorderColor);
	}
}

NLMultiDropdown.prototype.setHidden = function NLMultiDropdown_setHidden(val)
{
	if ( this.span != null )
        this.span.style.display = val ? "none" : "";
}


NLMultiDropdown.prototype.addOption = function NLMultiDropdown_addOption(text, val, selected, idx)
{
	if ( val == null )
		throw  "cannot create an option with null value";
	if ( text == null )
		throw  "cannot create an option with null text";

	text = String(text);
	val = String(val);

	if (typeof(idx)=='undefined') idx = this.valueArray.length;
	this.textArray.splice(idx,0,text);
	this.valueArray.splice(idx,0,val);
	this.valueToIndexMap[val] = idx;
	if ( selected )
		this.add(idx, false);

	if ( this.span != null )
		this.parentSpan.removeChild(this.span);
	this.span = null;  
    this.width = null;

    this.setWidth();
    this.setBackgroundColor(this.defaultBorderColor);
	this.setHiddenField();
	if ( !this.disabled )
	    this.handleScrolling(idx);
}

NLMultiDropdown.prototype.deleteAllOptions = function NLMultiDropdown_deleteAllOptions()
{
	this.valueArray.length = 0;
	this.textArray.length = 0;
	this.valueToIndexMap = {};

	this.previousIdx = -1;
	this.currentIdx = -1;

	this.selectedVals = [];
    if (this.span != null)
	    this.parentSpan.removeChild(this.span);
	this.span = null;  
	this.width = null;

	this.setWidth();
	this.setBackgroundColor(this.defaultBorderColor);
	this.setHiddenField();
}

NLMultiDropdown.prototype.deleteOneOption = function NLMultiDropdown_deleteOneOption(val)
{
	val = String(val);
	var i = this.valueToIndexMap[val];
	if (i == null)
		return;

	this.valueArray.splice(i,1);
	this.textArray.splice(i,1);

	delete this.valueToIndexMap[val];
	this.selectedVals = arrayRemove(this.selectedVals, val);
	if ( this.span != null )
		this.parentSpan.removeChild(this.span);
	this.span = null;  
	this.width = null;

	this.setWidth();
	this.setBackgroundColor(this.defaultBorderColor);
	this.setHiddenField();
}

NLMultiDropdown.prototype.getContainer = function NLMultiDropdown_getContainer()
{
    return this.span;
}

function resetNLDropDowns(frm)
{
	
	if ( window.dropdowns != null )
	{
		for ( i in window.dropdowns )
		{
			var dd = window.dropdowns[String(i)];
			if ( dd.elementsAreInitialized && (frm == null || dd.getForm() == frm ) )
				dd.resetDropDown();
		}
	}
	
	if ( window.multidropdowns != null )
	{
		for ( i in window.multidropdowns )
		{
			var dd = window.multidropdowns[String(i)];
			if ( frm == null || dd.hiddenField.form == frm )
				dd.resetDropDown();
		}
	}
}


var _popup_help = '<Enter first few letters then tab>';
var _short_popup_help = '<Type then tab>';
var _mult_popup_help = '<Type & tab for single value>';
var _popup_help_search = 'Type & tab...';


function getStyleForClass(className, property)
{
	var styleSheets = document.styleSheets;
	for ( var i = 0; i < styleSheets.length; i++ )
	{
		var rules = styleSheets[i].rules ? styleSheets[i].rules : styleSheets[i].cssRules;
		for (var j = 0; j < rules.length; j++)
		{
            var rule = rules[ j ];
            if (!rule.hasOwnProperty('style'))
            {
                continue;
            }
			var style = rule.style;
			var selectorText = rule.selectorText;
			if ( !isValEmpty(style[property]) && selectorText != null && selectorText.replace('.','') == className )
				return style[property];
		}
	}
	return null;
}


var dragger = null;
var mouseX=0, mouseY=0;
var currentPortlet = null;
var bar = null;

var EVENT_PORTLET_MAX = 0;
var EVENT_PORTLET_MIN = 1;
var EVENT_PORTLET_MOVE = 2;
var EVENT_PORTLET_DROP = 3;
var EVENT_PORTLET_DRAG = 4;

function NLPortletDragger()
{
  this.trToBeMoved = null;
  this.divContainer = null
  this.headerTR = null;
  this.width = null;
  this.originalColumn = null;
  this.originalNext = null;
  this.originalContainer = null;
  this.widthPlaceHolder = null;
  this.portletID = null;
}

function movedToDifferentWidthColumn(iOldColumn, iNewColumn)
{
    return ((iOldColumn == 1 || iOldColumn == 3) && iNewColumn == 2) || ((iNewColumn == 1 || iNewColumn == 3) && iOldColumn == 2);
}

NLPortletDragger.prototype.putDownPortlet = function NLPortletDragger_putDownPortlet()
{
	if (bar && bar.parentNode)
		bar.parentNode.removeChild(bar);

	var moveTo = currentPortlet;

	if(!isNS)
		this.divContainer.parentNode.removeChild(this.divContainer);
	if (moveTo != null)
    {

        // Figure out which column of the main table we are trying to put this portlet in (0 based)
        var newColumn = getCellIndex(moveTo.parentNode.parentNode.parentNode) + 1;

        //hide HC svg element before move it to the new place: solving the flashing original size chart issue
        var chart = NLHighChartManager_Instance.getChartObject("portletHC_child_portlet_"+this.portletID);

        if((typeof chart != 'undefined')&&(movedToDifferentWidthColumn(this.originalColumn, newColumn)))
        {
            //hide the HC element by seeting its size to 0
            chart.setSize(0,0);
        }

        moveTo.parentNode.insertBefore(this.trToBeMoved, moveTo);


        if (typeof this.updateLayoutInDatabase != 'undefined')
            this.updateLayoutInDatabase(this.portletID, moveTo.portletID, newColumn, this.originalColumn, this.trToBeMoved.id);
        else
            updateLayoutInDatabase(this.portletID, moveTo.portletID, newColumn, this.originalColumn);


        
        if( movedToDifferentWidthColumn(this.originalColumn, newColumn) == true)
            this.headerTR.setAttribute("ptlt_hasdisplayed", "F");

	}
    else
    {
        // this object has not moved, so put it back where it was without making any database changes
        if(this.widthPlaceHolder)
            this.originalContainer.insertBefore(this.trToBeMoved, this.originalNext);
    }

    // remove the width placeholder (tr)
    if(this.widthPlaceHolder)
        this.originalContainer.removeChild(this.widthPlaceHolder);

    clearTimeout(chartResizingTimeout);
    chartResizingTimeout = setTimeout(reflowAllCharts, 300);//reflowAllCharts(); // Issue 221984

    // we're done, so set the currentPortlet to null
	currentPortlet = null;

}

NLPortletDragger.prototype.putDownRow = function NLPortletDragger_putDownRow()
{
    if (bar && bar.parentNode)
        bar.parentNode.removeChild(bar);

    var moveTo = currentPortlet;
    if ( this.divContainer != null )
    {
        this.divContainer.parentNode.removeChild(this.divContainer);
        this.originalContainer.insertBefore(this.trToBeMoved, this.originalNext);
    }
    if ( moveTo == null )
        return;

    // remove  insertion mark
    if ( OrderedListMarkRowNavigation )
        OrderedListMarkRowNavigation(moveTo, false);

    if ( moveTo.isOrderedList && OrderedListMoveLineTo )
        OrderedListMoveLineTo(moveTo.machineName, moveTo.rowIndex);
    else if ( moveTo.machineName != null )
    {
        var newRowIdx = moveTo.rowIndex;
        var currentRowIdx = eval( moveTo.machineName+'_machine.getMachineIndex()' );
        var isInlineEdit = eval( moveTo.machineName+'_machine.isinline' );
        var machine = getMachineByName(moveTo.machineName);
        
        if ( isInlineEdit && currentRowIdx < moveTo.rowIndex && machine.moveButtons)
            newRowIdx--;
        eval( moveTo.machineName+'_machine.movelineto('+newRowIdx+')' );
    }

    // we're done, so set the currentPortlet to null
    currentPortlet = null;
}


function getCellIndex(td)
{
	

		return td.cellIndex;

	
}

function movePortlet(origElement, evnt)
{
  // I wrapped this entire method in a try/catch just to be safe.
  // If anything goes wrong here, we'll just do nothing to the layout
  try
  {
          // this handles cases where there are href links inside the TR that carries the onmousedown handler
          // for the portlet dragger.  This will fire the href, and leave the portlet where it is
          var clickedElem = getEventTarget(evnt);
          if(clickedElem.nodeName == "A" || clickedElem.nodeName == "SPAN")
              return true;
        // look for the closest element with the portlet handle class.  This should be our parent TR
        var element = findClassUp(origElement, 'portletHandle');
        dragger = new NLPortletDragger();
        dragger.portletID = getPortletId(origElement.id);
        dragger.headerTR = origElement;
        // grab the TR that contains the portlet and get the other objects we need to position it properly
        dragger.trToBeMoved = element;
        dragger.originalColumn = getCellIndex(element.parentNode.parentNode.parentNode) + 1;
        dragger.originalContainer = element.parentNode;
        dragger.originalNext = element.nextSibling;
        dragger.width = element.offsetWidth;
        // create the temporary div that we will drag around with the portlet in it
        dragger.divContainer = document.createElement("div");
        dragger.divContainer.style.position = "absolute";
        dragger.divContainer.style.width = dragger.width;
        dragger.divContainer.style.background = document.body.bgColor;

        // make the portlets slightly opaque when dragging them
        if(isIE)
        {
           dragger.divContainer.style.filter = "alpha(opacity=92)";
        }
        else
        {
            dragger.divContainer.style.opacity = (0.92);
            dragger.divContainer.style.MozOpacity = (0.92);
        }

        // insert a temp TR so that the width doesn't jump around on us
        // currently this is stretch.gif, but it could just as easily be a block level element
        dragger.widthPlaceHolder = document.createElement("tr");
        var td = document.createElement("td");
        var img = document.createElement("img");
        td.appendChild(img);
        dragger.widthPlaceHolder.appendChild(td);
        img.src = "/images/nav/stretch.gif";
        img.width = dragger.width;
        img.height = "0";
        // add it to the end so that you don't see the 1 px jump
        if(dragger.widthPlaceHolder)
            dragger.originalContainer.appendChild(dragger.widthPlaceHolder);
        dragger.originalContainer.removeChild(element);

        var eTable = document.createElement("table");
        eTable.style.borderWidth = 0;
        eTable.width = "100%";
        var tBody = document.createElement("tbody");
        eTable.appendChild(tBody);
        tBody.appendChild(element);
        dragger.divContainer.appendChild(eTable);
        if(!isNS)
        {
            document.body.appendChild(dragger.divContainer);
            // calculate the position of the floating portlet div that will follow the mouse
            positionFloatingPortlet(dragger.divContainer, 4);
        }
    }
    catch(e)
    {
        
        dragger = null;
    }
}

function portletDraggerOnMouseMove(evnt)
{
	// update the mouse position
    updateMousePosition(evnt);

	if (dragger)
	{
        // if there are scroll bars and we try to drag the portlet above or below
        // the current viewable area, we'll pop the scroll bars to the top or bottom
        // depending on which way they are dragging
		if( (document.body.scrollHeight > getDocumentHeight()) && (getDocumentHeight()-mouseY) < 10 )
			document.body.scrollTop = document.body.scrollHeight - getDocumentHeight();
		else if (mouseY < 15 && document.body.scrollTop > 0)
			document.body.scrollTop = 0;

		if(!isNS)
            positionFloatingPortlet(dragger.divContainer, 4);
        // keep track of where we are portlet-wise
		var elem = getEventTarget(evnt);
        elem = findClassUp(elem, 'portletHandle');
		if ((elem != null) && (elem != currentPortlet) && elem != dragger.trToBeMoved)
		{
			currentPortlet = elem;

			if (bar != null && bar.parentNode != null)
				bar.parentNode.removeChild(bar);
			bar = getPositionUpdateBar();
            currentPortlet.portletID = getPortletId(currentPortlet.id);

			// showing the bar will crash ie5.0 windows about 20% of the time
            // if this turns into an issue with customers, we can just create a div to float over
            // the spot rather than inserting the hr into the table
			currentPortlet.parentNode.insertBefore(bar, currentPortlet);
		}

        notifyPortlet(dragger.portletID, EVENT_PORTLET_MOVE);
    }
}

function updateMousePosition(evnt)
{
	// update the mouse position
	mouseX = getMouseX(evnt);
	mouseY = getMouseY(evnt);
}

function getPositionUpdateBar( adjacentrow )
{
	var tr = document.createElement("tr");
	var td = document.createElement("td");
	tr.appendChild(td);
    var hr = document.createElement("hr");
    hr.style.width='100%';
    hr.className = 'portletDragDropBar';
    td.appendChild(hr);
    if ( adjacentrow && adjacentrow.cells.length > 0 )
    {
        td.colSpan = adjacentrow.cells.length;
        hr.style.width='95%';
    }
	return tr;
}

function positionFloatingPortlet(dragger, iDistanceY)
{
    // set up some constants to make these easy to experiment with and change
    // margins specify the number of pixels between the edge of the page and the portlet div (prevents the div from leaving the page)
    var leftMargin = 8;
    var rightMargin = 10;
    var YdistanceFromMouseToDiv = iDistanceY;
    var clientWidth = getDocumentClientWidth();

    // div would extend off the left screen, so we put it along the left margin
    if(mouseX < 15)
        dragger.style.left = leftMargin + "px";
    // div would extend off the right of the screen, so put it along the right margin
    else if( (mouseX + dragger.offsetWidth)  > (clientWidth - rightMargin) )
        dragger.style.left = (clientWidth - rightMargin) - dragger.offsetWidth + "px";
    // we have room, so keep it aligned with the mouse pointer
    else
        dragger.style.left = mouseX - 10 + "px";

    // the div must be slightly below the mouse so that we can keep track of which portlet the mouse is over
    // it's very important to include scrollTop property here...
    // And, we only change the y position if we are actually within the browser window
    if ( mouseY < getDocumentHeight())
    {
		var top = mouseY + document.body.scrollTop + YdistanceFromMouseToDiv;
		if ( !((mouseY + dragger.offsetHeight) < getDocumentHeight())){
			top = top - dragger.offsetHeight - 15 ;
		}
		top = top > 0 && top || 0;
		dragger.style.top = top + "px";
	}
}

function portletDraggerOnMouseDown(evnt)
{
    if (dragger || getButtonId(evnt) > 1)
        return;
    var target = getEventTarget(evnt);
    var element = findClassUp(target, 'portletlabelDragDrop');
    if (element != null && element.id != null)
    {
        movePortlet(element, evnt);

        var id = getPortletId(element.id);
        notifyPortlet(id, EVENT_PORTLET_DRAG);
    }
}

function portletDraggerOnMouseUp()
{
	if (dragger)
	{
        dragger.putDownPortlet();
        notifyPortlet(dragger.portletID, EVENT_PORTLET_DROP);

		dragger = null;
        return false;  // if the user dropped the portlet on a link, don't navigate away
	}
}

function getPortletId(elementID)
{
    if (elementID == null)
        return -1;
    else
        return elementID.substring(elementID.lastIndexOf("_")+1,elementID.length);

}


function updateLayoutInDatabase(moving, pushedDown, newColumn, oldColumn)
{
    //Send a parameter indicate if the chart portlet has been moved: solving chart flash twice issue(cause: if iframe is moved the url inside will be executed again.)
        //For IE, iframe inside portlet moved, wont have its url executed. So we need to refresh the portle here
    if((typeof NLHighChartManager_Instance.getChartObject("portletHC_child_portlet_"+ moving) != 'undefined')&& !Ext.isIE)
        //Moving in the same column may also need refresh due to some SVG and IE conflict
        var sUrl = "/app/center/portletlayout.nl?movedid=" + moving + "&replacedid=" + pushedDown + "&sectionid=-29&newcolumn=" + newColumn + "&oldcolumn=" + oldColumn + "&chartMoved=" + "true";
    else
        var sUrl = "/app/center/portletlayout.nl?movedid=" + moving + "&replacedid=" + pushedDown + "&sectionid=-29&newcolumn=" + newColumn + "&oldcolumn=" + oldColumn + "&chartMoved=" + "false";
    var entityId = getParameter("entityid", document);
    if(entityId != null)
        sUrl += "&entityid=" + entityId;
    var project = getParameter("project", document);
    if (project)
        sUrl += "&project=" + project;
    sendRequestToFrame(sUrl, "server_commands");
}

function hidePortlet(iSection, iPortlet, elementId)
{
    var element = document.getElementById(elementId);
    // now get the main TR that this portlet occupies in the table, and remove it
    element = findClassUp(element, 'portletHandle');
    if(element != null)
    {
        var sUrl = "/app/center/setup/dashboard.nl?portletid="+iPortlet+"&sectionid="+iSection+"&dynamic=T"+"&elementid="+elementId;
        sUrl += "&method=hideportlet";
        if (window.editDashboard)
            sUrl += "&e=T";
        sendRequestToFrame(sUrl, "server_commands");
    }

    clearTimeout(chartResizingTimeout);
    chartResizingTimeout = setTimeout(reflowAllCharts, 300);
}

function doHidePortlet(elementId)
{
    var element = document.getElementById(elementId);
    // now get the main TR that this portlet occupies in the table, and remove it
    element = findClassUp(element, 'portletHandle');
    if(element != null)
    {
        element.parentNode.removeChild(element);
    }

    //when hide a portlet, the same column chart may be affected
    clearTimeout(chartResizingTimeout);
    chartResizingTimeout = setTimeout(reflowAllCharts, 300);

}


var portletMaxControlImgUrl = "/images/icons/dashboard/portletelements/chiles/maximize.gif";
var portletMaxControlHighLightImgUrl = "/images/icons/dashboard/portletelements/chiles/maximize_hl.gif";
var portletMinControlImgUrl = "/images/icons/dashboard/portletelements/chiles/minimize.gif";
var portletMinControlHighLightImgUrl = "/images/icons/dashboard/portletelements/chiles/minimize_hl.gif";

function minimizePortlet(iSection, iPortlet, elementId, sElementQueryId, sStickyTag, bDynamic)
{
    var element = document.getElementById(elementId);
    if(element != null && element.nodeName == "TR")
    {
        var hasDisplayedContent = element.getAttribute("ptlt_hasdisplayed") == "T";
        var contentElement = document.getElementById(elementId + "_content");
        var wasMinimized = contentElement.style.display == "none";
        var sDisplayMode = wasMinimized ? "" : "none";

        if(!wasMinimized || hasDisplayedContent || !bDynamic)
        {
		    var portletTable = document.getElementById('table_'+elementId);
            for(var i=contentElement.rowIndex; i<portletTable.rows.length; i++)
            {
                portletTable.rows[i].style.display = sDisplayMode;
            }

            var maxminElement = document.getElementById(elementId + "_maxmin" );
            if( wasMinimized )
            {
                maxminElement.className =  maxminElement.className.replace('portletIconMaximize', 'portletIconMinimize');
            }
            else
            {
                maxminElement.className =  maxminElement.className.replace('portletIconMinimize', 'portletIconMaximize');
            }
        }
        element.setAttribute("ptlt_hasdisplayed","T");
        var sUrl = "/app/center/setup/minimizeportlet.nl?portletid="+iPortlet+"&sectionid="+iSection;
        sUrl = addParamToURL(sUrl, "elemid", sElementQueryId);
        sUrl = addParamToURL(sUrl, "sticky", sStickyTag);
        sUrl = addParamToURL(sUrl, "_minimize", (wasMinimized ? "F" : "T"));
        sUrl = addParamToURL(sUrl, "_reload", (wasMinimized && !hasDisplayedContent && bDynamic ? "T" : "F"));
        sendRequestToFrame(sUrl, "server_commands");
        notifyPortlet(iPortlet, wasMinimized ? EVENT_PORTLET_MAX : EVENT_PORTLET_MIN);

        clearTimeout(chartResizingTimeout);
        chartResizingTimeout = setTimeout(reflowAllCharts, 300);
    }
}

function minimizeProjectDashboardPortlet(iSection, iPortlet, elementId, sElementQueryId, sStickyTag, bDynamic, projectId)
{
    var element = document.getElementById(elementId);
    if(element != null && element.nodeName == "TR")
    {
        var hasDisplayedContent = element.getAttribute("ptlt_hasdisplayed") == "T";
        var contentElement = document.getElementById(elementId + "_content");
        var wasMinimized = contentElement.style.display == "none";
        var sDisplayMode = wasMinimized ? "" : "none";

        if(!wasMinimized || hasDisplayedContent || !bDynamic)
        {
            var portletTable = document.getElementById('table_' + elementId);
            for(var i = contentElement.rowIndex; i < portletTable.rows.length; i++)
            {
                portletTable.rows[i].style.display = sDisplayMode;
            }

            var maxminElement = document.getElementById(elementId + "_maxmin");
            if(wasMinimized)
            {
                maxminElement.className =  maxminElement.className.replace('portletIconMaximize', 'portletIconMinimize');
            }
            else
            {
                maxminElement.className =  maxminElement.className.replace('portletIconMinimize', 'portletIconMaximize');
            }
        }
        element.setAttribute("ptlt_hasdisplayed","T");
        var sUrl = "/app/accounting/project/minimizeprojectdashboardportlet.nl?portletid=" + iPortlet + "&sectionid=" + iSection;
        sUrl = addParamToURL(sUrl, "elemid", sElementQueryId);
        sUrl = addParamToURL(sUrl, "sticky", sStickyTag);
        sUrl = addParamToURL(sUrl, "_minimize", (wasMinimized ? "F" : "T"));
        sUrl = addParamToURL(sUrl, "_reload", (wasMinimized && !hasDisplayedContent && bDynamic ? "T" : "F"));
        sUrl = addParamToURL(sUrl, "project", projectId);
        sendRequestToFrame(sUrl, "server_commands");
        notifyPortlet(iPortlet, wasMinimized ? EVENT_PORTLET_MAX : EVENT_PORTLET_MIN);

        clearTimeout(chartResizingTimeout);
        chartResizingTimeout = setTimeout(reflowAllCharts, 300);
    }
}


function refreshPortlet(sElementQueryId, sStickyTag, noreload, sSectionId, iPortletId, iEntityId, bEntityHasChild, iNewSearchId, sAdditionalUrlParams, sLineId)
{
    if (NS.Dashboard) {
        return refreshPortletCompat(sElementQueryId, noreload, iPortletId, iNewSearchId, sAdditionalUrlParams, sLineId);
    }

    // whenever we are refreshing the portlet, we change the "Refresh" link to an unclickable animated "Refreshing..."
    setPortletToUpdating(sElementQueryId);

    var serverUrl = "/app/center/setup/portletrefresher.nl?elemid="+sElementQueryId+"&sticky="+sStickyTag;
    if(noreload != null)
        serverUrl += "&noreload=" + (noreload ? "T" : "F") ;
    if(sSectionId != null)
        serverUrl += "&sc=" + sSectionId;
    if(iPortletId != null)
        serverUrl += "&portletid=" + iPortletId;
    if(iEntityId != null)
        serverUrl += "&entityid=" + iEntityId + "&haschild="+(bEntityHasChild ? "T" : "F");
    if(iNewSearchId != null)
        serverUrl += "&searchid=" + iNewSearchId;
    if(sLineId != null)
        serverUrl += "&lineid=" + sLineId;

    

    if(sAdditionalUrlParams != null && sAdditionalUrlParams.length > 0)
    {
        if(sAdditionalUrlParams.charAt(0) == "?")
            sAdditionalUrlParams = sAdditionalUrlParams.substring(1);
        serverUrl += "&addparams="+escape(sAdditionalUrlParams);
    }
    sendRequestToFrame(serverUrl,"server_commands");
}

/** @author jnguyen **/
function refreshPortletCompat(sElementQueryId, noreload, iPortletId, iNewSearchId, sAdditionalUrlParams, sLineId) {
    var dataParams = {
        noreload: (noreload ? "T" : "F"),
        searchid: iNewSearchId,
        lineid: sLineId
    };

    //split the additional params into name value pairs
    var regex = /([\w]+)=([^&]*)/g;
    var match;
    while((match = regex.exec(sAdditionalUrlParams)) !== null)
    {
        dataParams[match[1]] = match[2];
    }

    // .. fallback for partial calls
    if (!iPortletId && sElementQueryId) {
        var results = /[0-9]+/.exec(sElementQueryId);
        var isSystemPortlet = /neg/.test(sElementQueryId);
        iPortletId = isSystemPortlet ? -results[0] : results[0];
    }

    // .. decode URL parameters to ensure legacy compatibility with already
    // .. encoded special chars (typically pseudo-separators in search/reporting)
    var decodedParams = decodeURIComponent(jQuery.param(dataParams));

    var portlet = NS.Dashboard.getInstance().getPortlet(iPortletId);
    portlet.reload("refresh", decodedParams);
}

function refreshProjectPortlet(sElementQueryId, sStickyTag, noreload, sSectionId, projectId, iPortletId, iEntityId, bEntityHasChild, iNewSearchId, sAdditionalUrlParams, sLineId)
{
    // whenever we are refreshing the portlet, we change the "Refresh" link to an unclickable animated "Refreshing..."
    setPortletToUpdating(sElementQueryId);

    var serverUrl = "/app/center/setup/portletrefresher.nl?elemid=" + sElementQueryId + "&sticky=" + sStickyTag;
    if(noreload)
        serverUrl += "&noreload=" + (noreload ? "T" : "F") ;
    if(sSectionId)
        serverUrl += "&sc=" + sSectionId;
    if(iPortletId)
        serverUrl += "&portletid=" + iPortletId;
    if(iEntityId)
        serverUrl += "&entityid=" + iEntityId + "&haschild="+(bEntityHasChild ? "T" : "F");
    if(iNewSearchId)
        serverUrl += "&searchid=" + iNewSearchId;
    if(sLineId)
        serverUrl += "&lineid=" + sLineId;
    if (projectId)
       serverUrl += "&project=" + projectId;

    

    if(sAdditionalUrlParams != null && sAdditionalUrlParams.length > 0)
    {
        if(sAdditionalUrlParams.charAt(0) == "?")
            sAdditionalUrlParams = sAdditionalUrlParams.substring(1);
        serverUrl += "&addparams=" + escape(sAdditionalUrlParams);
    }
    sendRequestToFrame(serverUrl,"server_commands");
}


function disablePortletLinks(sElementID)
{
    for(var i=0;;i++)
	{
		var anchor = document.getElementById(sElementID+i);
        if (anchor == null)
            break;
		anchor.disabled = true;
	}
    return true;
}


function sendRequestToFrame(url, frame)
{
	try {
		
			document.frames[frame].document.location.replace(url); 
	} catch (e) { if(console) console.log(e.message); }
}

function getFrame(sFrameId)
{
	try {
		
			return document.frames[sFrameId]; 
	} catch (e) { if(console) console.log(e.message); }
}


var quickAddDragger = null;
function quickaddDraggerOnMouseDown(evnt)
{
   if(quickAddDragger || getButtonId(evnt) > 1)
       return;
   var target = getEventTarget(evnt);
   var element = findClassUp(target, 'quickaddDragDropIcon');
   if (element != null && element.id != null)
   {
        quickAddDragger = findClassUp(element, "quickadddragger");
   }
}

function quickaddDraggerOnMouseMove(evnt)
{
	if(quickAddDragger != null)
	{
		positionFloatingPortlet(quickAddDragger, 0);
	}
}

function quickaddDraggerOnMouseUp()
{
	quickAddDragger = null;
	return false;
}

/**
 * When you dynamically update a portlet, it's nice to see some visual evidence that the update
 * is actually happening.  We change the "Update" link to "Updating..." and the 3 dots are animated
 * suggesting the action is in progress.
 */
function setPortletToUpdating(sElementId)
{
	var nodeId = "rfsh_" + sElementId;
	var node = document.getElementById(nodeId);
	if(node != null)
	{
		var arrowImg = node.parentNode.previousSibling != null ? node.parentNode.previousSibling.firstChild : null;
		if (arrowImg != null && arrowImg.nodeName == "IMG")
			arrowImg.src = "/images/nav/dingbats/btn_cl_refresh.gif";
        
        while ( node.firstChild != null )
            node.removeChild(node.firstChild);
		var fontTag = document.createElement("font");
		fontTag.color = "#999999";
		var text = document.createTextNode("Refreshing");
		fontTag.appendChild(text);
		node.appendChild(fontTag);
		var img = document.createElement("img");
		img.src = "/images/setup/updating.gif";
		img.border = 0;
		node.appendChild(img);
	}
	else
	{
		
		var refreshId = sElementId + "_refresh";
		var refAnchor = document.getElementById(refreshId);
		if (refAnchor && refAnchor.className.indexOf('portletIconRefreshing') < 0)
		{
			refAnchor.className = refAnchor.className.replace('portletIconRefresh', 'portletIconRefreshing');
		}
	}
}




var ExtFontNames =
                [
                  
					["Verdana","Verdana"],
					["Arial","Arial"],
					["Courier New","Courier New"],
					["Times New Roman","Times New Roman"],
					["Comic Sans MS","Comic Sans"],
					["Georgia","Georgia"],
					["Tahoma","Tahoma"],
					["Trebuchet MS","Trebuchet"]
				];

// -- initialize editor fonts
var fontNames =	{	"Font" : "",
					"Verdana" : "Verdana",
					"Arial"	: "Arial",
					"Courier New" : "Courier New",
					"Times New Roman" : "Times New Roman",
					"Comic Sans" : "Comic Sans MS",
					"Georgia" : "Georgia",
					"Tahoma" : "Tahoma",
					"Trebuchet" : "Trebuchet MS"
				};

// -- initialize editor font colors
var fontColors = {	"Color"         : "",
					"Black"         : "#000000",
					"Red"	        : "#FF0000",
					"Blue"          : "#0000FF",
					"Dark Blue"     : "#00008B",
					"Navy Blue"     : "#000080",
					"Brown"         : "#A52A2A",
					"Green"         : "#008000",
					"Orange"        : "#FFA500",
					"Light Grey"    : "#D3D3D3",
					"Silver"        : "#C0C0C0"
				 };

// -- initialize editor font sizes
var fontSizes =	{	"Size" : "",
					"8"  :  "1",
					"10" : "2",
					"12" : "3",
					"14" : "4",
					"18" : "5",
					"24" : "6",
					"36" : "7"
				};


function _getFontSizePts(id)
{
	for (var pts in fontSizes)
	{
		if (fontSizes[pts] == id) return pts;
	}
	return null;
}





// -- cache all html editors on page
//var htmleditors = new Object();  //no equiv is needed since NetSuite.RTEManager is a static class


function makeHtmlEditor(name, value, onChange, width, height, textMode, iFlags, defaultFont, defaultFontSize)
{
	// -- ensure that container span exists
	if ( document.getElementById(name+'_fs') == null )
		return null;

	if ( !isNaN( height ) )
		height = Math.min( height*20, 500);
	if ( !isNaN( width ) )
		width = Math.min( width*6, 800);

	var editor = new NLHtmlEditor(name, value, onChange, width, height, textMode, iFlags);
    window.htmleditors[name] = editor;  //this whole makeHtmlEditor function is not used in the new Ext approach

	if ( defaultFont != null )
		editor.defaultFont = defaultFont;
	if ( defaultFontSize != null )
		editor.defaultFontSize = defaultFontSize;
	editor.launchEditor( );

	if ( editor.hasAttribute(128) )
		editor.setMandatory( true );
	if ( editor.hasAttribute(2048) )
		editor.setDisabled( true );

	return editor;
}


var NLHTMLEDITOR_FORMATTED_LABEL = "Formatted Text";
var NLHTMLEDITOR_SOURCECODE_LABEL = "HTML Source Code";
var NLHTMLEDITOR_FORMATTED_HELPER_TEXT = "Type text and format it using the toolbar.";
var NLHTMLEDITOR_FORMATTED_HELPER_TEXT_WITH_STYLE = "<font color=\"#666666\">"+NLHTMLEDITOR_FORMATTED_HELPER_TEXT+"</font>";
var NLHTMLEDITOR_SOURCECODE_HELPER_TEXT = "<!-- Type or paste HTML code -->";
var NLHTMLEDITOR_STYLE_SMALL_TEXT = "smalltext";

function NLHtmlEditor(name, value, onChange, width, height, textMode, flags)
{
	this.name = name;
	this.span = document.getElementById(name+'_fs');
	this.value = value;
	this.defaultValue = value;
	this.main = null;
	this.editor = null;
	this.toggleHeader = null;
	this.toolbar = null;
	this.hddn = null;
	this.defaultTextMode = textMode;
	this.textMode = textMode;
	this.width = width != null ? width : 400;
	this.height = height != null ? height : 200;
	this.onChangeFunc = onChange;
	this.flags = flags ? flags : 0;
	this.toggleSpan = null;

	this.disabled = false;
	this.mandatory = false;
	this.mandatoryBgColor = "#FFFFE5";
	this.defaultFont = null;
	this.defaultFontSize = null;


	this.responseLock = false;
	this.responseQueue = 0;
}


NLHtmlEditor.prototype.launchEditor = function NLHtmlEditor_launchEditor()
{
	this.main = document.createElement("DIV");
	this.main.id = this.name+'_main';
	this.main.unselectable = 'on';
	this.main.style.border = "solid 1px #999999";
	this.main.style.backgroundColor= "#ECEFF6";
	this.main.className = 'htmleditormain';
	this.span.appendChild( this.main );

	this.buildToggleHeader();
	this.buildToolBar();
	this.buildEditor();
	this.setEditorMode( this.textMode );
}


NLHtmlEditor.prototype.buildEditor = function NLHtmlEditor_buildEditor()
{
	this.editor = document.createElement("DIV");
	this.editor.id = this.name+'_editor';
	this.editor.unselectable = 'on';
	this.editor.style.width = '100%';
	this.editor.style.borderWidth='1px 0 0px 0';
	this.editor.style.borderStyle='solid';
	this.editor.style.borderColor='#999999';
    
    this.main.appendChild( this.editor );

	this.editorHtml = document.createElement("IFRAME");
	this.editorHtml.id = this.name+'_html';
    this.editorHtml.src = 'javascript:false';
	this.editorHtml.style.height = this.height;
	this.editorHtml.style.width = '100%';
	this.editorHtml.frameBorder = "0";

	this.editorText = document.createElement("TEXTAREA");
	this.editorText.id = this.name+'_text';
	this.editorText.className = 'input'+ ( this.mandatory ? 'req' : '');
    this.editorText.onkeypress = new Function("event", "setEventCancelBubble(event); return true");
	this.editorText.style.height = this.height;
	this.editorText.style.width = '100%';
	this.editorText.style.borderWidth='0px';
}

NLHtmlEditor.prototype.buildToggleHeader = function NLHtmlEditor_buildToggleHeader()
{
	this.toggleHeader = document.createElement("DIV");
	this.toggleHeader.id = this.name+'_footer';
	this.toggleHeader.unselectable = 'on';
	this.toggleHeader.style.padding = "5px 2px 3px 5px";
	this.toggleHeader.style.width = this.width;

	this.toggleSpan = document.createElement("SPAN");
	this.toggleSpan.className = "tinytext";

	
	var richTextAnchor = document.createElement("A");
	richTextAnchor.className = "tinytextnolink";
	var sourceCodeAnchor = document.createElement("A");
	sourceCodeAnchor.className = "tinytextnolink";
	this.setToggleLinks(richTextAnchor, sourceCodeAnchor);

	this.toggleSpan.appendChild(richTextAnchor);
	this.toggleSpan.appendChild(sourceCodeAnchor);

	this.toggleHeader.appendChild( this.toggleSpan );


    this.hddn = document.createElement("INPUT");
    this.hddn.type = 'hidden';
	this.hddn.value = this.value;
	this.hddn.name = this.name;
	this.hddn.id = this.name;
	if ( this.onChangeFunc != null )
		this.hddn.onchange = new Function(this.onChangeFunc);
    this.toggleHeader.appendChild( this.hddn );

    this.main.appendChild( this.toggleHeader );
	this.span.parentNode.style.paddingBottom = "5px";
}


NLHtmlEditor.prototype.buildToolBar = function NLHtmlEditor_buildToolBar()
{
	this.toolbar = document.createElement("DIV");
	this.toolbar.id = this.name+'_toolbar';
	this.toolbar.style.padding = '4px 4px 2px 4px';
	this.toolbar.style.height = '22px';
	this.toolbar.unselectable = 'on';
	this.toolbar.style.backgroundColor = "#ECEFF6";
	this.toolbar.style.borderWidth='0px';
	this.main.appendChild( this.toolbar );

	// -- now add toolbar icons
	this.buildToolBarIcon('fontname', 'Font', 'FontName');
	this.buildToolBarIcon('fontsize', 'Size', 'FontSize');
	this.buildToolBarIcon('fontcolor', 'Color', 'ForeColor');
	if ( isNaN(this.width) || parseInt(this.width) > 425 )
		this.buildToolBarLiner();
	else
		this.buildToolBarLineBreak();
	this.buildToolBarIcon('bold', 'Bold', 'Bold');
	this.buildToolBarIcon('italic', 'Italic', 'Italic');
	this.buildToolBarIcon('underline', 'Underline', 'Underline');
	this.buildToolBarLiner();
	this.buildToolBarIcon('justifyleft', 'Justify Left', 'JustifyLeft');
	this.buildToolBarIcon('justifycenter', 'Justify Center', 'JustifyCenter');
	this.buildToolBarIcon('justifyright', 'Justify Right', 'JustifyRight');
    
    this.buildToolBarLiner();
	this.buildToolBarIcon('insertorderedlist', 'Ordered List', 'InsertOrderedList');
	this.buildToolBarIcon('insertunorderedlist', 'Unordered List', 'InsertUnorderedList');
	this.buildToolBarIcon('outdent', 'Outdent', 'Outdent');
	this.buildToolBarIcon('indent', 'Indent', 'Indent');
    
}


NLHtmlEditor.prototype.buildToolBarIcon = function NLHtmlEditor_buildToolBarIcon(name, title, cmd)
{
	var id = this.name+'_toolbar_'+name;
	if ( cmd == 'FontName' || cmd == 'FontSize' || cmd == 'ForeColor' )
	{
		var optionsArray = new Array();
		var menuArray;

		if ( cmd == 'FontName' )
			menuArray = fontNames;
		else if ( cmd == 'FontSize' )
			menuArray = fontSizes;
		else
			menuArray = fontColors;

		for ( var menuOption in menuArray )
		{
			optionsArray[optionsArray.length] = menuOption;
			optionsArray[optionsArray.length] = menuArray[menuOption];
		}

		var slct = document.createElement("SELECT");
		slct.name = id;
		slct.id = id+'_fs';
		slct.className = 'input';
		slct.unselectable = 'on';
		slct.tabIndex = -1;
		slct.onchange = new Function('getHtmlEditor("'+this.name+'").setFocus(); getHtmlEditor("'+this.name+'").handleToolBarEvent("'+cmd+'", getSelectValue(this)); NS.form.setChanged(true);');

		for ( var i = 0; i < optionsArray.length; i += 2)
		{
			var opt = document.createElement("OPTION");
			opt.text = optionsArray[i];
			opt.value = optionsArray[i+1];
			opt.unselectable = 'on';
			
			slct.add( opt );
			
		}
		this.toolbar.appendChild( slct );
	}
	else
	{
		var btn = document.createElement("BUTTON");
		btn.id = id;
		btn.btnCommand = cmd;
        btn.tabIndex = -1;
		btn.className = 'editorbutton';
		btn.unselectable = 'on';
		btn.title = title;
        btn.style.padding = "1px";
        btn.style.margin = 0;
		btn.style.marginTop = "3px";
		btn.style.backgroundColor = "#ECEFF6";
        
        btn.onmouseover = new Function("if (this.className =='editorbutton') this.className='editorbuttonhover'");
        btn.onmousedown = new Function("this.className='editorbuttondown';");
		btn.onmouseout = new Function("if (this.className =='editorbuttonhover') this.className='editorbutton'");
		btn.onclick = new Function("getHtmlEditor('"+this.name+"').handleToolBarEvent('"+cmd+"'); return false;");

		var img = document.createElement("IMG");
		img.src = '/images/nav/editor/'+name+'.gif';
		img.unselectable = "on";
        img.padding = 0;
        img.margin = 0;
		img.border = 0;
		img.style.height = '18px';
		img.style.width = '18px';
		btn.appendChild( img );

		this.toolbar.appendChild( btn );
	}
}

NLHtmlEditor.prototype.buildToolBarLineBreak = function NLHtmlEditor_buildToolBarLiner()
{
	var br = document.createElement("BR");
	br.unselectable = 'on';

	this.toolbar.appendChild( br );
}

NLHtmlEditor.prototype.buildToolBarLiner = function NLHtmlEditor_buildToolBarLiner()
{
	var span = document.createElement("SPAN");
	span.style.width = '1px';
	span.style.height = '16px';
	span.style.border = '1px inset';
	span.style.margin = '0 3px 0 3px';
	span.unselectable = 'on';
	span.style.display = 'inline';
	span.style.padding = 0;

	this.toolbar.appendChild( span );
}

NLHtmlEditor.prototype.hasAttribute = function NLHtmlEditor_hasAttribute(flag)
{
    return (this.flags & flag) != 0;
}


NLHtmlEditor.prototype.getValue = function NLHtmlEditor_getValue()
{
	return this.value;
}


NLHtmlEditor.prototype.getDisplayValue = function NLHtmlEditor_getDisplayValue()
{
	var val = null;
	if ( this.textMode )
    {
        val = this.editorText.value;
    }
	else
    {
		val = this.editorHtml.contentWindow.document.body.innerHTML;
    }

    
	val = this.handleEscaping( val, false );
    return val;
}


    var NLExtHtmlEditor = {};

    NLExtHtmlEditor.createEditor = function(parentName, name, value, textMode, onChangeFunc, iFlags, hddnInput,
                                            backgroundColor, isEditorEnabled, hasMandatoryFlag, hasDisabledFlag, width, height, htmlHeader)
    {
		var renderTo = NS.jQuery("#exthtmlfield-" + parentName);
		var preferenceFontFamily = renderTo.data("font-family");
		var preferenceFontSize = renderTo.data("font-size");

        var tmpBodyStyle = "'background-color:"+backgroundColor+";'";
        var editor = (htmlHeader? Ext.form.WholeHtmlEditor : Ext.form.HtmlEditor);
        Ext.onReady(function() {
            Ext.QuickTips.init();
            NetSuite.RTEManager.initialize();
            var exthtmleditorform = new Ext.Panel({
                renderTo: 'exthtmlfield-'+parentName,
                layout: 'fit',
                style: 'border-color: #D5DEE7;',
                hideMode: 'offsets',
                id: 'html-editor-container-'+name,
                name: 'html-editor-container-'+name,
                bodyStyle: tmpBodyStyle,
                items: [
                        new editor({
                            id: 'html-editor-'+name,
                            name: 'html-editor-'+name,
                            disabled: (!isEditorEnabled),
                            renderWidth: width,
                            renderHeight: height,
                            width: width,
                            height: height,
                            readOnly: true,
						    defaultFont: preferenceFontFamily,
							customFontSize: preferenceFontSize,
                            emptyText: NLHTMLEDITOR_SOURCECODE_HELPER_TEXT,
                            plugins: Ext.ux.form.HtmlEditor.plugins(),
                            hideLabel: true,
                            labelSeparator: '',
                            listeners: {
                                editmodechange: function( editor, sourceEdit ) {
                                    // chrome not behaving like other browsers - always validate
                                    if(Ext.isChrome){
                                        var match = editor.onChangeFunc.match(/validate_html\(this, '(.*)'\);};/);
                                        var val_type = (match && match[1]) || null;

                                        validate_html(editor.hddn, val_type);
                                    // validate html when going into source mode
                                    } else if(sourceEdit){
                                        editor.el.dom.blur();
                                        editor.el.dom.focus();
                                    }
                                    editor.setSize(editor.wrap.getSize());
                                    NetSuite.RTEManager.resyncSizeAll(true);
                                },
                                initialize: function( editor ) {
                                    editor.toggleSourceEdit(textMode,true);
                                    NS.form.setChanged(false);
                                    editor.lastEditMadeInSourceMode = textMode;
                                    editor.setReadOnly(false);
                                    var resizer = new Ext.Resizable(editor.wrap,{handles:'e,s,se', minWidth: width, minHeight: height});
                                    resizer.on('resize',function(resizer, width, height, eventObj) {
                                        editor.setSize(editor.wrap.getSize());
                                        NetSuite.RTEManager.resyncSizeAll(true);
                                    });
                                    var initFunction = NetSuite.RTEManager.getDeferredInitializationInstance(editor.getName());
                                    if (initFunction != null) {
                                        initFunction();
                                        NetSuite.RTEManager.unregisterDeferredRTEInitialization(editor.getName());
                                    }
                                    NetSuite.RTEManager.finalizeIfLastInitialized(editor.getName());
                                }
                            } //end of listeners
                        })  //end of new HtmlEditor
                        //}  //end of xtype HtmlEditor lazy load config
                ] //end of FormPanel items list
            });  //end of new FormPanel

            var tmpEditor = Ext.getCmp("html-editor-"+name);
            this.textModeHasFocus = false;
            tmpEditor.mandatory = false;
            tmpEditor.finalized = false;
            tmpEditor.defaultFontSize = preferenceFontSize;
            tmpEditor.flags = iFlags ? iFlags : 0;
            tmpEditor.hddn = hddnInput;
            if (!tmpEditor.hddn) {
                 tmpEditor.hddn = document.createElement("INPUT");
                 tmpEditor.hddn.type = 'hidden';
                 tmpEditor.hddn.value = value;
                 tmpEditor.hddn.name = name;
                 tmpEditor.hddn.id = name;
            }
            tmpEditor.value = value;
            tmpEditor.defaultTextMode = textMode;
            tmpEditor.defaultValue = value;
            tmpEditor.onChangeFunc = onChangeFunc;
            if (onChangeFunc != null && typeof tmpEditor.hddn.onchange != "function")
                tmpEditor.hddn.onchange = new Function(onChangeFunc);
            Ext.get(parentName).appendChild( tmpEditor.hddn );
            //if (tmpEditor.defaultFontSize != null)
            //    tmpEditor.setFontSize(tmpEditor.defaultFontSize);

            tmpEditor.el.dom.onblur = function(event){
                event = event || window.event;
                var target = event.target || event.srcElement;
                var editor = getHtmlEditor(target.id);

                // inconsistent browser behaviour - some browsers not firing change event during textareaOnblur
                // ignore html validation and validate after textareaOnblur
                editor.hddn.ignoreValidation = true;
                editor.textareaOnblur();
                editor.hddn.ignoreValidation = false;
                var match = editor.onChangeFunc.match(/validate_html\(this, '(.*)'\);};/);
                var val_type = (match && match[1]) || null;

                validate_html(editor.hddn, val_type);
            };

            if (!Ext.isIE) tmpEditor.el.dom.onkeyup = new Function("var editor = getHtmlEditor('html-editor-"+name+"'); NetSuite.RTEManager.saveSelection(document); editor.setValue( editor.getDisplayValue() ); editor.pushValue(); NetSuite.RTEManager.restoreSelection();");
            tmpEditor.el.dom.onfocus = new Function("getHtmlEditor('html-editor-"+name+"').textareaOnfocus()");
            NetSuite.RTEManager.registerRTE({
                widgetID: "html-editor-"+name,
                widgetComponentInstance: tmpEditor,
                widgetHiddenElementID: name
            });

            tmpEditor.lastEditMadeInSourceMode = tmpEditor.defaultTextMode;
            NS.form.setChanged(false);

			if ( hasMandatoryFlag )
				tmpEditor.setMandatory( true, '"+nl.getNLUser().getLook().getColors().m_bgrequiredfld+"' );

            if ( hasDisabledFlag )
				tmpEditor.setDisabled( true );

        });  //end of onReady
    };

    NLExtHtmlEditor.setValue = function(editorID, value, bDisplayValue)
    {
        var setDisplayValue = ((typeof bDisplayValue == "undefined") ? false : bDisplayValue);
        var tmpEditor = NetSuite.RTEManager.getInstance(editorID);
        if (tmpEditor)
        {
            if (tmpEditor.hddn.value != value)
            {
                NS.form.setChanged(true);
            }
            //from original version
            var oldValue = (tmpEditor.value ? tmpEditor.value : "");
            tmpEditor.value = value;
            tmpEditor.hddn.value = tmpEditor.value;
            if ( tmpEditor.onChangeFunc != null )
            {
                var isvalid = tmpEditor.hddn.onchange();
                if ( isvalid != null && !isvalid )
                {
                    /* if auto text truncation occurred, value has already been updated otherwise revert to old value */
                    tmpEditor.value = tmpEditor.hddn.truncatedValue ? tmpEditor.hddn.value : oldValue;
                    tmpEditor.hddn.value = tmpEditor.value;
                    tmpEditor.setDisplayValue( tmpEditor.value );
                }
            }
            if ( setDisplayValue )
            {
                tmpEditor.setDisplayValue( tmpEditor.value );
            }
        }
    };

    NLExtHtmlEditor.resetEditor = function(editorID)
    {
        var tmpEditor = NetSuite.RTEManager.getInstance(editorID);
        
	    tmpEditor.reset();
        // Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8
        tmpEditor.setDesignMode(false);  //toggle off first
        tmpEditor.setDesignMode(true);
        tmpEditor.lastEditMadeInSourceMode = this.defaultTextMode;
        //end hack
    };


NLHtmlEditor.prototype.setValue = function NLHtmlEditor_setValue( value, setDisplayValue )
{
    var oldValue = this.value;
	this.value = value;
	this.hddn.value = this.value;
	if ( this.onChangeFunc != null )
	{
		var isvalid = this.hddn.onchange();
		if ( isvalid != null && !isvalid )
		{
            
			this.value = this.hddn.truncatedValue ? this.hddn.value : oldValue;
			this.hddn.value = this.value;
			this.setDisplayValue( this.value );
		}
	}
	if ( setDisplayValue )
		this.setDisplayValue( this.value );
}


NLHtmlEditor.prototype.setDisplayValue = function NLHtmlEditor_setDisplayValue( value )
{
    
	var displayval = this.handleEscaping( value, true );
	
    var bShowHelperText = isValEmpty(displayval);

	if ( this.textMode )
	{
		if(bShowHelperText)
		{
			this.editorText.value = NLHTMLEDITOR_SOURCECODE_HELPER_TEXT;
			this.editorText.style.fontFamily = "courier";
			this.editorText.style.color = "#666666";
		}
		else
		{
			this.editorText.value = displayval;
			this.editorText.style.fontFamily = "";
			this.editorText.style.color = "";
		}
    }
	else
	{
		if(bShowHelperText)
			displayval = "<font color='#666666'>"+NLHTMLEDITOR_FORMATTED_HELPER_TEXT+"</font>";
		this.editorHtml.contentWindow.document.open( );
        
        var appFontSize = getStyleForClass( 'smalltext', 'fontSize' );
        var appFontFamily = getCascadedStyle( document.body, "fontFamily", "font-family" );
		this.editorHtml.contentWindow.document.write("<html><body contenteditable='true' width=100%; height=100%; topmargin=1 leftmargin=1 style='font-size: "+appFontSize+"; font-family: "+appFontFamily+"'>");
        
        var bUseFontPrefs = ( this.defaultFontSize != null || this.defaultFont != null ) && this.value == this.defaultValue;
        if ( bUseFontPrefs )
        {
            var sizeStyle = this.defaultFontSize != null ? "size="+fontSizes[this.defaultFontSize] : "";
            var fontStyle = this.defaultFont != null ? "face='"+this.defaultFont+"'" : "";
            this.editorHtml.contentWindow.document.write( "<FONT "+sizeStyle+" "+fontStyle+">" );
        }
        
		var hasDivs = /\s*<div>(.*)<\/div>\s*$/i;
		if (!hasDivs.test(displayval.split('\n').join('\r')))
			displayval =  "<DIV>" + displayval + "</DIV>";

		this.editorHtml.contentWindow.document.write( displayval );
        if ( bUseFontPrefs )
            this.editorHtml.contentWindow.document.write("</FONT>");
        this.editorHtml.contentWindow.document.write("</body></html>");
		this.editorHtml.contentWindow.document.close( );
		if ( this.mandatory )
			this.editorHtml.contentWindow.document.body.style.backgroundColor = this.mandatoryBgColor;
        else
            this.editorHtml.contentWindow.document.body.style.backgroundColor = getRuntimeStyle(this.editorText, "backgroundColor");

        
        
        
        setTimeout(this.setupEventHandlers.bind(this), 500);

        
	}
}


NLHtmlEditor.prototype.stripExtraDivs = function NLHtmlEditor_stripExtraDivs( val )
{
    
	var divStart = /<div/i;
	var divEnd = /<\/div>/i;
	var divEmpty = /^>/;
	var divEmptyBR = /^>.*<BR(>| .*>)\s*$/i;
	var lineEndBR = /<BR(>| .*>)\s*$/i;

	


	
    var arr = (' '+val+' ').split(divStart);

	
	var divStack = new Array();
	divStack.push(arr[0]);

	for (var j=1; j < arr.length; j++)
	{
		
		var divBody = arr[j].split(divEnd);

		
		divStack.push(divBody[0]);

		

		for (var k=1; k < divBody.length; k++)
		{
			
			var divLine = divStack.pop();

			
			if (divEmptyBR.test(divLine))
				divLine = divLine.substring(1);
			else if (divEmpty.test(divLine))
				divLine = divLine.substring(1) + "<BR>";
			else if (!divEmpty.test(divLine))
				divLine = "<div" + divLine + "</div>";

			
			divStack.push(divStack.pop() + divLine + divBody[k]);
		}
	}

	
	var lastLine = divStack.pop();
	lastLine = lastLine.substring(0,lastLine.length-1);

	while (lineEndBR.test(lastLine))
	{
		lastLine = lastLine.replace(lineEndBR, '');
	}

	
	divStack.push(lastLine);
	val = divStack.join('<div');

	
	val = val.substring(1);

	return val;
}


NLHtmlEditor.prototype.handleEscaping = function NLHtmlEditor_handleEscaping( val, escape  )
{
	if ( !isValEmpty( val ) && !this.textMode )
	{
		val = this.stripExtraDivs(val);
		
        val = val.replace(/<STRONG>/gi,'<B>').replace(/<\/STRONG>/gi,'</B>').replace(/<EM>/gi,'<I>').replace(/<\/EM>/gi,'</I>');
        
		val = escape ? val.replace(/<NL([^>]{2,})>/g,'&lt;NL$1&gt;') : val.replace(/&lt;NL([^&\]]{2,})(&gt;|>)/g,'<NL$1>');
        
   		val = escape ? val.replace(/<(SCRIPT)\b/gi,'<\!--NLHIDE:$1').replace(/(<\/SCRIPT\s*)>/gi,'$1:NLHIDE-->')
		             : val.replace(/<\!--NLHIDE:/g,'<').replace(/:NLHIDE-->/g,'>');
	}
	return val;
}


NLHtmlEditor.prototype.insertValue = function NLHtmlEditor_insertValue( value, insertNow )
{
	if ( isValEmpty( value ) )
		return;

	if ( this.disabled )
		return;

    if ( !insertNow )
    {
        this.setFocus();
        setTimeout(new Function("getHtmlEditor('"+this.name+"').insertValue('"+value+"',true)"), 200);
        return;
    }

	
	var displayValue = this.handleEscaping( value, true );

	var sel, range;
	var doc = this.textMode ? document : this.editorHtml.contentWindow.document; 

	if ((this.textMode && this.editorText.value == NLHTMLEDITOR_SOURCECODE_HELPER_TEXT) ||
		(!this.textMode && this.getValue() != null && this.getDisplayValue().indexOf(NLHTMLEDITOR_FORMATTED_HELPER_TEXT) != -1))
	{
		this.setDisplayValue(displayValue);
	}
	else if (window.getSelection) 
	{
		sel = this.textMode ? window.getSelection() : this.editorHtml.contentWindow.getSelection(); 

		range = sel.getRangeAt(0);

		var txt = doc.createTextNode(this.textMode ? displayValue : value);

		
		if (range.startContainer.tagName == 'DIV' && range.startContainer.firstChild.tagName == 'TEXTAREA')
		{	
			var ta = range.startContainer.firstChild;
			var pos = ta.selectionEnd + displayValue.length;
			ta.value = ta.value.substring(0, ta.selectionEnd) + displayValue + ta.value.substring(ta.selectionEnd);
			ta.selectionStart = ta.selectionEnd = pos;
		}
		else
		{
			if (range.collapsed)
				range.insertNode(txt);
			else
			{
				var frag = doc.createDocumentFragment();
				frag.appendChild(range.extractContents());
				frag.appendChild(txt);
				range.insertNode(frag);
			}

			range.selectNodeContents(txt);
			range.collapse(false);
			range.commonAncestorContainer.normalize();
		}
	}
	else if (doc.selection) 
	{
		sel = doc.selection;
		range = sel.createRange();

		if (this.textMode)
			range.text = range.text + displayValue;
		else
			range.pasteHTML(range.htmlText + displayValue);

		range.collapse(false);
		range.select();
	}

    this.setValue( this.getDisplayValue() );
}


NLHtmlEditor.prototype.setMandatory = function NLHtmlEditor_setMandatory( mandatory, bgColor )
{
	this.mandatory = mandatory;
    this.mandatoryBgColor = bgColor != null ? bgColor : "#FFFFE5";
    if (this.mandatoryBgColor.charAt(0) != '#') 
        this.mandatoryBgColor = '#' + this.mandatoryBgColor;
    this.editorText.className = 'input' + (this.mandatory ? 'req' : '');
    this.editorHtml.contentWindow.document.body.style.backgroundColor = this.mandatory ? this.mandatoryBgColor : "#FFFFFF";
}

NLHtmlEditor.prototype.getMandatory = function NLHtmlEditor_getMandatory( )
{
	return this.mandatory;
}

NLHtmlEditor.prototype.handleToolBarEvent = function NLHtmlEditor_handleToolBarEvent( cmd, value )
{
    

    if ( this.disabled )
		return;

	if ( this.textMode )
		return;

	if ( cmd == 'FontName' || cmd == 'FontSize' || cmd == 'ForeColor' )
	{
		if ( !isValEmpty( value ) )
		{
            
            this.editorHtml.contentWindow.document.execCommand(cmd, false, value);
			
			var child = this.editorHtml.contentWindow.document.body.firstChild;
			if (isValEmpty(child.innerHTML) && child.nodeType != 3)  
			{
				if (cmd == 'FontName')
					child.style.fontFamily = value;
				else if (cmd == 'FontSize')
					child.style.fontSize = _getFontSizePts(value) + "pt";
				else if (cmd == 'ForeColor')
					child.style.color = value;
			}
		}
	}
	else
		this.editorHtml.contentWindow.document.execCommand(cmd, false, null);

	this.setValue( this.getDisplayValue() );

    

    this.syncToolBarWithEditor(cmd, value);
}

NLHtmlEditor.prototype.scheduleEditorEventHandler = function NLHtmlEditor_scheduleEditorEventHandler( action, ms )
{
	if ( this.disabled )
		return;
    setTimeout(new Function("getHtmlEditor('"+this.name+"').handleEditorEvent('" + action + "')"), ms );
}

NLHtmlEditor.prototype.handleEditorEvent = function NLHtmlEditor_handleEditorEvent(action, evnt)
{
	if ( this.disabled )
		return true;

    
    if ( this.responseLock )
    {
		
        if (action != 'mouseup') this.responseQueue++;
        return true;
    }

    this.responseLock = true;
    var func = new Function("var editor = getHtmlEditor('"+this.name+"'); editor.responseLock = false; if ( editor.responseQueue > 0 ) { editor.responseQueue = 0; editor.handleEditorEvent('"+action+"'); }");
    setTimeout(func, 333);

    if ( this.getValue() != null && this.getDisplayValue().indexOf(NLHTMLEDITOR_FORMATTED_HELPER_TEXT)==-1 && this.getDisplayValue() != this.getValue() )
       this.setValue( this.getDisplayValue() );

    

    

    // update the toolbar state after some time
    if (this.ToolbarUpdateTimer)
    {
        clearTimeout(this.ToolbarUpdateTimer);
    }
    this.ToolbarUpdateTimer = setTimeout(function() { this.syncToolBarWithEditor();}.bind(this), 100);

    return true;
};






NLHtmlEditor.prototype.resetEditor = function NLHtmlEditor_resetEditor()
{
	this.setValue( this.defaultValue );

	var chkbox = this.toggleHeader.firstChild;
	if ( chkbox != null && ( (this.defaultTextMode && !chkbox.checked) || (!this.defaultTextMode && chkbox.checked) ) )
		setFormValue(this.toggleHeader.firstChild, this.defaultTextMode);
	this.setEditorMode( this.defaultTextMode );
}


NLHtmlEditor.prototype.setDisabled = function NLHtmlEditor_setDisabled(bDisable)
{
	this.disableToolBar( bDisable );
	this.editor.disabled = bDisable;
	if ( this.textMode )
		this.editorText.disabled = bDisable;
	else
		this.editorHtml.contentWindow.document.body.disabled = bDisable;

	this.toggleHeader.disabled = bDisable;
	this.toggleHeader.firstChild.disabled = bDisable;
	this.disabled = bDisable;
}


NLHtmlEditor.prototype.disableToolBar = function NLHtmlEditor_disableToolBar(bDisable)
{
	this.toolbar.disabled = bDisable;
	var elems = this.toolbar.getElementsByTagName("BUTTON");
	for ( var i = 0; i < elems.length; i++ )
	{
		elems[i].disabled = bDisable;
		if ( bDisable && elems[i].className == 'editorbuttondown' )
			elems[i].className = 'editorbutton';
	}
	elems = this.toolbar.getElementsByTagName("SPAN");
	for ( var i = 0; i < elems.length; i++ )
		elems[i].disabled = bDisable;
	elems = this.toolbar.getElementsByTagName("IMG");
	for ( var i = 0; i < elems.length; i++ )
		elems[i].disabled = bDisable;

	var elems = this.toolbar.getElementsByTagName("SELECT");
	for ( var i = 0; i < elems.length; i++ )
		disableSelect(elems[i], bDisable);
}

NLHtmlEditor.prototype.syncToolBarWithEditor = function NLHtmlEditor_syncToolBarWithEditor(cmd, value)
{
    if ( this.disabled )
		return;

	if ( this.textMode )
		return;


    var doc = this.editorHtml.contentWindow.document;

    // -- sync button menu items
	var btns = this.toolbar.getElementsByTagName("BUTTON");
	for ( var i = 0; i < btns.length; i++ )
	{
        var cmd = btns[i].btnCommand;
        try{
            if (doc.queryCommandState(cmd))
                btns[i].className = "editorbuttondown";
            else
                btns[i].className = "editorbutton";
        }
        catch(e)
        {
            btns[i].className = "editorbutton";
        }
	}

    
    var value = doc.queryCommandValue("fontsize");   
    if (!value || value.length == 0)
        value = "";
    
    setSelectValue( document.getElementById(this.name+'_toolbar_fontsize_fs'), value );

    
    value = doc.queryCommandValue("fontname");
    var sel = document.getElementById(this.name+'_toolbar_fontname_fs');
    var opt = getSelectValueArray(sel);
    if (value)
    {
        for (var i=0; i < opt.length; i++)
        {
            if (opt[i].length>0 && value.indexOf(opt[i])>=0)
            {
                setSelectIndex(sel, i);
                break;
            }
        }
    }
    if (i == opt.length)
        setSelectValue( document.getElementById(this.name+'_toolbar_fontname_fs'), "");


    
    value = doc.queryCommandValue("forecolor");
    var hexColor = "";
    if (value)
        hexColor = (String(value).charAt(0) == '#') ? value : getHexColorValue(value);
    setSelectValue( document.getElementById(this.name+'_toolbar_fontcolor_fs'), hexColor );
}


function getHexColorValue(val)
{
    if (typeof val != "number")
    {
        if(val.indexOf("rgb(") ==0)   
        {
            var rgb = val.substring(4, val.length-1).split(",");
            return "#" + getTwoDigitHexString(rgb[0]) + getTwoDigitHexString(rgb[1]) + getTwoDigitHexString(rgb[2]);
        }
    }
    else
        return getHexValueFromDecimal(val);
}

NLHtmlEditor.prototype.setToggleLinks = function NLHtmlEditor_setToggleLinks(firstElement, secondElement)
{
	this.setActiveToggleLink(firstElement, this.textMode ? NLHTMLEDITOR_SOURCECODE_LABEL : NLHTMLEDITOR_FORMATTED_LABEL);
	this.setInactiveToggleLink(secondElement, this.textMode ? NLHTMLEDITOR_FORMATTED_LABEL : NLHTMLEDITOR_SOURCECODE_LABEL, !this.textMode);
}

NLHtmlEditor.prototype.setActiveToggleLink = function NLHtmlEditor_setActiveToggleLink(anchorElement, label)
{
	  anchorElement.onclick = new Function("return false;");
	  anchorElement.removeAttribute("href");
	  anchorElement.innerHTML = "<b>" + label + "</b>&nbsp;";
      anchorElement.className = "textnolink";
}

NLHtmlEditor.prototype.setInactiveToggleLink = function NLHtmlEditor_setInactiveToggleLink(anchorElement, label, toggleOn)
{
	  anchorElement.onclick = new Function("getHtmlEditor('"+this.name+"').setEditorMode("+toggleOn+"); return false;");
	  anchorElement.href = "javascript:void('"+label+"')";
	  anchorElement.innerHTML = "(" + label + ")";
      anchorElement.className = "dottedlink";
}


NLHtmlEditor.prototype.setEditorMode = function NLHtmlEditor_setEditorMode( textMode )
{
	if ( this.disabled )
		return;

    this.textMode = textMode;
	if ( textMode )
	{
		if ( this.editorText == null )
			return;

		if ( document.getElementById( this.editorHtml.id ) != null )
        {
			this.editor.removeChild( this.editorHtml );
            
            if ( this.editorText.style.width == '100%' )
                this.editorText.style.width = document.getElementById( this.name + "_main" ).offsetWidth;
        }

		this.setDisplayValue( this.value );
		this.editor.appendChild( this.editorText );

		
		this.toolbar.style.display = 'none';
		this.setupEventHandlers();
    }
    else
	{
		if ( this.editorHtml == null )
			return;

		if ( document.getElementById( this.editorText.id ) != null )
			this.editor.removeChild( this.editorText );

		this.editor.appendChild( this.editorHtml );
		this.setDisplayValue( this.value );

		
		this.toolbar.style.display = 'inline';
	}
	
	this.setToggleLinks(this.toggleSpan.childNodes[0], this.toggleSpan.childNodes[1]);
}


NLHtmlEditor.prototype.getFieldId = function NLHtmlEditor_getFieldId()
{
	return (this.textMode) ? this.editorText.id : this.editorHtml.id;
}


NLHtmlEditor.prototype.getField = function NLHtmlEditor_getField()
{
	return (this.textMode) ? this.editorText : this.editorHtml.contentWindow.document.body;
}


NLHtmlEditor.prototype.setupEventHandlers = function NLHtmlEditor_setupEventHandlers()
{
	if ( this.textMode )
	{
		this.editorText.onblur = new Function("var editor = getHtmlEditor('"+this.name+"'); editor.setValue( editor.getDisplayValue() )");
		this.editorText.onfocus = new Function("getHtmlEditor('"+this.name+"').textareaOnfocus()");
	}
	else
	{
        if(document.addEventListener)
        {
            this.editorHtml.contentWindow.document.onkeydown      = null;
            this.editorHtml.contentWindow.document.onkeypress     = null;
            this.editorHtml.contentWindow.document.onkeyup        = null;
            this.editorHtml.contentWindow.document.onmousedown    = null;
            this.editorHtml.contentWindow.document.onmouseup      = null;
            this.editorHtml.contentWindow.document.body.oncut     = null;
            this.editorHtml.contentWindow.document.body.onpaste   = null;
            this.editorHtml.contentWindow.document.onfocus   = null;
            this.editorHtml.contentWindow.document.addEventListener("keydown",  function(evnt){return this.handleEditorEvent('keydown', evnt);}.bind(this), false);
            this.editorHtml.contentWindow.document.addEventListener("keypress",  function(evnt){return this.handleEditorEvent('keypress', evnt);}.bind(this), false);
            //this.editorHtml.contentWindow.document.addEventListener("keyup",  function(evnt){this.handleEditorEvent('keyup', evnt);}.bind(this), false);
            this.editorHtml.contentWindow.document.addEventListener("mouseup",  function(evnt){return this.handleEditorEvent('mouseup', evnt);}.bind(this), false);
            this.editorHtml.contentWindow.document.addEventListener("mousedown",  function(evnt){return this.handleEditorEvent('mousedown', evnt);}.bind(this), false);
            this.editorHtml.contentWindow.document.addEventListener("cut",  function(evnt){this.scheduleEditorEventHandler('cut', 100, evnt);}.bind(this), false);
            this.editorHtml.contentWindow.document.addEventListener("paste",  function(evnt){this.scheduleEditorEventHandler('paste', 100, evnt);}.bind(this), false);
            this.editorHtml.contentWindow.document.addEventListener("focus",  function(evnt){this.iFrameOnfocus();}.bind(this), true);
        }
        else
        {
            this.editorHtml.contentWindow.document.onkeydown      = new Function("getHtmlEditor('"+this.name+"').handleEditorEvent('keydown')");
            this.editorHtml.contentWindow.document.onkeypress     = new Function("getHtmlEditor('"+this.name+"').handleEditorEvent('keypress')");
            this.editorHtml.contentWindow.document.onkeyup        = new Function("getHtmlEditor('"+this.name+"').handleEditorEvent('keyup')");
            this.editorHtml.contentWindow.document.onmousedown    = new Function("getHtmlEditor('"+this.name+"').handleEditorEvent('mousedown')");
            this.editorHtml.contentWindow.document.onmouseup      = new Function("getHtmlEditor('"+this.name+"').handleEditorEvent('mouseup')");
            this.editorHtml.contentWindow.document.body.oncut     = new Function("getHtmlEditor('"+this.name+"').scheduleEditorEventHandler( 'cut', 100 )");
            this.editorHtml.contentWindow.document.body.onpaste   = new Function("getHtmlEditor('"+this.name+"').scheduleEditorEventHandler( 'paste', 100 )");
            
            this.editorHtml.onfocus = new Function("getHtmlEditor('"+this.name+"').iFrameOnfocus()");
            this.editorHtml.onblur = new Function("getHtmlEditor('"+this.name+"').iFrameOnblur();");
        }
    }
}

NLHtmlEditor.prototype.iFrameOnfocus = function NLHtmlEditor_iFrameOnfocus()
{
    var doc = this.editorHtml.contentWindow.document;
    
    doc.body.contentEditable = true;
    
    if(doc.body.innerHTML.indexOf(NLHTMLEDITOR_FORMATTED_HELPER_TEXT)>-1)
    {
        doc.body.innerHTML = "<div><br></div>";
        doc.body.focus();
    }
}

NLHtmlEditor.prototype.iFrameOnblur = function NLHtmlEditor_iFrameOnblur()
{
    // this method is for IE only
    var doc = this.editorHtml.contentWindow.document;
    doc.body.contentEditable = false;
    return true;
}

NLHtmlEditor.prototype.textareaOnfocus = function NLHtmlEditor_textareaOnfocus()
{
	if(this.editorText.value == NLHTMLEDITOR_SOURCECODE_HELPER_TEXT)
    {
        this.editorText.style.fontFamily = "";
        this.editorText.style.color = "";
        this.editorText.value = "";
    }
}


NLHtmlEditor.prototype.setFocus = function NLHtmlEditor_setFocus()
{
	if ( this.disabled )
		return;

    
	if ( this.textMode )
        setTimeout(new Function("getHtmlEditor('"+this.name+"').editorText.focus()"), 100);
	else
        setTimeout(new Function("getHtmlEditor('"+this.name+"').editorHtml.contentWindow.document.body.focus()"), 100);
}

function insertHtmlValue(name, val)
{
    // See if it is an HTML editor.
    var editor = getHtmlEditor(name);
    if ( editor != null )
    {
        editor.insertValue(val, false);
        return;
    }

    // Try to insert the text into a DOM element (like a textarea) (on Mozilla).
    var elem = document.getElementById(name);
    if (elem)
    {
        var length = elem.textLength;
        var start = elem.selectionStart;
        var end = elem.selectionEnd;
        if (end == 1 || end == 2) end = length;
        elem.value = elem.value.substring(0,start) + val + elem.value.substr(end,length);
    }

    // I don't know what to do for Safari.
}

function setHtmlFieldValue( fld, val, win )
{
	if ( fld == null )
		return;
	if ( win == null )
		win = window;
	var editor = win.getHtmlEditor( fld.name );

	if ( editor != null )
		editor.setValue( val, true, true );
	else
		fld.value = val;
}

function disableHtmlField( val, fld )
{
	if ( fld == null )
		return;
	var editor = getHtmlEditor( fld.name );
	if ( editor != null )
		editor.setDisabled( val );
	else
		fld.disabled = val;
}

function resetHtmlEditors( frm )
{
	if ( typeof NetSuite == "object" && typeof NetSuite.RTEManager == "object" )
	{
        NetSuite.RTEManager.getMap().eachKey(function (key, value) {
            var editor = value.obj;
            if ( frm == null || editor.hddn.form == frm )
	            NLExtHtmlEditor.resetEditor( key );
        });
	}
}


function getHtmlEditor(name)
{
    
    
    if (typeof Ext != "object" || typeof NetSuite != "object") return null;   //fix for webstore which doesn't support usage of Ext
    if (typeof name == "undefined" || name == null) return null;
    if (name.indexOf("html-editor-")!=0) {
        name = "html-editor-"+name;
    }
	return NetSuite.RTEManager.getInstance(name);
}


/**
 * get selected element in a document
 * bHead whether to get the sart node or end node (if the selection spans across multi nodes)
 */
function getSelectedElement(window)
{
    var node = null;
    if (window.document.selection) 
    {
        selection = window.document.selection;
        range = selection.createRange();
        try {
            node = range.parentElement();
        }
        catch (e) {
            return null;
        }
    } else 
    {
        try {
            selection = window.getSelection();
            range = selection.getRangeAt(0);
        }
        catch(e){
            return null;
        }
        node = range.commonAncestorContainer;
    }
    return node;
}


// dynamically set the quick date selector dropdown to a new value.  sPreference is the key, not the display text
function updateQuickDateSelector(sPreference)
{
	var input = document.getElementById("quickdateselector");
	if(input != null)
	{
		var onChangeFunction = input.onchange;
		input.onchange = null;
		var dd = getDropdown(input);
		if(dd != null)
		{
			var idx = dd.getIndexForValue(sPreference);
			dd.setIndex(idx);
		}
		input.onchange = onChangeFunction;
	}
}




function statusMessage(ms,s)
{
	if(ms == null)
		ms = 2000;
    window.status = s;
    setTimeout("window.status = ''", ms);
}


function NLAccelMenu_cancelCurrentTimer()
{
    var div = window.accelMenuDiv;
    if(div && div.nTimerId)
    {
        clearTimeout(div.nTimerId);
        div.nTimerId = 0;
    }
}

function NLAccelMenu_closeCurrentMenu()
{
    var div = window.accelMenuDiv;
    if(div)
    {
        var bMachine = div.getAttribute("bMachine") == "T";
        NLAccelMenu_cancelCurrentTimer();

    
        // restore the menu div to the original location and state
        div = div.parentNode.removeChild(div);
        div.origParent.appendChild(div);
        div.style.position = "relative";
        div.style.top = div.style.origTop;
        div.style.left = div.style.origLeft;
        div.style.zIndex = "";
        nlRemoveCanvas(div);
	

		
		div.style.display = "none";
        div.img.src = "/images/nav/popupselectup"+(bMachine ? "" : "2")+".gif";
        div.img.className = div.img.className.replace('_focus', '');
   }
    window.accelMenuDiv = null;
}

function NLAccelMenu_onMouseOut(sDivId)
{
    var div = window.accelMenuDiv;
    if(div)
    {
        div.nTimerId = setTimeout(function(){NLAccelMenu_closeCurrentMenu()}, 200);
    }
}

function NLAccelMenu_onMouseOver(sDivId)
{
    
    NLAccelMenu_cancelCurrentTimer();
}

function NLAccelMenu_onButtonClick(evt, sDivId, bMachine, imageClicked)
{
    var div = document.getElementById(sDivId);
    div.setAttribute("bMachine", bMachine ? "T" : "F");

    imageClicked.src = "/images/nav/popupselectdown"+(bMachine ? "" : "2")+".gif";
    div.img = imageClicked;

    if (imageClicked != null)
	{
        
        imageClicked.className = imageClicked.className + '_focus';
	}

    NLAccelMenu_closeCurrentMenu();

    window.accelMenuDiv = div;

    
    div.parentNode.style.display = "inline";
	div.style.display = "";

	
	var w = div.firstChild.offsetWidth;

	

     if (w != undefined)
		div.style.width = w;

    div.style.display = "block";
    div.parentNode.style.zIndex = "9000";

	NLAccelMenu_positionDIV(div);

    
    
       div.style.zIndex = div.parentNode.style.zIndex;
       div.origParent = div.parentNode;
       div.style.origLeft = div.style.left;
       div.style.origTop = div.style.top;
       offsetY = findPosY (div);
       offsetX = findPosX (div);
       div.style.position = "absolute";
       div = div.parentNode.removeChild(div);
       document.body.insertBefore(div, document.body.firstChild);
       div.style.left = offsetX;
       div.style.top = offsetY;
	   nlInsertCanvas(div);

        if(div.firstChild.firstChild)
            div.firstChild.firstChild.style.borderWidth = "0px";
    
}


function NLAccelMenu_positionDIV(div)
{
    var y = findPosY(div.img);
    var fy = y + 22;
    var iDocHeight = getDocumentHeight();
    var iDivHeight = parseInt(div.offsetHeight);

	if ( fy + iDivHeight > iDocHeight )
    {
        y = - iDivHeight;
    }
    else
    {
        y = 22;
    }
	div.style.top = y + "px";
}



function NLAccelMenuButton_onMouseDown(entry)
{
    entry.firstChild.onclick();
}

function NLAccelMenuButton_onMouseOver(entry)
{
    entry.className = "dropdownSelected";
}

function NLAccelMenuButton_onMouseOut(entry)
{
    entry.className = "dropdownNotSelected";
}



var burstTimer = 0;
var bursting = -1;

// see comment in showBurstRollover() below
var newBGImageMap = new Array();
newBGImageMap[0] = "/images/icons/dashboard/top_bkg.gif";
newBGImageMap[1] = "/images/icons/dashboard/left_edge_bkg.gif";
newBGImageMap[2] = "/images/icons/dashboard/right_edge_bkg.gif";
newBGImageMap[3] = "/images/icons/dashboard/bottom_edge_bkg.gif";

function showBurstRollover(img, date, id, kDefinition)
{
  try {
	clearTimeout(burstTimer);
	if(bursting == id+"_"+kDefinition)
		return;
	if(img != null && date != null && date.length>0)
	{
		var top = findPosY(img);
		var left = findPosX(img);
        // we must account for scrolling when we position the burst icon.  (not all portlets will be scrollable)
        var scrollingDiv = document.getElementById('rptsnap'+kDefinition);
        if(scrollingDiv != null)
            top -= scrollingDiv.scrollTop;
		var div = document.getElementById('burst_div_'+kDefinition);
		if(div != null)
		{
            // This entire if block sets the background images for particular elements in the "isnew" graphic
            // it must be done this way because of a bug introduced in an IE security patch in july 2004.
            // It works fine in NS as well so we just do it in all cases.  But we only do it the first time we try to display the graphic
            if(div.getAttribute("_setBG") != "T")
            {
                var TDs = div.firstChild.getElementsByTagName("TD");
                for(var i=0; i < TDs.length; i++)
                {
                    if( TDs[i].getAttribute("_resbg") != null )
                    {
                        var idx = Number(TDs[i].getAttribute("_resbg"));
                        TDs[i].style.backgroundImage = "url("+newBGImageMap[idx]+")";
                    }
                }
                div.setAttribute("_setBG","T");
            }

			dateSpan = document.getElementById('date_span_'+kDefinition);
			dateSpan.removeChild(dateSpan.firstChild);
			var txt = document.createTextNode(date);
			dateSpan.appendChild(txt)
			div.style.display = "block";
			div.style.position = "absolute";
			div.style.top = top+8 + "px";
			div.style.left = left-32 + "px";
			bursting = id+"_"+kDefinition;
		}
	}
   } catch (e) { if(console) console.log(e.message); }
}

function removeBurst(kDefinition)
{
	burstTimer = setTimeout(new Function("removeBurstNow('"+kDefinition+"');"), 200);
}

function removeBurstNow(kDefinition)
{
		var div = document.getElementById('burst_div_'+kDefinition);
		if(div != null)
		{
			div.style.display = 'none';
			bursting = -1;
		}
}

function expandCollapseNode(tBodyId, href)
{
	var topRow = document.getElementById(tBodyId+"_top");
	var totalRow = document.getElementById(tBodyId+"_total");

    if( topRow == null || totalRow == null ) return;


	var parentTable = findClassUp(topRow, "enhtable");
    var bNoTotals = topRow.getAttribute("_nototals") == "T";
	// toggle based on the current display property of the first row in this node's group
    var nextRow = parentTable.rows[topRow.rowIndex+1];
	var sDisplayType = nextRow.style.display == "" || nextRow.style.display == "block" ? "none" : "";
	setHrefToggleLabel(sDisplayType, href);

    if(!bNoTotals)
    {
        if(sDisplayType != "none")
            expandNodeRestoreData(topRow);
        else
            collapseNodeCopyData(topRow, totalRow);
    }

	var currentRow = null;
	var innerCollapsedCount = 0;
	for(var i=topRow.rowIndex+1; i<=totalRow.rowIndex; i++)
	{
		// we must be tricky to retain the curent properties of the inner nodes (that may be expanded or collapsed as we iterate through
		currentRow = parentTable.rows[i];

		if( innerCollapsedCount > 0 && currentRow.id == null )
			continue;

		var prevCollapseCount = innerCollapsedCount;

		if( sDisplayType != "none" && currentRow.id != null )
		{
			if( currentRow.id.substring(currentRow.id.length-4)=="_top" && currentRow.firstChild.firstChild.getAttribute("_state")=="plus" )
				innerCollapsedCount++;
			else if( currentRow.id.substring(currentRow.id.length-6)=="_total"  && document.getElementById(currentRow.id.substring(0,currentRow.id.length-6)+"_top").firstChild.firstChild.getAttribute("_state")=="plus" )
				innerCollapsedCount = Math.max(innerCollapsedCount-1,0);
			if(prevCollapseCount >0)
					continue;
		}
        // if we're not showing totals, and were expanding a node, don't set the total row to show
        if( ! (sDisplayType != "none" && bNoTotals && currentRow.id.substring(currentRow.id.length-6)=="_total") )
            currentRow.style.display = sDisplayType;
	}
}

function setHrefToggleLabel(sDisplayType, href)
{
	if(sDisplayType != "none")
    {
		href.firstChild.src = "/images/nav/reporting/tree_minus.gif";
        href.setAttribute("_state","minus");
    }
	else
    {
		href.firstChild.src = "/images/nav/reporting/tree_plus.gif";
        href.setAttribute("_state","plus");
    }
}

function expandNodeRestoreData(topRow)
{
	if(topRow != null)
	{
		for(var i=1; i < topRow.cells.length; i++)
		{
			if(topRow.cells[i].getAttribute("_orightml") != null && topRow.cells[i].getAttribute("_orightml").length>1)
			{
				topRow.cells[i].innerHTML = topRow.cells[i].getAttribute("_orightml");
				topRow.cells[i].className = topRow.cells[i].getAttribute("_origclass");
				topRow.cells[i].align = topRow.cells[i].getAttribute("_origalign");
			}
			else
			{
				topRow.cells[i].innerHTML = "&nbsp;"
			}
		}
	}
}

function collapseNodeCopyData(topRow, totalRow)
{
	if(totalRow != null && topRow != null)
	{
		for(var i=1; i < totalRow.cells.length; i++)
		{

			// keep track of what's in the cells now so that we can restore it on expand
			topRow.cells[i].setAttribute("_orightml",topRow.cells[i].innerHTML);
			topRow.cells[i].setAttribute("_origclass",topRow.cells[i].className);
			topRow.cells[i].setAttribute("_origalign",topRow.cells[i].align);

			// set the top row equal to the total row
			topRow.cells[i].align = totalRow.cells[i].align;
			topRow.cells[i].className = totalRow.cells[i].className;
			topRow.cells[i].innerHTML = totalRow.cells[i].innerHTML;
		}
	}
}


function manageScrollDiv(divid, sPortletId)
{
    var scrollDiv = document.getElementById(divid);
    if(scrollDiv != null)
    {
        // if the div is already scrollable and it needs to stay that way, do nothing
        if(scrollDiv.className == "scrollarea" && scrollDiv.scrollHeight > 325)
            return;
        var bScrollable = false;
        if(scrollDiv.offsetHeight > 325)
        {
            scrollDiv.className = "scrollarea";
            scrollDiv.style.height = "325px";
            document.getElementById("scrl_line_"+divid).style.display = "";
            bScrollable = true;
        }
        else
        {
            scrollDiv.className = "";
            scrollDiv.style.height = "";
            document.getElementById("scrl_line_"+divid).style.display = "none";
        }
        
        if(sPortletId != null && sPortletId != -1)
            resetLabelRowCellSizes(document.getElementById("enhlabel"+sPortletId), scrollDiv.firstChild, bScrollable);
    }
}


function resetLabelRowCellSizes(labelRow, mainTable, bScrollable)
{
    if(labelRow != null && mainTable != null)
    {
        clearAllWidths(mainTable);
        var firstMainRow = mainTable.rows[0];
        firstMainRow.style.display = "";
        var secondMainRow = mainTable.rows[1];
        
        if(secondMainRow == null || secondMainRow.cells.length <= 1)
        {
            firstMainRow.style.display = "none";
            return;
        }
        var totalMain = mainTable.offsetWidth - (bScrollable ? 17 : 0);
        var totalLabel = labelRow.parentNode.parentNode.offsetWidth;

        var hiddenLabelCellWidths = new Array();
        
        for(var p=0; p < secondMainRow.cells.length; p++)
            hiddenLabelCellWidths[p] = secondMainRow.cells[p].offsetWidth;

        for(var i= (labelRow.cells.length-1); i>= 0; i--)
        {
            var currRow = null;
            var bIsLastColumn = i == (labelRow.cells.length-1);
            
            var bUsePercentage = labelRow.cells.length <= 2 || i > 1;

            if( bIsLastColumn )
            {
                if(bScrollable)
                    labelRow.cells[i].style.paddingRight = "16px";
                else
                    labelRow.cells[i].style.paddingRight = "";
            }
            var currentLabelPercent = (((hiddenLabelCellWidths[i]+(bIsLastColumn && bScrollable ? 17 : 0))/totalLabel)*100);
            var currentMainPercent = ((hiddenLabelCellWidths[i]/totalMain)*100);
            labelRow.cells[i].style.width = bUsePercentage ? currentLabelPercent+"%" : (hiddenLabelCellWidths[i]+(bIsLastColumn && bScrollable ? 17 : 0)+"px");

            for(var j=0; j < mainTable.rows.length; j++)
            {
                currRow = mainTable.rows[j];
                if(currRow.cells[i] == null || currRow.id == '_totallinerow')
                        continue;
                currRow.cells[i].style.width = bUsePercentage ? currentMainPercent+"%" : (hiddenLabelCellWidths[i] + "px");
            }
		}
        firstMainRow.style.display = "none";
    }
}





function clearAllWidths(table)
{
    for(var i=0; i < table.rows.length; i++)
    {
        for(var j=0; j < table.rows[i].cells.length; j++)
        {
            table.rows[i].cells[j].style.width = "";
        }
    }
}


var menuCtx = null;
var menuCtxTarget = null;

document.oncontextmenu = function(evnt)
{
    if(menuCtx && NS.form.isInited())
    {
        menuCtxTarget = getEventTarget(evnt);
        menuCtx.menu.showHide(true);
        return false;
    }
    else
    {
        return true;
    }
}


function NLContextMenu(pOptions)
{
    var params = new Array();

    
    for(i=0; i< pOptions.length;i++)
    {
        params[i] = [pOptions[i][0], 'javascript:' + pOptions[i][1] + '; return false;', ''];
    }
    this.sParams = params;

    var name = "contextmenu";
    var menu = this.menu = new NLMenu(name, params, 0, null);
    menus[name] = menu;
    menuTimers[name] = 0;

    menu.setBackgroundColor('#FFFFFF');

    menuCtx = this;
}



var iMAX_SUGGESTIONS = 25;
var popupsuggesttimer = 0;
var hidesuggesttimer = 0;
var loadingimagetimer = 0;
var hideloadingimagetimer = 0;
var popupAutoSuggest = null;

var autoSuggestSeqNum = 0;


var highestSeqNumReturned = 0;

function NLPopupAutoSuggest()
{
	this.inputfield;
	this.mapkey;
	this.uniqueuserkey;
	this.asheep;  
	this.initialLastUserVal;
	this.fieldname;
	this.fieldname_hidden;
	this.fieldvalue;
	this.optionmasterfield;
	this.xPos;
	this.yPos;
	this.suggestiondiv;
	this.visible = false;
	this.currentcell;
	this.bUbersearch = false;
	this.bmultiselect = false;
	this.bautoselectsingleresult = true;
	this.bOnlyOneResult = false;
}

NLPopupAutoSuggest.prototype.setAttributes = function NLPopupAutoSuggest_setAttributes(inputField, mapkey, bAutoSelectSingleResult, optionMasterFields)
{
	this.inputfield = inputField;
	this.mapkey = mapkey;
	this.fieldname = inputField.name;
	this.fieldname_hidden = this.fieldname.indexOf("_display") > 0 ? this.fieldname.substring(0, this.fieldname.indexOf("_display")) : this.fieldname;
	this.fieldvalue = inputField.value;
	this.optionmasterfields = optionMasterFields;
	this.bautoselectsingleresult = bAutoSelectSingleResult;
	this.xPos = findPosX(inputField);
	this.yPos = findPosY(inputField);
	this.currentcell = -1;
	this.bUbersearch = mapkey == "uberautosuggest";
	this.bmultiselect = NLPopupAutoSuggest_isMultiSelect(inputField);
	
	if(isValEmpty(this.uniqueuserkey))
	{
		this.asheep = inputField.getAttribute("asheep");
		this.uniqueuserkey = inputField.getAttribute("asuuk");
		this.initialLastUserVal = GetCookie("lastUser") + "_" + GetCookie("JSESSIONID");
	}
}

function constructSuggestionBoxFromResponse(response)
{
    if(popupAutoSuggest != null)
	{
		hideAutoSuggestLoadingImage();
		var objJSON, autoFillResults;
		try
		{
			objJSON = eval("(" + response.getBody() + ")");
            var seqNum = parseInt( objJSON.circid );
			if ( highestSeqNumReturned > seqNum )
			    return;
            highestSeqNumReturned = seqNum;
			autoFillResults = objJSON.autofill;
		}
		catch (e)
		{
			
			return;
		}

		if(autoFillResults.length>0)
		{
			var i;
			var sHtml = new StringBuffer();
			sHtml.append("<table cellpadding=0 cellspacing=0 border=0><tbody>");
			for(i=0; i<autoFillResults.length; i++)
			{
				sHtml.append("<tr>");
				popupAutoSuggest.constructCell(sHtml, autoFillResults[i], popupAutoSuggest.fieldname_hidden);
				sHtml.append("</tr>");
			}
			if(i==iMAX_SUGGESTIONS)
			{
				sHtml.append("<tr>");
				popupAutoSuggest.constructMoreCell(sHtml, popupAutoSuggest.fieldname_hidden, popupAutoSuggest.fieldvalue);
				sHtml.append("</tr>");
			}
			sHtml.append("</tbody></table>");

			popupAutoSuggest.showSuggestionBox(sHtml.toString());
			
			if(popupAutoSuggest.bautoselectsingleresult && i==1)
			{
				popupAutoSuggest.selectNextCell();
				popupAutoSuggest.bOnlyOneResult = true;
			}
		}
		else
		{
			
			popupAutoSuggest.showSuggestionBox(getAutoSuggestMessageHTML("No results found"));
			hidesuggesttimer = setTimeout("popupAutoSuggest.hideSuggestionBox()", 2000);
		}
	}
}


function logAutoSuggestSessionError(popupAutoSuggest, responseUserKey)
{
	var oldUserCredentials = popupAutoSuggest.uniqueuserkey+"%20|%20"+popupAutoSuggest.initialLastUserVal;
	var newUserCredentials = responseUserKey + "%20|%20"+GetCookie("lastUser") + "_" + GetCookie("JSESSIONID");
	parent.document.location = "/core/pages/logAutoSuggestSessionError.nl?olduserkey="+oldUserCredentials+"&newuserkey="+newUserCredentials;
}

function getAutoSuggestMessageHTML(sMessage)
{
	var sHtml = new StringBuffer();
	sHtml.append("<table cellpadding=0 cellspacing=0 border=0><tbody>");
	sHtml.append("<tr><td style='padding:2' class=tinygraytext>"+sMessage+"</td></tr>");
	sHtml.append("</tbody></table>");
	return sHtml.toString();
}

function hideAutoSuggestLoadingImage()
{
	clearTimeout(loadingimagetimer);
	clearTimeout(hideloadingimagetimer);
	if(popupAutoSuggest != null)
		popupAutoSuggest.inputfield.style.backgroundImage = "";
}

function showAutoSuggestRefineSearchMessage()
{
	if(popupAutoSuggest != null)
	{
		popupAutoSuggest.showSuggestionBox(getAutoSuggestMessageHTML("Please enter more characters or click Go"));
		hidesuggesttimer = setTimeout("popupAutoSuggest.hideSuggestionBox()", 4000);
	}
}


function showAutoSuggestLoadingImage()
{
	clearTimeout(hideloadingimagetimer);
	if(popupAutoSuggest != null)
	{
		popupAutoSuggest.inputfield.style.backgroundImage = "url(/images/help/animated_loading.gif)";
		popupAutoSuggest.inputfield.style.backgroundRepeat = "no-repeat";
		popupAutoSuggest.inputfield.style.backgroundPosition = "100% 1px";
		hideloadingimagetimer = setTimeout("hideAutoSuggestLoadingImage(); showAutoSuggestRefineSearchMessage();", 10*1000);  // GSAS times out at 10 seconds so we need to kill the espinner
	}
}

NLPopupAutoSuggest.prototype.constructSuggestionBox = function NLPopupAutoSuggest_constructSuggestionBox()
{
	if (this.fieldvalue!= null && trim(this.fieldvalue).length>0)
	{
		try
		{
            var queryString = "cur_val="+encode(this.bmultiselect ? getCurrentMultiSelectUserInputValue(this.inputfield) : this.fieldvalue);
			if (this.optionmasterfields != null)
            {
                for ( var name in this.optionmasterfields )
                    queryString += "&si_"+name+"="+encode(getSelectValue(this.optionmasterfields[name]));
            }
            var sUrl = "/app/common/autosuggest.nl?mapkey=" + this.mapkey + "&circid=" + (++autoSuggestSeqNum) + "&" + queryString;
			loadingimagetimer = setTimeout("showAutoSuggestLoadingImage()", 1000);
			nlXMLRequestURL(sUrl, null, null, new Function ("response", "constructSuggestionBoxFromResponse(response);"), true);
		}
		catch (e)
		{
			// if anything goes wrong with the JSON XML request, just return and ignore the error.  This is typically caused by a session timeout
            // see comments in catch() handler above
			//this.hideSuggestionBox();
        }
	}
}

NLPopupAutoSuggest.prototype.constructCell = function NLPopupAutoSuggest_constructCell(sbHtml, autoFillResult, fieldname)
{
	if(this.bUbersearch)
	{
		
		var bAllowEdit = (autoFillResult.bedit=="T");
		sbHtml.append("<td nowrap style='padding:1 3 2 3;' class='autosuggcell text'>");
			sbHtml.append("<table cellpadding=0 cellspacing=0 border=0 width='100%'><tr>");
				sbHtml.append("<td nowrap>");
					sbHtml.append("<a class=smalltextnolink href=\""+autoFillResult.key+"\" onclick='popupAutoSuggest.hideSuggestionBox(true); return true;'>");
					if(!isValEmpty(autoFillResult.descr))
                        
						sbHtml.append("<span></span><span style='color:#666666'><i>"+autoFillResult.descr+":&nbsp;</i></span><span>"+autoFillResult.sname+"</span>");
					else
						sbHtml.append(autoFillResult.sname);
					sbHtml.append("</a>");
				sbHtml.append("</td>");
				sbHtml.append("<td style='padding-left:7; padding-right:2' class=text align=right valign=bottom>");
					sbHtml.append("<span style='visibility:hidden'>");
						if(!isValEmpty(autoFillResult.dashurl))
						{
							sbHtml.append("<a"+(bAllowEdit ? " style='position:relative; top:2'" : "")+" href='"+autoFillResult.dashurl+"' onclick='popupAutoSuggest.hideSuggestionBox(true); return true;' class=text title='View Dashboard'>");
							sbHtml.append("<img class='i_dashboard_white' border=0 src='/images/nav/ns_x.gif' width=14 height=12>");
							sbHtml.append("</a>");
							if(bAllowEdit)
								sbHtml.append("&nbsp;&nbsp;");
						}
						sbHtml.append("<a href=\""+autoFillResult.key+"&e=T\" onclick='popupAutoSuggest.hideSuggestionBox(true); return true;' class=textwhite"+(!bAllowEdit ? " style='display:none'" : "")+">Edit</a>");
					sbHtml.append("</span>");
				sbHtml.append("</td>");
			sbHtml.append("</tr>");
		sbHtml.append("</table>");
		sbHtml.append("</td>");
	}
	else
	{
		sbHtml.append("<td nowrap style='padding:1 3 2 3; cursor:hand;' class='autosuggcell text' ");
		sbHtml.append(" onmousedown='popupAutoSuggest.setValueFromSuggestion(\""+fieldname+"\", \""+autoFillResult.key+"\", this, event); return false;'>");
		sbHtml.append(autoFillResult.sname);
		sbHtml.append("</td>");
	}
}

NLPopupAutoSuggest.prototype.constructMoreCell = function NLPopupAutoSuggest_constructMoreCell(sbHtml, fieldname, fieldvalue)
{
	sbHtml.append("<td nowrap style='cursor:pointer; padding:1 3 2 3; font-style:italic;' class='autosuggcell text' ");
	sbHtml.append("onmousedown=\"NLPopupAutoSuggest_hidePopupSuggestion(); ");
	if(this.bUbersearch)
		sbHtml.append("popupAutoSuggest.runMoreUbersearch();");
	else
	{
		var safeVal = fieldvalue.replace(/\'/g,"\\\'").replace(/\"/g,"\\\\&quot;");
		sbHtml.append("NLPopupSelect_runMoreSearch('"+fieldname+"', '"+safeVal+"');");
	}
	sbHtml.append(" return false;\">");
	sbHtml.append("More...");
	sbHtml.append("</td>");
}

NLPopupAutoSuggest.prototype.runMoreUbersearch = function NLPopupAutoSuggest_runMoreUbersearch()
{
	document.getElementById("_searchSubmitter").onclick();
}

NLPopupAutoSuggest.prototype.selectCell = function NLPopupAutoSuggest_selectCell(td)
{
	if(td != null)
	{
		this.unSelectCurrentCell();
		td.className = "dropdownSelected";
		if(this.bUbersearch && td.firstChild && td.firstChild.rows)
			setAutoSuggestCellProperties(td, true);
		else if(td.childNodes.length>1)
				td.childNodes[1].style.color = "#EEEEEE";
		this.currentcell = Number(td.parentNode.rowIndex);
	}
}

NLPopupAutoSuggest.prototype.unSelectCell = function NLPopupAutoSuggest_unSelectCell(td)
{
	if(td != null)
	{
		td.className = 'autosuggcell text';
		if(this.bUbersearch && td.firstChild && td.firstChild.rows)
			setAutoSuggestCellProperties(td, false);
		else if(td.childNodes.length>1)
				td.childNodes[1].style.color = "#666666";
		this.currentcell = -1;
	}
}

function setAutoSuggestCellProperties(td, bSelected)
{
	var innerTd = td.firstChild.rows[0].cells[0];
	var innerEditTd = td.firstChild.rows[0].cells[1];
	innerTd.firstChild.className = bSelected ? "textwhitenolink" : "smalltextnolink";
	if(innerTd.firstChild.childNodes.length>1)
		innerTd.firstChild.childNodes[1].style.color = bSelected ? "#EEEEEE" : "#666666";
	innerEditTd.firstChild.style.visibility = bSelected ? "visible" : "hidden";
}

NLPopupAutoSuggest.prototype.selectCellByIndex = function NLPopupAutoSuggest_selectCellByIndex(index)
{
	var cell = this.getCell(index);
	this.selectCell(cell);
}

NLPopupAutoSuggest.prototype.unSelectCurrentCell = function NLPopupAutoSuggest_unSelectCurrentCell()
{
	if(this.currentcell >= 0)
	{
		var cell = this.getCell(this.currentcell);
		this.unSelectCell(cell);
	}
}

NLPopupAutoSuggest.prototype.doUberSearchClick = function NLPopupAutoSuggest_doUberSearchClick()
{
	var cell = this.getCell(this.currentcell);
	if(cell != null && cell.firstChild && cell.firstChild.rows)
	{
		var innerTd = cell.firstChild.rows[0].cells[0];
		innerTd.firstChild.onclick();
		var location = innerTd.firstChild.href;
		
		if(this.bOnlyOneResult && !isValEmpty(this.fieldvalue))
		{
			if(this.fieldvalue.toUpperCase().indexOf("E ")==0 || isUpperCase(this.fieldvalue.charAt(0)))
				location = addParamToURL(location, "e", "T", true);
			if(this.fieldvalue.indexOf("::")>0 || this.fieldvalue.indexOf("^")>0)
				nlOpenWindow(location, 'uberres2');
			else
				document.location = location;
		}
		else
		{
			document.location = location;
		}
	}
	else
	{
		cell.onmousedown();
	}
}

NLPopupAutoSuggest.prototype.getTableRows = function NLPopupAutoSuggest_getTableRows()
{
	return this.suggestiondiv.firstChild.firstChild.childNodes;
}

NLPopupAutoSuggest.prototype.getCell = function NLPopupAutoSuggest_getCell(index)
{
	if(index>=0 && index<(this.getTableRows()).length)
		return this.getTableRows()[index].firstChild;
	else
		return null;
}

NLPopupAutoSuggest.prototype.selectNextCell = function NLPopupAutoSuggest_selectNextCell()
{
	var index = this.currentcell;
	this.unSelectCurrentCell();
	if(index>=0)
	{
		if(++index>this.getTableRows().length-1)
			index = 0;
		this.selectCellByIndex(index);
	}
	else
	{
		this.selectCellByIndex(0);
	}
}

NLPopupAutoSuggest.prototype.selectPreviousCell = function NLPopupAutoSuggest_selectPreviousCell()
{
	var index = this.currentcell;
	this.unSelectCurrentCell();
	if(index>=1)
	{
		this.selectCellByIndex(index-1);
	}
	else
	{
		this.selectCellByIndex(this.getTableRows().length-1);
	}
}

NLPopupAutoSuggest.prototype.getSuggestionBoxDiv = function NLPopupAutoSuggest_getSuggestionBoxDiv()
{
	if(this.suggestiondiv == null)
	{
		this.suggestiondiv = document.createElement("DIV");
		this.suggestiondiv.style.position = "absolute";
		this.suggestiondiv.style.backgroundColor = "#FFFFFF";
		this.suggestiondiv.className = "popupsuggest";
		this.suggestiondiv.style.borderColor = "#999999";
		this.suggestiondiv.style.borderStyle = "solid";
		this.suggestiondiv.style.borderWidth = "1px 1px 1px 1px";
		this.suggestiondiv.style.display = "none";
		this.suggestiondiv.style.zIndex = "20";
		document.body.appendChild(this.suggestiondiv);
	}
	return this.suggestiondiv;
}

NLPopupAutoSuggest.prototype.showSuggestionBox = function NLPopupAutoSuggest_showSuggestionBox(sInnerHtml)
{
	clearTimeout(hidesuggesttimer);
	var div = this.getSuggestionBoxDiv();
	div.innerHTML = sInnerHtml;
	div.style.display = "";
	this.visible = true;
	this.positionSuggestionBox();
}

NLPopupAutoSuggest.prototype.positionSuggestionBox = function NLPopupAutoSuggest_positionSuggestionBox()
{
	var div = this.getSuggestionBoxDiv();
    div.style.overflow = "";
    div.style.width = "";
    div.firstChild.style.width = "";
    var width = div.firstChild.offsetWidth;
	
	if(width > 400)
	{
        if ((getDocumentClientWidth()-100) < div.firstChild.offsetWidth)
    		div.style.overflow = "hidden";
		width = Math.min((getDocumentClientWidth()-100), div.firstChild.offsetWidth);
        div.style.width = width;
	}
	var leftPos = this.xPos + (this.bmultiselect ? 1 : 0);
	var topPos = this.yPos + this.inputfield.offsetHeight - 1;
    
	
	if(div.offsetWidth < this.inputfield.offsetWidth)
		div.firstChild.style.width = this.inputfield.offsetWidth - 2 + "px";

	
	if(((this.yPos + this.inputfield.offsetHeight - 1 + div.offsetHeight) > getDocumentHeight()) && (this.yPos > (getDocumentHeight() - this.yPos)))
		topPos = this.yPos - div.offsetHeight + (this.bmultiselect ? 1 : 0);
	
	if((this.xPos + width + 10) > getDocumentWidth())
		leftPos = this.xPos - (width-this.inputfield.offsetWidth);

	div.style.top = topPos + "px";
	div.style.left = leftPos + "px";
}

NLPopupAutoSuggest.prototype.hideSuggestionBox = function NLPopupAutoSuggest_hideSuggestionBox(bClearFieldValue)
{
	if(this.visible)
	{
		clearTimeout(popupsuggesttimer);
		this.suggestiondiv.style.display = "none";
		
		this.suggestiondiv.style.width = "";
		this.suggestiondiv.style.overflow = "";
		this.visible = false;
		if(bClearFieldValue)
			this.inputfield.value = "";
        this.suggestiondiv = null;
    }
}

NLPopupAutoSuggest.prototype.addMultipleSelectValue = function NLPopupAutoSuggest_addMultipleSelectValue(val, displayVal)
{
	var fld_display = getFormElement(this.inputfield.form,this.fieldname);
	var fld_hidden = getFormElement(this.inputfield.form,this.fieldname_hidden);
	addMultiSelectValue(fld_hidden,val,displayVal);
	
	fld_display.value += "\n";
	setSelectionRange(fld_display, fld_display.value.length, fld_display.value.length);
}

NLPopupAutoSuggest.prototype.setValueFromSuggestion = function NLPopupAutoSuggest_setValueFromSuggestion(fieldname, val, fieldElem, evnt)
{
    setEventPreventDefault(evnt);
    setEventCancelBubble(evnt);
    NLPopupAutoSuggest_hidePopupSuggestion();
	if(this.bUbersearch)
	{
		if(this.fieldvalue.indexOf("::")>0 || this.fieldvalue.indexOf("^")>0)
		{
			nlOpenWindow(val, 'uberres2');
		}
		else
		{
			document.location = val;
			this.inputfield.value = "";
		}
	}
	else
	{
		var fld_display = getFormElement(this.inputfield.form,this.fieldname);
		if(fld_display!=null)
		{
			var displayVal = fieldElem.innerHTML.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
			var fldHidden = getFormElement(this.inputfield.form,this.fieldname_hidden);
			if(this.bmultiselect)
			{
				this.addMultipleSelectValue(val,displayVal);
                
                fld_display.haschanged = true;
                fld_display.isvalid = true;
                if(fldHidden.onchange)
                    fldHidden.onchange();
            }
			else
			{
                
                
                fld_display.value = displayVal;
                var oldValue = fldHidden.value;
                fldHidden.value = val;
                if(fldHidden.onchange)
                {
                    if (fldHidden.onchange() == false)
                    {
                        fldHidden.value = oldValue;
                        fld_display.value = fld_display.getAttribute("previousvalue");
                    }
                    else
                    {
                        
                        fld_display.haschanged = true;
                        fld_display.isvalid = true;
                        fld_display.setAttribute("previousvalue", fld_display.value);
                        if (NS && NS.form)
                        {
                            NS.form.setValid(true);
                        }
                    }
                }
                
            }
			NLPopupSelect_removeLoadingMessage();
		}
	}
}

function NLPopupAutoSuggest_makePopupSuggestion(inputField, mapkey, bAutoSelectSingleResult, optionMasterFields)
{
	if(popupAutoSuggest == null)
		popupAutoSuggest = new NLPopupAutoSuggest();
	popupAutoSuggest.setAttributes(inputField, mapkey, bAutoSelectSingleResult, optionMasterFields);

	clearTimeout(popupsuggesttimer);
	popupsuggesttimer = setTimeout("popupAutoSuggest.constructSuggestionBox()", popupAutoSuggest.bUbersearch ? 250 : 200);
}

function autoSuggestOnMouseMove(evt)
{
	if(popupAutoSuggest != null)
	{
		var td = findClassUp(getEventTarget(evt), 'autosuggcell text');
		if(td != null)
			popupAutoSuggest.selectCell(td);
	}
}

function NLPopupAutoSuggest_onMouseDown(evt)
{
	if(popupAutoSuggest != null)
	{
		clearTimeout(popupsuggesttimer);
		if(popupAutoSuggest.visible)
		{
			var clickdiv = findClassUp(getEventTarget(evt), 'popupsuggest');
			if (clickdiv == null)
				popupAutoSuggest.hideSuggestionBox();
		}
	}
}

function NLPopupAutoSuggest_onKeyDown(evt)
{
	
	try {
	if(popupAutoSuggest != null && popupAutoSuggest.visible)
	{
		var keypress = getEventKeypress(evt);
		if(keypress == 40)
			popupAutoSuggest.selectNextCell();
		else if(keypress == 38)
			popupAutoSuggest.selectPreviousCell();
		else if((keypress == 13 || keypress == 9) && popupAutoSuggest.currentcell>=0)
		{
			if(popupAutoSuggest.bUbersearch)
				popupAutoSuggest.doUberSearchClick();
			else
				popupAutoSuggest.getCell(popupAutoSuggest.currentcell).onmousedown();
		}
	}
	} catch (e) { if(console) console.log(e.message); }
}

function NLPopupAutoSuggest_ignoreKeyStrokes(evt)
{
    if(popupAutoSuggest != null && popupAutoSuggest.visible)
	{
        var keypress = getEventKeypress(evt);
		if(keypress == 40 || keypress == 38 || (popupAutoSuggest.currentcell>=0 && (keypress == 13 || keypress == 9)))
	        return true;
	}
    return false;
}

function NLPopupAutoSuggest_isMultiSelect(inputfield)
{
	return inputfield.getAttribute("bmultiautosuggest")=="T";
}

function NLPopupAutoSuggest_handleKeyStroke(inputfield, mapkey, evt, bAutoSelectSingleResult, optionMasterFields)
{
    var userEnteredValue = NLPopupAutoSuggest_isMultiSelect(inputfield) ? getCurrentMultiSelectUserInputValue(inputfield) : inputfield.value;
    var keypress = getEventKeypress(evt);
	if(keypress == 37 || keypress == 39 || keypress == 16)
		return false;

    var sText = trim(userEnteredValue);
    var iTextLen = sText.length;
    var bUberSearch = mapkey=='uberautosuggest';
    if ( bUberSearch )
    {
        var iColonIdx = sText.indexOf(':');
        if ( iColonIdx > 0 )
            iTextLen -= ( iColonIdx+1 );
    }
	if( (iTextLen<=2 && sText.charCodeAt(0) < 2048 && (userEnteredValue!='%' || bUberSearch))  // allow single character in popup selects if it is % or if it's non-Roman (e.g. Chinese) character.
				|| keypress == 13 || keypress == 9)
		NLPopupAutoSuggest_hidePopupSuggestion();
	else
		NLPopupAutoSuggest_makePopupSuggestion(inputfield, mapkey, bAutoSelectSingleResult, optionMasterFields);
}

function NLPopupAutoSuggest_hidePopupSuggestion()
{
	clearTimeout(popupsuggesttimer);
	if(popupAutoSuggest != null)
		popupAutoSuggest.hideSuggestionBox();
}


function NLPopupSelect_runMoreSearch(fieldname, sValue)
{
	eval("Search"+fieldname+"(\""+sValue+"\")");
}




function NLPopupSelect_positionDIV()
{
	var BORDER_SPACE = 75;

    var div = window.popupDIV;
    var bListOnly = div.getAttribute("bListOnly") == "T";
    var bActualMultiSelect = div.getAttribute("bMultiselect") == "T" && !bListOnly;
    var bIsMultiButton = div.getAttribute("bIsMultiButton") == "T";

    var btn = div.getAttribute("displayField") != null ?
                NLPopupSelect_getDisplayField(div.getAttribute("displayField")) :
                NLPopupSelect_getLaunchButton(div.getAttribute("launchbutton"), bIsMultiButton, bListOnly);

    var x;
    var y;
    
	if( div.getAttribute("bPositionWithMachine") == "T" && div.getAttribute("machineName") != null)
    {
        //the expression/object as the eval() argument may be 'undefined', it need to be treated differently
        //e.g.: for CSV import assistant default value dropdown, it is not in a machine, so the eval argument is 'undefined'. The err can be catched, and x, y will also be set.
        try
        {
            var table = eval( div.getAttribute("machineName")+"_machine.tableobj;" );
            var machine = table.machine;

            var column = 0;
            for (var i=0; i < machine.countFormElements(); i++)
            {
                var elem = machine.getFormElement( i );
                if(elem != null && (elem.name == window.popupDIV.getAttribute("fieldName") || elem.name == window.popupDIV.getAttribute("fieldName")+'_display'))
                    break;
                if( elem.type!="hidden" && machine.getFormElementLabel(i) != null )
                    column++;
            }
            var cell = table.rows[ (machine.currentRowNum) ].cells[ column ];
            x = findAbsolutePosX( cell );
            y = findAbsolutePosY( cell ) + 5;
        }
        catch(err)
        {
            x = btn == null ? Math.max(lastX,10) : findAbsolutePosX(btn) + (bIsMultiButton ? 1 : 0);
            y = btn == null ? Math.max(lastY,10) : findAbsolutePosY(btn) + (bIsMultiButton ? 1 : 0);
        }
    }
    else
    {
        x = btn == null ? Math.max(lastX,10) : findAbsolutePosX(btn) + (bIsMultiButton ? 1 : 0);
        y = btn == null ? Math.max(lastY,10) : findAbsolutePosY(btn) + (bIsMultiButton ? 1 : 0);
    }


    
    var scrollTopOffset = 0;
    var scrollLeftOffset = 0;
    if(btn != null)
    {
        var scrollDiv = findClassUp(btn,'scrollarea');
        if(scrollDiv!=null)
        {
            scrollTopOffset = scrollDiv.scrollTop;
            scrollLeftOffset = scrollDiv.scrollLeft;
        }
    }

    var fx = x - scrollLeftOffset;
    var fy = y + 15 - scrollTopOffset;
    var iDocHeight = getDocumentHeight();
    var iDocWidth  = getDocumentWidth() - BORDER_SPACE;

    
    if( window.opener && (iDocHeight <= 250 || iDocWidth <= 510) )
    {
        window.resizeTo( Math.max(600, iDocWidth), Math.max(350, iDocHeight) );
        iDocHeight = getDocumentHeight();
        iDocWidth  = getDocumentWidth() - BORDER_SPACE;
    }

    
    var innerDiv = document.getElementById("inner_popup_div");
    var innerDivSelectList = document.getElementById("popup_select_list");
    var innerTable = innerDiv.firstChild;

    var iDivHeight = parseInt(div.offsetHeight);
    var iMaxDivHeight = 325;
    
    if(iDivHeight > iMaxDivHeight || iDivHeight >= iDocHeight)
    {
        var surroundElementsHeight = iDivHeight - innerDiv.offsetHeight + 25;  
        var InnerListDefaultHeight = 350;  
        var iSelectListHeight = Math.min(InnerListDefaultHeight,Math.abs(iDocHeight - surroundElementsHeight));
        innerDiv.style.height = iSelectListHeight + "px";
        if(bActualMultiSelect)
        {
            innerDivSelectList.style.height = iSelectListHeight + "px";
        }
    }
    
    iDivHeight = parseInt(div.offsetHeight);

    var bMultiColumn = innerTable.rows[0].cells.length > 2;
    if(bMultiColumn)
    {
        if (bActualMultiSelect)
        {
                var listWidth = 600;
                var selectionWidth = 250;
                if( iDocWidth < (listWidth + selectionWidth))
                {
                    var wFactor = Math.floor( iDocWidth/3);
                    listWidth = 2*wFactor;
                    selectionWidth = wFactor;
                }
                innerDiv.style.width = listWidth + "px";
                document.getElementById("lower_header_label").style.width = listWidth + "px";
                innerDivSelectList.style.width = selectionWidth + "px";
        }
        else
        {
                innerDiv.style.width = Math.min(650, iDocWidth) + "px";
        }
    }
    else if (bActualMultiSelect)
    {
            var listWidth = Math.floor((Math.min(600, Math.floor(iDocWidth)))/2);
            innerDiv.style.width = listWidth + "px";
            innerDivSelectList.style.width = listWidth + "px";
    }
    else
    {
        div.style.width = Math.min(350, iDocWidth) + "px";
    }

    var iDivWidth  = parseInt(div.offsetWidth);
	if ( fy + iDivHeight > iDocHeight )
    {
        if ( (y - scrollTopOffset - document.body.scrollTop - iDivHeight ) > 0 ) 
        {
    		fy = y - scrollTopOffset - iDivHeight + 1;
        }
        else
        {
            
            fy = parseInt(( iDocHeight - iDivHeight ) / 2) + document.body.scrollTop;
        }
        if( div.getAttribute("bPositionWithMachine") == "T" )
            fy -= 5;
    }

	if ( (fx + iDivWidth) > iDocWidth )
    {
		fx = getDocumentWidth() - iDivWidth;
    }
    
    if ( fx + iDivWidth > iDocWidth )
    {
        fx = getDocumentWidth() - iDivWidth - 40;
    }
    
    if ( fx < document.body.scrollLeft )
    {
       fx = document.body.scrollLeft;
    }

    NLPopupSelect_removeLoadingMessage();

    div.style.left = fx + "px";
	div.style.top = fy + "px";
}

function NLPopupSelect_isLoadingOrSearching()
{
    return window.popupDIV != null || (window.popupDivLoadingMessage != null && document.getElementById(window.popupDivLoadingMessage.id) != null);
}

function NLPopupSelect_removeLoadingMessage()
{
    if(window.popupDivLoadingMessage != null && document.getElementById(window.popupDivLoadingMessage.id) != null)
        document.body.removeChild(window.popupDivLoadingMessage);
	NLPopupAutoSuggest_hidePopupSuggestion();
}

function NLPopupSelect_init(bMultiselect, bIsMultiButton, bListOnly, bPositionWithMachine, bShowQuantities)
{
    NLPopupSelect_close();
    var outerDiv = document.createElement("DIV");
    outerDiv.style.zIndex  = 1000;
    outerDiv.id            = 'popup_outerdiv';
    outerDiv.className     = 'popupouter';
    outerDiv.setAttribute("bIsMultiButton", (bIsMultiButton ? "T" : "F") );
    outerDiv.setAttribute("bListOnly", (bListOnly ? "T" : "F") );
    outerDiv.setAttribute("bMultiselect", (bMultiselect ? "T" : "F") );
    outerDiv.setAttribute("bPositionWithMachine", (bPositionWithMachine ? "T" : "F") );
	outerDiv.setAttribute("bShowQuantities", (bShowQuantities ? "T" : "F") );
    document.body.appendChild(outerDiv);
    window.popupDIV = outerDiv;
    if(isIE)
    {
        if (window.addEventListener)
        {
            window.addEventListener("onresize", new Function("NLPopupSelect_reposition();"));
        }
        else
        {
            window.attachEvent("onresize", new Function("NLPopupSelect_reposition();"));
        }
    }
}

function NLPopupSelect_reposition()
{
    if(window.popupDIV != null)
        NLPopupSelect_positionDIV();
}

function NLPopupSelect_open(fieldName, machineName)
{
    if(window.popupDIV != null)
    {
        var bIsMultiButton = window.popupDIV.getAttribute('bIsMultiButton')=="T";
        var bListOnly = window.popupDIV.getAttribute('bListOnly')=="T";
        var bMultiselect = window.popupDIV.getAttribute('bMultiselect')=="T";
        window.popupDIV.setAttribute("fieldName", fieldName);
        if( machineName != null )
            window.popupDIV.setAttribute("machineName", machineName);

        
        var imageId = fieldName + ( bListOnly ? "_popup_listonly" : bIsMultiButton ? "_popup_multi" : "_popup_list") ;
        var img  = NLPopupSelect_getLaunchButton(imageId, bIsMultiButton, bListOnly);
        if(img != null && img.nodeName == "IMG")
        {
            window.popupDIV.setAttribute('launchbutton',imageId);
        }

        if (bMultiselect && (typeof top.popupAnchorId != "undefined" && top.popupAnchorId != null && document.getElementById(top.popupAnchorId) != null))
            window.popupDIV.setAttribute('displayField', top.popupAnchorId);

        
        if(!bMultiselect && document.getElementById(fieldName + "_display") != null)
            window.popupDIV.setAttribute('displayField', (fieldName + "_display") );

        NLPopupSelect_positionDIV();
        window.popup_onClickHandler = NLPopupSelect_onClick;

        
        if (isIE)
            nlInsertCanvas(window.popupDIV);
    }
}

function NLPopupSelect_getLaunchButton(imageId, bIsMultiButton, bListOnly)
{
    var img  = document.getElementById(imageId);
    if(img != null && !bIsMultiButton && !bListOnly)
        img = img.firstChild;
    return img;
}

function NLPopupSelect_getDisplayField(displayFieldName, doc)
{
    var popupSelectDoc = doc ? doc : document;
    return popupSelectDoc.getElementById(displayFieldName);
}

function NLPopupSelect_getDisplayFieldByValueInput(sel)
{
    var displayFieldName = sel.name+'_display';
    var field = getFormElement(sel.form, displayFieldName);
    if (!field)
        field = NLPopupSelect_getDisplayField(displayFieldName, sel.ownerDocument);
    return field;
}

function NLPopupSelect_displayLoadingDiv(fieldName, bMultiselect, sMessage)
{
    if(window.popupDivLoadingMessage == null)
    {
        var div = document.createElement("DIV");
        div.id = "popup_load_message";
        div.style.backgroundColor = "white";
        div.style.position = "absolute";
        div.style.borderWidth='1px';
        div.style.borderStyle='solid';
        div.style.borderColor='black';
        div.style.width = "150px";
        window.popupDivLoadingMessage = div;
    }
	var msg = sMessage == null ? "Loading" : sMessage;
    window.popupDivLoadingMessage.innerHTML = "<table width='100%'><tr><td valign='middle' class='texttablectr'>"+msg+"</td></tr></table>";
    document.body.appendChild(window.popupDivLoadingMessage);
    var dispFld  = document.getElementById(fieldName + "_display");
    var top = 0;
    var left = 0;

    
    var scrollDiv = findClassUp(dispFld,'scrollarea');
    var scrollTopOffset = 0;
    var scrollLeftOffset = 0;
    if(scrollDiv!=null)
    {
        scrollTopOffset = scrollDiv.scrollTop;
        scrollLeftOffset = scrollDiv.scrollLeft;
    }

    if(dispFld != null && !bMultiselect)
    {
        top = findAbsolutePosY(dispFld) + dispFld.offsetHeight - 1 - scrollTopOffset;
        left = findAbsolutePosX (dispFld) - scrollLeftOffset;
        window.popupDivLoadingMessage.style.width = Math.max(75,dispFld.offsetWidth) + "px";
    }
    else
    {
        top = Math.max(lastY,10) + document.body.scrollTop;
        left = Math.max(lastX,10) + document.body.scrollLeft;
    }

    if( (top + 30) > (getDocumentHeight() + document.body.scrollTop - 10) )
        top = getDocumentHeight() + document.body.scrollTop - 30;
    if( (left + 150) > (getDocumentWidth() + document.body.scrollLeft - 10) )
        left = getDocumentWidth() + document.body.scrollLeft - 175;
    window.popupDivLoadingMessage.style.left = left + "px";
    window.popupDivLoadingMessage.style.top = top + "px";
    window.popupDivLoadingMessage.style.zIndex = 10;
}

function NLPopupSelect_onClick(evnt)
{
    
        var popupDiv = window.popupDIV
        if(  popupDiv != null )
        {
            var target = getEventTarget(evnt);
            var div = findClassUp(target,'popupouter');

            if ( div == null || div != popupDiv || target.title == 'Close' )
            {
                NLPopupSelect_close();
            }
        }
    
}

function NLPopupSelect_close(bFocusNextField)
{
    var popupWindow = window;
    while(((popupWindow.popupDIV == null) || (typeof popupWindow.popupDIV == 'undefined')) && (popupWindow != window.parent))
        popupWindow = window.parent;

    var popupDIV = popupWindow.popupDIV;
    if((popupWindow.popupDIV == null) || (typeof popupWindow.popupDIV == 'undefined'))
        return;

    
    if (isIE)
        nlRemoveCanvas(popupDIV);

    if(popupDIV.getAttribute('launchbutton') != null && popupDIV.getAttribute('bIsMultiButton')=="F")
    {
        var img = NLPopupSelect_getLaunchButton(popupDIV.getAttribute('launchbutton'), popupDIV.getAttribute('bIsMultiButton')=="T", popupDIV.getAttribute('bListOnly')=="T");
    }
    jQuery("#" + popupDIV.id).remove();

     
    if(bFocusNextField)
    {
        var dispFld  = popupWindow.document.getElementById(popupDIV.getAttribute("fieldName") + "_display");
        if (dispFld != null)
            NLPopupSelect_focusNextInputField(dispFld.name, dispFld.form, true);
    }

    popupWindow.popupDIV = null;
}


function NLPopupSelect_getElementOrFromParent(elementID)
{
	var elem = document.getElementById(elementID);
	if(elem == null)
		elem = parent.document.getElementById(elementID);
	return elem;
}

function NLPopupSelect_addSelection(value, label)
{
    var selectDiv = NLPopupSelect_getElementOrFromParent("popup_select_list");
    var tableElem = selectDiv.firstChild;
    NLPopupSelect_addSelectionRow(value, label, tableElem, selectDiv);
}

function NLPopupSelect_addSelectionRow(value, label, tableElem, scrollDiv)
{
	var bQuantity = window.popupDIV.getAttribute('bShowQuantities')=="T";
    var tr = document.createElement("tr");
    tr.className = "multiselecttr";
    var td = document.createElement("td");
    td.className = "text";
    td.style.width = "14px";
    td.style.whitespace = "nowrap";
    td.style.verticalAlign = bQuantity ? "top" : "middle";
    td.style.align = "right";
    var anchor = document.createElement("a");
    anchor.href = "javascript:void(0)";
    
    value = value.replace(/'/g,"\\'");
    anchor.onclick = new Function("NLPopupSelect_updateSelection('"+value+"','', false, this); return false;");
    var btnx = document.createElement("img");
    btnx.className = "uir-popup-x-icon";
    btnx.border = "0";
    btnx.height = 13;
    btnx.width = 13;
    btnx.src = "/images/x.gif";
    anchor.appendChild(btnx);
    td.appendChild(anchor);
    tr.appendChild(td);
    td = document.createElement("td");
    td.className = "text";
    if (bQuantity)
        td.style.verticalAlign = "top";
	// lot/multi items will be formatted as "lot/item(quantity)".  Separate the lot/item from the quantity
	var quantity = null;
	if (window.popupDIV.getAttribute('bShowQuantities')=="T")
	{
		var itemArray = NLPopupSelect_getQuantityArray(label);
		if (itemArray != null)
		{
			label = itemArray[0];
			quantity = itemArray[1];
		}
	}

	td.innerHTML = label;
	tr.appendChild(td);

    // add an extra field to allow for the entry of quantities
	if (window.popupDIV.getAttribute('bShowQuantities')=="T")
	{
		var quantitytd = document.createElement("td");
		quantitytd.className = "text";
		quantitytd.style.whitespace = "nowrap";
		quantitytd.style.verticalAlign = "top";
		quantitytd.style.align = "right";
		quantitytd.innerHTML = "<input class=input type=text name='quantity_"+value+"' size=4 value='"+(quantity != null ? quantity : "")+"' onChange='NLPopupSelect_updateQuantity(\""+value+"\",this.value)'>";
		tr.appendChild(quantitytd);
	}
	if(tableElem.rows.length == (bQuantity ? 2 : 1) && tableElem.rows[bQuantity ? 1 : 0].className == "noselections")
		tableElem.deleteRow(bQuantity ? 1 : 0);
	tableElem.firstChild.appendChild(tr);
	if(scrollDiv != null && (scrollDiv.scrollHeight > scrollDiv.offsetHeight) )
        scrollDiv.scrollTop = (scrollDiv.scrollHeight - scrollDiv.offsetHeight);

    return tr;
}

/* Given a value in the form "lot/item(quantity)", returns a
   2-element array where the first element is the lot/item number and
   the second element is the quantity.  If the value is not of
   the form "lot/item(quantity)", returns a 2-element array where the
   first element is the value passed and the second element is empty. */
function NLPopupSelect_getQuantityArray(value)
{
	var re = new RegExp('^\\s*(\\S+)\\s*\\(\\s*(-?\\d+\\.?\\d*)\\s*\\)\\s*$');
	var matchArr = re.exec(value);
	if (matchArr != null)
	{
		return new Array(matchArr[1], matchArr[2]);
	}
	else
	{
		return new Array(value,'');
	}
}

/* given a lot/item number and a quantity, returns
   a string of the form "lot/item(quantity)" */
function NLPopupSelect_getQuantityText(item, quantity)
{
    quantity = NLStringToNumber(quantity);
    if (isNaN(quantity))
        return item;
    else
        return item + "(" + quantity + ")";
}

/* Updates the multiselect hidden data when a lot/item quantity is
   entered */
function NLPopupSelect_updateQuantity(item, quantity)
{
	var form = NLPopupSelect_getElementOrFromParent("multisel_complete");
	var datafld = form.elements['_mdata'];
	var labelfld = form.elements['_mlabels'];
	var selvals = trim(datafld.value), sellabels = trim(labelfld.value);
	var vals = selvals.split(String.fromCharCode(5)), labels = sellabels.split(String.fromCharCode(5));
	var bFoundItem = false;
	for (var i = 0; i < vals.length; i++)
	{
		var itemArray = NLPopupSelect_getQuantityArray(vals[i]);
		if (itemArray[0] == item)
		{
			bFoundItem = true;
			vals[i] = NLPopupSelect_getQuantityText(item,quantity);
			labels[i] = vals[i];
		}
	}
	if (bFoundItem)
	{
		datafld.value = vals.join(String.fromCharCode(5));
		labelfld.value = labels.join(String.fromCharCode(5));
	}
}


var nlpopupselect_removerow = null;
function NLPopupSelect_removeSelection(value, anchorElement)
{
	var mainTable = NLPopupSelect_getElementOrFromParent("popup_select_list").firstChild;
    	var remove_tr = findClassUp(anchorElement,"multiselecttr");
	nlpopupselect_removerow = remove_tr;
	setTimeout("NLPopupSelect_removeRowAfterTimeout()",1);
}

function NLPopupSelect_removeRowAfterTimeout()
{
	var mainTable = nlpopupselect_removerow.parentNode.parentNode;
	nlpopupselect_removerow.parentNode.deleteRow(nlpopupselect_removerow.rowIndex);
	NLPopupSelect_insertNoSelectionRow(mainTable.firstChild);
	nlpopupselect_removerow = null;
}

function NLPopupSelect_insertNoSelectionRow(tbody)
{
	var bQuantity = window.popupDIV.getAttribute('bShowQuantities')=="T";
    var bAddNoSelectionRow = tbody.rows.length == (bQuantity ? 1 : 0);
    if(bAddNoSelectionRow)
    {
        var tr = document.createElement("tr");
        var td = document.createElement("td");
        tr.className = "noselections";
        td.className = "textctr";
        td.innerHTML = "No Selections Made";
        if (bQuantity)
            td.colSpan = 3;
        tr.appendChild(td);
        tbody.appendChild(tr);
        
		var form = NLPopupSelect_getElementOrFromParent("multisel_complete");
		form.elements['_mdata'].value = '';
		form.elements['_mlabels'].value = '';
    }
}

function NLPopupSelect_updateSelection(value, label, adding, anchorElement)
{
	var form = NLPopupSelect_getElementOrFromParent("multisel_complete");
    var datafld = form.elements['_mdata'];
    var labelfld = form.elements['_mlabels'];
    var selvals = trim(datafld.value), sellabels = trim(labelfld.value);
    var vals, labels;
    if (isValEmpty(selvals))
    {
        vals = new Array();
        labels = new Array();
    }
    else
    {
        vals = selvals.split(String.fromCharCode(5));
        labels = sellabels.split(String.fromCharCode(5));
    }

    var updateSelectWindow = false;

    
    if (adding)
    {
        var addpair = true;
        for (i=0; i < vals.length; i++)
        {
            var itemId = null;
            var parenthesisPosition = vals[i].indexOf("(");

            
            if (parenthesisPosition > 0)
            {	//quantity is present, remove it
                itemId = vals[i].substring(0, parenthesisPosition);
            }
            else
            {	//vals[i] contains only the ID
                itemId = vals[i];
            }

            
            if (itemId == value)
            {	//prevent the item to be added again
                addpair = false;
                break;
            }
        }
        var bCanAdd = (typeof NLPopupSelect_canAddSelection == "undefined" || NLPopupSelect_canAddSelection == null) ? true : NLPopupSelect_canAddSelection(value, label, vals);
        if (addpair && bCanAdd)
        {
            if (selvals == '')
            {
                labelfld.value = label;
                datafld.value = value;
            }
            else
            {
                datafld.value += String.fromCharCode(5) + value;
                labelfld.value += String.fromCharCode(5) + label;
            }
			updateSelectWindow = true;
            NLPopupSelect_addSelection(value, label);
        }
    }
    
    else
    {
        var bQuantity = window.popupDIV.getAttribute('bShowQuantities')=="T";
        updateSelectWindow = true;
        var numParams = 0;
        datafld.value='';
        labelfld.value='';
        for (i=0; i < vals.length; i++)
        {
            if (vals[i] == value || (bQuantity && NLPopupSelect_getQuantityArray(vals[i])[0] == value))
            {
                NLPopupSelect_removeSelection(value, anchorElement);
                continue;
            }
            else
            {
                datafld.value += (numParams==0 ? '' : String.fromCharCode(5)) + vals[i];
                labelfld.value += (numParams==0 ? '' : String.fromCharCode(5)) + labels[i];
                numParams++;
            }
        }
    }
}


function NLPopupSelect_focusNextInputField(currentFieldName, form, bSelectField)
{
	try
	{
        if( currentFieldName == null || form == null)
            return;

        var bFoundCurrentField = false;
        for(var i=0; i<form.elements.length; i++)                           //>
        {
            
            if(!bFoundCurrentField)
            {
                if(form.elements[i].name == currentFieldName)
                    bFoundCurrentField = true;
                continue;
            }

            var input = form.elements[i]
            
            if ( isFocusable(input) )
            {
                
                if (isNLDropDown(input))
                    setSelectFocus(input);
                else if (input.focus)
                   input.focus();
                if(bSelectField && input.select)
                    input.select();
                
                return;
            }
        }
	}
	catch(e)
	{
		
	}
}


function setSafeBlurValue(fldid,val)
{
	var s="document.getElementById('"+fldid+"').value='"+val+"'";
	setTimeout(s,0);
}



function setButtonDown(isDown, isLower, btn)
{
    var bodyTr = btn.parentNode.parentNode;
	if (isDown)	{
		if (bodyTr.className.indexOf("_sel") == -1)
        {
		   bodyTr.className = bodyTr.className.split(" ").join("_sel ") + "_sel";
        }
	}
	else {
	   bodyTr.className = bodyTr.className.replace(/_sel/g, "");
	}
}

function onTristateClick(img)
{
  setTristate(img, img.nextSibling.value + 1);
}

function onTristateHighlight(img,on)
{
  var input = img.nextSibling;
  img.src = '/images/icons/controls/checkbox_' + (input.value & 3) + (on ? '_hl.gif' : '.gif');
  return true;
}

function setTristate(img, newValue)
{
  
  var input = img.nextSibling;
  input.value = 4 | (newValue % 3);
  img.src = '/images/icons/controls/checkbox_' + (input.value & 3) + '.gif';
  return true;
}

function disableLineRefresh(anchor)
{
    anchor.disabled = true;
    anchor.firstChild.src = "/images/icons/dashboard/refresh_line_disabled.gif";
}

function doNewbarAction(elemName)
{
    var elem = document.getElementById(elemName);
    if( elem != null && elem.onclick )
    {
        elem.onclick();
    }
}

function nlQuickLooksPopup(role_name)
{
    var dest='/images/guide/quicklooks.html?'+role_name;
    var newWin = window.open(dest,'popupguide','toolbar=no,statusbar=no,menubar=no,resizable=no,left=1,top=1,height=700,width=300');
    newWin.focus();
}

var Class =
{
    create: function()
    {
        return function()
        {
            this.initialize.apply(this, arguments);
        }
    }
}

NLProgressBar = Class.create();
NLProgressBar.prototype =
{
    initialize: function(sId)
    {
        this.hndDialogDiv = null;
        this.sId = sId || "NLProgressBar";
    },

    show: function(msg)
    {
        var posX = jQuery(document).width() / 2;
        var posY = jQuery(document).height() / 2;

        if (!this.hndDialogDiv)
        {
            this.hndDialogDiv = document.createElement("div");
            var sHTML = '<table style="font-size:70%;" cellpadding=0 cellspacing=0 border=0 width=350>' +
                        '    <tr>' +
                        '        <td colspan=3><IMG SRC="/images/icons/progress/progress_waitBar_top.gif" ALT="" WIDTH=350 HEIGHT=10 BORDER=0></td>' +
                        '    </tr>' +
                        '    <tr>' +
                        '        <td background="/images/icons/progress/progress_waitBar_l.gif"><IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=4 HEIGHT=1 BORDER=0></td>' +
                        '        <td bgcolor="#F1F1F1" align=center>' +
                        '            <IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=342 HEIGHT=4 BORDER=0><br>' +
                        '            <table cellpadding=0 cellspacing=0 border=0>' +
                        '                <tr><td colspan=2  style="font-size:70%;">' + msg + '</td></tr>' +
                        '                <tr><td colspan=2><IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=1 HEIGHT=3 BORDER=0></td></tr>' +
                        '                <tr>' +
                        '                    <td align=center><IMG SRC="/images/icons/progress/progress_waitBar.gif" ALT="" WIDTH=249 HEIGHT=20 BORDER=0></td>' +
                        '                    <td>&nbsp;</td>' +
                        '                </tr>' +
                        '                <tr><td colspan=2><IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=1 HEIGHT=10 BORDER=0></td></tr>' +
                        '            </table>' +
                        '        </td>' +
                        '        <td background="/images/icons/progress/progress_waitBar_r.gif"><IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=4 HEIGHT=1 BORDER=0></td>' +
                        '    </tr>' +

                        '    <tr>' +
                        '        <td background="/images/icons/progress/progress_waitBar_l.gif"><IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=4 HEIGHT=1 BORDER=0></td>' +
                        '        <td bgcolor="#F1F1F1" align=center>' +
                        '            <IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=342 HEIGHT=10 BORDER=0><br>' +
                        '        </td>' +
                        '        <td background="/images/icons/progress/progress_waitBar_r.gif"><IMG SRC="/images/icons/progress/progress_x.gif" ALT="" WIDTH=4 HEIGHT=1 BORDER=0></td>' +
                        '    </tr>' +

                        '    <tr>' +
                        '        <td colspan=3><IMG SRC="/images/icons/progress/progress_waitBar_bot.gif" ALT="" WIDTH=350 HEIGHT=10 BORDER=0></td>' +
                        '    </tr>' +
                        '</table>';
            this.hndDialogDiv.innerHTML = sHTML;
            this.hndDialogDiv.style.display = "none";
            this.hndDialogDiv.style.zIndex = "1000";
            this.hndDialogDiv.style.position = "absolute";
            document.body.appendChild(this.hndDialogDiv);
        }
        if (this.hndDialogDiv.style.display == "block")
            return;
        this.hndDialogDiv.style.display = "block";
        this.hndDialogDiv.style.top = posY - (this.hndDialogDiv.clientHeight / 2) + "px";
        this.hndDialogDiv.style.left = posX - (this.hndDialogDiv.clientWidth / 2) + "px";
    },

    hide: function()
    {
        if (this.hndDialogDiv != null)
            this.hndDialogDiv.style.display = "none";
    }
}

function getIFrameDocument(aID)
{
    var rv = null;

    // if contentDocument exists, W3C compliant (Mozilla)
    if (document.getElementById(aID).contentDocument)
    {
        rv = document.getElementById(aID).contentDocument;
    }  else
    {
        // IE
        rv = document.frames[aID].document;
    }

    return rv;
}

function getIFrameWindow(aID)
{
    var rv = null;

    // if contentDocument exists, W3C compliant (Mozilla)
    if (document.getElementById(aID).contentWindow)
    {
        rv = document.getElementById(aID).contentWindow;
    }  else
    {
        // IE
        rv = document.frames[aID].window;
    }

    return rv;
}


/**
 * Notify portlet of dragdrop events
 * Can add more parameters in the future as part of a generic notificatiion mechanism.
 */
function notifyPortlet(portletId, portletEvent)
{
    if (portletId == "-10018" )
    {
        if(window['schedulersef'] != "undefiined" && window['schedulersef'] != null)
        {
            if (portletEvent == EVENT_PORTLET_MIN)
                window['schedulersef'].handlePortletMin();
            else if (portletEvent == EVENT_PORTLET_MAX)
                window['schedulersef'].handlePortletMax();
            else if (portletEvent == EVENT_PORTLET_MOVE)
                window['schedulersef'].handlePortletMove();
            else if (portletEvent == EVENT_PORTLET_DROP)
                window['schedulersef'].handlePortletDrop();
            else if (portletEvent == EVENT_PORTLET_DRAG)
                window['schedulersef'].handlePortletDrag();
        }
    }
}

/**
 * To enable or disable an image button
 * An image button is an anchor tag with an image tag in it
 * "disabled" is just a flag, it will not prevent mouse events from firing. All image button event handlers need
 * to check this flag to process properly.
 * @param buttonId The id of the button
 * @param bEnabled To enable or disable the button
 * @param imageUrl a string that represents a url to the image for the enabled/disabled state
 * @param scope The window/frame that the button is in
  */
function setImageButtonState(buttonId, bEnabled, imageUrl, scope)
{
    var doc = document;
    if (typeof scope != "undefined" && scope != null)
        doc = scope.document;


    //get the anchor object
    var elem = doc.getElementById(buttonId);

    if (elem == null)
        return;

    elem.disabled = !bEnabled;

    if (typeof imageUrl == "undefined" && imageUrl == null)
        return;


    elem = elem.getElementsByTagName("img")[0];
    if (elem)
        elem.src = imageUrl;
}

/**
 * To enable or disable a multi button
 * @param buttonId The id of the button
 * @param bEnabled To enable or disable the button
 */
function setMultiButtonState(buttonId, bEnabled)
{
    var multiButton = getNLMultiButtonByName(buttonId);

    if (multiButton != null)
    {
        multiButton.setState(bEnabled);
    }
}

/**
 * To set enabled or disabled look and feel of an label. The label is assumed to be put in a div or span tag
 * @param labelId The id of the label
 * @param className the style sheet class to be used
 * @param scope The window/frame that the button is in
  */
function setLabelState(labelId, className, scope)
{
    var doc = document;
    if (typeof scope != "undefined" && scope != null)
        doc = scope.document;

    //get the label container
    var elem = doc.getElementById(labelId);

    if (elem == null)
        return;

    elem.className = className;

}

function setNewbarGif(bUp)
{
    var moreImage = document.getElementById("img_newbar_more");
    if(moreImage != null)
	{
		if (bUp)
			moreImage.className = 'ri_personalize';
		else
			moreImage.className = 'ri_personalize_hover';
	}
}

<!-- Spinner Stuff!!!!!!!!!!!!!!-->
var allSpinners = new Array();
var spinnerCounter = 0;
var NLSpinner = Class.create();
NLSpinner.prototype =
{
    initialize: function(sTagName, initialValue, step, lowerBound, upperBound)
    {
        this.sTagName = sTagName;

        this.currentValue=initialValue;
        this.step = step;
        this.lowerBound = parseFloat(lowerBound);
        this.upperBound = parseFloat(upperBound);

        this.interval = parseInt(500);
        this.repeatInterval = parseInt(200);
        this.timer=null;
		this.direction = 1;
	},
    _step: function()
    {
        if (this.direction >= 0)
			var temp = parseFloat(parseFloat($(this.sTagName).value) + parseFloat(this.step));
		else
			var temp = parseFloat(parseFloat($(this.sTagName).value) - parseFloat(this.step));

		if (temp>this.upperBound)
            temp=this.upperBound;
        else if (temp<this.lowerBound)
            temp=this.lowerBound

		$(this.sTagName).value = parseFloat(temp);
	},
	_mousedown:function(z)
	{
		this._step();
		var x = this._mousedown.bind(this, 'F');
		this.timer = setTimeout(x, (z=='T'?this.interval:this.repeatInterval));
	},
	_releasemouse: function()
	{
	  if (this.timer)
		{
			clearTimeout(this.timer);
			this.timer=null;
			$(this.sTagName).onchange();
		}
  	  if (this.direction >= 0)
			$(this.sTagName + '_rarrow').setAttribute('src', '/images/forms/rarrow.gif');
	  else
			$(this.sTagName + '_larrow').setAttribute('src', '/images/forms/larrow.gif');

		//invoke onchange
	},
	_scrollUp:function ()
	{
		this.direction=1;
		$(this.sTagName + '_rarrow').setAttribute('src', '/images/forms/rarrow_down.gif');
		this._mousedown('T');
	},
	_scrollDown:function ()
	{
		this.direction=-1;
		$(this.sTagName + '_larrow').setAttribute('src', '/images/forms/larrow_down.gif');
		this._mousedown('T');
	}

}
function makeSpinner(sTagName, initialValue, step, min, max)
{
    var s = new NLSpinner(sTagName, initialValue, step, min, max);

	$(sTagName).value=initialValue;

	//Left Arrow
	var limage = document.createElement('img');
	limage.setAttribute('id', sTagName + '_larrow');
	limage.setAttribute('src', '/images/forms/larrow.gif');
	$(sTagName+'_fs').appendChild(limage);

	$(sTagName + '_larrow').onmousedown = function() {s._scrollDown();};
	$(sTagName + '_larrow').onmouseup   = function() {s._releasemouse();};
	$(sTagName + '_larrow').onmouseout  = function() {s._releasemouse();};

	//Right Arrow
	var rimage = document.createElement('img');
	rimage.setAttribute('id', sTagName + '_rarrow');
	rimage.setAttribute('src', '/images/forms/rarrow.gif');
	$(sTagName+'_fs').appendChild(rimage);

	$(sTagName + '_rarrow').onmousedown = function() {s._scrollUp();};
	$(sTagName + '_rarrow').onmouseup   = function() {s._releasemouse();};
	$(sTagName + '_rarrow').onmouseout  = function() {s._releasemouse();};

	spinnerCounter++;
    var nameC = sTagName + spinnerCounter;
    if ( window.allSpinners[nameC] == null )
		window.allSpinners[nameC] = s;

    return s;
}


function NLDragDrop (sourceElem, listener, doc)
{
    this.doc = doc ? doc : document;
    this.sourceElem = sourceElem;

    this.listener = listener;

    this.eventSource = null;
    this.bInitDrag = true;

    if (window.loadcomplete)
        this.attachEventHandlers(sourceElem);
    else
        attachEventHandler ("load", window, function(evnt){this.attachEventHandlers();}.bind(this));
}

NLDragDrop.prototype.attachEventHandlers = function NLDragDrop_attachEventHandlers()
{
    if (typeof this.sourceElem == "string")
        this.sourceElem = doc.getElementById(sourceElem);
    if (!this.sourceElem)
        return;
    attachEventHandler ("mousedown", this.sourceElem, function(evnt){ this.handleMouseDown(evnt);}.bind(this));
    attachEventHandler ("mousemove", this.doc, function(evnt){ this.handleMouseMove(evnt);}.bind(this));
    attachEventHandler ("mouseup", this.doc, function(evnt){ this.handleMouseUp(evnt);}.bind(this));
}

NLDragDrop.prototype.handleMouseDown = function NLDragDrop_handleMouseDown(evnt)
{
    var evnt = getEvent(evnt);
    this.eventSource = getEvent(evnt);

    if (!this.onMouseDown(evnt))
        return true;

    var evnt = getEvent(evnt);

    this.mouseDown = true;

    return true;
}

NLDragDrop.prototype.handleMouseMove = function NLDragDrop_handleMouseMove(evnt)
{
    if (!this.mouseDown)
        return true;

    var evnt = getEvent(evnt);
    var bContinue = true;
    if (this.bInitDrag)
        bContinue = this.onInitMouseMove(evnt);

    if (bContinue)
        this.bInitDrag = false;
    else
    {
        this.clear();
        evnt.cancelBubble = true;
        evnt.returnValue=false;
        return false;
    }

    this.onMouseMove(evnt);

    evnt.cancelBubble = true;
    evnt.returnValue=false;
    return false;
}

NLDragDrop.prototype.handleMouseUp = function NLDragDrop_handleMouseUp(evnt)
{
    if (!this.mouseDown)
        return true;

    var evnt = getEvent(evnt);

    this.onMouseUp(evnt);

    this.clear();
    evnt.cancelBubble = true;
    evnt.returnValue=false;
    return false;
}

NLDragDrop.prototype.clear = function NLDragDrop_clear()
{
    this.mouseDown = false;
    this.eventSource = null;
    this.bInitDrag = true;
}


NLDragDrop.prototype.onMouseDown = function NLDragDrop_onMouseDown(evnt)
{
    if (this.listener && this.listener.onMouseDown)
        return this.listener.onMouseDown(evnt);

    return true;
}


NLDragDrop.prototype.onInitMouseMove = function NLDragDrop_onInitMouseMove(evnt)
{
    if (this.listener && this.listener.onInitMouseMove)
        return this.listener.onInitMouseMove(evnt);

    return true;
}


NLDragDrop.prototype.onMouseMove = function NLDragDrop_onMouseMove(evnt)
{
    if (this.listener && this.listener.onMouseMove)
        return this.listener.onMouseMove(evnt);

    return true;
}


NLDragDrop.prototype.onMouseUp = function NLDragDrop_onMouseUp(evnt)
{
    if (this.listener && this.listener.onMouseUp)
        return this.listener.onMouseUp(evnt);

    return true;
}

var NLDRAG_LEFT = 1;
var NLDRAG_RIGHT = 2;
var NLDRAG_LEFT_RIGHT = 3;
var NLDRAG_UP = 4;
var NLDRAG_DOWN = 8;
var NLDRAG_UP_DOWN = 12;




function NLAttachSimpleColumnResizer(triggerElem, targetElem, direction, min, max, listener, doc)
{
    return new NLSimpleColumnResizer (triggerElem, targetElem, direction, min, max, listener, doc);
}


function NLSimpleColumnResizer (triggerElem, targetElem, direction, min, max, listener, doc)
{
    doc = doc ? doc : document;

    this.triggerElem = (typeof triggerElem == "string") ? doc.getElementById(triggerElem) : triggerElem;
    this.targetElem =  (typeof targetElem == "string") ? doc.getElementById(targetElem) : targetElem;

    new NLDragDrop (this.triggerElem, this, doc);

    this.direction = (direction == NLDRAG_UP_DOWN) ? NLDRAG_UP_DOWN : NLDRAG_LEFT_RIGHT;
    this.min = min >= 0? min : 0;
    this.max = (max >= 0 && max > min) ? max : Number.MAX_VALUE;
    this.listener = listener;
    this.initVal = null;

    this.sCursor =  this.direction == NLDRAG_UP_DOWN ? "n-resize" : "w-resize";
    this.setCursor(this.sCursor, this.triggerElem);

}

NLSimpleColumnResizer.prototype.getValue = function NLSimpleColumnResizer_getValue(evnt)
{
    if(this.direction == NLDRAG_LEFT_RIGHT)
        return getMouseX(evnt);
    else if (this.direction == NLDRAG_UP_DOWN)
        return getMouseY(evnt);

    return null;
}

NLSimpleColumnResizer.prototype.onMouseDown = function NLSimpleColumnResizer_onMouseDown(evnt)
{
    var source = getEventTarget(evnt);
    if(!contains (this.triggerElem, source))
        return false;

    this.initVal = this.getValue(evnt);

    if (!this.canResize(evnt))
        return false;

    return true;
}

NLSimpleColumnResizer.prototype.onInitMouseMove = function NLSimpleColumnResizer_onInitMouseMove(evnt)
{
    var evnt = getEvent(evnt);

    if (this.listener && this.listener.onStartResize)
        this.dragDiv = this.listener.onStartResize(evnt, this);
    else
        this.startResize(evnt, this);

    return true;
}

NLSimpleColumnResizer.prototype.onMouseMove = function NLSimpleColumnResizer_onMouseMove(evnt)
{
    var evnt = getEvent(evnt);

    if (!this.canResize(evnt))
        return false;

    if (this.listener && this.listener.onResize)
        this.listener.onResize(evnt, this);
    else
        this.resize(evnt);
    return true;
}

NLSimpleColumnResizer.prototype.onMouseUp = function NLSimpleColumnResizer_onMouseUp(evnt)
{
    var evnt = getEvent(evnt);
    if (this.listener && this.listener.onEndResize)
        this.listener.onEndResize(evnt, this);
    else
        this.endResize(evnt);

    this.resetCursor();
}

NLSimpleColumnResizer.prototype.canResize = function NLSimpleColumnResizer_canResize(evnt)
{
    if (this.listener && this.listener.onCanResize)
        return this.listener.onCanResize(evnt, this);

    var delta = this.getValue(evnt) - this.initVal;
    var val = (this.direction == NLDRAG_LEFT_RIGHT) ? this.targetElem.offsetWidth : this.targetElem.offsetHeight;

    var newVal = val + delta;

    if (newVal >= this.min && newVal <= this.max)
        return true;
    
    else if (newVal < this.min && delta > 0)
        return true;
    else if (newVal > this.max && delta < 0)
        return true;

    return false;
}

NLSimpleColumnResizer.prototype.startResize = function NLSimpleColumnResizer_startResize(evnt)
{
	this.setCursor(this.sCursor);
	this.showDragDiv(evnt);
}

NLSimpleColumnResizer.prototype.resize = function NLSimpleColumnResizer_resize(evnt)
{
    this.positionDragDiv(evnt);
}

NLSimpleColumnResizer.prototype.endResize = function NLSimpleColumnResizer_endResize(evnt)
{
    var newValue = null;
    if (this.direction == NLDRAG_LEFT_RIGHT)
        newValue = this.targetElem.offsetWidth + this.getValue(evnt) - this.initVal;
    else
        newValue = this.targetElem.offsetHeight + this.getValue(evnt) - this.initVal;

    if (newValue > this.max)
        newValue = this.max;
    else if (newValue < this.min)
        newValue = this.min;

    if (this.direction == NLDRAG_LEFT_RIGHT)
        this.targetElem.style.width = newValue + "px";
    else
        this.targetElem.style.height = newValue + "px";

    this.cleanUp();
}


NLSimpleColumnResizer.prototype.showDragDiv = function NLSimpleColumnResizer_showDragDiv(evnt)
{
	if(this.dragDiv == null)
	{
		this.dragDiv = document.createElement("div");
		this.dragDiv.style.position = "absolute";
		var image = document.createElement("img");
		image.src = "/images/nav/stretch.gif";
		image.width = "3";
		this.dragDiv.appendChild(image);
		this.dragDiv.style.backgroundColor = "#999999";
		setObjectOpacity(80, this.dragDiv);
		document.body.appendChild(this.dragDiv);
	}
    if (this.direction == NLDRAG_LEFT_RIGHT)
    {
        this.dragDiv.style.top = findPosY(this.targetElem) + "px";
        this.dragDiv.firstChild.height = this.targetElem.offsetHeight;
    }
    else
    {
        this.dragDiv.style.left = findPosX(this.targetElem) + "px";
        this.dragDiv.firstChild.width = this.targetElem.offsetWidth;
    }
    this.dragDiv.style.display = "";
	this.positionDragDiv(evnt);
}

NLSimpleColumnResizer.prototype.cleanUp = function NLSimpleColumnResizer_cleanUp()
{
    this.hideDragDiv();
    this.initVal = null;
}

NLSimpleColumnResizer.prototype.hideDragDiv = function NLSimpleColumnResizer_hideDragDiv()
{
	this.dragDiv.style.display = "none";
}

NLSimpleColumnResizer.prototype.positionDragDiv = function NLSimpleColumnResizer_positionDragDiv(evnt)
{
    var val = this.getValue(evnt);

    if (this.direction == NLDRAG_LEFT_RIGHT)
        this.dragDiv.style.left = val + "px";
    else
        this.dragDiv.style.top = val + "px";
}

NLSimpleColumnResizer.prototype.setCursor = function NLSimpleColumnResizer_setCursor(sCursor, elem)
{
    if (!elem)
        elem = document.body;

    if (!elem.origCursor)
        elem.origCursor = elem.style.cursor;
    elem.style.cursor = sCursor;
}

NLSimpleColumnResizer.prototype.resetCursor = function NLSimpleColumnResizer_restoreCursor(elem)
{
    if (!elem)
        elem = document.body;

    if (elem.origCursor && elem.origCursor.length > 0)
    {
        elem.style.cursor = "default";
        elem.origCursor = null;
    }
    else
        elem.style.cursor = "default";
}


function closeBanner(id) {
   var uibanner = document.getElementById(id);
   if (uibanner) {
       uibanner.parentNode.removeChild(uibanner);
       sendRequestToFrame('/core/pages/uibannerpref.nl?prefValue=F&prefName=SHOWCHILESUEBANNER', 'server_commands');
   }
}
