
// <script type="text/javascript">












var s_machineKeyDown = NLMachine_EditFieldOnKeyDown;
var s_docKeyDown     = document.onkeydown;

var mchMachineWithFocus = null;

if (s_docKeyDown == null)
{
    document.onkeydown = s_machineKeyDown;
}
else
{
    document.onkeydown = function(evnt){ s_machineKeyDown(evnt); s_docKeyDown(evnt);};
}



function NLMachine_onMouseUp(evnt)
{
    var parDIV = Machine_getParentTABLE(getEventTarget(evnt));
    if(parDIV && parDIV.machine)
    {
        mchMachineWithFocus = parDIV.machine;
    }
    else
    {
        mchMachineWithFocus = null;
    }
}


function NLMachine_safeSetFocus(fld)
{
    setFieldFocus(fld);
    
    if(document.activeElement != fld)
    {
        setTimeout(function (){ setFieldFocus(fld);}, 0);
    }
    

}

function NLMachine_EditFieldOnKeyDown(evnt)
{
	var kc = getEventKeypress(evnt);
    
    if(kc == 9 )
    {
		
		if (window.popupDIV || (popupAutoSuggest && popupAutoSuggest.visible))
            return;

        var parDIV = Machine_getParentDIV(getEventTarget(evnt));
        
        if(mchMachineWithFocus || (parDIV && parDIV.className == 'divhover'))
        {
            var mch = mchMachineWithFocus;
            if(!mch)
            {
                mch = parDIV.sourceMachine;
                mchMachineWithFocus = mch;
            }

            var delta = (getEventShiftKey(evnt)) ? -1 : 1;

            
            if( mch.isinline && mch.gotoField(delta) )
            {
                setEventPreventDefault(evnt);
                setEventCancelBubble(evnt);
                return false;
            }
            else
            {
                
                mchMachineWithFocus = null;
                return true;
            }
        }
    }
}


function getMachineByName(machineName)
{
    return window.machines[machineName];
}

function Machine(name, mainform, miniform, tableobj, allow_insert)
{
    this.name = name;
	this.mainform = mainform;
	this.miniform = miniform;

	this.tableobj = tableobj;
    if(this.tableobj != null)
        this.tableobj.machine = this;
	this.allow_insert = allow_insert;
	this.tableborder = false;
	this.isinline = false;
    this.bShowAllEditedFields = false;
    this.hasInterceptedEvents = false;
    
	this.ischanged = false;
    
    this.waschanged = false;
	
	this.isdeleting = false;
	this.hasBeenSqueezed = false;
	this.showEditor = true;
	this.showRowNumbers = false;
	this.rowNumberLabel = '#';
	this.autoEdit = true;
	this.sortable = false;
	this.allowMoveLines = false;
    this.allowQuickDeleteLines = false;
    this.showButtons = true;
    this.moveButtons = true;
    this.sortDirUp = true;
	this.sortIndex = -1;
    this.allWhiteDisplayMode = false;
	this.bResizeBackgroundDiv = false;
    this.fieldSetIncludesCancelButton = false;
	this.addonly = false;
    this.savedState = new Object();
    this.indentFirstVisibleColumn = false;

	
    this.form_elems = splitIntoCells( this.mainform.elements[name+"fields"].value );
    this.table_labels = splitIntoCells( this.mainform.elements[name+"labels"].value );
    this.miniform_elem_types = splitIntoCells( this.mainform.elements[name+"types"].value );
    this.miniform_elem_flags = splitIntoCells( this.mainform.elements[name+"flags"].value );
    this.miniform_elem_fieldsets = splitIntoCells( this.mainform.elements[name+"fieldsets"].value );
	
	this.elementCache = new Array();
	
	this.getFormName = Machine_getFormName;
	this.getFormElementType = Machine_getFormElementType;
	this.getRowFormElementType = Machine_getRowFormElementType;
    this.getFormElementName = Machine_getFormElementName;
	this.getFormElementLabel = Machine_getFormElementLabel;
    this.setFormElementLabel = Machine_setFormElementLabel;
    this.getFormElementFieldSet = Machine_getFormElementFieldSet;
	this.getFormElement = Machine_getFormElement;
	this.getElementDisplayLabel = Machine_getElementDisplayLabel;
	this.getArrayPosition = Machine_getArrayPosition;
	this.countFormElements = Machine_countFormElements;
	this.getNextIndex = Machine_getNextIndex;
	this.getMaxIndex = Machine_getMaxIndex;
	this.setMachineIndex = Machine_setMachineIndex;
	this.getMachineIndex = Machine_getMachineIndex;
	this.setMainFormData = Machine_setMainFormData;
	this.getMainFormData = Machine_getMainFormData;
	this.incrementIndex = Machine_incrementIndex;
	this.decrementIndex = Machine_decrementIndex;
	this.setIndex = Machine_setIndex;
	this.getFormFieldNames = Machine_getFormFieldNames;
	this.isElementPopupDisplayField = Machine_isElementPopupDisplayField;
    this.isElementDisplayOnlyWithField = Machine_isElementDisplayOnlyWithField;
	this.isElementRequired = Machine_isElementRequired;
    this.isMandatoryOnThisLine = Machine_isMandatoryOnThisLine;
	this.getElementRequired = Machine_getElementRequired;
	this.setElementRequired = Machine_setElementRequired;
	this.isElementNoCopy = Machine_isElementNoCopy;
	this.isCurrentRowRequired = Machine_isCurrentRowRequired;
    this.isRowRequired = Machine_isRowRequired;
	this.getDisplayHeaderCell = Machine_getDisplayHeaderCell;
	this.getDisplayCellContent = Machine_getDisplayCellContent;
	this.getTableName = Machine_getTableName;
	this.getAlignmentForColumn = Machine_getAlignmentForColumn;

	this.getSortImage = Machine_getSortImage;
	this.setAddOnly = Machine_setAddOnly;
	this.addOnly = Machine_addOnly;

	
    this.getNumOfRows = Machine_getNumOfRows;
	this.getsyncline = Machine_getsyncline;
	this.clearline = Machine_clearline;
	this.viewline = Machine_viewline;
	this.synclinefields = Machine_lineInit;
	this.nlapilineinit = Machine_nlapiLineInit;
	this.deleteline = Machine_deleteline;
	this.validatedelete = Machine_validatedelete;
	this.insertline = Machine_insertline;
	this.validateinsert = Machine_validateinsert;
	this.copyline = Machine_copyline;
	this.addline = Machine_addline;
	this.updateLineData = Machine_updateLineData;
	this.validateline = Machine_validateline;
	this.checkunique = Machine_checkunique;
	this.setPreferredValue = Machine_setPreferredValue;
	this.buildtable = Machine_buildtable;
	this.constructMainTableRow = Machine_constructMainTableRow;
	this.recalc = Machine_recalc;
	this.nlapirecalc = Machine_nlapirecalc;
	this.loadline = Machine_loadline;
    this.setupLineData = Machine_setupLineData;
    this.sort = Machine_sort;
	this.insertdata = Machine_insertdata;
	this.addblankrow = Machine_addblankrow;
	this.deletelines = Machine_deletelines;
	this.clearmachine = Machine_clearmachine;
	this.refresheditmachine = Machine_refreshEditMachine;
    this.updateMachineData = Machine_updateMachineData;
    this.moveline = Machine_moveline;
	this.movelineto = Machine_movelineto;
	this.moveLineToTopOrBottom = Machine_moveLineToTopOrBottom;
    this.preSelectRow = Machine_preSelectRow;
	this.editRow = Machine_editRow;
	this.suspendEdit = Machine_suspendEdit;
	this.getInputElements = Machine_getInputElements;
    this.createEditorMap = Machine_createEditorMap;
	this.addEditor = Machine_addEditor;
	this.setFocus = Machine_setFocus;
	this.showMachine = Machine_showMachine;
    this.machineIsVisible = Machine_machineIsVisible;
    this.getFieldSetIncludesCancelButton = Machine_getFieldSetIncludesCancelButton;
    this.getFieldSetDoneAction = Machine_getFieldSetDoneAction;
    this.setEnableEdit = Machine_setEnableEdit;
    this.clearSavedState = Machine_clearSavedState;

    
    this.imalive = Machine_imalive;
    this.gotoField = Machine_gotoField;
    this.gotoFieldWithName = Machine_gotoFieldWithName;
    this.fieldHasFocus = Machine_fieldHasFocus;
    this.setFocusToCurrentColumn = Machine_setFocusToCurrentColumn;
    this.getDisplayHTMLOfField = Machine_getDisplayHTMLOfField;
    this.getFieldOffset = Machine_getFieldOffset;
    this.getFieldValue = Machine_getFieldValue;
    this.getLineFieldValue = Machine_getLineFieldValue;
    this.setColToFirstEditable = Machine_setColToFirstEditable;
    this.setFocusToFirstEditable = Machine_setFocusToFirstEditable;
    this.transferInputFieldValuesToDisplayOnly = Machine_transferInputFieldValuesToDisplayOnly;
    this.isFieldEditable = Machine_isFieldEditable;
    this.checkMandatoryData = Machine_checkMandatoryData;
    this.doCheckMandatoryData = Machine_doCheckMandatoryData;
	this.adjustButtonPosition = NLMachine_adjustButtonPosition;
	this.createFocusElement = NLMachine_createFocusElement;
	this.applyFocusToFocusElement = NLMachine_applyFocusToFocusElement;

	this.relayout = Machine_relayout;
    this.getParentTD = Machine_getParentTD;
    this.getParentDIV = Machine_getParentDIV;
    this.createColumnHeaderCell = Machine_createColumnHeaderCell;
    this.createGrippyCell = Machine_createGrippyCell;
    this.createDeleteCell = Machine_createDeleteCell;


    
    this.currentRowNum = 0;
    this.segmentSelect = null;
    this.segmentStartIndex = 1;
    this.lastStartSegmentIndex = 1;
    this.segmentable = false;
    this.isCurrentlySegmented = false;
    this.getSegmentAdjustedRowNum = Machine_getSegmentAdjustedRowNum;
    this.getSegmentSelect = Machine_getSegmentSelect;
    this.manageSegmentSelect = Machine_manageSegmentSelect;
    this.getAdjustedSegmentIndex = Machine_getAdjustedSegmentIndex;

    
    this.getDisplayCellContentOverride = Machine_getDisplayCellContentOverride;
    this.getFieldOverride = Machine_getFieldOverride;
    this.getRowFormElementTypeOverride = null;
    this.isFieldEditableOverride = Machine_isFieldEditableOverride;
    this.isNeedUpdateFieldDisplayValue = Machine_isNeedUpdateFieldDisplayValue;
    this.postBuildTable = Machine_postBuildTable;
    this.postdeleteline = Machine_postdeleteline;
    this.postEditRow = Machine_postEditRow;
    this.postprocessline = Machine_lineCommit;
    this.nlapilinecommit = Machine_nlapiLineCommit;

    editmachineCounter++;

    if(!window.machines)
        window.machines = new Object;
    window.machines[this.name] = this;
}


function Machine_getNumOfRows ()
{
	var lines = getLineArray(this.name);

    return (lines && lines.length) ? lines.length : 0;
}

function Machine_getSegmentAdjustedRowNum()
{
    if(this.segmentable)
        return this.currentRowNum + Math.max(0,(this.segmentStartIndex - 1));
    else
        return this.currentRowNum;
}

function Machine_getAdjustedSegmentIndex(base, bAdd)
{
    if(this.segmentable)
        return base - ( (bAdd ? -1 : 1 )* (Math.max(0,this.segmentStartIndex-1)) ) ;
    else
        return base;
}

function Machine_getSegmentSelect()
{
    
    if(this.segmentSelect == null)
    {
        var selectName = this.name+"_segment_select";
        //var selInpt = document.getElementById(selectName);
        var selInpt = document.forms[this.name+"_form"].elements[selectName];
        this.segmentSelect = selInpt;
    }
    return this.segmentSelect;
}


function Machine_getsyncline( line )
{
    
    if ( window.virtualBrowser ) return;

    var syncline = "";
	for (var i=0; i < this.countFormElements(); i++)
	{
		if ( (this.getFormElementType( i ) == "select" || this.getFormElementType( i ) == "slaveselect" || ( this.getFormElementType( i ) == "integer" && i > 0 && this.isElementPopupDisplayField(i - 1) )) && !isMultiSelect( this.getFormElement( i )))
		{
			var elem = this.getFormElement(i);
            var val = getSelectValue( elem );
			if ((val != null) && (val.length > 0))
				syncline += getSyncFunctionName( elem.name, this.name ) + '(true,' + line + ');';
		}
	}
	if (syncline.length > 0)
		eval(syncline);
}

function Machine_nlapirecalc()
{
	if ( document.forms['main_form'].elements['nlapiRC'] != null || document.forms['main_form'].elements['nsapiRC'] != null )
		nlapiRecalc(this.name);
}

function Machine_recalc()
{
}

function Machine_getFieldSetIncludesCancelButton()
{
    return this.fieldSetIncludesCancelButton;
}

function Machine_getFieldSetDoneAction()
{
    return this.name + "_machine.gotoField(1); setEventCancelBubble(evnt); return false;";
}


function Machine_getFormName( )
{
	return this.miniform.name;
}

function Machine_getRowFormElementType( nIndex, rowNum )
{
    var type = null;
    if (this.getRowFormElementTypeOverride)
        type = this.getRowFormElementTypeOverride (nIndex, rowNum);
    if (type != null)
        return type;

    return this.getFormElementType(nIndex);
}


function Machine_getFormElementType( nIndex)
{
    return this.miniform_elem_types[ nIndex ];
}


function Machine_getFormElementName( nIndex )
{
	return this.form_elems[ nIndex ];
}

function Machine_getFormElementFieldSet( nIndex )
{
	return this.miniform_elem_fieldsets[ nIndex ];
}

function Machine_getFormElement( nIndex )
{
	var name = this.getFormElementName(nIndex);
	var elem = this.elementCache[name];
	if (elem)
		return elem;

	
			elem = this.miniform.elements[ name ];
	

	this.elementCache[name] = elem;
	return elem;
}


function Machine_countFormElements()
{
	return this.form_elems.length;
}

function Machine_getNextIndex( )
{
	return parseInt(this.mainform.elements['next'+this.name+'idx'].value);
}

function Machine_getMaxIndex( )
{

	return this.getNextIndex( );

}

