
var pageSize = 20 ;

function envqMellowInputStyle()
{	return ('style="color: #0000ff; font-family:Trebuchet MS, Verdana, Serif, Arial;  font-size: xx-small; background-color: #EDECE7"') ;
}


// Constructor for my Cunningt Table Object
function eNVQTable(myName,myDivName,myColumns,aHeader,aRowPrefix,prevPageHRef,nextPageHRef,aTableFooter,someRows)
{	this.name = myName ;
	this.myDiv = myDivName ;
	this.noColumns = myColumns ;
	this.rowsPerPage = pageSize ;
	this.pageNumber = -1 ;
	this.noRows = someRows.length ;
	this.pageHeader = aHeader ;
	this.rowPrefix = aRowPrefix ;
	this.tableFooter = aTableFooter ;
	this.allRows = someRows ;
	this.currentSubscripts = 0 ;
	this.sortDirection = -1 ;
	this.sortColNo = -999 ;
	this.prevPage = prevPageHRef ;
	this.nextPage = nextPageHRef ;
	this.sortDivName = 'sort' + myName ;
	this.sortFieldsListTable = 'sortfdiv' + myName ;
	this.sortFieldsNames = new Array() ;
	this.sortFieldsSubs = new Array() ;
	this.complexSortSubs = new Array() ;
}

function tableSortSubscriptObject(aTableObj,aSubscript)
{	var objectName ;
	objectName = aTableObj.name + 'Subs' + aSubscript ;
	return (objectName) ;
}
function tableSortPositionObject(aTableObj,aSubscript)
{	var objectName ;
	objectName = aTableObj.name + 'Pos' + aSubscript ;
	return (objectName) ;
}

function envqSetTablePageSize(aTableObj,aControl)
{	var s ;
	var v = aControl.value ;
	if (v == "") return (1) ;
	var i = parseInt(v) ;
	if (v <= "0" || v > "999" || i <= 0 || i > 999)
	{	alert("Rows per page must be between 1 and 999\n\nAnd you typed ["+v+"]") ;
		aControl.value = "" ;
		aControl.focus() ;
		return (0) ;
	}
	aTableObj.rowsPerPage = i ;
	genTableHtml(aTableObj,0) ;
}

function showSortDiv(whatdiv)
{	var itsStyle ;
	var theObj ;
	theObj = dereferenceObject(whatdiv) ;
	itsStyle = theObj.style ;
	itsStyle.posTop=aty - theObj.clientHeight;
	itsStyle.posLeft=atx+10;
	itsStyle.visibility = "visible" ;
}


function sortTableHRef(aTableObj)
{	var myHTML = '' ;
	myHTML += '<img src="../images/smarttablesort.gif" ' ;
	myHTML += 'title="Click here to specify a multi-column sort order for the data in this table" ' ;
	myHTML += 'onClick="javascript:showSortDiv(' ;
	myHTML += "'" ;
	myHTML += aTableObj.sortDivName ;
	myHTML += "'" ;
	myHTML += ');">' ;
	return (myHTML) ;
}

function rowNumberFromSub(aSub)
{	var answer = Math.abs(aSub) ;
	return (answer-1) ;
}

