/**
 *
 * Used to sort HTML tables by column. A 'sortType'
 * must be specified for each sortable column (e.g.
 * Number, Text, <Custom>).  The sortType is then
 * matched to a function (e.g. compareNumber,
 * compareText, compare<Custom>) that determines how rows
 * should be ordered. By specifying that the 'sortDirection'
 * of a column is "Desc", you can change the default sort
 * order of that column.  "Asc" is the default.
 *
 *
 * History (Author, Date, Comment)
 * --------------------------------------
 * Jeff Li      30 Jul 2006          created
 */
var secondSortCol;
var sortCol = 0;
var lastSortCol = sortCol;
var defaultSortDirection = "Asc";
var sortAsc = true;
var columnSortTag = '';
var imgUp = contextPath+"/images/up_sort_arrow.gif";
var imgDown = contextPath+"/images/down_sort_arrow.gif";
var imgInactive = contextPath+"/images/spacer.gif"; //"../images/dkgreyspacer.gif";

function setCommonSortDefaultColumn(index){
	sortCol = index;
	lastSortCol = sortCol;
}
function setSecondSortColumn(index){
	secondSortCol = index;
}

function setCommonSortDirectionAsc(sortAscBool){
	sortAsc = sortAscBool;
}
function setSort(column, direction, type, theDiv){
	var divEle = document.getElementById(theDiv);
	if(divEle==null) return;
	var props = divEle.getElementsByTagName('input');
	for(var i = 0; i < props.length; i++){
		var name = props[i].getAttribute('name');
		if(name == "sortColTXT") props[i].value = column;
		else if (name == "sortDirTXT") props[i].value = direction;
		else if (name == "sortTypeTXT") props[i].value = type;
	}
}
var presort = null;
var postsort = null;
function backSort(div){
	var sortType = null;
	var sortAscVal = null;
	var sortColumn = null;
	var offset = null;
	var rowid = div.id.replace("sortRecall", "sorterRow");
	var row = document.getElementById(rowid);
	if(row == null) return;
	var inputs = div.getElementsByTagName("input");
	for(var i = 0; i < inputs.length; i++){
		var name = inputs[i].getAttribute("name");
		if(name == null || name == "") continue;
		else if(inputs[i].value == null || inputs[i].value == ""){
		 continue;
		}
		else if(name == "sortColTXT") sortColumn = parseInt(inputs[i].value);
		else if(name == "sortOffsetTXT") offset = parseInt(inputs[i].value);
		else if(name == "sortTypeTXT"){
			sortType = inputs[i].value;
		}
		else if(name == "sortDirTXT") sortAscVal = inputs[i].value=="true" || inputs[i].value=="TRUE" ? true:false;
	}
	if(sortType != null && sortAscVal != null && sortColumn != null){
		var cell = row.getElementsByTagName("td")[sortColumn];
		setCommonSortDirectionAsc(!sortAscVal);
		if(presort != null)
			presort.call(this);
			//clearChartRows();
		//if(!sortAscVal)
		lastSortCol = sortColumn;
		commonFakeSortTable(cell, sortType, offset);
		if(postsort != null)
			postsort.call(this);
	}
}
function recallSorts(){
	var savedSorts = getElementSet("sortRecall", "div");
	for(var i = 0; i < savedSorts.length; i++){
		backSort(savedSorts[i]);
	}
}
$(document).ready(function(){ 	recallSorts();	});
function sortTableMain(th, sortType, offSet, sortCol, sortRow, secondSortColumn){
    
	var localSecondSort;
	if (secondSortColumn){
		localSecondSort = secondSortColumn;
	} else if (secondSortCol){
		localSecondSort = secondSortCol;
	}

	//Find the <table> tag for the table which data rows to be sorted
    var tbl = getUntilParent(th, "table");

    var rows = tbl.rows;
    var oBody = tbl.tBodies[0];
    var sortTemp = new Array();
    var nonSortTemp = new Array();

    // Toggle the sort direction if the user is sorting
    // the same column again; otherwise, use default direction.
    // Default to DESC for Number columns
    if (sortCol==lastSortCol){   		// if sorting the same column, reverse
        if(sortType=="ID"){ sortType = "Number"; }
        sortAsc = !sortAsc;
    } else if (sortType=='Number'||sortType=='Phase1Phase2'){    	// if sorting a Number column, default to DESC
    	sortAsc = false;
    } else if(sortType == "ID"){     // treat ID as number but starting as ASC
        sortAsc = true;
        sortType = "Number";
    }else {					    	// use default
    	sortAsc = (defaultSortDirection != "Desc");
    }
	
	setSort(sortCol, sortAsc, sortType, sortRow.id.replace("sorterRow", "sortRecall"));
	
    columnSortTag = (sortAsc?'':'-')+th.id;
    
    var k=0;
    var j=0;
    // load temp array with table rows
    for (var i = offSet; i < rows.length; i++){
        if(rows[i].id != "portfolioTotals"){
            sortTemp[j++] = rows[i];
        } else {
            nonSortTemp[k++] = rows[i];
        }
    }
    // sort temp array
    sortTemp.sort(compareByColumn(sortCol, sortType, sortAsc, localSecondSort));
	
    // replace the sorting table rows
    for (var i = 0; i < sortTemp.length; i++)    {
        oBody.appendChild(sortTemp[i]);        // replaces existing rows, no need to delete
    }
    
    // replace the non sorting table rows
    for (var i = 0; i < nonSortTemp.length; i++) {
        oBody.appendChild(nonSortTemp[i]);        // replaces existing rows, no need to delete
    }    

    lastSortCol = sortCol;

    toggleRows(rows, offSet);
    toggleImages(sortRow);
}
/**
 * Method called by client. Determines the sort column
 * and sort direction. Delegates to sorting routine.
 *
 */
