




var NLListMachineOptions = new function()
{
    var listOptions = {};

    // Class for holding list options
    var ListOptions = function()
    {
        this.lastSortCol = -1;
        this.lastSortOrder = true;
        this.lastSortDataType = 'TEXT';
        this.currentSortCol = -1;
        this.currentSortOrder = true;
        this.currentSortDataType = 'TEXT';

        this.updateSortOptions = function(col, order, datatype)
        {
            // Initial sort
            if(this.currentSortCol == -1)
                this.currentSortCol = col;

            if(this.currentSortCol != col)
            {
                this.lastSortCol = this.currentSortCol;
                this.lastSortOrder = this.currentSortOrder;
                this.lastSortDataType = this.currentSortDataType;
            }

            this.currentSortCol = col;
            this.currentSortOrder = order;
            this.currentSortDataType = datatype;
        }
    };

    this.get = function(machine){

        if(!listOptions.hasOwnProperty(machine))
        {
            // Register new machine
            listOptions[machine] = new ListOptions();
        }

        return listOptions[machine];
    }
};

function l_node(html, cols, type, dir_up, hier, html2, type2, dir_up2, linenum)
{
    this.html = html;
    
    var inputElem = NS.jQuery('<span>' + html + '</span>').find('input[type=text]:first');
    if(inputElem.length > 0) {
        this.name = inputElem.val();
    }
    else {
	this.name = html.indexOf('>') == -1 ? html : html.substring(html.indexOf('>')+1,html.indexOf('</'));
    }
	this.name = trim(this.name);
	this.row = cols;
	this.dir_up = dir_up;
	this.hier = hier ? hier : '';
	this.type = type;
	if (html2 != null && html2.length > 0)
	{
		this.html2 = html2;
		this.name2 = html2.indexOf('>') == -1 ? html2 : html2.substring(html2.indexOf('>')+1,html2.indexOf('</'));
		this.name2 = trim(this.name2);
		this.type2 = type2;
		this.dir_up2 = dir_up2;
	}
	this.linenum = linenum;
}

function l_isBlank(str)
{
	return (str=='&nbsp;' || str=='');
}


function l_sortnodes(node1, node2)
{
    var result = l_sortnodes2(node1.name, node2.name, node1.type) * (node1.dir_up ? 1 : -1);
    if (result == 0 && node1.type2 != null)
		return l_sortnodes2(node1.name2, node2.name2, node1.type2) * (node1.dir_up2 ? 1 : -1);
	else
		return result;
}

function l_sortnodes2(node1name, node2name, coltype)
{
    if (coltype.indexOf('CURRENCY')!=-1 || coltype == 'INTEGER' || coltype == 'FLOAT' || coltype == 'POSFLOAT' || coltype == 'PERCENT')
    	return l_numnodes(node1name, node2name, coltype);
    else if( coltype == 'PRIORITY')
        return l_prioritynodes(node1name, node2name);
    else if( coltype == 'DATE' || coltype == 'MMYYDATE' || coltype == 'DATETIME' )
        return l_datenodes(node1name, node2name, coltype == 'DATETIME');
    else if( coltype == 'TIMEOFDAY' )
        return l_timenodes(node1name, node2name);
    else
    	return l_charnodes(node1name,node2name);
}

function l_charnodes(str1, str2)
{
	if (l_isBlank(str1) || l_isBlank(str2))
	{
		var empty1 = l_isBlank(str1);
		var empty2 = l_isBlank(str2);
		return (empty1 && !empty2) ? 1 : ((empty2 && !empty1) ? -1 : 0);
	}
	else
		return str1.toLowerCase().localeCompare(str2.toLowerCase());
}

function l_numnodes(node1name, node2name, type)
{
	var num1 = l_num(node1name, type);
	var num2 = l_num(node2name, type);
	return  num1 < num2 ? -1 : (num1 == num2 ? 0 : 1);
}

function l_getpriority(nodename)
{
	var node = nodename.toLowerCase();
  	if (node.charAt(0) == 'l')
   		return 30;
  	else if (node.charAt(0) == 'm')
    	return 20;
  	else if (node.charAt(0) == 'h')
    	return 10;
}

function l_prioritynodes(node1name, node2name)
{
	var num1 = l_getpriority(node1name);
	var num2 = l_getpriority(node2name);
	return num1 < num2 ? -1 : (num1 == num2 ? 0 : 1);
}

function l_datenodes(node1name, node2name, bDateTime)
{
  var date1;
  var date2;

  date1 = stringtodate(node1name).getTime();
  date2 = stringtodate(node2name).getTime();

  if (isNaN(date1)) return 1;
  else if (isNaN(date2)) return -1;
  else return (date1 < date2) ? -1 : (date1 == date2 ? 0 : 1);
}

function l_timenodes(node1name, node2name)
{
  var date1 = new Date();
  var date2 = date1 ;

  date1 = l_time(node1name, date1);
  date2 = l_time(node2name, date2);
  return date1 < date2 ? -1 : (date1 == date2 ? 0 : 1);
}