function genTableHtml(aTableObj,aPage)
{	var howMany = aTableObj.allRows.length ;
	var thisSub ;
	var newHTML = '' ;
	var startSub = aPage * aTableObj.rowsPerPage ;
	var iStartedAt ;
	if (startSub > howMany) startSub = 0 ;
	iStartedAt = startSub ;
	var endSub = startSub + aTableObj.rowsPerPage ;
	if (endSub > howMany) endSub = howMany ;
	aTableObj.pageNumber = aPage ; 
	newHTML = aTableObj.pageHeader ;
	for (var i = startSub ; i < endSub ; i++)
	{	thisSub = i ;
		if (aTableObj.sortDirection == 1) thisSub = howMany - 1 - i ;
		newHTML += aTableObj.rowPrefix ;
		newHTML += aTableObj.allRows[rowNumberFromSub(aTableObj.currentSubscripts[thisSub])] ;
		// newHTML += '[' + i + ']' ;
	}
	if (aTableObj.rowsPerPage <= howMany)
	{	newHTML += aTableObj.tableFooter ;
		newHTML += '<table><td width=33% align=left>'
		newHTML += ' Rows ' + (iStartedAt + 1) + '-' + endSub + ' of ' + howMany + ' ' ;
		newHTML += sortTableHRef(aTableObj) ;
		newHTML += '<td width=33% align=center><a href="javascript:envqPrevTablePage('+aTableObj.name+');">PgUp</a>' ;
		newHTML += ' - <a href="javascript:envqNextTablePage('+aTableObj.name+');">PgDn</a>' ;
		newHTML += '<td width=33% align=right>Show <input size=3 '
			+ envqMellowInputStyle()
			+ ' id="' 
			+ aTableObj.name + 'RC' 
			+ '" value='
			+ '"' + aTableObj.rowsPerPage + '"'
			+ '> rows per page ' ;
		newHTML += '<img src="../images/Go_White.gif" onClick="javascript:envqSetTablePageSize(' 
			+ aTableObj.name 
			+ ',' 
			+ aTableObj.name + 'RC' 
			+ ');">' ;
	}
	else
	{	newHTML += aTableObj.tableFooter ;
		if (aTableObj.noRows > 4) newHTML += sortTableHRef(aTableObj) ;
	}
	newHTML += '</table>' ;
	//aTableDiv.innerHTML = newHTML ;
	aTableObj.myDiv.innerHTML = newHTML ;
}

function envqReallySortTable(aTableObj,theSubscripts,theColNo)
{	//alert('Really sort with subs '+theSubscripts) ;
	if (theColNo == -99 || theColNo != aTableObj.sortColNo)
	{	aTableObj.currentSubscripts = theSubscripts ;
		if (theColNo == -99) // From the complex sort
		{	aTableObj.sortColNo = aTableObj.sortFieldsSubs[0] ;
		}
		else
		{	aTableObj.sortColNo = theColNo ;
		}
		aTableObj.sortDirection = 0 ;
	}
	else /* Same column - reverse order */
	{	if (aTableObj.sortDirection == 1)
		{	aTableObj.sortDirection = 0 ;
		}
		else
		{	aTableObj.sortDirection = 1 ;
		}
	}
	aTableObj.pageNumber = 0 ;
	genTableHtml(aTableObj,0) ;
}

function envqNextTablePage(aTableObj)
{	var nextPage ;
	nextPage = aTableObj.pageNumber + 1 ;
	if (nextPage * aTableObj.rowsPerPage >= aTableObj.noRows) return ;
	genTableHtml(aTableObj,nextPage) ;
}	

function envqPrevTablePage(aTableObj)
{	var prevPage ;
	prevPage = aTableObj.pageNumber - 1 ;
	if (prevPage < 0) return ;
	genTableHtml(aTableObj,prevPage) ;
}	

var whatTableObj ;
var whatSubscripts ;
var whatColNo = -1 ;

function haveItNow()
{	envqReallySortTable(whatTableObj, whatSubscripts, whatColNo) ;
	MakeInVisible('SortingTable') ;
}

function envqSortTable(aTableObj,aSubs,aColNo)
{	whatTableObj = aTableObj ;
	whatSubscripts = aSubs ;
	whatColNo = aColNo ;
	MakeVisible('SortingTable') ;
	//haveItNow() ;
	setTimeout('haveItNow()',1);		 
}