function commonSortTable(event, sortType, offSet, secondSortColumn)
{
    // to make it compatible with IE and Firefox
    if(!event){  // no event, the browser is IE
        event = window.event;
    }
    if(!sortType)  sortType = "Text";
    if(!offSet) offSet = 1;

    var eType = event.type;
    var eTarget = event.target || event.srcElement;

    var th = getUntilParent(eTarget, "td");
    var sortRow = th.parentNode;
    sortCol = getCellIndex(sortRow, th);//th.cellIndex;
    
    sortTableMain(th, sortType, offSet, sortCol, sortRow, secondSortColumn);
}
/**
 * Method called by client. Determines the sort column
 * and sort direction. Delegates to sorting routine.
 *
 */
function commonFakeSortTable(eTarget, sortType, offSet)
{

    var th = getUntilParent(eTarget, "td");
    var sortRow = th.parentNode;
    sortCol = th.cellIndex;
	
	sortTableMain(th, sortType, offSet, sortCol, sortRow);
}
/**
 * Method retrieves cell text and calls main sort routine
 */
function compareByColumn(iCol, sSortType, fSortAsc, sCol) {

    var colIndex = iCol;
    var secondColIndex = sCol;
    var sortType = sSortType;
    var sortAsc = fSortAsc;

    function _compare(n1, n2) {

        var v = _getValue(n1, n2, colIndex);
   		if (v==0 && secondColIndex && colIndex!=secondColIndex){
   			v =  _getValue(n1, n2, secondColIndex);
   		}
        
        function _getValue(n1, n2, index){
        	var v = 0;
	        var hasCells = false;
	
	        try {
	            // retrieve cell text
	            var c1 = n1.cells[index].innerHTML;
	            var c2 = n2.cells[index].innerHTML;
	            hasCells = true;
	        } catch(e) { }
	
	        if (hasCells) {
	            // call main sort routine
	            v = compareValues(c1, c2, sortType, sortAsc);
	        }
	        return v;
        }

        return v;
    }

    return _compare;
}


/**
 * Toggles images for ascending and descending sorts
 */
function toggleImages(row){
    var img;
    for (var i = 0; i < row.cells.length; i++) {
        img = row.cells[i].getElementsByTagName("img")[0];
        if (img) {
            if (i != sortCol) img.src = imgInactive;
            else img.src = (sortAsc ? imgUp : imgDown);
        }
    }
}

/**
 * Toggles back color for odd and even rows
 */
function toggleRows(rows, skipRow){
    for (var i = skipRow; i < rows.length; i++){
        if((i % 2) == 0)
        	$(rows[i]).addClass("oddRow").removeClass("evenRow");
        else
        	$(rows[i]).addClass("evenRow").removeClass("oddRow");
    }
}

/**
 * Finds first parent with specific html tag
 */
function getUntilParent(el, sParentTag){
    if (el == null){
        return null;
    } else if (el.nodeType == 1 && el.tagName.toLowerCase() == sParentTag.toLowerCase())    {
        return el;
    } else {
        return getUntilParent(el.parentNode, sParentTag);
    }
}

