/**
 * Written by Neil Crosby. 
 * http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting
 **/
//common
function addEvent(element, type, handler) {
	if (!handler.$$guid) handler.$$guid = addEvent.guid++;
	if (!element.events) element.events = {};
	var handlers = element.events[type];
	if (!handlers) {
		handlers = element.events[type] = {};
		if (element["on" + type]) {
			handlers[0] = element["on" + type];
		}
	}
	handlers[handler.$$guid] = handler;
	element["on" + type] = handleEvent;
};
addEvent.guid = 1;
function removeEvent(element, type, handler) {
	if (element.events && element.events[type]) {
		delete element.events[type][handler.$$guid];
	}
};
function handleEvent(event) {
	var returnValue = true;
	event = event || fixEvent(window.event);
	var handlers = this.events[event.type];
	for (var i in handlers) {
		this.$$handleEvent = handlers[i];
		if (this.$$handleEvent(event) === false) {
			returnValue = false;
		}
	}
	return returnValue;
};

function fixEvent(event) {
	event.preventDefault = fixEvent.preventDefault;
	event.stopPropagation = fixEvent.stopPropagation;
	return event;
};
fixEvent.preventDefault = function() {
	this.returnValue = false;
};
fixEvent.stopPropagation = function() {
	this.cancelBubble = true;
};
function createElement(element) {
	if (typeof document.createElementNS != 'undefined') {
		return document.createElementNS('http://www.w3.org/1999/xhtml', element);
	}
	if (typeof document.createElement != 'undefined') {
		return document.createElement(element);
	}
	return false;
}