function drawSortFieldsTable(aTableObj)
{	var newHTML ;
	var i ;
	var noFields = aTableObj.sortFieldsNames.length ;
	newHTML = '<table class="noshadTableNB" cellpadding=0 cellspacing=0>' ;
	for (i = 0 ; i < noFields ; i++)
	{	newHTML += '<tr valign=center bgcolor=white><td>' ;
		if (i == 0)
		{	newHTML += '&nbsp;' ;
		}
		else
		{	newHTML += '<a href="javascript:moveSortFieldUp('+aTableObj.name+','+i+');"  title="Move Up">' ;
			newHTML += '<img src="../images/triangle_up.gif">' ;
			newHTML += '</a>' ;
		}
		newHTML += '<td>' + aTableObj.sortFieldsNames[i]+ '<td>' ;
		if (i == (noFields-1))
		{	newHTML += '&nbsp;' ;
		}
		else
		{	newHTML += '<a href="javascript:moveSortFieldDown('+aTableObj.name+','+i+');"  title="Move Down">' ;
			newHTML += '<img src="../images/triangle_down.gif">' ;
			newHTML += '</a>' ;
		}
		newHTML += '<td><a href="javascript:moveSortFieldOut('+aTableObj.name+','+i+');"  title="Remove from list">' ;
		newHTML += '<img src="../images/LittleDelBtn.gif">' ;
		newHTML += '</a>' ;
	}
	newHTML += '</table>' ;
	var sortFieldsDiv = dereferenceObject(aTableObj.sortFieldsListTable) ;
	//alert('Is currently ' + sortFieldsDiv.innerHTML) ;
	sortFieldsDiv.innerHTML = newHTML ;
}

function moveSortField(aTableObj,aSubscript,aDirection)
{	var swapWith = aSubscript - aDirection ;
	var tmpField = aTableObj.sortFieldsNames[swapWith] ;
	var tmpSub = aTableObj.sortFieldsSubs[swapWith] ;
	aTableObj.sortFieldsNames[swapWith] = aTableObj.sortFieldsNames[aSubscript] ;
	aTableObj.sortFieldsSubs[swapWith] = aTableObj.sortFieldsSubs[aSubscript] ;
	aTableObj.sortFieldsNames[aSubscript] = tmpField ;
	aTableObj.sortFieldsSubs[aSubscript] = tmpSub ;
	drawSortFieldsTable(aTableObj) ;
}
function moveSortFieldUp(aTableObj,aSubscript)
{	moveSortField(aTableObj,aSubscript,1) ;
}
function moveSortFieldDown(aTableObj,aSubscript)
{	moveSortField(aTableObj,aSubscript,-1) ;
}
function moveSortFieldOut(aTableObj,aSubscript)
{	aTableObj.sortFieldsNames.splice(aSubscript,1) ;
	aTableObj.sortFieldsSubs.splice(aSubscript,1) ;
	drawSortFieldsTable(aTableObj) ;
}

function envqAddSortFieldToTable(aTableObj, aFieldName, aFieldSub)
{	//alert('Add to table ' + aTableObj + ' field ' + aFieldName + ' Sub ' + aFieldSub) ;
	var noFields = aTableObj.sortFieldsNames.length ;
	aTableObj.sortFieldsNames[noFields] = aFieldName ;
	aTableObj.sortFieldsSubs[noFields] = aFieldSub ;
	drawSortFieldsTable(aTableObj) ;
}

function ithValue(aTableObj,iRow,iColumn)
{
}

function ithSubscript(aTableObj,iSub,aSubsArray)
{	return(aSubsArray[0][iSub]) ;
}

function oneColumnRowOrderSub(aSubArray,row1,row2)
{	var row1SeenAt = -1 ;
	var row2SeenAt = -1 ;
	var isDupBlock = 1 ;
	var r1 = Math.abs(row1) ;
	var r2 = Math.abs(row2) ;
	row1Seen = 0 ;
	row2Seen = 0 ;
	for (iCount = 0 ; iCount < aSubArray.length ; iCount++)
	{	if (Math.abs(aSubArray[iCount]) == r2) row2SeenAt = iCount ;
		if (Math.abs(aSubArray[iCount]) == r1) row1SeenAt = iCount ;
		if (row1SeenAt != -1 && row2SeenAt != -1) break ;
		if (isDupBlock == 1 && (row1SeenAt != -1 || row2SeenAt != -1)) // Was dup, now isn't, only one seen
		{	if (aSubArray[iCount] > 0) // Not Dup, and one or other seen
			{	isDupBlock = 0 ;
			}
		}
		if (isDupBlock == 0 && (row1SeenAt != -1 || row2SeenAt != -1)) // Not dup and seen one or t'other
		{	if (row1SeenAt != -1) return (-1) ; // r1 b4 r2
			if (row2SeenAt != -1) return (1) ; // r2 b4 r1
		}
	}
	// Must find both rows..
	if (row1SeenAt == -1 || row2SeenAt == -1)
	{	alert('Couldnt find row ('+row1+','+row2+') in array '+aSubArray) ;
		return (0) ;
	}
	if (isDupBlock == 1) return (0) ; // they're level
	if (row2SeenAt > row1SeenAt) return (-1) ; // Row1 is before row2
	return (1) ; // row1 comes after row 2
}