var alertCount = 0;
function showAlert(value){
	if (alertCount++<5){
		alert(value);
	}
}

/**
 * Maps column sortType to appropriate comparison function. Each comparison
 * returns 1, -1, or 0, as required by the Array.sort() routine.
 *
 */
function compareValues(v1, v2, sSortType, fSortAsc){
    //alert("up v1: "+v1+" v2: "+v2);
    // note: new RegExp( "%|,|(<.*>)", "g" );  will match out everything(greedy) including the number in IE, though works fine
    // in FireFox
    var rel = new RegExp("(<[^>]*>)", "g");
       
    v1 = v1.replace(rel, "");
    v2 = v2.replace(rel, "");    
    //alert("up after v1: "+v1+" v2: "+v2);
     
	// Sort N/A's to the bottom
    var s1 = new String(v1).trim().toUpperCase();
    var s2 = new String(v2).trim().toUpperCase();
	if (commonIsNA(s1, s2)) return sortNA(s1, s2);
     
    return eval("compare" + sSortType + "(v1, v2, fSortAsc)");
}

/**
 * Base comparison functions
 */

function compareNumber(v1, v2, fSortAsc){
	// Remove "%" and "," from values
    var rel = new RegExp( "%|,", "g" );
    v1 = v1.replace(rel, "");
    v2 = v2.replace(rel, "");
    		
    var r;
    var n1 = new Number(v1);
    var n2 = new Number(v2);
    
    //if both strings are numbers  - compare as numbers, otherwise as text.
    if ((n1.toString()) != "NaN" && (n2.toString()) != "NaN") {
        if (n1 < n2)
            r = (fSortAsc) ? -1 : +1;
        else if (n1 > n2)
            r = (fSortAsc) ? +1 : -1;
        else
            r = 0;
        
        return r;
    } else {
        return compareText(v1, v2, fSortAsc);
    }
}

function compareText(v1, v2, fSortAsc){
    var r;
    var s1 = new String(v1);
    var s2 = new String(v2);
    // replace all N/A type values (ignoring case and extra spaces)
    // N/A should be the highest values
    // new values are only for sorting, they do not alter the data on the page
    var re1 = /^\s*N\s*\/\s*A\s*$/i
    s1 = s1.replace(re1, String.fromCharCode(254, 253)).trim();
    s2 = s2.replace(re1, String.fromCharCode(254, 253)).trim();

    if (s1 < s2)
        r = (fSortAsc) ? -1 : +1;
    else if (s1 > s2)
        r = (fSortAsc) ? +1 : -1;
    else
        r = 0;

    return r;
}

function comparePhase1Phase2(v1, v2, fSortAsc){
	var r;
    
    var a1 = v1.split("/") ;
	var a2 = v2.split("/") ;
	
    //alert(a1[0]+" "+a2[0]);
    //Compare Good Scores
    if (a1[0]* 1.0 < a2[0]* 1.0){
        r = (fSortAsc) ? -1 : +1;
    } else if (a1[0]* 1.0 > a2[0]* 1.0){
        r = (fSortAsc) ? +1 : -1;
    //Compare Bad Scores
    } else if (a1[1]* 1.0 < a2[1]* 1.0){
        r = (fSortAsc) ? +1 : -1;
    } else if (a1[1]* 1.0 > a2[1]* 1.0){
        r = (fSortAsc) ? -1 : +1;
    } else {
    	r = 0
    }

    return r;	
}

function sortNA(s1, s2){
    if ((s1=="N/A" || s1=="CNBS") && (s2!="N/A" || s2!="CNBS")) return 1;
    if ((s1!="N/A" || s1!="CNBS") && (s2=="N/A" || s2=="CNBS")) return -1;
    if ((s1=="N/A" || s1=="CNBS") && (s1=="N/A" || s1=="CNBS")) return 0;
}

function commonIsNA(s1, s2){
    //alert("v1: "+s1+" v2: "+s2+" "+(s1=='N/A'||s2=='N/A'));
    return (s1=='N/A'||s2=='N/A'||s1=='CNBS'||s2=='CNBS');
}

function returnFalse(){
    return false;
}


// this will handle the hidden column td.cellindex mismatch of IE 
function getCellIndex(row, cell){
    var elements = row.getElementsByTagName('td');
    if(elements.length == 0) elements = row.getElementsByTagName('th');
    for (var i = 0; i < elements.length; i++){
        if(elements[i] == cell) return i;
    }
}