function getEventTarget(e) {
	var targ;
	if (!e) {
		e = window.event;
	}
	if (e.target) {
		targ = e.target;
	} else if (e.srcElement) {
		targ = e.srcElement;
	}
	if (targ.nodeType == 3) {
		targ = targ.parentNode;
	}

	return targ;
}
// css func
var css = {
	getElementsByClass : function(node, searchClass, tag) {
		var classElements = new Array();
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
		for (var i = 0, j = 0; i < elsLen; i++) {
			if (this.elementHasClass(els[i], searchClass) ) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	},
	privateGetClassArray: function(el) {
		return el.className.split(' '); 
	},
	privateCreateClassString: function(classArray) {
		return classArray.join(' ');
	},
	elementHasClass: function(el, classString) {
		if (!el) {
			return false;
		}
		
		var regex = new RegExp('\\b'+classString+'\\b');
		if (el.className.match(regex)) {
			return true;
		}

		return false;
	},
	addClassToId: function(idString, classString) {
		this.addClassToElement(document.getElementById(idString), classString);
	},
	addClassToElement: function(el, classString) {
		var classArray = this.privateGetClassArray(el);

		if (this.elementHasClass(el, classString)) {
			return;
		}

		classArray.push(classString);

		el.className = this.privateCreateClassString(classArray);
	},
	removeClassFromId: function(idString, classString) {
		this.removeClassFromElement(document.getElementById(idString), classString);
	},
	removeClassFromElement: function(el, classString) {
		var classArray = this.privateGetClassArray(el);

		for (x in classArray) {
			if (classString == classArray[x]) {
				classArray[x] = '';
				break;
			}
		}
		el.className = this.privateCreateClassString(classArray);
	}
}

//table sort
var standardistaTableSorting = {
	that: false,
	sortColumnIndex : -1,
	lastAssignedId : 0,
	newRows: -1,
	lastSortedTable: -1,
	init : function() {
		if (!document.getElementsByTagName) {
			return;
		}
		this.that = this;
		this.run();
	},
	run : function() {
		var tables = document.getElementsByTagName("table");
		
		for (var i=0; i < tables.length; i++) {
			var thisTable = tables[i];
			
			if (css.elementHasClass(thisTable, 'sortable')) {
				this.makeSortable(thisTable);
			}
		}
	},
	makeSortable : function(table) {
		if (!table.id) {
			table.id = 'sortableTable'+this.lastAssignedId++;
		}
		if (!table.tHead || !table.tHead.rows || 0 == table.tHead.rows.length) {
			return;
		}
		var row = table.tHead.rows[table.tHead.rows.length - 1];
		for (var i=0; i < row.cells.length; i++) {
			
			//Link
			var linkEl = createElement('a');
			linkEl.href = '#';
			linkEl.onclick = this.headingClicked;
			linkEl.setAttribute('columnId', i);

			//Eerste sortering aangeven
			if(i == 0)
			{
				linkEl.className = "sort";
			}
			
			var innerEls = row.cells[i].childNodes;
			for (var j = 0; j < innerEls.length; j++) {
				linkEl.appendChild(innerEls[j]);
			}
			row.cells[i].appendChild(linkEl);

			//Span
			var spanEl = createElement('span');
  		    spanEl.className = 'tableSortArrow';
			spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
			
			//Eerste sortering aangeven
			if(i == 0)
			{
			   var im = document.createElement('DIV');
			   im.setAttribute('className','downNaam');
			   spanEl.appendChild(im);
			} 

			row.cells[i].appendChild(spanEl);
		
		}
	},
	headingClicked: function(e) {
		var that = standardistaTableSorting.that;
		var linkEl = getEventTarget(e);
		var td     = linkEl.parentNode;
		var tr     = td.parentNode;
		var thead  = tr.parentNode;
		var table  = thead.parentNode;
		if (!table.tBodies || table.tBodies[0].rows.length <= 1) {
			return false;
		}
		var column = linkEl.getAttribute('columnId') || td.cellIndex;
		var arrows = css.getElementsByClass(td, 'tableSortArrow', 'span');
		var previousSortOrder = '';
		if (arrows.length > 0) {
			previousSortOrder = arrows[0].getAttribute('sortOrder');
		}
		var itm = that.getInnerText(table.tBodies[0].rows[0].cells[column]);
		var sortfn = that.determineSortFunction(itm);
		if (table.id == that.lastSortedTable && column == that.sortColumnIndex) {
			newRows = that.newRows;
			newRows.reverse();
		} else {
			that.sortColumnIndex = column;
			var newRows = new Array();
			for (var j = 0; j < table.tBodies[0].rows.length; j++) { 
        if (!table.tBodies[0].rows[j].infoTrigger) // WGR InfoExpander filter
				  newRows[newRows.length] = table.tBodies[0].rows[j];
			}
			newRows.sort(sortfn);
		}
		that.moveRows(table, newRows);
		that.newRows = newRows;
		that.lastSortedTable = table.id;
		var linkC = css.getElementsByClass(tr, 'sort', 'A');
		for (var j = 0; j < linkC.length; j++) {
			linkC[j].className = '';
			}
		var arrows = css.getElementsByClass(tr, 'tableSortArrow', 'span');
		for (var j = 0; j < arrows.length; j++) {
			var arrowParent = arrows[j].parentNode;
			arrowParent.removeChild(arrows[j]);
			if (arrowParent != td) {
				spanEl = createElement('span');
				spanEl.className = 'tableSortArrow';
				spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
				arrowParent.appendChild(spanEl);
			}
		}
		var spanEl = createElement('span');
		spanEl.className = 'tableSortArrow';
		if (null == previousSortOrder || '' == previousSortOrder || 'DESC' == previousSortOrder) {
			var im = document.createElement('DIV');
			im.setAttribute('className','down');
			spanEl.appendChild(im);
			linkEl.className = 'sort';
			spanEl.setAttribute('sortOrder', 'ASC');
		} else {
			var im = document.createElement('DIV');
			im.setAttribute('className','up');
			spanEl.appendChild(im);
			linkEl.className = 'sort';
			spanEl.setAttribute('sortOrder', 'DESC');
		}
		td.appendChild(spanEl);
		return false;
	},
	getInnerText : function(el) {
		if ('string' == typeof el || 'undefined' == typeof el) {
			return el;
		}
		if (el.innerText) {
			return el.innerText;
		}
		var str = el.getAttribute('standardistaTableSortingInnerText');
		if (null != str && '' != str) {
			return str;
		}
		str = '';
		var cs = el.childNodes;
		var l = cs.length;
		for (var i = 0; i < l; i++) {
			if (1 == cs[i].nodeType) {
				str += this.getInnerText(cs[i]);
				break;
			} else if (3 == cs[i].nodeType) {
				str += cs[i].nodeValue;
				break;
			}
		}
		el.setAttribute('standardistaTableSortingInnerText', str);
		return str;
	},
	determineSortFunction : function(itm) {
		//var sortfn = this.sortCaseInsensitive;
    var sortfn = this.sortWithCollation; // WGR For extended characters
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
			sortfn = this.sortDate;
		}
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) {
			sortfn = this.sortDate;
		}
		if (itm.match(/^[£$]/)) {
			sortfn = this.sortCurrency;
		}
		//if (itm.match(/^[\d\.]+[]$/)) {
    if (itm.match(/^[\d\.]+[\sa-zA-Z0-9_]*$/)) { // WGR
			sortfn = this.sortNumeric;
		}
    		if (itm.match(/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/)) {
        		sortfn = this.sortIP;
   		}
		return sortfn;
	},
	sortCaseInsensitive : function(a, b) {
		var that = standardistaTableSorting.that;	
		var aa = that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase();
		var bb = that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase();
		if (aa==bb) {
			return 0;
		} else if (aa<bb) {
			return -1;
		} else {
			return 1;
		}
	},
  sortWithCollation : function(a, b) {
    function collateString(s, m) {
      var table = [
        [65, 192, 193, 194, 195, 196, 197, 198], [97, 224, 225, 226, 227, 228, 229, 230],
        [67, 199], [99, 231], [69, 200, 201, 202, 203], [101, 232, 233, 234, 235],
        [73, 204, 205, 206, 207], [105, 236, 237, 238, 239], [78, 209], [110, 241],
        [79, 210, 211, 212, 213, 214], [111, 242, 243, 244, 245, 246], [115, 223],
        [85, 217, 218, 219, 220], [117, 249, 250, 251, 252], [89, 221], [121, 253]
      ];
      var r = "";
      for (var i = 0, l = s.length; i < l; i++) {
        if (!m || (m && i < m - 1)) {
          var c = s.charAt(i);
          for (var j in table) {
            for (var k in table[j]) {
              if (table[j][k] == c.charCodeAt(0))
                r += String.fromCharCode(table[j][0]);
            }
          }
          if (i > r.length - 1) r += c;
        }
        else {
          r += s.substring(i);
          break;
        }
      }
      return r;
    }
    var that = standardistaTableSorting.that;	
		var aa = collateString(that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase(), 2);
		var bb = collateString(that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase(), 2);
    if (aa==bb) {
      return 0;
    } else if (aa<bb) {
      return -1;
    } else {
      return 1;
    }
  },
	sortDate : function(a,b) {
		var that = standardistaTableSorting.that;
		var aa = that.getInnerText(a.cells[that.sortColumnIndex]);
		var bb = that.getInnerText(b.cells[that.sortColumnIndex]);	
		var dt1, dt2, yr = -1;
		if (aa.length == 10) {
			dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
		} else {
			yr = aa.substr(6,2);
			if (parseInt(yr) < 50) { 
				yr = '20'+yr; 
			} else { 
				yr = '19'+yr; 
			}
			dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
		}
		
		if (bb.length == 10) {
			dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
		} else {
			yr = bb.substr(6,2);
			if (parseInt(yr) < 50) { 
				yr = '20'+yr; 
			} else { 
				yr = '19'+yr; 
			}
			dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
		}
		
		if (dt1==dt2) {
			return 0;
		} else if (dt1<dt2) {
			return -1;
		}
		return 1;
	},
	sortCurrency : function(a,b) { 
		var that = standardistaTableSorting.that;

		var aa = that.getInnerText(a.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
		var bb = that.getInnerText(b.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
		return parseFloat(aa) - parseFloat(bb);
	},
	sortNumeric : function(a,b) { 
		var that = standardistaTableSorting.that;

		var aa = parseFloat(that.getInnerText(a.cells[that.sortColumnIndex]));
		if (isNaN(aa)) { 
			aa = 0;
		}
		var bb = parseFloat(that.getInnerText(b.cells[that.sortColumnIndex])); 
		if (isNaN(bb)) { 
			bb = 0;
		}
		return aa-bb;
	},
	makeStandardIPAddress : function(val) {
		var vals = val.split('.');
		for (x in vals) {
			val = vals[x];
			while (3 > val.length) {
				val = '0'+val;
			}
			vals[x] = val;
		}
		val = vals.join('.');
		return val;
	},
	sortIP : function(a,b) { 
		var that = standardistaTableSorting.that;
		var aa = that.makeStandardIPAddress(that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase());
		var bb = that.makeStandardIPAddress(that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase());
		if (aa==bb) {
			return 0;
		} else if (aa<bb) {
			return -1;
		} else {
			return 1;
		}
	},
	moveRows : function(table, newRows) {
		var odd = false;
		for (var i=0;i<newRows.length;i++) { 
			var rowItem = newRows[i];
			if(odd) {
				css.addClassToElement(rowItem, 'odd');
			} else {
				css.removeClassFromElement(rowItem, 'odd');
			}
			odd = !odd;

			table.tBodies[0].appendChild(rowItem); 
      if (rowItem.infoRow) table.tBodies[0].appendChild(rowItem.infoRow); // WGR InfoExpander correction
		}
	}
}
function setTableSort() {
	standardistaTableSorting.init();
}
/*addEvent(window, 'load', standardistaTableSortingInit)*/
