//==================== SORT COLUMNS =======================

function convert(sCell, sDataType) {
	var sValue;
	if (sCell == null) return "";
	if (sCell.hasAttribute("value")) sValue = sCell.getAttribute("value");
	if (sCell.firstChild == null) return "";
	if (sCell.firstChild.nodeValue) sValue = sCell.firstChild.nodeValue;
	if (sValue == "&nbsp;") return "";
	if (sValue == null) return "";
	switch(sDataType) {
		case "int":
		return parseInt(sValue);
		case "float":
		return parseFloat(sValue);
		case "date":
		return new Date(Date.parse(sValue));
		default:
		return sValue.toString();

	}
}

function generateCompareTRs(iCol, sDataType) {

	return  function compareTRs(oTR1, oTR2) {
		var vValue1, vValue2;

		vValue1 = convert(oTR1.cells[iCol], sDataType);
		vValue2 = convert(oTR2.cells[iCol], sDataType);

		if (vValue1 < vValue2) {
			return -1;
		} else if (vValue1 > vValue2) {
			return 1;
		} else {
			return 0;
		}
	};
}

function sortTable(sTableID, iCol, sDataType) {
	var oTable = document.getElementById(sTableID);
	var oTBody = oTable.tBodies[0];
	var colDataRows = oTBody.rows;
	var aTRs = new Array;
	
	for (var i=2; i < colDataRows.length; i++) {
		aTRs[i-2] = colDataRows[i];
	}


	if (oTable.sortCol == iCol) {
		aTRs.reverse();
	} else {
		aTRs.sort(generateCompareTRs(iCol, sDataType));
	}

	var oFragment = document.createDocumentFragment();

	
	for (var i=0; i < aTRs.length; i++) {
		oFragment.appendChild(aTRs[i]);
	}

	oTBody.appendChild(oFragment);
	oTable.sortCol = iCol;
}

//==================== MOUSEOVER TOOLTIP =======================


var xmlHttp;
var dataDiv;
var dataTable;
var dataTableBody;
var offsetEl;

var posx = 0;
var posy = 0;

function setCoords(e) {
	if (!e) var e = window.event;
	if (e.pageX || e.pageY) 	{
		posx = e.pageX;
		posy = e.pageY;
	}
	else if (e.clientX || e.clientY) 	{
		posx = e.clientX + document.body.scrollLeft
		+ document.documentElement.scrollLeft;
		posy = e.clientY + document.body.scrollTop
		+ document.documentElement.scrollTop;
	}
}

