//add event function
function addEvent( obj, type, fn ) {
	if (obj.addEventListener) {
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}
	else if (obj.attachEvent) {
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}
	else {
		obj["on"+type] = obj["e"+type+fn];
	}
}

//remove event function
function removeEvent( obj, type, fn )
{
	EventCache.remove(obj, type, fn);
}

//flush all events on page unload
var EventCache = function()
{
var listEvents = [];
return {
listEvents : listEvents,
add : function(node, sEventName, fHandler)
{
listEvents.push(arguments);
},
remove : function(node, sEventName, fHandler)
{
var i, item;
for(i = listEvents.length - 1; i >= 0; i = i - 1) {
if(node == listEvents[i][0] && sEventName == listEvents[i][1] && fHandler == listEvents[i][2]) {
item = listEvents[i];
if(item[0].removeEventListener) {
item[0].removeEventListener(item[1], item[2], item[3]);
}
if(item[1].substring(0, 2) != "on") {
item[1] = "on" + item[1];
}
if(item[0].detachEvent) {
item[0].detachEvent(item[1], item[0][sEventName+fHandler]);

}
item[0][item[1]] = null;
}
}
},
flush : function()
{
var i, item, eventtype;
for(i = listEvents.length - 1; i >= 0; i = i - 1) {
item = listEvents[i];
if(item[0].removeEventListener) {
item[0].removeEventListener(item[1], item[2], item[3]);
}
eventtype = item[1];
if(item[1].substring(0, 2) != "on") {
item[1] = 'on' + item[1];
}
if(item[0].detachEvent) {
item[0].detachEvent(item[1], item[2]);
item[0].detachEvent(item[1], item[0][eventtype+item[2]]);
}
item[0][item[1]] = null;
}
}
}
}();

//stripe a table with default css and add mouseover effect. 
var stripe = function(tablesName) {
		var tables = getElementsByClassName(tablesName);	

		for(var x=0;x!=tables.length;x++){
			var table = tables[x];
			if (! table) { return; }
			
			var tbodies = table.getElementsByTagName("tbody");
			
			for (var h = 0; h < tbodies.length; h++) {
				var even = false;
				var trs = tbodies[h].getElementsByTagName("tr");
				
				for (var i = 0; i < trs.length; i++) {
					trs[i].onmouseover=function(){
						this.className += " ruled"; return false
					}
					trs[i].onmouseout=function(){
						this.className = this.className.replace("ruled", ""); return false
					}
					
					if(even)
						trs[i].className += " even";
					
					even = !even;
				}
			}
		}
	}

//event added using the addEvent() function above
addEvent(window, 'load', function(){stripe('defaulttablestyle');});
addEvent(window, 'load', function(){stripe('scrolltablestyle');});


//find html element by class function
function getElementsByClassName(classname){
        var rl = new Array();
        var re = new RegExp('(^| )'+classname+'( |$)');
        var ael = document.getElementsByTagName('*');
        var op = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
        if (document.all && !op) ael = document.all;
        for(i=0, j=0 ; i<ael.length ; i++) {
                if(re.test(ael[i].className)) {
                        rl[j]=ael[i];
                        j++;
                }
        }
        return rl;
}



function cleanUpJs(){
	EventCache.flush;
}

addEvent(window,'unload',cleanUpJs);