function Machine_incrementIndex( )
{
    
	this.mainform.elements['next'+this.name+'idx'].value -= -1;
}

function Machine_decrementIndex( )
{
	this.mainform.elements['next'+this.name+'idx'].value -= 1;
}

function Machine_setIndex( nIndex )
{
	this.mainform.elements['next'+this.name+'idx'].value = parseInt(nIndex);
}

function Machine_setMachineIndex( nNewIndex )
{
 	if (this.miniform.elements[this.name + "_lineindex"])
    	this.miniform.elements[this.name + "_lineindex"].value = nNewIndex;
	if (this.miniform.elements["lineindex"] != null)
        this.miniform.elements["lineindex"].value = nNewIndex;
}

function Machine_getMachineIndex( )
{
    if (this.miniform.elements[this.name + "_lineindex"])
        return parseInt(this.miniform.elements[this.name + "_lineindex"].value);
    return parseInt(this.miniform.elements["lineindex"].value);
}

function Machine_setMainFormData( data )
{
	this.mainform.elements[ this.name+'data'].value = data;
    this.waschanged = true;
}

function Machine_getMainFormData( )
{
	return this.mainform.elements[ this.name+'data' ].value;
}

function Machine_getFormFieldNames( )
{
	return splitIntoCells( this.mainform.elements[this.name+'fields'].value );
}
function Machine_isElementDisplayOnlyWithField( nIndex )
{
	return (this.miniform_elem_flags[ nIndex ] & 32) != 0;
}
function Machine_isElementPopupDisplayField( nIndex )
{
	return (this.miniform_elem_flags[ nIndex ] & 8) != 0;
}

function Machine_isElementRequired( nIndex )
{
	return (this.miniform_elem_flags[ nIndex ] & 1) != 0;
}

function Machine_getElementRequired( fieldName )
{
	var nIndex = this.getArrayPosition( fieldName );
	return (this.miniform_elem_flags[ nIndex ] & 1) != 0;
}

function Machine_setElementRequired( fieldName, bRequired )
{
	var nIndex = this.getArrayPosition( fieldName );
	if (bRequired)
		this.miniform_elem_flags[ nIndex ] |= 1;
	else
		this.miniform_elem_flags[ nIndex ] &= ~1;
	var curElement = this.getFormElement( nIndex );
	setRequired(curElement, bRequired);
}

function Machine_isElementNoCopy( nIndex )
{
	return (this.miniform_elem_flags[ nIndex ] & 2) != 0;
}
function Machine_getArrayPosition( name )
{
	var nPos = -1;
	if ( name != null )
	{
		var aFields = this.getFormFieldNames();
		for ( var i = 0; i < aFields.length && nPos == -1; i++ )
		{
			if ( aFields[i] == name )
				nPos = i;
		}
	}
	return nPos;
}

function Machine_isCurrentRowRequired( )
{
    return this.isRowRequired( this.getMachineIndex() );
}

function Machine_setAddOnly(bAddOnly)
{
	this.addonly = bAddOnly;
}

function Machine_addOnly()
{
	return this.addonly;
}

function Machine_isRowRequired( index )
{
	
	if(this.addOnly())
		return true;

	var nPos = this.getArrayPosition( '_reqline' );
	if ( nPos == -1 )
		return false;
	var data = getLineArrayLine(this.name,index - 1);
	return data != null && data.length > nPos && 'T' == data[ nPos ] ;
}


function Machine_getElementDisplayLabel( nIndex )
{
	return this.getFormElementLabel( nIndex ).length > 0
			? this.getFormElementLabel( nIndex )
			: this.getFormElementLabel( nIndex - 1 );
}

function Machine_getFormElementLabel( nIndex )
{
	return this.table_labels[nIndex];
}


function Machine_setFormElementLabel( fieldName, sLabel )
{
    this.table_labels[ this.getArrayPosition(fieldName) ] = sLabel;
}


function Machine_getDisplayHeaderCell( nIndex, cell )
{
	var curType = this.getFormElementType( nIndex );
	var classname = "smalltext";
    var divClassname = "machineheadernosort";
    var onClick = "";
    var imgsrc = "";
    if(this.sortable)
    {
       divClassname = "listheader";
       onClick = this.name+"_machine.sort("+nIndex+"); window.ischanged=true; return false;";
       imgsrc = this.getSortImage( nIndex );
    }
	if ( curType == "currency" || curType == "currency2" || curType == "rtext" || curType == "rate" || curType == "float" || curType == "pct")
		classname += "rt";

    if( this.allWhiteDisplayMode )
        divClassname += "wht";

    cell.height = "100%";
    cell.className = classname;
    cell.onclick = new Function(onClick);
    var div = document.createElement("div");
    div.className = divClassname;
    div.innerHTML = this.getFormElementLabel( nIndex ).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br>') + imgsrc;
    cell.appendChild(div);
    return cell;
}

function Machine_getSortImage( nIndex )
{
    var imgsrc = "nlempty.gif";
    if (nIndex == this.sortIndex)
       imgsrc = this.sortDirUp ? "nlup.gif" : "nldown.gif";
    return "&nbsp;<img id="+this.name+"dir"+nIndex+" src='/images/nav/"+imgsrc+"' width=8 height=7 border=0>";
}


function Machine_getAlignmentForColumn(nIndex)
{
	var curType = this.getFormElementType(nIndex);
	if (curType == "currency" || curType == "currency2" || curType == "rtext" ||
	    curType == "rate" || curType == "float" || curType == "pct")
	{
		return "right";
	}
    else
	    return "left";
}






function Machine_getDisplayCellContentOverride(nIndex, data, lineNum)
{
    return null;
}



function Machine_getDisplayCellContent( nIndex, data, lineNum)
{
    var displayCellContent = this.getDisplayCellContentOverride(nIndex, data, lineNum);
    if (displayCellContent != null)
    {
        if (displayCellContent.length > 0 && displayCellContent.search(/[^ \t]/) >= 0)
            return displayCellContent;
        else
            return '&nbsp;';
    }
	var curType = this.getFormElementType( nIndex );
	var curName = this.getFormElementName( nIndex );
	var curElement = this.getFormElement( nIndex );

	if (data == null)
		data = '';
	else
		data = data.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');

	// Decode newlines that were encoded in NLMachine to BR for the display version of a machine
	if( curType == 'address' || curType == 'textarea' )
	{
		// Truncate long, non-edit fields so they don't result in very tall machine rows.
		// BMS: moved to this case because the other cases (fieldset specifically) are negatively impacted
		if (data.length > 250)
        {
			data = data.substring(0, 250)+'(more...)';
        }
		var addrList = data.split(String.fromCharCode(5));
		data = addrList.join("<br>");
	}
	var innerContent = '';
	if ( curType == "select" || curType == "slaveselect")
	{
		if ( isMultiSelect( curElement ) )
			innerContent += getmultiselectlisttext( curElement , data );
		else
			innerContent += getlisttext( curElement, data );
		innerContent = innerContent.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
	}
	else if (curType == "currency")
		innerContent += format_currency( parseFloat( data ) );
	else if (curType == "currency2" || curType == "rate")
		innerContent += format_rate( parseFloat( data ), data.indexOf('%') != -1 );
	else if (curType == "checkbox")
		innerContent += data == "T" ? "Yes" : "";
	else if (curType == "radio")
		innerContent += getradiotext( curElement, data );
	else if (curType == "namevaluelist")
		innerContent += getnamevaluelisttext( data , "<br>" );
	else if (curType == "fieldset")
    {
        var fsContent = getFieldSetDisplayText( this, curName, lineNum );
        if( fsContent != null && fsContent.length > 0)
		    innerContent += "<img src='/images/reportbuilder/fieldsetup.gif' border=0><img src='/images/nav/stretch.gif' height=1 width=6 border=0>";
        innerContent += fsContent;
    }
    else if (curType == "phone" && window.tapidevice != null && window.tapidevice.length > 0)
        innerContent += "<a href='#' src='/images/forms/phone.gif' onclick='NLDial("+'"'+data+'"'+");event.cancelBubble=true;return false;'>"+data+"</a>";
    else if (curType == "password")
        innerContent = data.replace(/./g,'&bull;');
    else if (curType == "color" && data.length>0)
    {
        if (this.isinline)
            innerContent = "<span style='width:40px' align='center'><img src='/images/nav/stretch.gif' style='border:1px solid; padding:0px; height:12px; width:12px; background-color:" + data + "' /></span>";
        else
            innerContent = "<img align='top' style='background-color:"+data+"' border=1 src='/images/nav/stretch.gif' width='18' height='12'>&nbsp;"+data;
    }
    else if ( data != null )
		innerContent += data.replace(/\n/g,'<br>');

	// Make sure that innerContent contains something other than whitespace.
	// Returning a string that contains only whitespace will cause innerHtTML
	// to be empty and won't get copied properly.
	if (innerContent.length > 0 && innerContent.search(/[^ \t]/) >= 0)
		return innerContent;
	else
		return '&nbsp;';
}


function Machine_clearline(sync, startSegmentIndex)
{
    
	if (!window.isinited) return false;
    if (this.isinserting)
        return this.deleteline();

    this.setColToFirstEditable();

    var oldidx = this.getAdjustedSegmentIndex( this.getMachineIndex(), false );

	if (this.getFormName() == 'main_form')
	{
        for (var i = 0; i < this.countFormElements() ; i++ )
        {
            var elem = this.getFormElement( i );
            elem.value = '';
            if (isNLDropDown(elem)||isNLMultiDropDown(elem))
            {
                var dropdown = getDropdown(elem);
                if (dropdown)
                    dropdown.resetDropDown();
            }
        }
	}
	else
	{
		
		this.miniform.reset();
		
        if (typeof(resetNLDropDowns) != 'undefined')
		    resetNLDropDowns(this.miniform);
	}
	if (!sync)
	{
		
		for (var i=0; i < this.countFormElements(); i++)
			if ( this.getFormElementType( i ) == "slaveselect" )
				deleteAllSelectOptions(this.getFormElement(i));
	}

	this.setMachineIndex( this.getNextIndex() );

	
	if (sync)
	{
		for (var i=0; i < this.countFormElements() ; i++)
            
            if (this.getFormElementFieldSet(i) == "" && this.getFormElementType( i ) == "slaveselect")
				eval( getSyncFunctionName( this.getFormElementName( i ), this.name ) + '(true,null,true);');
    }

    
	for (var i=0; i < this.countFormElements() ; i++)
	{
		if ((this.getFormElementType(i) == "text" || this.getFormElementType(i) == "textarea") && this.isElementPopupDisplayField(i)
				&& i < this.countFormElements()-1
				&& (this.getFormElementType( i+1 ) == "integer" && isSelect(this.getFormElement( i+1 ))))
		{
			setFormValue(this.getFormElement(i), getSelectText(this.getFormElement(i + 1)));
		}
	}

	
	this.synclinefields( );

	
    this.buildtable(startSegmentIndex);
	this.ischanged = false;
	this.isinserting = false;

	
}


function Machine_preSelectRow(rowNum)
{
    return true;
}


function Machine_viewline( linenum, colnum, bForce )
{
    if (!bForce && !window.isinited) return false;
    if ( this.isCurrentlySegmented && linenum < this.getNextIndex() && ( linenum < this.segmentStartIndex || linenum >= (this.segmentStartIndex + max_segment_size + (this.segmentStartIndex == this.lastStartSegmentIndex ? min_segment_size : 0) ) ) )
    {
        var linenumber = linenum >= this.lastStartSegmentIndex + max_segment_size ? linenum - min_segment_size : linenum; 
        var idx = Math.floor((linenumber-1)/max_segment_size)*max_segment_size + 1;
        this.segmentStartIndex = Math.max(1, idx);
    }
    var currentRow = this.getSegmentAdjustedRowNum();
    if (linenum == currentRow && !this.isdeleting && this.isinline)
    {
        if(this.focusedColumn == colnum)
        {
            return false;
        }
        else
        {
            this.gotoField( colnum, true);
            return true;
        }
    }
    else if (!this.isdeleting)
    {
        
        
        if ( this.autoEdit && this.ischanged)
            if (!this.addline())
                return false;
    }

    if(colnum != null && colnum >= 0)
    {
        this.focusedColumn = colnum;
    }
    else
    {
		
        this.setColToFirstEditable(true);
    }

    
    if( !this.preSelectRow( linenum ) )
    {
        return;
    }

	this.setupLineData(linenum);

	
    this.buildtable( );
	this.ischanged = false;
    this.isinserting = false;
}


function Machine_lineInit( )
{
}

function Machine_nlapiLineInit()
{
	if (document.forms['main_form'].elements.nlapiLI != null || document.forms['main_form'].elements.nsapiLI != null)
		nlapiLineInit(this.name);
}

function Machine_machineIsVisible(i)
{
    var machineContainer = document.getElementById(this.name+"_layer");
    return machineContainer.style.display != "none" &&
        machineContainer.style.visibility == "inherit" ?
            machineContainer.parentNode.style.visibility == "visible" || machineContainer.parentNode.style.visibility == "" :
            machineContainer.style.visibility == "visible";
}

function Machine_showMachine( shown )
{
    var singleMachineSpacer = document.getElementById(this.name+"_singlespacer");
    if(singleMachineSpacer != null)
        singleMachineSpacer.style.display = shown ? "" : "none";
    document.getElementById(this.name+"_layer").style.display = shown ? "" : "none";
    if (this.bResizeBackgroundDiv)
        sizeLowerTabBGDiv(this.name);
}


