
// --------------------------------------------------
// Tabellen Sortierung
// --------------------------------------------------
//
// Init : <table ... rel="sortable">
// 
// Erste Zeile nach <table> muss dann die 
// Überschriften mit <th> sein.
//
// Parameter "sort" in <th>-Tag
//
// <th .. sort="no|caseSensitive|integer|float|date|currency">
//
// --------------------------------------------------


var SortableTable = Class.create() ;

SortableTable.prototype = { 

	// Init : Tabelle sortieren

	initialize : function (table) {
	
  		this.table = table ;
  		this.rows = $A(table.rows).map(function(r) { return $(r) }) ;

		// 1. Überschriften-Zeile

  		this.headerRow = this.rows.shift() ; 
  	
  		// 2. Überschriften-Zeile ggf. raus

  		if ( Selector.findChildElements(this.rows[0],['th']) != '' ) {
  		
  			this.headerRow2 = this.rows.shift() ; 	
  		}
 	
  		// Sortierungslink für Überschriften einbauen
  		
  		var me = this ;
  		
  		Selector.findChildElements(this.headerRow,['th']).each( 
  		
  			function(th) {

    			var span = $(document.createElement('span')) ;
    			th.observe('click', me.sortOnColumn.bind(me,th,span) ) ; 
  			}
  		);

	} ,


	// Sortierung ausführen

	simpleCompare : function (a,b) { 
	
  		return ( a < b ? -1 : a == b ? 0 : 1 ) ; 
	} ,


	// Sortierfunktion über Tag laden

	compareComposer : function (normalizeFn) { 
	
		var me = this ;
  		return ( function(a,b) { return me.simpleCompare( normalizeFn(a) , normalizeFn(b) ) } ) ;
	} ,


	//Sortiertyp auswählen

	compareFunction : function (sType) { 

		switch (sType) {
    
    		case "caseSensitive" :  
    
      			return ( this.simpleCompare ) ;
    
    		case "integer" : 
    
      			return this.compareComposer(function(a) { 
      			
        			return ( parseInt(a.replace(/^.*?(\d+).*$/,"$1")) ) ;
      			});
    
    		case "float" :
    
       			return this.compareComposer(function(a) { 
       		
       				var fval = a.replace(/^.*?(\d+[\,\.]\d+|\d+).*$/,"$1") ;
        			return ( parseFloat(fval.replace(/\,/,"\.")) ) ;
      			});
    
    		case "currency" :
    
       			return this.compareComposer(function(a) { 
       		
       				var fval = a.replace(/\./,"") ;
        			return ( parseFloat(fval.replace(/\,/,"\.")) ) ;
      			});
      			
    		case "date" :  
    	
      			return ( this.compareComposer(Date.parse) ) ;
    
    		default :
    	
      			return this.compareComposer(function(a) { 
      			
	      			return ( a.toLowerCase() ) ; 
      			}) ;
  		}
	} ,


	// Sortierungstyp ermitteln

	sortTyp : function (cellval,cellsort) {

		return ( cellsort || this.sortDetectors.detect(function(d){return d.re.test(cellval);})['type'] ) ;
	} ,
	
	sortDetectors : $A([

		{re: /^\d+$/, type : "integer"} ,
		{re: /^\d+[\.\,]+\d+$/, type : "float"} ,
		{re: /^\d+\.\d+\,\d+$/, type : "currency"} ,
		{re: /[\d]{4}-[\d]{2}-[\d]{2}(?:T[\d]{2}\:[\d]{2}(?:\:[\d]{2}(?:\.[\d]+)?)?(Z|([-+][\d]{2}:[\d]{2})?)?)?/, type : "date-iso"} , // 2005-03-26T19:51:34Z
		{re: /^sun|mon|tue|wed|thu|fri|sat\,\s\d{1,2}\sjan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec\s\d{4}(?:\s\d{2}\:\d{2}(?:\:\d{2})?(?:\sGMT(?:[+-]\d{4})?)?)?/i, type : "date"} , //Mon, 18 Dec 1995 17:28:35 GMT 
		{re: /^\d{2}-\d{2}-\d{4}/i, type : "date-eu"} ,
		{re: /^\d{1,2}\:\d{2}(?:\:\d{2})?(?:\s[a|p]m)?$/i, type : "time"} ,
		{re: /.*/, type : ""} ,
	]),


	// Tabelle sortieren

	sortOnColumn : function (th,span) {

		var pos = $A(this.headerRow.cells).indexOf(th) ;
		var sortTYP = this.sortTyp(this.rows[0].getCellText(pos),th.getAttribute('sort')) ;
		var sortFn = this.compareFunction(sortTYP) ;
  		span.order = span.order || 1 ;
  		  
  		if ( th.getAttribute('sort') != 'no' ) {
  
  			this.rows.sort(
  		
	    		function (rowA,rowB) { 
	    		
      				return ( span.order * sortFn( rowA.getCellText(pos) , rowB.getCellText(pos) ) ) ;  
    			}
  			);

			// Sortierreihenfolge tauschen
  	
  			span.order *= -1 ;

  			// Tabelle neu aufbauen
  		
  			var tabcol = 0 ; 
  			var tbody = this.table.tBodies[0] ;
	
  			this.rows.each( function(row) { 
  			
  				if ( ( tabcol += 1 ) % 2 ) { 
  			 	
  			 		Selector.findChildElements(row,['td']).each(function(td) {
    
    					td.style.background = bgc_list2 ; 
			 		});
 			 	
  				} else {
  			 	
  			 		Selector.findChildElements(row,['td']).each(function(td) {
    
	    				td.style.background = bgc_list1 ; 
			 		});
  				} 
	    
				tbody.appendChild(row) ;
  			});
  		} 
  	} 

} ;


// Hilfsfunktionen

Element.addMethods({ 

	// Text aus Element zurückgeben
	getText : function (e) {
		
		return ( e.text = e.text || e.textContent || e.innerText || '' ) ;
	} ,
	
	//Tabellenzelle auslesen
	getCellText : function (row,pos) { 
    
    	row.cellTexts = ( row.cellTexts || [] ) ;
   		row.cellTexts[pos] = ( row.cellTexts[pos] || row.down("td", pos).getText() ) ; 
    	
    	return ( row.cellTexts[pos] ) ;
  	}
  	
}); 


// Tabellen initalisieren 
// ggf. wegen performance ins Template wo nötig
// function tab1() { new SortableTable($('tp_detail_table')) }
// Event.observe(window, 'load', tab1, false) ;  
// $$('table[rel="sortable"]').each(function(table) {


// --------------------------------------------------
// END
// --------------------------------------------------