function oneColumnRowOrder(aSubArray,r1,r2)
{	return (aSubArray[r1] - aSubArray[r2]) ;
}

function compareRows(subArrays,row1,row2)
{	var r1 = Math.abs(row1) - 1 ;
	var r2 = Math.abs(row2) - 1 ;
	var colCount ;
	var myAnswer = 0 ;
	for (colCount = 0 ; colCount < subArrays.length ; colCount++)
	{	var thisColArray = subArrays[colCount] ;
		if ((myAnswer=oneColumnRowOrder(thisColArray,r1,r2)) != 0)
		{	//alert('cmp '+r1+'('+thisColArray[r1]+'),'+r2+'('+thisColArray[r2]+') at col '+colCount+' :='+myAnswer) ;
			return (myAnswer) ;
		}
	}
	return (0) ;
}


var globSortArrays ;
var noComps = 0 ;
function globSortCompare(row1,row2)
{	noComps++ ;
	return (compareRows(globSortArrays,row1,row2)) ;
}

function envqComplexTableSort(aTableObj)
{	var i ;
	//var msgStr = 'ComplexSort:\n' ;
	var noFields = aTableObj.sortFieldsNames.length ;
	var dupSeen = 0 ;
	var noSwaps = 0 ;
	if (noFields == 0)
	{	alert('Please choose at least one column for me to sort the table by') ;
		return ;
	}
	var colSortSubs = new Array() ;
	var aSubArrayName ;
	for (i = 0 ; i < noFields ; i++)
	{	aSubArrayName = tableSortPositionObject(aTableObj,aTableObj.sortFieldsSubs[i]) ;
		//msgStr += i + ' : ' + aSubArrayName + '\n' ;
		colSortSubs[i] = eval(aSubArrayName) ;
		//msgStr += colSortSubs[i] + '\n' ;
	}
	//alert(msgStr) ;
	var firstColSubs = eval(tableSortSubscriptObject(aTableObj,aTableObj.sortFieldsSubs[0])) ;
	for (i = 0 ; i < aTableObj.noRows ; i++)
	{	aTableObj.complexSortSubs[i] = firstColSubs[i] ;
		if (aTableObj.complexSortSubs[i] < 0) dupSeen = 1 ;
	}
	// And now let's sniff out the dups...
	if (noFields > 1 && dupSeen != 0)
	{	globSortArrays = colSortSubs ;
		noComps = 0 ;
		aTableObj.complexSortSubs.sort(globSortCompare) ;

		if (0) for (var bubOuter = 0 ; bubOuter < aTableObj.noRows-1 ; bubOuter++)
		{	var row1 = Math.abs(aTableObj.complexSortSubs[bubOuter]) ;
			var row2 = Math.abs(aTableObj.complexSortSubs[bubOuter+1]) ;
			noComps++ ;
			if (compareRows(colSortSubs,row1,row2) != 1) continue ; // so long as they're not higher
			// Swap and re-start
			noSwaps++ ;
			aTableObj.complexSortSubs[bubOuter] = row2 ;
			aTableObj.complexSortSubs[bubOuter+1] = row1 ;
			//alert('bubble at '+bubOuter) ;
			bubOuter -= 2 ;
			if (bubOuter < 0) bubOuter = -1 ;
		}
	}
	MakeInVisible(aTableObj.sortDivName) ;
	//alert('bubbled ' + aTableObj.noRows + ' ,'+noComps+' comps, '+noSwaps+' swaps') ;
	envqReallySortTable(aTableObj, aTableObj.complexSortSubs, -99) ;
//	alert(aTableObj.myDiv.innerHTML);
}