function Machine_loadline(linenum,iscopy)
{
    var i;
    linedata = getLineArrayLine(this.name,linenum-1 );

    for ( i = 0; i < this.countFormElements(); i++ )
    {
        if (iscopy == true && this.isElementNoCopy( i ))
            continue;
        var typeFormField = this.getFormElementType( i );
        var objField = this.getFormElement( i );

        if (typeFormField == "select" || typeFormField == "slaveselect")
        {
            if ( isMultiSelect(objField) || isPopupMultiSelect(objField) )
                syncmultiselectlist( objField ,linedata[i], (i > 0 && this.isElementPopupDisplayField(i-1)) ? linedata[i-1] : null, true);
             else
                 synclist( objField,linedata[i], false );
        }
        else if ( typeFormField == "radio" )
            syncradio( objField,linedata[i], false );
        else if ( typeFormField == "address" || typeFormField == "textarea")
        {
             // Decode newlines that were encoded as char(5) by NLMachine.java to \n for the edit version of a field
             var addrList = linedata[i].split(String.fromCharCode(5));
             objField.value = addrList.join("\n");
        }
        else if (typeFormField == "currency")
            objField.value = format_currency( parseFloat(linedata[i]) );
        else if (typeFormField == "currency2" || typeFormField == "rate")
            objField.value = format_rate( parseFloat(linedata[i]) , linedata[i].indexOf('%') != -1);
        else if ( typeFormField == "checkbox" )
            objField.checked = (linedata[i] == "T");
        else if ( typeFormField == "namevaluelist" )
        {
            objField.value = linedata[i];
            syncnamevaluelist( objField );
        }
        else if (typeFormField == 'fieldset_inline')
        {
            setInlineTextValue(document.getElementById(this.getFormElementName(i)+"_val"), linedata[i]);
        }
        
        else if ( objField.className == 'nldropdown' || objField.type == "select-one" )
            synclist( objField,linedata[i], false );
        else if ( typeFormField == "color" )
        {
            objField.value = linedata[i];
            document.getElementById(objField.name+'_chip').style.backgroundColor = linedata[i].length>0 ? linedata[i] : "#FFFFFF";
        }
        else if ( typeFormField != "fieldset" )
        {
            objField.value = linedata[i];
            
            if (isCheckboxImageField(objField))
                objField.onclick();

            
            
            if(this.isElementPopupDisplayField(i))
                objField.setAttribute('previousvalue',objField.value);
        }
    }
}


function Machine_setupLineData(linenum,iscopy)
{
    if (linenum <=0)
        return;

    var linearray = getLineArray(this.name);

    if(!linearray || linearray.length==0)
        return;

    if (linenum > linearray.length)
        linenum = linearray.length;

    this.loadline( linenum,iscopy );

	this.setMachineIndex( linenum );

	for (var i=0; i < this.countFormElements(); i++)
	{
		if (this.getFormElementType( i ) == 'slaveselect')
		{
			eval(getSyncFunctionName( this.getFormElementName( i ), this.name ) + '(true, ' + (linenum - 1).toString()+', true);');
		}
	}

	
	this.synclinefields();
}



function Machine_validatedelete()
{
	return true;
}


function Machine_postdeleteline()
{
}


function Machine_deleteline(linenum)
{
	if (!window.isinited)
		return false;
	this.isdeleting = true;

	if (document.forms['main_form'].elements.nsapiVD != null && !nlapiValidateDelete(this.name))
	   return false;

	if (!this.validatedelete())
		return false;
	if(!linenum)
        linenum = parseInt( this.getMachineIndex() );
    linenum -= 1;
	if ( linenum+1 == this.getNextIndex() )
		return false;
    
	linearray = getLineArray(this.name);
	linearray = linearray.slice(0,linenum).concat(linearray.slice(linenum+1));
	setLineArray(this.name,linearray);

	this.decrementIndex( );

	this.recalc();
    this.isinserting = false;
    if (linenum < parseInt(this.getNextIndex())-1)
    {
        this.ischanged=false;
        this.viewline(linenum+1)
    }
    else
    {   
        this.clearline(false, this.isCurrentlySegmented ? (this.lastStartSegmentIndex == this.segmentStartIndex && this.getNextIndex()-1 < this.lastStartSegmentIndex + min_segment_size ? Math.max(1, this.lastStartSegmentIndex - max_segment_size) : this.lastStartSegmentIndex ) : null);
		this.getsyncline( 0 );
	}

	this.isdeleting = false;
	this.postdeleteline();
    this.waschanged = true;
	return true;
}


function Machine_moveline(dir)
{
	if (!window.isinited) return false;
	linenum = parseInt( this.getMachineIndex() ) - 1;
	if (linenum+1 == this.getNextIndex() )
		return false;
	if ((linenum == 0 && dir == -1) || (linenum+1 == parseInt( this.getNextIndex() ) - 1 && dir == 1))
		return false;
	this.movelineto( linenum+dir+1 );
	return true;
}


function Machine_movelineto( newseq, bUpdateDataOnly )
{
	if (!window.isinited) return false;
	newseq -= 1;
	linenum = parseInt( this.getMachineIndex() ) - 1;
	if (linenum+1 == this.getNextIndex() )
		return false;

	linearray = getLineArray(this.name);
	var oldrow = linearray[linenum];
	// reorder the line array accordingly
	if (newseq < linenum)
	{
		for(var i = (linenum-1); i >= newseq; i--)
			linearray[i+1] = linearray[i];
		linearray[newseq] = oldrow;
	}
	else
	{
		for ( var i = linenum; i < newseq; i++)
			linearray[i] = linearray[i+1];
		linearray[newseq] = oldrow;
	}
	setLineArray(this.name,linearray);

	this.setMachineIndex( newseq + 1 );
    if( !bUpdateDataOnly )
    {
        this.recalc();
        this.buildtable();
    }

    return true;
}


function Machine_moveLineToTopOrBottom(top)
{
	var bottom = !top;

	if (!window.isinited) return false;
	linenum = parseInt( this.getMachineIndex() ) - 1;

	// if they attempt to move a line that's on the bottom to the bottom, or
	// a line that's on the top to the top, just return
	if (top && linenum == 0)
		return;
	if (bottom && linenum+1 == this.getNextIndex()-1)
		return false;

	this.movelineto( top ? 1 : linearray.length);
	return true;
}


function Machine_validateinsert()
{
	return true;
}


function Machine_checkunique()
{
	var uniquefields = new Array(this.uniquefield);
	var uniquelabels = new Array( window.virtualBrowser ? this.uniquefield : this.getElementDisplayLabel(this.getArrayPosition(this.uniquefield)) );
	if (this.uniquefield2 != null)
	{
		uniquefields.push(this.uniquefield2);
		uniquelabels.push( window.virtualBrowser ? this.uniquefield2 : this.getElementDisplayLabel(this.getArrayPosition(this.uniquefield2)) );
	}
	var labels = checkUniqueFields(this.name, uniquefields, uniquelabels)
	if ( labels != null && labels.length > 0 )
	{
		alert(labels.join('/')+" must be unique");
		return false;
	}
	return true;
}


function Machine_setPreferredValue(linenum)
{
	return setPreferredFields( this.name, this.preferredfield, linenum )
}


function Machine_insertline()
{
	if (!window.isinited) return false;
	var linenum = parseInt( this.getMachineIndex() ) - 1;;
	if ( this.ischanged )
		this.addline();

	if (document.forms['main_form'].elements.nsapiVI != null && !nlapiValidateInsert(this.name))
	   return false;	

	if (!this.validateinsert())
		return false;
	if (linenum+1 == this.getNextIndex() )
		return false;
	var linedata = new Array();
	linedata[ this.countFormElements() -1 ] = "";
	linearray = getLineArray( this.name );
	linearray = (linearray.slice(0,linenum).concat(linedata.join(String.fromCharCode(1)))).concat(linearray.slice(linenum));
	setLineArray(this.name,linearray);

	this.incrementIndex() ;
	this.recalc();
	var oldidx = linenum+1;
	this.clearline(false);
	this.setMachineIndex( oldidx );
    
    this.isinserting = true;
    this.ischanged = true;

	this.getsyncline(linenum);

	
	this.buildtable();
	return true;
}


function Machine_copyline()
{
	if (!window.isinited) return false;
	var linenum = parseInt( this.getMachineIndex() );
	if (linenum == this.getNextIndex() )
		linenum -= 1;
	else
    {
        if ( this.ischanged )
		    this.addline();
        else
            this.clearline();
    }

    this.loadline(linenum,true);

	for (var i=0; i < this.countFormElements(); i++)
	{
		if (this.getFormElementType( i ) == 'slaveselect')
		{
			eval(getSyncFunctionName( this.getFormElementName( i ), this.name ) + '(true, ' + (linenum - 1).toString()+', true);');
		}
	}
	this.synclinefields( );

	
	this.buildtable();
    this.ischanged=true;
    this.isinserting = false;

	return true;
}

function Machine_insertdata(data, linenum)
{
	var linenum;

	linearray = getLineArray(this.name);
 	linearray1 = linearray.slice(0,linenum-1);
 	linearray2 = linearray.slice(linenum-1);

 	newlinearray = splitIntoRows(data);
	setLineArray(this.name,linearray1.concat(newlinearray).concat(linearray2));
	linearray = getLineArray(this.name);

	this.setIndex( linearray.length + 1 );
	this.setMachineIndex( linearray.length + 1 );
	return true;
}


function Machine_refreshEditMachine(bNoFocus)
{
	this.setMachineIndex( this.getNextIndex() );
	this.buildtable(null, bNoFocus);
	return true;
}


function Machine_clearmachine()
{
    return Machine_clearLineItems(this.name);
}


function Machine_clearLineItems(name)
{
	var machine = eval(name+'_machine')
	machine.setMainFormData( '' );
	machine.setIndex( 1 );
	
    clearLineArray(machine.name);
	machine.clearline(true);
    return true;
}


function Machine_deletelines(start, end)
{
    return Machine_deleteLineItems(this.name, start, end);
}


function Machine_deleteLineItems(name, start, end)
{
	var machine = eval(name+'_machine')
	var linearray = getLineArray(machine.name);
	setLineArray(machine.name,linearray.slice(0,start).concat(linearray.slice(end)));
	machine.setIndex( machine.getNextIndex() - (end - start) );
    return true;
}


function Machine_addblankrow()
{
	var linearray = getLineArray(this.name);
    var fieldnames = this.getFormFieldNames();
    var blankrow = new Array(fieldnames.length);

    for (var i=0; i < fieldnames.length; i++)
		blankrow[i] = '';

    linearray[linearray.length] = blankrow.join(String.fromCharCode(1));
	setLineArray(this.name,linearray);

	this.incrementIndex();

	return true;
}


function Machine_validateline()
{
	return true;
}


function Machine_lineCommit(linenum)
{
}
function Machine_nlapiLineCommit(linenum)
{
	if (document.forms['main_form'].elements.nsapiLC != null)
		nlapiLineCommit(this.name, linenum);
}		


function Machine_getDisplayHTMLOfField(i)
{
    var sReturn = "";
    var curType = this.getFormElementType( i );
    var curElement = this.getFormElement( i );

    if ( curType == "select" || curType == "slaveselect" )
    {
        if( i > 0 && this.isElementPopupDisplayField(i-1))
        {
            
            sReturn = (curElement.value.length == 0 ? '' : this.getFormElement(i-1).value);
        }
        else
        {
            sReturn = getFormValue(curElement);
        }
    }
    else if ( curType == "checkbox" )
    {
        sReturn = getCheckboxState(curElement) ? "T" : "F";
    }
    else if ( curType == "radio" )
    {
        for (var j=0; j < curElement.length; j++)
            if ( curElement[j].checked)
                sReturn = curElement[j].value;
    }
    else if (curType == "integer" && i > 0 && this.isElementPopupDisplayField(i - 1))
    {
        sReturn = (curElement.value.length == 0 ? '' : this.getFormElement( i - 1).value);
    }
    else if ( curType == "address" || curType == "textarea")
    {
        if(curElement.value != null)
        {
            var lineList = curElement.value.split(/\r?\n/);
            sReturn = lineList.join(String.fromCharCode(5));
        }
        else
        {
            curElement = curElement[0];
            var lineList = curElement.value.split(/\r?\n/);
            sReturn = lineList.join(String.fromCharCode(5));
        }
    }
    else if (curType != "fieldset" )
    {
        sReturn = curElement.value;
    }

    return sReturn;
}

function Machine_doCheckMandatoryData(fldnam, linenum)
{
 return true;
}

function Machine_checkMandatoryData(skipfield)
{
    var emptylabels = "";
	for (var i = 0; i < this.countFormElements() ; i++)
	{
		if ( this.isElementRequired( i ) && this.getFormElement( i ).name != skipfield)
        {
            var field = this.getFormElement( i );
            for (var linenum=1;linenum < this.getMachineIndex(); linenum++)
            {
				// we can override the mandatoryness of a field on a line by line
				// basis by creating a field called "mandatoryFIELDNAME", where FIELDNAME
				// is the name of the field.  If the value of the "mandatoryFIELDNAME"
				// field is "F" for a particular line, the field is not mandatory
				// for that line.  For an example, see "mandatorylocation" in NLItemMachine.java.
				if (this.doCheckMandatoryData(field.name,linenum) &&
					getEncodedValue(this.name,linenum,'mandatory'+field.name) != 'F' &&
                    getEncodedValue(this.name,linenum,field.name).length == 0)
                {
                    emptylabels += (emptylabels.length != 0 ? ", " : "") + this.getElementDisplayLabel( i ) + " (on line " + linenum + ")";
                    break;
                }
            }
        }
        else if (this.getFormElementType( i ) == "namevaluelist")
        {
            var field = this.getFormElement( i );
            var mandfields = new Array();
            for (var linenum=1;linenum <this.getMachineIndex(); linenum++)
            {
                var nvarray = getEncodedValue(this.name,linenum,field.name).split(String.fromCharCode(4));
                for (var j=0; j < nvarray.length; j++)
                {
                  var nv = nvarray[j].split(String.fromCharCode(3));
                  if (nv[1] == 'T' && !(mandfields[nv[0]] == true))
                  {
                      if (nv[3].length == 0)
                      {
                        emptylabels += (emptylabels.length != 0 ? "," : "") + nv[2];
                        mandfields[nv[0]] = true;
                      }
                  }
                }
            }
        }
    }
    if (emptylabels.length > 0)
    {
        if (emptylabels.indexOf(',') != -1)
          alert('Please enter value(s) for: ' + emptylabels);
        else
          alert('Please enter a value for ' + emptylabels);
        return false;
    }
    else
        return true;
}


function Machine_isMandatoryOnThisLine(linenum,elementnum)
{
    var mand = false;
    if (this.miniform.elements['mandatory'+this.getFormElementName(elementnum)])
        mand = this.miniform.elements['mandatory'+this.getFormElementName(elementnum)].value != 'F';
    else if (hasEncodedField(this.name,'mandatory'+this.getFormElement(elementnum).name))
        mand = getEncodedValue(this.name,linenum,'mandatory'+this.getFormElement(elementnum).name) != 'F';
    else if (this.getFormElement( elementnum ) != null)
        mand = getRequired(this.getFormElement( elementnum ));
    return mand;
}