function l_time(time, date)
{
	var re = /([0-9][0-9]?)(:[0-5][0-9])\s?([AaPp])?[Mm]?/;
	var result = re.exec(time);

	var hours = parseInt(RegExp.$1);
	var minutes = parseInt(RegExp.$2.substr(1));
	var ampm = (RegExp.$3.length == 0 || RegExp.$3.toUpperCase() == 'A') ? 'am' : 'pm';
	hours = (ampm == 'pm') ? (hours%12)+12 : hours%12;
	return hours*60+minutes;
}

function l_num(num, type)
{
	// Remove any non-numeric characters (with exc. of negative prefix/suffix and decimal separator)
	num = num.replace(window.number_blacklist_regex, '');

	// Replace system dec. separator with javascript's '.'
	num = num.replace(window.decimalseparator, '.');

	var negPrefixLen = window.negativeprefix.length;
	var negSuffixLen = window.negativesuffix.length;

	if(    (negPrefixLen > 0 && num.substring(0,negPrefixLen) == window.negativeprefix) // Starts with negative prefix
		|| (negSuffixLen > 0 && num.substring(num.length - negSuffixLen, num.length) == window.negativesuffix)) //  or ends with negative suffix
	{
		num = '-'+num.substring(negPrefixLen ,num.length-negSuffixLen);
	}

	if (isNaN(num) || num == '')
		num = (type=='INTEGER') ? '0' : '0.0';
	return (type=='INTEGER') ? parseInt(num) : parseFloat(num);
}

function l_elem(id)
{
    var theBodyForm = getBodyForm();
    if ((typeof theBodyForm != 'undefined') && (typeof theBodyForm.elements != 'undefined')){
	    return theBodyForm.elements[id];
    }
    return null;
}

function l_sort(col,coltype,hier,hiercol,mach,colname,sAlternateSortType,allCol)
{
    // this is used in cases where a column needs to be sorted by something different than it's type/value
	if(sAlternateSortType != null)
		coltype = sAlternateSortType;
	var node,node2, numRows = 0, rnode, col2 = -1, col2type;
	var elems = [], elem, cols;
	var dir_up = true, dir_up2;
	var ordered_mach = false;
    var theBodyForm = getBodyForm();

    if (mach == '' || mach == null) mach = '';
	else if (l_elem(mach+'sortidx') != null)
	{
		col2 = theBodyForm.elements[mach+'sortidx'].value;
		if (col2 == col)
			col2 = -1;
		else
		{
			col2type = theBodyForm.elements[mach+'sorttype'].value;
			dir_up2 = theBodyForm.elements[mach+'sortdir'].value == "UP";
		}
		ordered_mach = hasEncodedField(mach,mach+"seqnum");
	}

	node = document.getElementById(mach+'dir'+col);
	if (node.className.indexOf('up') != -1)
		dir_up = false;
	node.className = 'listheadersort' + (dir_up ? 'up' : 'down');
	node2 = document.getElementById(mach+'header');
	for (var idx=0; idx < node2.cells.length; idx++)
	{
		if (idx == col)
			continue;
		node = document.getElementById(mach+'dir'+idx);
		if (node != null)
			node.className = 'listheadersort';
	}

    var listOptions = NLListMachineOptions.get(mach);
    listOptions.updateSortOptions(col, dir_up, coltype);
    if(col2 == -1)
    {
        col2 = listOptions.lastSortCol;
        dir_up2 = listOptions.lastSortOrder;
        col2type = listOptions.lastSortDataType;
    }

    //Issue 189077 -> 244343: Need to take into account of hidden fields.
    var hasHiddenFields = false;

    if (typeof allCol != 'undefined')
    {
        node = document.getElementById(mach+'row0');
        if (node != null)
        {
            var firstCellRow = node.cells;
            if (typeof firstCellRow !='undefined')
            {
                for (var jk=0; jk < firstCellRow.length; jk++)
                {
                    var child = firstCellRow[jk].children[0];
                    if ( (typeof child != 'undefined') && child.getAttribute("type") == "hidden")
                    {
                        hasHiddenFields = true;
                        break;
                    }
                }
            }
        }
    }

    var sortCol = hasHiddenFields ? allCol : col;
    var i = 0;
    while (true)
    {
        //node is the machine row
        node = document.getElementById(mach+'row'+i);
        if (node != null)
        {
            // when we are sorting by a different type/value than the cell contiains, that value will
            // exist in a hidden span - which will always be the first child within the <TD>
	        if(sAlternateSortType != null)
	            elem = node.cells[sortCol].firstChild.innerHTML;
	        else
	            elem = node.cells[sortCol].innerHTML;
        	cols = [];

			if (hier)
			{
				var hierfld = l_elem('_hier'+i);
				if (hiercol)
					elem = hierfld.value;
				elems[i] = new l_node(elem.toLowerCase(),cols,coltype,dir_up,hierfld.value);
			}
			else if (col2 != -1)
				elems[i] = new l_node(elem.toLowerCase(),cols,coltype,dir_up,null,node.cells[col2].innerHTML,col2type,dir_up2, ordered_mach ? findEncodedValue(mach, mach+"seqnum", i+1) : -1);
            else
				elems[i] = new l_node(elem.toLowerCase(),cols,coltype,dir_up,null,null,null,null,ordered_mach ? findEncodedValue(mach, mach+"seqnum", i+1) : -1);

            //add this in so we can manipulate the DOM after sorting
            elems[i].id = mach + 'row' + i;

            i++;
        }
        else
            break;
    }

    numRows = i;

    if (numRows > 1){
	    elems.sort(l_sortnodes);

        var firstNode = document.getElementById(mach+ 'row0');
        var currNode = null;

        //insert the rows in the new sort order by inserting row elements in the specified order in elems Array.
        for(var j = (numRows-1); j >=0; --j)
        {
            //keep hier and encoding code
    	    rnode = elems[j];

            //keep track of row highlight
            elems[j].hasHighLight = (j % 2);

		    if (hier)
		    {
			    hierfld = l_elem('_hier'+j);
			    hierfld.value = rnode.hier;
		    }
		    if (ordered_mach)
			    setEncodedValue(mach,rnode.linenum,mach+'seqnum',j+1);

            //insert current node before first node in the list
            currNode = document.getElementById(rnode.id);
            if (currNode != firstNode){
                currNode.parentNode.insertBefore(currNode, firstNode);
            }
            //update first node in the list
            firstNode = currNode;

        }

        //** For Highlighting **
        //need to copy classnames from one highlighted and non-highlighted node, since we are directly manipulating the DOM and nodes will immediately be overwritten
        //can use cloneNode() but IE does not support true cloning of table row node
        var notHL = l_copyClassnamesToArray(document.getElementById(mach + 'row0'));
        var hasHL = l_copyClassnamesToArray(document.getElementById(mach + 'row1'));

        //make sure these are applicable classnames before resetting highlights
        var setHL = ((currNode.cells.length > 0) && ((currNode.cells[0].className.indexOf('listtext') >= 0) || (currNode.cells[0].className.indexOf('portlettext') >= 0)));

        //1) set ids to be in ascending order
        //2) set the row background colors to be alternating
        for (var i = 0; i < numRows; ++i)
        {
            //update id
            currNode.id = mach + 'row' + i;

            //set highlight
            if(setHL)
            {
                //loop through all the children and set className to set/unset background Highlight
                setUnsetHighlight(i, elems, currNode, notHL, hasHL)
            }

            //get next node
            currNode = currNode.nextSibling;

        }
    }

    l_saveprefs(mach, col, colname, coltype, dir_up);
}