function createXMLHttpRequest() {
	if (window.ActiveXObject) {
		xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else if (window.XMLHttpRequest) {
		xmlHttp = new XMLHttpRequest();
	}
}

function initVars() {
	dataTableBody = document.getElementById("courseDataBody");
	dataTable = document.getElementById("courseData");
	dataDiv = document.getElementById("popup");
}

function getCourseData(element, data, event) {
	setCoords(event);
	initVars();
	offsetEl = element;

	setData(data);
}

function callback() {
	if (xmlHttp.readyState == 4) {
		if (xmlHttp.status == 200) {
			setData(xmlHttp.responseXML);
		}
	}
}

function setData(courseData) {
	clearData();
	setOffsets();

	var row2;
	row2 = createRow(courseData);
	dataTableBody.appendChild(row2);
}

function createRow(data) {
	var row, cell, txtNode;
	row = document.createElement("tr");
	cell = document.createElement("td");

	cell.setAttribute("bgcolor", "#FFFAFA");
	cell.setAttribute("border", "0");

	txtNode = document.createTextNode(data);
	cell.appendChild(txtNode);
	row.appendChild(cell);

	return row;
}

function setOffsets() {
	var end = offsetEl.offsetWidth;
	var top = calculateOffsetTop(offsetEl);
	dataDiv.style.border = "black 1px solid";
	dataDiv.style.left = posx + 5;//end + 15 + "px";
	dataDiv.style.top = top + 5 + "px";
}

function calculateOffsetTop(field) {
	return calculateOffset(field, "offsetTop");
}

function calculateOffset(field, attr) {
	var offset = 0;
	while(field) {
		offset += field[attr];
		field = field.offsetParent;
	}
	return offset;
}

function clearData() {
	var ind = dataTableBody.childNodes.length;
	for (var i = ind - 1; i >= 0 ; i--) {
		dataTableBody.removeChild(dataTableBody.childNodes[i]);
	}
	dataDiv.style.border = "none";
}

//==================== FILTER =======================
var TblId, StartRow, SearchFlt;
TblId = new Array, StartRow = new Array;

function setFilterGrid(id)
/*====================================================
- Checks if id exists and is a table
- Then looks for additional params
- Calls fn that adds inputs and button
=====================================================*/
{
	var tbl = document.getElementById(id);
	var ref_row, fObj;
	if(tbl != null && tbl.nodeName.toLowerCase() == "table")
	{
		TblId.push(id);
		if(arguments.length>1)
		{
			for(var i=0; i<arguments.length; i++)
			{
				var argtype = typeof arguments[i];

				switch(argtype.toLowerCase()){
					case "number":
					ref_row = arguments[i];
					break;
					case "object":
					fObj = arguments[i];
					break;
				}//switch

			}//for
		}//if
		ref_row == undefined ? StartRow.push(2) : StartRow.push(ref_row+2);

		
		var ncells = getCellsNb(id,ref_row);
		AddRow(id,ncells,fObj);
	}
}

function AddRow(id,n,f)
/*====================================================
- adds a filter (input) for each column (td)
- adds button on last column
=====================================================*/
{
	
	var filerRowInserIndex=1;
	
	// Adde: Hack för fixa filterrad placering
	var browser=String(navigator.userAgent);
	var isMoz=browser.indexOf("Gecko") > -1;
	filerRowInserIndex=1;
	
	
	var t = document.getElementById(id);
	var fltrow = t.insertRow(filerRowInserIndex);
	var inpclass;

	
	for(var i=0; i<n; i++)
	{
		var fltcell = fltrow.insertCell(i);
		//alert(fltcell);
		fltcell.className='filterrow';
		i==n-1 ? inpclass = "flt_s" : inpclass = "flt";

		if(f==undefined || f["col_"+i]==undefined || f["col_"+i]=="none")
		{
			var inp = document.createElement("input");
			inp.setAttribute("id","flt"+i+"_"+id);
			if(f==undefined || f["col_"+i]==undefined) {
				inp.setAttribute("type","text");
			}
			else inp.setAttribute("type","hidden");
			//inp.setAttribute("class","flt"); //doesn't seem to work on ie<=6
			fltcell.appendChild(inp);
			document.getElementById("flt"+i+"_"+id).className = inpclass;
			document.getElementById("flt"+i+"_"+id).onkeypress = DetectKey;
		}
		else if(f["col_"+i]=="select")
		{
			var slc = document.createElement("select");
			slc.setAttribute("id","flt"+i+"_"+id);
			fltcell.appendChild(slc);
			PopulateOptions(id,i,n);
			//alert(inpclass);
			document.getElementById("flt"+i+"_"+id).className = inpclass;
			document.getElementById("flt"+i+"_"+id).onkeypress = DetectKey;
		}

		
		/*if(i==n-1) // this adds button
		{
		var btn = document.createElement("a");

		btn.setAttribute("id","btn"+i+"_"+id);
		btn.setAttribute("href","javascript:Filter('"+id+"');");
		btn.setAttribute("class","go");
		fltcell.appendChild(btn);
		btn.appendChild(document.createTextNode("go"));

		document.getElementById("btn"+i+"_"+id).className = "btn";
		}*///if

	}// for i
	//Filter(id);
	//window.setTimeout("", 1);
	
}

function PopulateOptions(id,cellIndex,ncells)
/*====================================================
- populates select
- adds only 1 occurence of a value
=====================================================*/
{
	var t = document.getElementById(id);
	var start_row = getStartRow(id);
	var row = t.getElementsByTagName("tr");
	var OptArray = new Array;
	var optIndex = 0; // option index
	
	for(var k=start_row; k<row.length; k++)
	{
		var cell = getChildElms(row[k]).childNodes;
		var nchilds = cell.length;

		if(nchilds == ncells){// checks if row has exact cell #

			for(var j=0; j<nchilds; j++)// this loop retrieves cell data
			{
				if(cellIndex==j)
				{
					var cell_data = getCellText(cell[j]);
					if(OptArray.toString().search(cell_data) == -1)
					// checks if celldata is already in array
					{
						optIndex++;
						OptArray.push(cell_data);
						var currOpt = new Option(cell_data,cell_data,false,false);
						document.getElementById("flt"+cellIndex+"_"+id).options[optIndex] = currOpt;
					}
				}//if cellIndex==j
			}//for j

		}//if

	}//for k
}

function Filter(id)
/*====================================================
- gets search strings from SearchFlt array
- retrieves data from each td in every single tr
and compares to search string for current
column
- tr is hidden if all search strings are not
found
=====================================================*/
{
	getFilters(id);
	var t = document.getElementById(id);
	var SearchArgs = new Array();
	var ncells = getCellsNb(id);
	
	for(i in SearchFlt){
		//alert(SearchFlt[i]);
		SearchArgs.push((document.getElementById(SearchFlt[i]).value).toLowerCase());
	}

	var start_row = getStartRow(id);
	var row = t.getElementsByTagName("tr");

	for(var k=start_row; k<row.length; k++)
	{
		/*** if table already filtered some rows are not visible ***/
		if(row[k].style.display == "none") row[k].style.display = "";

		var cell = getChildElms(row[k]).childNodes;
		var nchilds = cell.length;

		if(nchilds == ncells){// checks if row has exact cell #
			var cell_value = new Array();
			var occurence = new Array();
			var isRowValid = true;

			for(var j=0; j<nchilds; j++)// this loop retrieves cell data
			{
				var cell_data = getCellText(cell[j]).toLowerCase();
				cell_value.push(cell_data);

				if(SearchArgs[j]!="")
				{
					occurence[j] = cell_data.split(SearchArgs[j]).length;
				}
			}//for j

			for(var t=0; t<ncells; t++)
			{
				if(SearchArgs[t]!="" && occurence[t]<2)
				{
					isRowValid = false;
				}
			}//for t

		}//if

		if(isRowValid==false) row[k].style.display = "none";
		else row[k].style.display = "";

	}// for k
}

function getCellsNb(id,nrow)
/*====================================================
- returns number of cells in a row
- if nrow param is passed returns number of cells
of that specific row
=====================================================*/
{
	var t = document.getElementById(id);
	var tr;
	if(nrow == undefined) tr = t.getElementsByTagName("tr")[0];
	else  tr = t.getElementsByTagName("tr")[nrow];
	var n = getChildElms(tr);
	return n.childNodes.length;
}

function getFilters(id)
/*====================================================
- filter (input or select) ids are stored in
SearchFlt array
=====================================================*/
{
	SearchFlt = new Array;
	var t = document.getElementById(id);
	var tr = t.getElementsByTagName("tr")[1];
	var enfants = tr.childNodes;

	for(var i=0; i<enfants.length; i++) SearchFlt.push(enfants[i].firstChild.getAttribute("id"));
}

function getStartRow(id)
/*====================================================
- returns starting row for Filter fn for a
given table id
=====================================================*/
{
	var r;
	for(j in TblId)
	{
		if(TblId[j] == id) r = StartRow[j];
	}
	return r;
}

function getChildElms(n)
/*====================================================
- checks passed node is a ELEMENT_NODE nodeType=1
- removes TEXT_NODE nodeType=3
=====================================================*/
{
	if(n.nodeType == 1)
	{
		var enfants = n.childNodes;
		for(var i=0; i<enfants.length; i++)
		{
			var child = enfants[i];
			if(child.nodeType == 3) n.removeChild(child);
		}
		return n;
	}
}

function getCellText(n)
/*====================================================
- returns text + text of child nodes of a cell
=====================================================*/
{
	var s = "";
	var enfants = n.childNodes;
	for(var i=0; i<enfants.length; i++)
	{
		var child = enfants[i];
		if(child.nodeType == 3) s+= child.data;
		else s+= getCellText(child);
	}
	return s;
}

function DetectKey(e)
{
	/*====================================================
	- common fn that detects return key for a given
	element (onkeypress attribute on input)
	=====================================================*/
	var evt=(e)?e:(window.event)?window.event:null;
	if(evt){
		var key=(evt.charCode)?evt.charCode:
		((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
		if(key=="13")
		{
			var tblid = this.getAttribute("id").split("_")[1];
			Filter(tblid);
		}
	}
}