function Machine_addline(gonext)
{
    
    if(this.isCurrentlySegmented)
        gonext = true;

	if (!window.isinited) return false;

	var linenum = parseInt( this.getMachineIndex() );
	var maxline = parseInt( this.getMaxIndex() );
	if (!this.allow_insert && maxline < linenum+1)
	{
		alert("Please choose a line to edit");
		return false;
	}

	if ((document.forms['main_form'].elements.nlapiVL != null || document.forms['main_form'].elements.nsapiVL) && !nlapiValidateLine(this.name))
	   return false;

	if (!this.validateline())
		return false;

	var i;
	var fields = new Array();
	var labels = new Array();
	var allFieldsAreEmpty = true;

	for ( i = 0; i < this.countFormElements() ; i++)
	{
		if (((this.isElementRequired( i ) && this.isMandatoryOnThisLine(linenum,i)) || (this.getFormElementType( i ) == "namevaluelist" && this.getFormElement( i ).value.length > 0)) && this.doCheckMandatoryData(this.getFormElement( i ).name, linenum))
		{
			fields[fields.length] = this.getFormElement( i );
			labels[labels.length] = this.getElementDisplayLabel( i );
		}
		// there are cases where machines have no mandatory fields.  In this case you can hit the add button to add a row with no values.
		// this does not make sense, and complicates the back end a great deal.  As long as we think all the fields are
		// empty, we'll check each field for a value
		if( allFieldsAreEmpty && !isempty( this.getFormElement( i ) ) )
			allFieldsAreEmpty = false;
	}

    if ( fields.length > 0 )
	{
		var emptylabels = checkMandatoryFields(fields, labels);
		if ( emptylabels.length != 0 )
		{
			if (emptylabels.indexOf(",") != -1)
				alert("Please enter value(s) for: "+emptylabels);
			else
			    alert("Please enter a value for "+emptylabels);
			return false;
		}
	}

	// if all the fields are empty (a machine can have no mandatory fields) there is no point in adding the row
	if ( allFieldsAreEmpty )
	{
		alert("Please enter a value into at least one field before adding the row.");
		return false;
	}

    if (this.uniquefield != null && !this.checkunique())
        return false;

    
    this.updateLineData();

    if (this.preferredfield != null && getEncodedValue(this.name,linenum,this.preferredfield) == 'T')
        this.setPreferredValue(linenum);
	this.recalc();
    this.isinserting = false;
	
    if (gonext == true && linenum < this.getNextIndex()-1)
    {
        this.ischanged=false;
        this.viewline(linenum+1)
		this.postprocessline(linenum);
		this.nlapilinecommit(linenum);
    }
    else
	{
        this.clearline(false);
		this.postprocessline(linenum);
		this.nlapilinecommit(linenum);
		this.getsyncline( linenum - 1);
	}
    this.waschanged = true;
	return true;
}


function Machine_updateLineData( )
{
    
    var linenum = parseInt( this.getMachineIndex() );
    var formElems = this.countFormElements();
	var linedata = new Array();
	for (var i=0; i < formElems; i++)
	{
		var curType = this.getFormElementType( i );
		var curName = this.getFormElementName( i );
		var curElement = this.getFormElement( i );

		if ( curType == "select" || curType == "slaveselect" )
		{
			if (isMultiSelect( curElement ) || isPopupMultiSelect( curElement ))
			{
				linedata[i] = getMultiSelectValues( curElement );
			}
			else
			{
				linedata[i] = getSelectValue( curElement );
			}
		}
		else if ( curType == "checkbox" )
		{
            linedata[i] = curElement.checked ? "T" : "F";
		}
		else if ( curType == "radio" )
		{
			for (var j=0; j < curElement.length; j++)
				if ( curElement[j].checked)
					linedata[i] = curElement[j].value;
		}
		else if ((curType == "text" || curType == "textarea") && this.isElementPopupDisplayField(i)
				&& i < this.countFormElements()-1
				&& (this.getFormElementType( i+1 ) == "integer" || this.getFormElementType( i+1 ) == "slaveselect")
				&& this.getFormElement( i+1 ).value.length == 0)
		{
			linedata[i] = '';
		}
		else if ( curType == "address" || curType == "textarea")
		{
            linedata[i] = curElement.value.replace(/\r/g,'').replace(/\n/g,String.fromCharCode(5));
		}
		else if (curType == 'fieldset_inline')
		{
			 linedata[i] = getInlineTextValue(document.getElementById(this.getFormElementName(i)+"_val"));
		}
		else if (curType != "fieldset")
		{
			linedata[i] = curElement.value;
		}
		
		if (curElement != null && this.getFormElementFieldSet(i).length > 0)
		{
			var spanName = this.name + "_" + (curName.indexOf( '_display' ) == -1 ? curName : this.getFormElementName( i+1 )) + '_fs';
			var spanObj = document.getElementById( spanName );
			if (spanObj != null && spanObj.style.display == 'none')
			{
				linedata[i] = "";
			}
		}

		
        if (linedata[i] != null)
        {
            var regExp = new RegExp("[" + String.fromCharCode(1) + String.fromCharCode(2) + "]", "g");
			
            linedata[i] = new String(linedata[i]).replace(regExp,'.');
        }
        
        if ( window.virtualBrowser )
        {
            setEncodedValue(this.name, linenum, curName, linedata[i] != null ? linedata[i] : '')
        }
    }

    
	var linearray2 = getLineArray( this.name );

	var linearray = linearray2 == null ? new Array() :  linearray2;

	var maxline = parseInt( this.getNextIndex() );
	if (maxline < linenum+1)
	{
        this.setIndex( (linenum+1).toString() );
        linearray[linearray.length] = "";
	}

	linearray = (linearray.slice(0,linenum-1).concat(linedata.join(String.fromCharCode(1)))).concat(linearray.slice(linenum));
	setLineArray(this.name,linearray);
}


function machine_line(val, type, dir_up, idx)
{
	this.val = val
	this.dir_up = dir_up;
	this.type = type;
    this.idx = idx;
}

function Machine_sortlines(line1, line2)
{
    var result = l_sortnodes2(line1.val, line2.val, line1.type.toUpperCase()) * (line1.dir_up ? 1 : -1);
    return result;
}


function Machine_sort(nColumn)
{
    if (!window.isinited) return false;
    if(nColumn == this.sortIndex)
        this.sortDirUp = !this.sortDirUp;
    else
        this.sortDirUp = true;

    this.sortIndex = nColumn;
    var colType = this.getFormElementType(nColumn);
    window.status = this.sortIndex+' '+colType;
    var linearray = getLineArray(this.name);

    var lines = new Array();
    var i;
    var str = '';
    for (i=0;i < linearray.length;i++)
    {
        var cells = splitIntoCells(linearray[i]);
        var val = cells[nColumn];
        if(colType == 'select')
            val = getlisttext( this.getFormElement(nColumn), val );
        str += val + ' ';
        lines[i] = new machine_line(val, colType, this.sortDirUp, i);
    }

    lines.sort(Machine_sortlines);
    var newLineArray = new Array();
    for (i=0;i< linearray.length;i++)
    {
        newLineArray[i] = linearray[lines[i].idx];

    }
	setLineArray(this.name,newLineArray);

    this.buildtable();
}

function Machine_getTableName()
{
    return this.tableobj == null ? null : this.tableobj.id;
}


function Machine_createGrippyCell()
{
    var cell = null;

    if (this.allowMoveLines)
    {
		cell = document.createElement("TD");
        cell.innerText = ' ';
        cell.style.whiteSpace = "nowrap";
        if(isIE)
            cell.style.width = "1%";
        else
            cell.style.width = "5px";
    }
    return cell;
}

function Machine_createDeleteCell(index)
{
    var cell = null;

    if (this.allowQuickDeleteLines)
    {
		cell = document.createElement("TD");
        var img = document.createElement( "IMG" );
        img.border = 0;
        var bRequired = this.isRowRequired(index);
        img.src = "/images/icons/controls/machine_x"+(bRequired ? "_dis" : "")+".gif";
        if(!bRequired)
        {
            img.onclick = new Function(this.name+"_machine.deleteline("+(index)+");window.ischanged=true;return false;");
            cell.style.cursor = "hand";
        }
        cell.appendChild( img );
        cell.style.width = "14px";
        cell.valign = 'middle';
    }
    return cell;
}


function Machine_createColumnHeaderCell(sLabel)
{
    cell = document.createElement("TD");
    var div = document.createElement("div");
    div.className = "machineheadernosort";
    var txt = document.createTextNode(sLabel);
    div.appendChild(txt);
    cell.appendChild(div);
    cell.height = "100%";
    cell.className = "smalltextctr";

    return cell;
}

var min_segment_size = 5;
var max_segment_size = 25;

var editmachineCounter = 0;
var editmachineConstructorTime = 0;


function Machine_buildtable(startIndex, bNoFocus)
{

    var startTime = new Date().getTime();

    
    var timerID = pTransferTimeouts[this.name];
    if(timerID)
        clearTimeout(timerID);
    pTransferTimeouts[this.name] = null;

    if(window.fieldSetDiv != null && window.fieldSetDiv.parentNode)
    {
        var parent = window.fieldSetDiv.parentNode;
        parent.removeChild(window.fieldSetDiv);
    }

    
    if (this.currentRowNum == 0 && !this.allow_insert)
        this.setupLineData(this.getMachineIndex());

    this.currentRowNum = 0;      
    if (this.isinline && !this.hasInterceptedEvents)
    {
		
		this.createFocusElement();

        
        for (var i=0; i < this.countFormElements(); i++)
        {
			if (this.getFormElementFieldSet(i).length == 0)
				Mch_setUpEventHandlerInterception(this, this.getFormElement(i), this.getFormElementType(i));
        }
        this.hasInterceptedEvents = true;
    }

    this.suspendEdit();
	var tablename = this.getTableName();

    
    this.tableobj = document.getElementById(tablename);
    var maintable =   this.tableobj.firstChild ;

    
	if ( this.isinline && this.moveButtons)
		moveButtonDiv(this.name);
    if (maintable.hasChildNodes())
    {
    	var trs = maintable.getElementsByTagName("TR");
        for ( var j = trs.length; j >= 0; j-- )
        {
            if ( maintable.firstChild != null )
                maintable.removeChild( maintable.firstChild );
        }
    }
    
    var rowArray = new Array();
    var rowCount = 0;

    
    var row = document.createElement("TR");
    
	row.id = this.name+"_headerrow";
    var cell = null;

    
    if (this.allowMoveLines)
    {
        cell = this.createColumnHeaderCell(' ');
        cell.style.width = "5px";
        cell.innerText = " ";
        row.appendChild( cell );
    }

    
    if (this.showRowNumbers)
    {
        cell = this.createColumnHeaderCell(this.rowNumberLabel);
        row.appendChild( cell );
    }

    
    var nHeaderLabelCount = 0;
    for (var i = 0; i < this.countFormElements(); i++)
    {
        if ( this.getFormElementLabel( i ).length > 0 && this.getFormElementFieldSet( i ).length == 0 )
        {
			cell = document.createElement("TD");
            cell = this.getDisplayHeaderCell( i, cell);
			row.appendChild( cell );
            
            nHeaderLabelCount++;
        }
    }
    this.nHeaderLabelCount = nHeaderLabelCount;

    rowArray[rowCount++] = row;

    
    var linearray = getLineArray(this.name);
    var maxline = parseInt( this.getNextIndex() );

    this.segmentStartIndex = (startIndex && this.segmentable ? startIndex : this.segmentStartIndex);
    var bUseSegment = this.manageSegmentSelect(maxline);
    var actual = 1;
    var segmentLimit = Math.max(0,parseInt(this.segmentStartIndex)) + parseInt(max_segment_size);

    for (var linenum = 1; linenum < maxline; linenum++ )
    {
        if (bUseSegment && (linenum < this.segmentStartIndex || linenum >= segmentLimit ))
            continue;
        row = this.constructMainTableRow(linearray, linenum);
        rowArray[rowCount++] = row;
        actual++;
    }

    
    var limit = 1;
    if (this.isinline && this.allow_insert)
        limit = maxline;

    var elemCount = this.countFormElements();
    var fieldnames = this.getFormFieldNames();

    var onClick = "if (window.isinited) { if("+this.name + "_machine.ischanged) " +
                                                         this.name + "_machine.addline(); " +
                                                   "else " +
                                                          this.name + "_machine.clearline(false, "+this.lastStartSegmentIndex+");}";
    var bInLineEditingAwaitingInsert = this.isinline && this.allow_insert && ( this.getMachineIndex() != this.getNextIndex()  || ( bUseSegment && this.getMachineIndex() != this.getAdjustedSegmentIndex(actual, true) ) );
    for (; linenum <= limit; linenum++)
    {
		row = document.createElement("TR");

        if(!this.isinline)
        {
            row.onclick = new Function(onClick);
        }

        row.className = 'listtextnonedit';

        if(bInLineEditingAwaitingInsert)
        {
            var colspan = (this.showRowNumbers ? 1 : 0) + (this.allowMoveLines ? 1 : 0) + (this.allowQuickDeleteLines ? 1 : 0);

            
            for (var i=0; i < elemCount; i++)
            {
                if (this.getFormElementLabel(i).length > 0 && this.getFormElementFieldSet(i).length == 0 )
                {
                    colspan++;
                }
            }

            
            cell = document.createElement("TD");
            cell.colSpan = colspan;
            cell.className = this.allWhiteDisplayMode ? "listtexthlwht" : "listtexthl";
            cell.style.color="#666666";
            cell.style.cursor="default";
            cell.innerHTML = "[Click here for a new line]";
            row.appendChild( cell );
            row.onclick = new Function(onClick);
        }
        else
        {
            var iStartCol = (this.showRowNumbers ? 1 : 0) + (this.allowMoveLines ? 1 : 0);

            
            for(var j=0; j < iStartCol; j++)
            {
                cell = document.createElement("TD");
                cell.className = 'listtextnonedit';
                cell.innerText = " ";
                cell.style.width = "5px";
                row.appendChild( cell );
            }

            
            for (var i=0; i < elemCount; i++)
            {
                if (this.getFormElementLabel(i).length > 0 && this.getFormElementFieldSet(i).length == 0)
                {
                    
                    cell = document.createElement("TD");
                    cell.align = this.getAlignmentForColumn(i);

                    
                    if(this.isinline)
                    {
                        cell.className = 'listtextnonedit';
                        cell.style.cursor = "hand";
                        var di = this.isElementPopupDisplayField(i) ? 1 : 0;
						var colnum = this.isElementDisplayOnlyWithField(i) ? null : (i+di);
					    var jsClk = this.name + "_machine.viewline(" + linenum + "," + colnum +", true); return true;";
                        cell.onclick = new Function(jsClk);
                    }
                    cell.innerText = " ";
                    row.appendChild( cell );
                }
            }
            if(this.allowQuickDeleteLines)
            {
                cell = document.createElement("TD");
                cell.className = 'listtextnonedit';
                cell.innerText = " ";
                cell.style.width = "5px";
                row.appendChild( cell );
            }
        }
        rowArray[rowCount++] = row;
    }

    
    row = document.createElement("TR");

    if (cell = this.createGrippyCell())
    {
        row.appendChild( cell );
    }

    if (this.showRowNumbers)
    {
        
        cell = this.createColumnHeaderCell(this.rowNumberLabel);
        cell.style.width = "10px";
        row.appendChild( cell );
    }

    var i;
    var countElems = this.countFormElements();
    for ( i = 0; i < countElems; i++)
    {
        if ( this.getFormElementLabel( i ).length == 0 || this.getFormElementFieldSet( i ).length > 0 ) 
            continue;
        cell = document.createElement("TD");
        cell.className = 'listtextnonedit';
        cell.style.borderWidth = "1 0 1 1";
        cell.align = this.getAlignmentForColumn(i);
        cell.innerText = " ";
        row.appendChild( cell );
    }

    if (cell = this.createDeleteCell())
    {
        row.appendChild( cell );
    }

    this.lastRow = row;
    this.lastRow.style.height = "1px";
    this.lastRow.style.visibility = "hidden";
    rowArray[rowCount++] = row;

    
	
		
		for ( var i = 0; i < rowArray.length; i++ )
			maintable.appendChild( rowArray[i] );
	

    if(this.allow_insert || linearray.length>0)
    {
        if (this.showEditor)
        {
            this.editRow( this.getAdjustedSegmentIndex( this.getMachineIndex(), false), !bNoFocus );
        }
        else
        {
            this.setFocus(this.focusedColumn);
        }
    }
    window.status = "";
	this.hasRendered = true;
    
    if(this.bResizeBackgroundDiv)
        sizeLowerTabBGDiv(this.name);

    this.postBuildTable();

    editmachineConstructorTime += ( new Date().getTime() - startTime );
    return false;

}


