Element.addMethods({
	collectTextNodes: function(element){
		return $A($(element).childNodes).collect(function(node){
			return (node.nodeType == 3 ? node.nodeValue : (node.hasChildNodes()? Element.collectTextNodes(node) : ''));
		}).flatten().join('');
	}
});

var TableSorter = Class.create({
	initialize: function(element, startSort, sortOrder){
		this.first = true;
		this.element = $(element);
		this.sortIndex = startSort;
		this.sortOrder = sortOrder || 'asc';
		this.startSort = startSort || 0;
		this.initDOMReferences();
		this.initEventHandlers();
	},
	
	// zoeken naar thead en tbody
	initDOMReferences: function(){
		var head = this.element.down('thead');
		var body = this.element.down('tbody');
		if(!head || !body){
			throw 'Table must have a head and a body to be sortable';
		}
		// elke th een _colIndex waarde geven
		this.headers = head.down('tr').childElements();
		this.headers.each(function(e,i){
			if(e.getAttribute('order') != "no"){
				e._colIndex = i;
			}
		});
		this.body = body;
	},
	
	// clickHandler meegeven
	initEventHandlers: function(){
		this.handler = this.handleHeaderClick.bind(this);
		this.element.observe('click',this.handler, false);
	},
	
	//als we klikken op een td (dan is er geen _colIndex) dan moeten we zoeken naar zijn ancestor, zijn parent dus en die zijn _colIndex teruggeven
	handleHeaderClick: function(e){
		this.startTime=new Date().getTime();

		var element = e.element();
		if(!('_colIndex' in element)){
			element = element.ancestors().find(function(elt){
				return '_colIndex' in elt;
			});
			
			if(!((element) && '_colIndex' in element))
				return;
		}

		this.sort(element._colIndex);
	},
	
	adjustSortMarkers: function(index){
		// Als er reeds gesorteerd was op iets anders dan moet de class van het vorige verwijderd worden
		if(this.sortIndex != -1){
			this.headers[this.sortIndex].removeClassName('sort-'+this.sortOrder);
		}
		
		// Als een kolom nog niet gesorteerd is en je klikt er voor de eerste keer op SORT ASC
		if(this.sortIndex != index){
			this.sortOrder = 'asc';
			this.sortIndex = index;
			this.first = false;	
		}
		// Als een kolom wel gesorteerd is, dan kijk je of het asc of desc was en SORT dan andersom
		else{
			if(this.first){
				this.first = false;	
				this.headers[this.sortIndex].removeClassName('sort-'+this.sortOrder);
			}
			this.sortOrder = ('asc' == this.sortOrder ? 'desc' : 'asc');
		}
		// Toevoegen van de classname
		this.headers[index].addClassName('sort-'+this.sortOrder);
	},
	
	sort: function(index){
		this.adjustSortMarkers(index);
		// alle rijen uit de body ophalen
		var rows = this.body.childElements();
		// rijen sorteren op basis van de text in de rij (row) in de kolom die overeenkomt met sortIndex
		rows = rows.sortBy(function(row){
				var value = "";
				
				if(row.childElements()[this.sortIndex] != undefined){
					value = row.childElements()[this.sortIndex].collectTextNodes().replace(/^\s+|\s+$/g, "");
					
					/*if(row.getAttribute("master") == "true"){
						// We zorgen ervoor dat de master altijd vanboven staat door een aantal 'eerste' en 'laatste' karakters toe te voegen
						if(this.sortOrder == "asc"){
							if(!isNaN(value)){
								value = parseInt("00000"+value);
							}
							else{
								value = "\"\"\""+value;
							}
						}
						else{
							if(!isNaN(value)){
								value = parseInt("99999"+value);
							}
							else{
								value = "zzz"+value;
							}
						}
						return value;
					}
					else{*/
						var regexDate = /^(\d{2})\/(\d{2})\/(\d{4})$/;
						
						if(this.headers[index].getAttribute('varia') != null && this.headers[index].getAttribute('varia').toString() == "true"){
							if(value.length == 0){
								value = "zzz"+value;
							}
							// Dit wordt gebruikt voor de 'Online' kolom
							if(value.indexOf(" d.") >= 0){
								if(value.length == 4){
									value = "0"+value;	
								}
							}
						}
						else{
							if(value.length == 0){
								value = "zzz"+value;
							}
							else if(!isNaN(value)){
								return parseInt(row.childElements()[this.sortIndex].collectTextNodes());
							}
							else if(regexDate.test(value)){
								return RegExp.$3 + "" + RegExp.$2 + "" + RegExp.$1;
							}
						}
					//}
				}
				return value.toLowerCase();
		}.bind(this));
		
		var row_order = "rows.reverse()";
		// Als het desc is, rijen omdraaien
		if('desc' == this.sortOrder){
			row_order = "rows";
		}
		
		// we hebben nu een array met de gesorteerde lijsten
		// we moeten deze nu in onze DOM krijgen
		// we overlopen onze rijen ACHTERSTE VOREN omdat we de rijen telkens boven elkaar gaan inserten!
		var i = 0;
		eval(row_order).each(function(row,index){
			if(index > 0){
				if(row.getAttribute("style") == null || (row.getAttribute("style") != null && row.getAttribute("style").toString().indexOf("display") == -1)){
					row[(1 == i % 2 ? 'add': 'remove')+ 'ClassName']('alternate');
					i++;
				}
				this.body.insertBefore(row,rows[index-1]);
			}
		}.bind(this));
	}
});