//------------------------------------------------------
var fdTableSort = {

        regExp_Currency:        /^[£$€]/,
        regExp_Number:          /^(\-)?[0-9]+(\.[0-9]*)?$/,
        pos:                    -1,

        init: function() {
			
                if (!document.getElementsByTagName) return;

                headers = document.getElementsByTagName('th');
                for (var z=0, th; th = headers[z]; z++) {
                        if(th.className.match('sortable')) {
                                th.onclick = fdTableSort.initSort;
                                th.appendChild(document.createElement('span'));
								th.firstChild.onclick = 'return false';
								
                        }
                }
				
        },

        initSort: function(e) {

                var curr = this;
                var dbg = "";
                fdTableSort.pos = 0;

                // Get the column position
                while(curr.previousSibling) {
                        if(curr.previousSibling.nodeType != 3) fdTableSort.pos++;
                        curr = curr.previousSibling;
                }

                // Remove any old "reverse" class we might have previously added
                var thCollection = curr.parentNode.getElementsByTagName('th');

                for(var i=0, th; th=thCollection[i]; i++) {
                        if(i != fdTableSort.pos) {
                                th.className = th.className.replace('reverseSort','');
                                // Remove arrow
                                var span = th.getElementsByTagName('span');

                                if(span.length > 0) {
                                        var span = th.getElementsByTagName('span')[span.length - 1];
                                        if(span.firstChild) span.removeChild(span.firstChild);
                                        span.appendChild(document.createTextNode("\u00a0\u00a0"));
                                }
                        }
                }

                // Get the table
                var tableElem = this;
                while(tableElem.tagName.toLowerCase() != 'table' && tableElem.parentNode) {
                        tableElem = tableElem.parentNode;
                }

                // Has a row color been defined in the table's className?
                var style;

                if(tableElem.className.match(/style-(.+)/)) {
                        style = tableElem.className.match(/style-(.+)/)[1];
                }

                // Has the table a tbody ?
                // N.B. By definition, tables can have multiple tbody tags
                // this script assumes only one.
                if(tableElem.getElementsByTagName('tbody')) {
                        tableElem = tableElem.getElementsByTagName('tbody')[0];
                }

                // Get the tr tags
                var trs = tableElem.getElementsByTagName('tr');
                var trCollection = new Array();

                // If the current tr has any th child elements then skip it..
                for(var i = 0, tr; tr = trs[i]; i++) {
                        if(tr.getElementsByTagName('th').length == 0) trCollection.push(tr);
                }

                // Try to get the column data type
                var sortFunction;
                var txt = "";

                for(i = 0; i < trCollection.length; i++) {
                        txt = fdTableSort.getInnerText(trCollection[i].getElementsByTagName('td')[fdTableSort.pos]);
                        if(txt != "") break;
                }

                if(fdTableSort.dateFormat(txt) != 0)            sortFunction = fdTableSort.sortDate;
                else if(txt.match(fdTableSort.regExp_Number))   sortFunction = fdTableSort.sortNumeric;
                else if(txt.match(fdTableSort.regExp_Currency)) sortFunction = fdTableSort.sortCurrency;
                else                                            sortFunction = fdTableSort.sortCaseInsensitive;

                // Call the JavaScript array.sort method, passing in our bespoke sort function
                trCollection.sort(sortFunction);

                // Do we need to reverse the sort?
                var arrow;
                if(this.className.match('reverseSort')) {
                        trCollection.reverse();
                        this.className = this.className.replace('reverseSort','');
                        arrow = " \u2191";
                } else {
                        this.className = this.className + ' reverseSort';
                        arrow = " \u2193";
                }

                var span = this.getElementsByTagName('span');

                if(span.length > 0) {
                        var span = this.getElementsByTagName('span')[span.length - 1];
                        if(span.firstChild) span.removeChild(span.firstChild);
                        span.appendChild(document.createTextNode(arrow));
                }

                for(var i = 0, tr; tr = trCollection[i]; i++) {
                        if(style) {
                                tr.className = tr.className.replace(style,'');
                                tr.className = (i % 2 == 0) ? tr.className + " " + style : tr.className;
                        }
                        tableElem.appendChild(tr);
                }
        },

        getInnerText: function(el) {
                if (typeof el == "string" || typeof el == "undefined") return el;
                if(el.innerText) return el.innerText;
                var txt = '', i;
                for (i = el.firstChild; i; i = i.nextSibling) {
                        if (i.nodeType == 3)            txt += i.nodeValue;
                        else if (i.nodeType == 1)       txt += fdTableSort.getInnerText(i);
                }
                return txt;
        },

        dateFormat: function(dateIn) {

                var y, m, d, res;

                if(dateIn.match(/^(0[1-9]|1[012])([- \/.])(0[1-9]|[12][0-9]|3[01])([- \/.])(\d\d?\d\d)$/)) {
                        res = dateIn.match(/^(0[1-9]|1[012])([- \/.])(0[1-9]|[12][0-9]|3[01])([- \/.])(\d\d?\d\d)$/);
                        y = res[5];
                        m = res[1];
                        d = res[3];
                } else if(dateIn.match(/^(0[1-9]|[12][0-9]|3[01])([- \/.])(0[1-9]|1[012])([- \/.])(\d\d?\d\d)$/)) {
                        res = dateIn.match(/^(0[1-9]|[12][0-9]|3[01])([- \/.])(0[1-9]|1[012])([- \/.])(\d\d?\d\d)$/);
                        y = res[5];
                        m = res[3];
                        d = res[1];
                } else if(dateIn.match(/^(\d\d?\d\d)([- \/.])(0[1-9]|1[012])([- \/.])(0[1-9]|[12][0-9]|3[01])$/)) {
                        res = dateIn.match(/^(\d\d?\d\d)([- \/.])(0[1-9]|1[012])([- \/.])(0[1-9]|[12][0-9]|3[01])$/);
                        y = res[1];
                        m = res[3];
                        d = res[5];
                } else return 0;

                if(m.length == 1) m = "0" + m;
                if(d.length == 1) d = "0" + d;
                if(y.length != 4) y = (parseInt(y) < 50) ? '20' + y : '19' + y;

                return y+m+d;
        },

        sortDate: function(a,b) {
                aa = fdTableSort.dateFormat(fdTableSort.getInnerText(a.getElementsByTagName('td')[fdTableSort.pos]));
                bb = fdTableSort.dateFormat(fdTableSort.getInnerText(b.getElementsByTagName('td')[fdTableSort.pos]));
                if (aa == bb) return 0;
                if (aa < bb)  return -1;
                return 1;
        },

        sortCurrency:function(a,b) {
                aa = fdTableSort.getInnerText(a.getElementsByTagName('td')[fdTableSort.pos]).replace(/[^0-9.]/g,'');
                bb = fdTableSort.getInnerText(b.getElementsByTagName('td')[fdTableSort.pos]).replace(/[^0-9.]/g,'');
                if(isNaN(aa) || aa == "") aa = 0;
                if(isNaN(bb) || bb == "") bb = 0;
                return parseFloat(aa) - parseFloat(bb);
        },

        sortNumeric:function (a,b) {
                aa = parseFloat(fdTableSort.getInnerText(a.getElementsByTagName('td')[fdTableSort.pos]));
                if(isNaN(aa) || aa == "") aa = 0;
                bb = parseFloat(fdTableSort.getInnerText(b.getElementsByTagName('td')[fdTableSort.pos]));
                if(isNaN(bb) || bb == "") bb = 0;
                return aa-bb;
        },

        sortCaseInsensitive:function (a,b) {
                aa = fdTableSort.getInnerText(a.getElementsByTagName('td')[fdTableSort.pos]).toLowerCase();
                bb = fdTableSort.getInnerText(b.getElementsByTagName('td')[fdTableSort.pos]).toLowerCase();
                if(aa == bb) return 0;
                if(aa < bb)  return -1;
                return 1;
        }
}

addEvent(window, 'load', fdTableSort.init);