function Machine_postBuildTable()
{
    return;
}

function Machine_manageSegmentSelect(maxline)
{
    var totalSegments = Math.ceil( ((maxline-1)/max_segment_size) );
	var bShowAll = this.segmentStartIndex == -1;
	var bUseSegment = !bShowAll && totalSegments > 1;

	if(this.segmentable && (bUseSegment || bShowAll))
	{
		deleteAllSelectOptions(this.getSegmentSelect());
		var startSegment = 1;
		
		for(var i=0; i<totalSegments; i++)                                                        // >
        {
			var endSegment = Math.min(startSegment + max_segment_size - 1, maxline-1);
			addSelectOption(document,this.getSegmentSelect(),startSegment + " - " + endSegment + " of " + (maxline-1),startSegment,false);
			this.lastStartSegmentIndex = startSegment;
			
			if(!bShowAll && this.segmentStartIndex == startSegment)
            {
				setFormValue(this.getSegmentSelect(), startSegment);
                if(this.getMachineIndex() < startSegment || this.getMachineIndex() > endSegment)
                    this.setMachineIndex(this.getNextIndex());
				this.isCurrentlySegmented = true;
				this.segmentStartIndex = startSegment;
			}
			startSegment += max_segment_size;
		}


		
		addSelectOption(document,this.getSegmentSelect(),'All',-1,false);
        if(bShowAll)
        {
            setFormValue(this.getSegmentSelect(), -1);
            this.isCurrentlySegmented = false;
            this.lastStartSegmentIndex = -1;
        }
	}
    else
    {
		
		this.segmentStartIndex = 1;
        this.lastStartSegmentIndex = 1;
        this.isCurrentlySegmented = false;
    }

    
    showFieldAndLabel(this.name+"_segment_select_fs", (bUseSegment || bShowAll) );

    
    if( this.segmentable && bUseSegment )
    {
        var fieldSpan = document.getElementById(this.name+"_segment_select_fs");
        fieldSpan.parentNode.previousSibling.style.width = "80%";
	}

	
	return bUseSegment && this.segmentable;
}

	

function Machine_constructMainTableRow(linearray, index)
{
    if ( linearray == null )
        linearray = getLineArray(this.name);

    var linedata = splitIntoCells( linearray[index-1] );
    var classcolor = this.allWhiteDisplayMode ? "listtexthlwht" : "listtexthl";

    if (index == this.getMachineIndex() && !this.isinline)
    {
        classcolor = "seltexttable";
    }
    var rowClass = null;
    if (index == this.getMachineIndex() && this.isinline)
    {
        onclick = null;
        classcolor = 'listtextnonedit';
        rowClass = 'listtextnonedit';
    }

	row = document.createElement("TR");
	
	row.id = this.name+"_row_"+index;

    
    if (rowClass != null) row.className = rowClass;
    
    if ( this.allowMoveLines)
		addDragDropHandlersToRow( this.name, row, (index == this.getMachineIndex()) );

    
    if (this.allowMoveLines)
    {
		var cell = this.createGrippyCell();
        cell.className = classcolor;
        
        
        
        cell.style.backgroundImage = "url('" + location.protocol + "//" + location.host + "/images/nav/endcaps/grippy2.gif')";
        
        cell.style.backgroundRepeat = "no-repeat";
        cell.style.backgroundPosition = "center";
		row.appendChild( cell );
    }

    
    if (this.showRowNumbers)
    {
		var cell = document.createElement("TD");
        cell.className = classcolor;
        cell.align = "center";
        cell.innerText = " " + index + " ";
		row.appendChild( cell );
    }

    var i;
    var countElems = this.countFormElements();
    var di;
    var fieldnames = this.getFormFieldNames();
    var bFirstVisibleColumn = true;
    for ( i = 0; i < countElems; i++)
    {
        if ( this.getFormElementLabel( i ).length == 0 || this.getFormElementFieldSet( i ).length > 0 )   
        {
            continue;
        }
	    var cell = document.createElement("TD");
        cell.className = classcolor;
        cell.align = this.getAlignmentForColumn(i);
        cell.noWrap = cell.align == "right";
        if (this.indentFirstVisibleColumn && bFirstVisibleColumn)
        {
            var indentColumnIndex = i+1;
            if (fieldnames[i].indexOf('_display') != -1)
                indentColumnIndex++;
            var indentLevel = (linedata[indentColumnIndex]) ? linedata[indentColumnIndex] : 0;

            cell.style.paddingLeft = 20*parseFloat(indentLevel)+'px';
        }
        if (linedata != null)
            cell.innerHTML = this.getDisplayCellContent(i, linedata[i], index);
        else
            cell.innerHTML = "&nbsp;"; 
        cell.style.cursor = "hand";

        di = this.isElementPopupDisplayField(i) ? 1 : 0;
        var colnum = this.isElementDisplayOnlyWithField(i) ? null : (i+di);
        
            var jsClk = this.name + "_machine.viewline(" + index + "," + colnum +", true); return true;";
        


        cell.onclick = new Function(jsClk);
		row.appendChild( cell );
		bFirstVisibleColumn = false;
    }

    if (this.allowQuickDeleteLines)
    {
		var cell = this.createDeleteCell(index);
        cell.className = classcolor;
		row.appendChild( cell );
    }

    return row;
}


function addDragDropHandlersToRow( machinename, row, selected )
{
	row.machineName = machinename;
	if ( selected )
	{
		row.selectedRow = true;
		row.style.cursor = "move";
	}
	row.onmousedown = OrderedListOnMouseDown;
	row.onmousemove = OrderedListOnMouseMove;
	row.onselectstart = OrderedListCancelDragDrop;
}

function cleanUpCellContents(cell)
{
	while (cell.firstChild != null)
    {
		cell.removeChild(cell.firstChild);
    }
}


function setCellContents(cell, contents, mch, i, curType, elIndex)
{
    
    if( mch.bShowAllEditedFields )
    {
        cleanUpCellContents(cell);
        cell.appendChild(contents);
        return;
    }
    
	if (isIE)
		cell.style.height = cell.offsetHeight;
	else
		cell.style.height = "100%";

    mch.copiedlastrowcell = i;

    var bc = mch.lastRow.cells[i];
    if(bc.firstChild)
    {
        while(bc.firstChild)
        {
            bc.removeChild(bc.firstChild);
        }
    }

    
    var pChildren = cell.childNodes;
    var nChildren = pChildren.length;

    
    for(var i = 0; i < nChildren; i++)
    {
        bc.appendChild(pChildren[i].cloneNode(true));
    }

    
    while (cell.firstChild != null)
    {
        var temp = cell.firstChild;
        cell.removeChild(cell.firstChild);
    }

    var spc     = mch.cellContainerDIV;
    var spHover = mch.cellHoverDIV;

    if(!spc)
    {
        spc = document.createElement("div");
        spc.className      = "bigouter";
        spc.style.display  = "block";
        spc.style.margin   = "0 0 0 0";
        spc.style.padding  = "0 0 0 0";
        spc.style.border   = "0px dashed red";
        spc.style.position = "relative";
        spc.style.height   = "100%";
        spc.style.width    = "100%";
        spc.style.zIndex   = 1000;
        

        spHover = document.createElement("div");
        spHover.className = 'divhover';
        spHover.style.width    = "100%";
        spHover.style.height = "100%";
        spHover.style.left     = "0px";
        spHover.style.top      = "0px";
        spHover.style.padding  = "0 0 0 0";
        spHover.style.margin   = "0 0 0 0";
        

        spHover.sourceMachine = mch;

        spc.appendChild(spHover);

        mch.cellContainerDIV = spc;
        mch.cellHoverDIV = spHover;
    }


    spHover.style.border   = "0px solid black";
    spHover.style.position = "absolute";
    
    spc.style.border = "1px solid black";
    
    spc.style.overflow     = "visible";

    var bDoRelayout = true;

    if(curType == "fieldset")
    {
        spc.style.border = "0px solid black";
        spHover.style.position = "relative";
    }
    else if (curType == "integer" && elIndex > 0 && mch.isElementPopupDisplayField(elIndex-1))
    {
        if(getDropdown(contents))
        {
            curType = "select";
        }
        else
        {
            var field = contents.getElementsByTagName("TEXTAREA").length > 0 ? contents.getElementsByTagName("TEXTAREA")[0] : contents.getElementsByTagName("SELECT")[0];
            if(field)
				field.style.border ="1px solid #666666";

            if( contents.firstChild.style)
            {
                contents.firstChild.style.position = "relative";
                contents.firstChild.style.width = "100%";
            }
            else
            { 
                contents.style.width= "100%";
            }

        }
    }
    else if(curType == "textarea")
    {
		// This line causes a bizarre border effect when a textarea has a helper button.
		// We really just want a border on the textarea itself, not the entire div.
		// Luke helped me track this down, and he thought it was safe to comment this out,
		// but suggested that I talked to GYachuk about it.
		// RGrisso, 12/20/05
		// spHover.style.border   = "1px solid #999999";

        var field = contents.tagName == 'TEXTAREA' ? contents : contents.firstChild;
		field.style.width = "100%";
		field.style.border ="1px solid #666666";
		if(!field.origOnBlur)
        {
            
			field.origOnKeyUp = field.onkeyup ? field.onkeyup : function(){};
            field.onkeyup     = function(){this.origOnKeyUp(); NLMachine_updateTextAreaSize(this);};
            field.origOnBlur  = field.onblur ? field.onblur : function(){};
			// 'spc.style.overflow = "hidden"' causes problems when textareas have helper buttons.
			// This is a hack to prevent the problem in the specific case of binnumbers.  I
			// talked to Rajesh about a general solution, but he felt this was probably the
			// best workaround it is not a common use case.
			// Rgrisso, 12/20/05
			if (field.id.indexOf('binumbers') != -1)
				field.onblur      = function(){this.origOnBlur(); spc.style.overflow = "hidden";};
            field.origOnFocus = field.onfocus ? field.onfocus : function(){};
            field.onfocus     = function(){this.origOnFocus(); spc.style.overflow = "visible";};
        }
        NLMachine_updateTextAreaSize(field);
    }
    else if(curType == "slaveselect" && elIndex > 0 && mch.isElementPopupDisplayField(elIndex-1))
    {
		
		if(contents.tagName != 'SELECT' && contents.firstChild.style)
        {
            
            contents.firstChild.style.position = "relative";
            contents.firstChild.style.width = "100%";
        }
    }
    else if((curType == "select") || (curType == "slaveselect"))
    {
        if( mch.nHeaderLabelCount == 1 )
        {
            
            bDoRelayout = false;
            spc.style.borderWidth = "0 0 0 0";
        }
    }
    else if(curType == "namevaluelist")
    {
        contents.firstChild.style.width = "100%";
    }
    else if(curType == "color")
    {
        
    }
    else
    {
        contents.style.width   = "100%";
        if(curType == "checkbox")
        {
            contents.style.textAlign = "center";
        }
        else if (contents.tagName == "INPUT")
        {
            contents.style.width = "100%";
        }
        else
        {
            contents.firstChild.style.width = "100%";
        }
    }

    spHover.style.width = "100%";
    
    spHover.style.top = "-1px";
    

    spHover.appendChild(contents);


    
    if(bDoRelayout && (curType == "select" || curType == "slaveselect"))
    {
        var dd = getDropdown(contents);
        if( dd )
        {
            mch.layoutdd = dd;
            mch.layoutparent = cell;
            mch.showinparent = spc;
            dd.inpt.style.width = "100%";
			dd.inpt.style.height = "18";
			cell.style.borderWidth = "0 0 0 1";
            dd.setText(null, false, null);

            setTimeout(new Function("this.relayout(" + window.loadcomplete + "==true)").bind(mch), 100);
        }
        else
        {
            
			
            
        }
    }

    cell.appendChild(spc);

    
    if( curType=="fieldset" )
    {
        var div = document.createElement("DIV");
        div.id = "fieldset_options_div";
        window.fieldSetDiv = div;
        div.style.zIndex = 1000;
        div.style.borderWidth = 0;
        div.style.position = "absolute";

        var fieldDiv = null;
        var img = null;
		fieldDiv = document.createElement( "DIV" );
		fieldDiv.style.borderStyle = "solid";
		fieldDiv.style.zIndex = 1000;
		fieldDiv.style.borderWidth = 1;
		fieldDiv.style.borderColor = "#999999";
		fieldDiv.style.backgroundColor = "#EFEFEF";
		fieldDiv.style.position = "relative";


		var innerDiv = document.createElement( "DIV" );
		fieldDiv.appendChild( innerDiv );
		innerDiv.style.padding = 5;
		innerDiv.style.borderStyle = "solid";
		innerDiv.style.zIndex = 1000;
		innerDiv.style.borderWidth = 1;
		innerDiv.style.borderColor = "#FFFFFF #CCCCCC #CCCCCC #FFFFFF";

		var button = document.createElement("INPUT");
		button.type = "button";
		button.name = "done";
		button.id = mch.name + "_fldsetbutton_done";
		button.value = "Done";
		button.className = "nlbuttontiny";
		button.onclick = new Function('evnt', mch.getFieldSetDoneAction());

		contents.style.display = "block";
		innerDiv.appendChild(contents);
		innerDiv.appendChild(button);

		if(mch.getFieldSetIncludesCancelButton())
		{
			var buttonCancel = document.createElement("INPUT");
			buttonCancel.type = "button";
			buttonCancel.name = "cancel";
			buttonCancel.id = mch.name + "_fldsetbutton_cancel";
			buttonCancel.value = "Cancel";
			buttonCancel.className = "nlbuttontiny";
			buttonCancel.onclick = new Function('evnt', mch.name + "_machine.clearline(true); setEventCancelBubble(evnt); return false;");

			var spacerImg = document.createElement( "IMG" );
			spacerImg.src = "/images/nav/stretch.gif";
			spacerImg.height=10;
			spacerImg.width=8;
			spacerImg.border=0;

			innerDiv.appendChild(spacerImg);
			innerDiv.appendChild(buttonCancel);
		}

		img = document.createElement( "IMG" );
		img.border=0;
		img.src = '/images/reportbuilder/fieldsetdown.gif';
		img.height = '16';
		img.width = '17';
		img.style.position = "relative";
		img.style.zIndex = 10000;
		img.style.top = 1;

        var outerDiv = document.createElement( "DIV" );
        outerDiv.style.position = "relative";
		outerDiv.appendChild( img );
		outerDiv.appendChild( fieldDiv );
		outerDiv.style.left = 5;
        outerDiv.style.top = (-1*parseInt(cell.offsetHeight))+3;

        div.appendChild( outerDiv );

        cell.appendChild( div );

        NLMachine_positionFieldsetDiv(fieldDiv, cell, img);
        setTimeout(function (){NLMachine_positionFieldsetDiv(fieldDiv, cell, img);},  300);
    }
    cell.origClassName = cell.className;
    cell.className = "editedcell";
}