function setUnsetHighlight(i, elems, currNode, notHL, hasHL)
{
    for(var j = 0; j < currNode.cells.length; ++j)
    {
        if (elems[i].hasHighLight){
            currNode.cells[j].className = hasHL[j];
        } else{
            currNode.cells[j].className = notHL[j];
        }
    }
}


//helper function
function l_copyClassnamesToArray(tableRowNode)
{

    var classNamesArray = new Array(tableRowNode.cells.length);
    for (var i = 0; i < classNamesArray.length; ++i)
    {
            classNamesArray[i] = tableRowNode.cells[i].className;
    }

    return classNamesArray;
}


function l_sortprefs(col,coltype,mach,colname)
{
    var dir_up = true;
    var node = document.getElementById(mach+'dir'+col);
    if (node.className.indexOf('up') != -1)
        dir_up = false;
    l_saveprefs(mach, col, colname, coltype, dir_up);
}

function l_saveprefs(mach, col, colname, coltype, dir_up)
{
    var theBodyForm = getBodyForm();
    if ( mach != null && mach.length > 0 &&
        (l_elem(mach+'sortidx') != null))
    {
        if (theBodyForm.elements[mach+'sortname'].value != colname)
        {
            theBodyForm.elements[mach+'sort2name'].value = theBodyForm.elements[mach+'sortname'].value;
            theBodyForm.elements[mach+'sort2dir'].value = theBodyForm.elements[mach+'sortdir'].value;
        }
        theBodyForm.elements[mach+'sortidx'].value = col;
        theBodyForm.elements[mach+'sortname'].value = colname;
        theBodyForm.elements[mach+'sorttype'].value = coltype;
        theBodyForm.elements[mach+'sortdir'].value = dir_up ? "UP" : "DOWN";
    }
}

function l_bold(mach, chkd, rownum)
{
	var node = document.getElementById(mach+'row'+rownum);
	for (var idx=0; idx < node.cells.length; idx++)
	{
		var classname = node.cells[idx].className;
		if ( chkd && classname.indexOf('texttable') != -1 )
			classname = 'textdark'+classname.substring(classname.indexOf('texttable')+9);
		else if ( !chkd && classname.indexOf('textdark') != -1 )
			classname = 'texttable'+classname.substring(classname.indexOf('textdark')+8);
		node.cells[idx].className = classname;
	}
}

function getBodyForm()
{
    return document.forms['body_actions'];
}

function getFooterActionsForm()
{
    return document.forms['footer_actions_form'];
}