function NLMachine_positionFieldsetDiv(innerDiv, cell, img)
{
    var leftOffset = 0;
    var topOffset = 0;

    if( (findPosX(innerDiv) + innerDiv.offsetWidth) > (getDocumentClientWidth()+document.body.scrollLeft) )
    {
        leftOffset -= (findPosX(innerDiv) + innerDiv.offsetWidth) - (getDocumentClientWidth()+document.body.scrollLeft) + 10;
    }
    if( (findPosY(innerDiv) + innerDiv.offsetHeight) > (getDocumentClientHeight()+document.body.scrollTop) )
    {
        topOffset -= innerDiv.offsetHeight + 13;
        img.src = '/images/reportbuilder/fieldsetdown_above.gif';
    }

    innerDiv.style.left = leftOffset;
    innerDiv.style.top = topOffset;
}


function NLMachine_updateTextAreaSize(field)
{
    var sContent = field.value + ".";
    var pLines = sContent.split("\n");
    var nLines = pLines.length
    var nRows  = nLines;

    
    for(var i=0; i < nLines; i++)
    {
        nRows += parseInt( ((pLines[i]).length / 25) );
    }

    
    nRows++;

    
    if(nRows < 3)
    {
        nRows = 3;
    }
    else if(nRows > 20)
    {
        
        nRows = 20;
        field.style.overflow = "scroll";
    }
    else
    {
        
        field.style.overflow = "hidden";
    }

    if(nRows > 0)
    {
        field.rows = nRows;
    }
}

function Machine_relayout(bFocus)
{
	this.layoutdd.setText(null, bFocus==false? true : false, null);
	this.layoutdd.inpt.style.borderWidth = "0 0 1 0";
    this.layoutdd.inpt.style.borderColorTop = "#fefefe";
}

function Machine_imalive()
{
    alert('..imalive ' + this.name);
}


function Machine_transferInputFieldValuesToDisplayOnly()
{
    var rowNum = this.currentRowNum;
	var table = this.tableobj;
    var rows = table.getElementsByTagName("tr");

	if ( (rows.length - (this.isCurrentlySegmented && (this.segmentStartIndex != this.lastStartSegmentIndex) ? 3 : 0) ) <= rowNum)
		return;
    var newRow = rows[rowNum];
    var lastCell = null;

    var fieldnames = this.getFormFieldNames();
	var elems = this.getInputElements(false, fieldnames);

    
	var column = -1 + (this.showRowNumbers ? 1 : 0) + (this.allowMoveLines ? 1 : 0);

    var lastWasDisplay = false;

	for (var i=0; i < elems.length; i++)
    {
        var field = null;
        var label = null;

        var fieldAndLabel = this.getFieldOverride(elems, newRow, rowNum, i);
        if (fieldAndLabel)
        {
            field = fieldAndLabel == null ? null : fieldAndLabel[0];
            label = fieldAndLabel == null ? null : fieldAndLabel[1];
        }
        else
        {
            field = elems[i];
            label = (lastWasDisplay) ? this.getFormElementLabel(i-1) : this.getFormElementLabel(i);
        }
        if ((label == null) || (label.length == 0) || this.getFormElementFieldSet(i).length > 0)
            continue;
        if (!lastWasDisplay)
            ++column;
        lastWasDisplay = this.isElementPopupDisplayField(i);

        var parent = newRow.cells[column];

        
        if((field) && this.isNeedUpdateFieldDisplayValue(field))
        {
            var sVal = this.getDisplayHTMLOfField( field.indexOfEditor );
            sVal = this.getDisplayCellContent(field.indexOfEditor, sVal);
            parent.innerHTML = sVal;
        }

		var st = parent.style;

        if( this.nHeaderLabelCount == 1 )
        {
            
            
            st.background = "rgb(223,226,231)";
            continue;
        }

        
        st.borderStyle = "solid";
        st.borderWidth = "1 0 1 1";
        st.borderColor = "#999999";

        lastCell = parent;

        var bEditable = false;
        var sBackgroundColor = "#ffffff";

        if(field)
        {
            bEditable = this.isFieldEditable(i)

            if(this.isElementRequired(i) && !this.isElementDisplayOnlyWithField(i))
            {
                if( !this.allWhiteDisplayMode )
                    st.background = sBackgroundColor = "#ffffe7";
                st.cursor = "hand";
            }
            else if(bEditable)
            {
                if( !this.allWhiteDisplayMode )
                    st.background = "#ffffff";
                st.cursor = "hand";
            }
        }

        if( !bEditable && !this.isElementDisplayOnlyWithField(i) )
        {

            st.cursor = "default";
			
            
            var sBackground = sBackgroundColor + " url('" + location.protocol + "//" + location.host + "/images/nav/crosshatchtile.gif') repeat fixed top left";
            NLMachine_deferredSetBackgroundStyle(parent, sBackground);
            
        }
        else
        {
            
            parent.setAttribute("sCurrentBackground","");
        }
     }

     
     if( lastCell )
     {
        lastCell.style.borderRightWidth = "1px";
     }
	this.adjustButtonPosition();
}

function Mch_callAllOnBlur(mch, field)
{
    var returnValue = true;	
	if (field.onblur)
    {    	
    	var bForcedAttribute = false;
        if( field.type == "textarea" )
        {
            bForcedAttribute = true;
            field.isvalid = true;
        }

		mch.applyFocusToFocusElement();

        if(field.isvalid == false)
        {
            returnValue = false;
        }
        if(bForcedAttribute)
        {
            field.isvalid = null;
        }
    }
	var childNodes = field.childNodes;

	if (childNodes != null)
    {
        for (var i=0; i < childNodes.length; i++)
        {
            if(!Mch_callAllOnBlur(mch, childNodes[i]))
            {
                returnValue = false;
                break;
            }
        }
    }
    return returnValue;
}

function MachineField_handleBlur()
{
    return this.originalOnBlur();
}

function MachineField_handleChange()
{
	var bReturnValue = false;
	if (this.originalOnChange)
        bReturnValue = this.originalOnChange();

    Machine_scheduleTransfer(this.machine);

	return bReturnValue;
}


function Mch_setUpEventHandlerInterception(mch, field, curType)
{
    
    var fldOnChange = (curType == "namevaluelist") ? field.form.elements[field.name+"_display"] : field;

    if( true )
    {
        fldOnChange.originalOnChange = fldOnChange.onchange ? fldOnChange.onchange : null;
        fldOnChange.handleChange = MachineField_handleChange;
        fldOnChange.machine = mch;
        fldOnChange.onchange = new Function("this.handleChange();");

        field.style.border = "0px";
    }

	var childNodes = field.childNodes;

	if (childNodes != null)
    {
        for (var i=0; i < childNodes.length; i++)
        {
            
            if (childNodes[i].nodeType == 1)
                Mch_setUpEventHandlerInterception(mch, childNodes[i], curType);
        }
    }
}


function Machine_gotoFieldWithName( fieldName )
{
	var nIndex = this.getArrayPosition( fieldName );
    this.gotoField(nIndex, true);
    this.setFocus(this.focusedColumn, true);
}


function Machine_fieldHasFocus( fieldName )
{
	var nIndex = this.getArrayPosition( fieldName );
    return nIndex == this.focusedColumn;
}



function Machine_setFocusToCurrentColumn()
{
    this.setFocus(this.focusedColumn, false);
}



function Machine_gotoField(delta, bAbsolute)
{
    var origfocusedColumn = this.focusedColumn;

    var bLineSubmitted = false;

    if(bAbsolute)
    {
        this.focusedColumn = delta;
    }
    else
    {
        
        this.focusedColumn = this.getFieldOffset(this.focusedColumn, delta);
    }

    if(origfocusedColumn == this.focusedColumn)
    {
        
        return false;
    }

	
    var elems = this.getInputElements(true);

	
    for (var i=0; i < elems.length; i++)
    {
        var field = null;
        var fieldAndLabel = this.getFieldOverride(elems, this.tableobj.getElementsByTagName("tr")[this.currentRowNum], this.currentRowNum, i);
        if (fieldAndLabel)
            field = fieldAndLabel[0];
        else
            field = elems[i];
		if (field == null || this.getFormElementFieldSet(i).length > 0)
            continue;

        var parent = field.parentNode;

        if( parent != this.miniform && !this.bShowAllEditedFields)
        {
            if(!Mch_callAllOnBlur(this, field))
            {
                this.focusedColumn = origfocusedColumn;
                return true;
            }

            parent = this.getParentTD(parent);

            Machine_reparent(field, this.miniform);

            
            if (parent.origPaddingTop)
                parent.style.paddingTop = parent.origPaddingTop;
            if (parent.origPaddingRight)
                parent.style.paddingRight = parent.origPaddingRight;
            if (parent.origPaddingBottom)
                parent.style.paddingBottom = parent.origPaddingBottom;
            if (parent.origPaddingLeft)
                parent.style.paddingLeft = parent.origPaddingLeft;

            parent.className = parent.origClassName;
            
			var bc;
			if (this.lastRow)
				bc = this.lastRow.cells[this.copiedlastrowcell];
            if(bc && bc.firstChild)
            {
                while(bc.firstChild)
                {
                    bc.removeChild(bc.firstChild);
                }
            }
        }
    }

    if(!bLineSubmitted)
        this.editRow(this.currentRowNum, true);

    this.transferInputFieldValuesToDisplayOnly();
	
    return true; 
}

function Machine_getParentTD(node)
{
	while(node.parentNode != null && node.parentNode.nodeName != "TD")
		node = node.parentNode;
	return node.parentNode;
}

function Machine_getParentTABLE(node)
{
	while(node.parentNode != null && node.parentNode.nodeName != "TABLE")
		node = node.parentNode;
	return node.parentNode;
}

function Machine_getParentDIV(node)
{
	while(node.parentNode != null && node.parentNode.nodeName != "DIV")
		node = node.parentNode;
	return node.parentNode;
}



function Machine_addEditor(elems, newRow, rowNum)
{
    newRow.onclick = null;

	var lastWasDisplay = false;
	var fieldnames = this.getFormFieldNames();
    var column = -1 + (this.showRowNumbers ? 1 : 0) + (this.allowMoveLines ? 1 : 0);

    if(!this.focusedColumn || !this.isFieldEditable(this.focusedColumn))
    {
        this.setColToFirstEditable();
    }

	for (var i=0; i < elems.length; i++)
	{
		var field = null;
        var label = null;

        var fieldAndLabel = this.getFieldOverride(elems, newRow, rowNum, i);
        if (fieldAndLabel)
        {
            field = fieldAndLabel == null ? null : fieldAndLabel[0];
            label = fieldAndLabel == null ? null : fieldAndLabel[1];
        }
        else
        {
            field = elems[i];
	    	label = (lastWasDisplay) ? this.getFormElementLabel(i-1) : this.getFormElementLabel(i);
        }
		if ((label == null) || (label.length == 0) || this.getFormElementFieldSet(i).length > 0)
			continue;
		if (!lastWasDisplay)
			++column;
		lastWasDisplay = this.isElementPopupDisplayField(i);

        var theCell = newRow.cells[column];

		if (field == null)
			continue;

        if( (i == this.focusedColumn && !this.isElementDisplayOnlyWithField(i)) || this.bShowAllEditedFields)
        {
            var st = theCell.style;
            Machine_showField(field);

            
            theCell.origPaddingTop = st.paddingTop;
            theCell.origPaddingRight = st.paddingRight;
            theCell.origPaddingLeft = st.paddingLeft;
            theCell.origPaddingBottom = st.paddingBottom;

            st.padding = "0 0 0 0";

            
            storeCheckboxState(field);

            var parent = field.parentNode;
            parent.removeChild(field);
            setCellContents(theCell, field, this, column, this.getRowFormElementType(i, rowNum), i);

            restoreCheckboxState(field);

            this.focusedCell = field;
            if( !this.bShowAllEditedFields )
                break;
        }
	}
}

function getButtonDiv(name)
{
	return document.getElementById(name + "_buttons");
}

function hideButtons(name)
{
    if (getButtonDiv(name))
	    getButtonDiv(name).style.display = "none";
}

function moveButtonDiv(name)
{
	hideButtons(name);
	var buttonDiv = getButtonDiv(name);
    if (buttonDiv)
    {
        buttonDiv.parentNode.removeChild(buttonDiv);
	    document.body.appendChild(buttonDiv);
	}
}

function NLMachine_doSetBackground(element, sBackgroundStyle)
{
    
    if(element.getAttribute("sCurrentBackground") != sBackgroundStyle)
    {
        element.style.background = sBackgroundStyle;
        element.setAttribute("sCurrentBackground",sBackgroundStyle);
    }
}


function NLMachine_deferredSetBackgroundStyle(element, sBackgroundStyle)
{
    if(window.loadcomplete) 
    {
        NLMachine_doSetBackground(element, sBackgroundStyle);
    }
    else
    {   
        setTimeout(function(){NLMachine_doSetBackground(element, sBackgroundStyle);}, 1);
    }
}

function NLMachine_adjustButtonPosition()
{
	if (!this.isinline)
		return;
	
}

function putButtonsInMachine(machine, newRow, table)
{
    if(newRow.hasButton || !machine.moveButtons)
    {
        return;
    }

    var name = machine.name;

    
    var buttonContainerDiv = document.createElement("div");
    
    buttonContainerDiv.style.position= "relative";
    buttonContainerDiv.style.width = "100%";
    
    buttonContainerDiv.style.padding = "0px";

    var buttonDiv = getButtonDiv(name);
	buttonDiv.parentNode.removeChild(buttonDiv);
    NLMachine_deferredSetBackgroundStyle(buttonDiv, "url('/images/nav/editbarwedge.gif') no-repeat");
    buttonDiv.style.padding = "0px";
    buttonDiv.style.paddingLeft = "30px";
    buttonDiv.firstChild.style.backgroundColor = "rgb(223,226,231)";
    buttonDiv.className = 'inlineSelectedRow';
    buttonDiv.style.display = machine.showButtons ? "block" : "none";
    buttonDiv.style.position = "absolute";
    buttonDiv.style.right = "0px";

    var newIndex = 1 +  newRow.rowIndex ;

    var buttonRow = table.insertRow(newIndex);

	if ( machine.allowMoveLines )
		buttonRow.onselectstart = OrderedListCancelDragDrop;

    var rows = table.getElementsByTagName("tr");
    var buttonCell = buttonRow.insertCell(0);
    buttonCell.colSpan = Math.max(rows[0].cells.length, 1);
    buttonCell.className = 'inlineSelectedButtons';
    buttonCell.style.border = "1px solid rgb(223,226,231)";
    buttonCell.align = "right";
    buttonCell.appendChild(buttonContainerDiv);
    buttonContainerDiv.appendChild(buttonDiv);

    newRow.hasButton = true;
}


function focusDefaultButton(machine)
{
    
    if(!focusButton(machine.name + "_addedit"))
    {
        focusButton(machine.name + "_edit");
    }
}

function focusButton(buttonId)
{
	var button = document.getElementById(buttonId);
	if (button != null && isFocusable(button))
	{
        button.focus();
        return true;
	}
    return false;
}

function setButtonText(buttonId, txt)
{
	var button = document.getElementById(buttonId);
	if (button != null)
	{
		if (button.nodeName == "INPUT")
			button.value = txt;
		else
			button.innerHTML = txt;
	}
}

function disableButton(buttonId, value)
{
	var button = document.getElementById(buttonId);
	if (button != null && button.disabled != value)
	{
	
		if (button.nodeName == "INPUT")
			button.disabled = value;
		
	}
}

function getInputElementsFromTable(row)
{
	var inpts = row.getElementsByTagName("INPUT");
	var textareas = row.getElementsByTagName("TEXTAREA");

	var inputs = new Array();
	for (i=0; i < inpts.length; i++)
		inputs[inputs.length] = inpts[i];
	for (i=0; i < textareas.length; i++)
		inputs[inputs.length] = textareas[i];
	return inputs;
}

function getColumnWidthForNode(node)
{
	var display = node.style.display;
	node.style.display = "none";

	var up = node;
	var returnMe = 0;
	while (up != null && up.nodeName != "TD")
		up = up.parentNode;
	if (up != null)
		 returnMe = up.offsetWidth;
	node.style.display = display;
	return returnMe;
}


function Machine_editRow(rowNum, bFocusLine)
{
    if (!this.isinline)
		return;
	var table = this.tableobj;
    var rows = table.getElementsByTagName("tr");
	
	if ((rows.length-1) <= rowNum)
		return;
    var newRow = rows[rowNum];
	var elems = this.getInputElements();
    // Copy the contents of the row about to be edited to the last row
    // this is so that any slaving code that temporarily changes the contents
    // of a column don't cause the table to change size
    if(this.currentRowNum != rowNum)
    {
        
        var lastCells = this.lastRow.cells;
        var newCells  = newRow.cells;
        for(var iter = 0; iter < lastCells.length; iter++)
        {
            var cloned = newCells[iter]  .firstChild  .cloneNode(true);
            var bc = lastCells[iter];

            if(bc.firstChild)
            {
                while(bc.firstChild)
                {
                    bc.removeChild(bc.firstChild);
                }
            }
            bc.appendChild(cloned);
        }
    }

    this.currentRowNum = rowNum;
	this.addEditor(elems, newRow, rowNum);








    table.machineName = this.name;
    putButtonsInMachine(this, newRow, table);

    if (this.getMachineIndex() == this.getNextIndex())
    {
        setButtonText(this.name + "_addedit", "Add");
        setButtonText(this.name + "_copy", "Copy Previous");
        disableButton(this.name + "_copy", this.getNextIndex() == 1);
        disableButton(this.name + "_remove", true);
        disableButton(this.name + "_insert", true);
    }
    else
    {
        this.mode = "edit";
        
        setButtonText(this.name + "_addedit", "Done");
        setButtonText(this.name + "_edit", "Done");
        setButtonText(this.name + "_copy", "Make Copy");
        disableButton(this.name + "_copy", this.isinserting);
        disableButton(this.name + "_remove", this.isCurrentRowRequired() );
        disableButton(this.name + "_insert", this.isinserting);
    }
    
	if(bFocusLine && elementIsFocusable(this.tableobj) )
		this.setFocus(this.focusedColumn);
	Machine_scheduleTransfer(this);
	this.postEditRow();
}


function Machine_postEditRow()
{
}


var pTransferTimeouts = new Object();


function Machine_doDelayedTransfer(sMachineName, bForce)
{
    if (!window.isinited || bForce)
    {
        
        var timerID = pTransferTimeouts[sMachineName];
        if(timerID)
        {
            clearTimeout(timerID);
        }
        pTransferTimeouts[sMachineName] = setTimeout("Machine_doDelayedTransfer('" + sMachineName + "');", 100);
    }
    else
    {
        eval(sMachineName+"_machine.transferInputFieldValuesToDisplayOnly();");
    }
}


function Machine_scheduleTransfer(mch)
{
	mch.transferInputFieldValuesToDisplayOnly();	
	Machine_doDelayedTransfer(mch.name, true);
}


function Machine_isFieldEditable(nIndex)
{
    var bEditable = this.isFieldEditableOverride(nIndex)
    if (bEditable != null)
        return bEditable;

    bEditable = false;
    var curType = this.getFormElementType( nIndex );
	var curName = this.getFormElementName( nIndex );
	var curElement = this.getFormElement( nIndex );
    
    var bPrevIsDisplay = (nIndex > 0 && this.isElementPopupDisplayField(nIndex-1))
    var curLabel   = bPrevIsDisplay ? this.getFormElementLabel( nIndex - 1 ) : this.getFormElementLabel( nIndex );
    

    if (curLabel == null || curLabel.length == 0 || this.isElementDisplayOnlyWithField(nIndex) || this.getFormElementFieldSet(nIndex).length > 0)
    {
        
    }
    else if ( curType == "select" )
    {
        if( bPrevIsDisplay )
        {
            
            curElement = this.getFormElement(nIndex - 1);
        }
        bEditable = !curElement.disabled;
    }
    else if ( curType == "slaveselect")
    {
        bEditable = !curElement.disabled;
    }
    else if (curType == "integer" && bPrevIsDisplay)
    {
        
        if(curElement.disabled)
        {
            bEditable = (curElement.type != "hidden");
        }
        else
        {
            var displayElement = this.getFormElement( nIndex - 1 );

            if(displayElement.type == "hidden")
            {
                bEditable = true;
                if(window.getDropDown)
                {
                    var dd = getDropDown(displayElement);
                    bEditable = !dd.disabled;
                }
            }
            else
            {
                bEditable = !displayElement.disabled;
            }
        }
    }
    else if (curType == "fieldset")
    {
        
        bEditable = true;
    }
    else if (curType == "namevaluelist")
    {
        
        bEditable = true;
        curElement = curElement.form.elements[curElement.name+"_display"];
    }
    else if (curType == "color")
    {
        bEditable = true;
    }
    else
    {
        bEditable = (curElement.type != "hidden") && !curElement.disabled && !this.isElementPopupDisplayField(nIndex);
    }

    return bEditable ? curElement : false;
}

function Machine_setFocusToFirstEditable()
{
    if(this.isinline)
    {
        var iFocusedColumn = this.focusedColumn;
        this.gotoField(this.getFieldOffset(-1, 1), true);
        if(iFocusedColumn == this.focusedColumn)
        {
            
            this.setFocus(this.focusedColumn);
        }
    }
}


function Machine_setColToFirstEditable(bAutoOpenFieldset)
{
    this.focusedColumn = this.getFieldOffset(-1, 1, bAutoOpenFieldset);
}


function Machine_getFieldOffset(iStartColumn, delta, bAutoOpenFieldset)
{
    for (var i = iStartColumn + delta; (i < this.countFormElements()) && (i >=0) ; i += delta)
    {
        if(this.isFieldEditable(i) && (bAutoOpenFieldset || this.getFormElementType(i) != "fieldset") )
        {
            return i;
        }
    }
    return (iStartColumn == -1 ) ? 0 : iStartColumn;
}

function Machine_getFieldValue (fieldname, lineNum)
{
    if(!lineNum)
        lineNum = this.getMachineIndex();
    var lines = getLineArray(this.name);

    if (lineNum <= 0 || lineNum > lines.length)
	    return null;

    var linedata = splitIntoCells(lines[lineNum-1]);

    return this.getLineFieldValue(linedata, fieldname) ;
}

function Machine_getLineFieldValue (linedata, fieldname )
{
	var nPos = this.getArrayPosition( fieldname );
	if ( nPos == -1 )
		return false;
	return linedata != null && linedata.length > nPos ? linedata[ nPos ] : null ;
}


function Machine_setFocus(ct, bForce)
{
	
	if (!bForce && window.loadcomplete != true)
    {
		return;
    }

	
	 if (document.page_is_resetting)
	 	return;

    
    mchMachineWithFocus = this;
    if (!ct)
    {
        this.setColToFirstEditable();
        ct = this.focusedColumn;
    }

    var fldFocus;

    if(fldFocus = this.isFieldEditable(ct))
    {
        var bSelectFieldContents = (fldFocus.type != 'textarea');
        fldFocus.mch = this;
        setTimeout(function(){doSetFocusStatic(fldFocus, bSelectFieldContents);}, 100);
    }
}

function doSetFocusStatic(input, bSelectField)
{
	try
	{
        
        if(input.mch != mchMachineWithFocus)
        {
            return;
        }

        NLMachine_safeSetFocus(input);

        if(bSelectField)
        {
            if (isPopupSelect(input) || isPopupMultiSelect(input))
            {
                var displayField = NLPopupSelect_getDisplayFieldByValueInput(input);
                if (displayField && input.value.length > 0) 
                    displayField.select();
            }
            else
                input.select();
        }
	}
	catch(e)
	{
		
	}
}

function handleTab(evnt, func)
{
	
	if (getEventKeypress(evnt) == 9 && !getEventShiftKey(evnt)) 
		setTimeout(func,1);  
}


function Machine_setEnableEdit(bEnable, bRenderNow, bInsert)
{
	if (!this.isinline)
		return;

    bEnable = (bEnable != false);
    if(bEnable)
    {
        this.showEditor = true;
        if (typeof bInsert != "undefined" && bInsert != null)
            this.allow_insert = bInsert;
        else if (typeof this.savedState.allow_insert != "undefined")
            this.allow_insert = this.savedState.allow_insert;
        if (typeof this.savedState.allowMoveLines != "undefined")
            this.allowMoveLines = this.savedState.allowMoveLines;
    }
    else
    {

        this.savedState.allow_insert = this.allow_insert;
        this.savedState.allowMoveLines = this.allowMoveLines;
        this.allow_insert = false;
        this.showEditor = false;
        this.allowMoveLines = false;
    }
    if (bRenderNow == true)
        this.buildTable();
}

function Machine_clearSavedState()
{
    this.savedState = new Object();
}


function Machine_suspendEdit()
{
	if (!this.isinline)
		return;
	var elems = this.getInputElements(true);
    for (var i=0; i < elems.length; i++)
	{
		var field = elems[i];
		if (field == null || this.getFormElementFieldSet(i).length > 0)
			continue;

        Machine_reparent(field, this.miniform);
	}
	hideButtons(this.name);
	return elems;
}


function Machine_createEditorMap()
{
    this.idMap = new Array();
    var lastWasDisplay = false;
    var fieldnames = this.getFormFieldNames();

	for (var i=0; i < fieldnames.length; i++)
	{
        //get the field by id
        editorName = this.name + "_" + fieldnames[i] + "_fs";
        var field = document.getElementById(editorName);

        //otherwise get the field by id
        if(!field)
        {
            editorName = this.name + "_" + fieldnames[i] + "_fs";
            field = document.getElementById(editorName);
        }

        if(field)
        {
            field.indexOfEditor = lastWasDisplay ? i-1 : i;
            this.idMap[i] = field;
        }
		lastWasDisplay = this.isElementPopupDisplayField(i);
	}
}


function Machine_getInputElements(allElements, fieldnames)
{
	
	var returnMe = new Array();
	if (!fieldnames)
        fieldnames = this.getFormFieldNames();
	var lastWasDisplay = false;
    if ( this.idMap == null )
        this.createEditorMap();

    for (var i=0; i < fieldnames.length; i++)
	{
		var field = null;
		var label = (lastWasDisplay) ? this.getFormElementLabel(i-1) : this.getFormElementLabel(i);

        field = this.idMap[i];

		if (allElements != true && (label == null || label.length == 0 || this.getFormElementFieldSet(i).length > 0))
			field = null;
		returnMe[returnMe.length] = field;

		lastWasDisplay = this.isElementPopupDisplayField(i);
	}

	return returnMe;
}

function Machine_updateMachineData(data, bNoFocus)
{
    if (!isArray(data))
        return;
    var lines = getLineArray(this.name);

    for (var i=0; i < data.length; i++)
	{
        var rowIdx = data[i]["row"];
        if (rowIdx == null)
            rowIdx = this.getMachineIndex();

        var linedata = splitIntoCells(lines[rowIdx - 1]);

        for (col in data[i])
        {
            if (col == "row")
                continue;

            var colIdx = this.getArrayPosition(col);
            linedata[colIdx] = data[i][col];
        }
        lines[rowIdx - 1] = linedata;
    }
    setLineArray(this.name,lines);
    this.loadline(this.getMachineIndex());
    this.buildtable(null, bNoFocus);
}


function NLMachine_createFocusElement()
{
	var focusElementDiv = document.createElement("DIV");
	focusElementDiv.style.width = "1px";
	focusElementDiv.style.height = "1px";
	focusElementDiv.style.border = "none";
	focusElementDiv.style.position  = "absolute";
	focusElementDiv.tabIndex = 0;
	this.focusElement = document.createElement("A");
	this.focusElement.tabIndex = 0;
	focusElementDiv.appendChild(this.focusElement);
	this.tableobj.parentNode.appendChild(focusElementDiv);	
}


function NLMachine_applyFocusToFocusElement()
{
	if ( this.focusElement && isFocusable(this.focusElement) )
	{
		this.focusElement.parentNode.style.left = Number(document.body.scrollLeft) + 50 + "px";
		this.focusElement.focus();
	}
}

var scheduledSqueezes = new Array();
var squeezeFuncs = new Array();
function scheduleSqueeze(tableName)
{
	if (scheduledSqueezes[tableName] == null)
	{
		var func = squeezeFuncs[tableName];
		if (func != null)
			scheduledSqueezes[tableName] = setTimeout(func, 1);
	}
}

function setWidth(inpt, newWidth)
{
	inpt.style.width = newWidth;
	if (inpt.className == "dropdownInput")
	{
		var dd = getDropdown(inpt);
		dd.setText(dd.getText(), true , newWidth);
	}
}

function squeeze(tableName)
{
    return;
}

function tweakTable(tableName)
{
	
	var table = document.getElementById(tableName);
	table.style.tableLayout = "fixed";
	table.style.tableLayout = "auto";
}


function Machine_hideField(field)
{





    field.style.display = "none";
}

function Machine_showField(field)
{
    field.style.display = "block";
}


function Machine_reparent(child, newparent)
{
    
	Machine_hideField(child);
    

    var parent = child.parentNode;

    storeCheckboxState(child);

    parent.removeChild(child);
    newparent.appendChild(child);

    restoreCheckboxState(child);

    
}





function Machine_getDisplayCellContentOverride(nIndex, data, lineNum)
{
    return null;
}


function Machine_getFieldOverride(elems, row, rowNum, elemIdx)
{
    return null;
}


function Machine_isFieldEditableOverride(elemIdx)
{
    return null;
}


function Machine_isNeedUpdateFieldDisplayValue(field)
{
    return field.parentNode == this.miniform;
}




function storeCheckboxState(field)
{
	if (field.checked != null)
    {
		field.doubleCheck = field.checked;
    }
	var childNodes = field.childNodes;
	if (childNodes == null)
		return;
	for (var i=0; i < childNodes.length; i++)
		storeCheckboxState(childNodes[i]);
}

function restoreCheckboxState(field)
{
	if (field.doubleCheck != null)
	{
		field.checked = field.doubleCheck;
		field.doubleCheck = null;
	}
	var childNodes = field.childNodes;
	if (childNodes == null)
		return;
	for (var i=0; i < childNodes.length; i++)
		restoreCheckboxState(childNodes[i]);
}

function getCheckboxState(field)
{
    if( field.checked != null)
    {
        return field.checked;
    }
	var childNodes = field.childNodes;
	if (childNodes == null)
		return null;
	for (var i=0; i < childNodes.length; i++)
    {
        var ret = getCheckboxState(childNodes[i]);
		if( ret != null)
        {
            return ret;
        }
    }
    return null;
}

function setMachineChanged(name, fld)
{
    if ( fld == null || !fld.noslaving )
    {
        eval ( "setWindowChanged(window, true)" )
        if ( allowAddLines(name) )
            eval( name + "_machine."+(fld == null ? "waschanged" : "ischanged")+" = true;" )
        else
            eval( name + "ischanged = true;" )
    }
}


function isMachineChanged(name)
{
    if ( allowAddLines(name) )
		return eval ( name + "_machine.ischanged" );	
    else
        return eval( name + "ischanged" );
}


function wasMachineChanged(name)
{
    if ( allowAddLines(name) )
		return eval ( name + "_machine.waschanged" );
    else
        return eval( name + "ischanged" );
}


function popupBinDiv(binstr, fld, linenumber, qtyfield)
{
	if (binstr == null || binstr.length==0)
        return;
	var qty = parseFloat(qtyfield.value);

	if (!isNaN(qty))
		qty = Math.abs(parseFloat(qty));

	// check to see if the div exists.  If it does, remove it from the doc
	var binDiv=document.getElementById('BinInlineDIV'+linenumber);
	if (binDiv != null)
		document.body.removeChild(binDiv);

	// create a new div
	binDiv = document.createElement('div');
	binDiv.style.border     = '1px solid black';
	binDiv.style.position   = 'absolute';
	binDiv.style.padding    = '2px';
	binDiv.id               = 'BinInlineDIV'+linenumber;
	binDiv.className        = 'bglt';
	binDiv.style.display='none';
	binDiv.style.zIndex = 1000;

	// stash the target fields in the div object
	binDiv.targetField      = fld;
	binDiv.targetQtyField   = qtyfield;

	// add the div to the page
	document.body.appendChild(binDiv);

	// Convert the char(5) delimited list of bins to an array
	var unparsedBinList = binstr.split(String.fromCharCode(5));
	var bins = new Array(); // flat list of bins
	var binQtyMap = new Array(); // map of bin -> qty
	for (var i = 0; i < unparsedBinList.length; i++)
	{
		var binQtyArr = parseBinQuantityString(unparsedBinList[i]);
		if (binQtyArr != null)
		{
			bins[i] = binQtyArr[0];
			binQtyMap[binQtyArr[0]] = binQtyArr[1];
		}
	}

	// stash the count of bins in the div
	binDiv.binCount = bins.length;
	// convert the text in the bin numbers field into an associative array of bins->qty
	var binFieldArr = parseBinNumbers(fld.value, bins, qty);

	// write the html of the div
	var sHtml = '<form name=\'BinInlineDivForm'+linenumber+'\'><table border=0 cellpadding=0 cellspacing=0>'+
				'<tr><td class=text align=left><b>Bin</b></td><td nowrap class=text>&nbsp;&nbsp;</td><td class=text align=center><b>On Hand</b></td><td nowrap class=text>&nbsp;&nbsp;</td><td class=text align=center><b>Qty</b></td></tr>';

	// Loop through the available bins for the item and create a row in the table with bin number and an entry field
	// for the quantity.  The quantity is pre-populated from the associative array generated by the parseBinNumbers function.
	for (var i=0; i < binDiv.binCount; i++)
		sHtml += '<tr><td class=text align=left>'+bins[i]+'</td><td></td><td class=text align=center>'+binQtyMap[bins[i]]+'</td><td></td><td class=text align=right><input type=hidden name=\'BinInlineDivName'+i+'\' value='+bins[i]+'><input type=text maxlength=10 size=5 name=\'BinInlineDivQty'+i+'\' value='+(binFieldArr[bins[i]] == null ? '' : binFieldArr[bins[i]]) +'></td></tr>';

	// add a button that transfers the contents of the div to the bin numbers text field by calling 'syncBinDiv' and then closes the div
	sHtml += '</table>'+
			 '<center><INPUT type=\'button\' class=\'bgbutton\' value=\'Done\' id=\'done\' name=\'done\' onkeypress="event.cancelBubble=true;" onclick="syncBinDiv(BinInlineDivForm'+linenumber+', document.getElementById(\'BinInlineDIV'+linenumber+'\'),'+linenumber+'); document.getElementById(\'BinInlineDIV'+linenumber+'\').style.display=\'none\';"\'></center>'+
			 '</form>';

	binDiv.innerHTML = sHtml;

	// position the div under the bin numbers field
	binDiv.style.left=findPosX(fld);
    binDiv.style.top=findPosY(fld)+fld.offsetHeight;

	// show it!
	binDiv.style.display='';
}


function syncBinDiv(form, div, linenumber)
{
	var fldValue = '';
	var validQtyCount = 0;
	var sumquantity = 0;
	var decimalPrecision = 0;

	var totalquantity = parseFloat(div.targetQtyField.value);
	var absTotalQuantity = Math.abs(totalquantity);

	// first pass through, figure out how many valid quantities there are
	for (var i = 0; i < div.binCount; i++)
	{
		var qty = parseFloat(form.elements['BinInlineDivQty'+i].value);
		if (!isNaN(qty))
		{
			decimalPrecision = Math.max(decimalPrecision, getUserEnteredPrecision(form.elements['BinInlineDivQty'+i].value));
			// convert negative numbers to positive numbers
			if (qty < 0)
			{
				qty = Math.abs(qty);
				form.elements['BinInlineDivQty'+i].value = qty;
			}
			else if (qty > 0)
			{
				validQtyCount++;
				sumquantity += qty;
			}
		}
	}

	// if the sum of the bin quantities is not equal to the line quantity, ERROR!
	if (!isNaN(absTotalQuantity) && !equalsDouble(sumquantity, parseFloat(absTotalQuantity)))
	{
		alert('The sum of all bin quantities ('+sumquantity+') is not equal to the total line quantity ('+totalquantity+')');
		return;
	}
	else if (sumquantity != 0 && isNaN(totalquantity))
	{
		div.targetQtyField.value = roundDecimal(sumquantity, decimalPrecision);
	}

	// second pass through, convert quantities into "BinX(QtyX)\nBinY(QtyY)..." string.
	var hasBin = false;
	for (var i = 0; i < div.binCount; i++)
	{
		var qty = parseFloat(form.elements['BinInlineDivQty'+i].value);
		if (isNaN(qty))
			continue;
		// separate bins with a newline
		if (hasBin == true)
			fldValue += '\n';
		fldValue += form.elements['BinInlineDivName'+i].value;
		// If there is only one bin listed, quantity is implied.
		// If there is more than one bin listed, we'll need to add "(Qty)" after
		// each bin number.
		if (validQtyCount > 1)
			fldValue += '(' + roundDecimal(qty, decimalPrecision) + ')';
		hasBin = true;
	}
	// fill out the field text
	div.targetField.value = fldValue;

	// call the onchange function of the target field
	if (div.targetField.onchange != null)
		div.targetField.onchange();
}

function getUserEnteredPrecision(str)
{
	var intVal = parseInt(str);
	var floatVal = parseFloat(str);
	// Only procede if the float value and the int value are not the same
	if (!equalsDouble(intVal, floatVal))
	{
		// Find out how many numbers are entered after the decimal place.
		var idx = str.indexOf('.');
		if (idx >= 0)
		{
			var count = 0;
			for (var i=idx+1; i<str.length; i++, count++)
			{
				if ((str.charAt(i) < '0') || (str.charAt(i) > '9'))
				{
					break;
				}
			}
			return count;
		}
	}
	return 0;
}


var EPSILON = 0.000001;
function equalsDouble(double1, double2)
{
	if (isNaN(double1))
		return isNaN(double2);
	else if (isNaN(double2))
		return false;
	else
		return Math.abs(double1 - double2) < EPSILON;
}


function roundDecimal(num, decimalPrecision)
{
	var str = num.toFixed(decimalPrecision);
	if (decimalPrecision == 0)
	{
		return str;
	}
	else
	{
		var end = str.length;
		for (var i=str.length-1; true; i--)
		{
			if (str.charAt(i) == '.')
			{
				end = i;
				break;
			}
			if (str.charAt(i) != '0')
			{
				end = i+1;
				break;
			}
		}
		return str.substring(0, end);
	}
}


function parseBinNumbers(binfieldstr, binsArr, qty)
{
	var retArr = new Array();

	// if no quantity was passed, assume 1
	if (isNaN(qty))
		qty = 1;

	// first check to see if there is just a single bin with no explicit quantity
	// if there is, return an array with the single bin and the full quantity
	var re = new RegExp('^\\s*(\\S+)\\s*$');
	var singleMatch = re.exec(binfieldstr);
	if (singleMatch != null)
	{
		retArr[singleMatch[1]] = qty;
		return retArr;
	}

	// go through the list of bins and find the quantity associated with each
	for (var i = 0; i < binsArr.length; i++)
	{
		var bin = binsArr[i];
		// create a regexp to find strings of the form "bin(qty)", where qty is a captured expression.
		re = new RegExp('\\b'+bin+'\\s*\\(\\s*(\\d+\\.?\\d*)\\s*\\)');
		var matchArr = re.exec(binfieldstr);
		if (matchArr != null)
			retArr[bin] = matchArr[1];
	}
	return retArr;
}


function parseBinQuantityString(binstring)
{
	re = new RegExp('^\\s*(\\S+)\\s*\\(\\s*(\\d+\\.?\\d*)\\s*\\)\\s*$');
	var matchArr = re.exec(binstring);
	if (matchArr != null)
	{
		matchArr.shift(); // remove the first element
		return matchArr;
	}
	else
		return null;
}


// </script>
