

/**************************************************************

	Script		: Sortable Table
	Version		: 1.4
	Authors		: Samuel Birch
	Desc		: Sorts and filters table elements
	Licence		: Open Source MIT Licence

**************************************************************/

var sortableTable = new Class({
							  
	getOptions: function(){
		return {
			overCls: false,
			onClick: false,
			sortOn: 0,
			sortBy: 'ASC',
			rowHeight: null,
			filterHide: true,
			filterHideCls: 'hide',
			filterSelectedCls: 'selected',
			pager: false,
			amountPages: null,
			itemsPerPage: 10,
			availablePages: null,
			currentNr: null,
			currentSelected: null
		};
	},

	initialize: function(table, options){
		this.setOptions(this.getOptions(), options);
		this.table = $(table);
		this.tHead = this.table.getElement('thead');
		this.tBody = this.table.getElement('tbody');
		this.tFoot = this.table.getElement('tfoot');
		this.elements = this.tBody.getElements('tr');
		this.filtered = false;
		
		/*for(i=0;i<10;i++){
			this.elements.clone().injectInside(this.tBody);
		}
		this.elements = this.tBody.getElements('tr');*/
		if($chk(this.elements) && this.elements.length > 0){
			this.options.rowHeight = this.elements[0].getStyle('height');
		}
		this.elements.each(function(el,i){
			if(this.options.overCls){
				el.addEvent('mouseover', function(){
					el.addClass(options.overCls);
				}, this);
				el.addEvent('mouseout', function(){
					el.removeClass(options.overCls);
				});
			}
			if(this.options.onClick){
				el.addEvent('click', options.onClick);
			}
		}, this);
		
		//setup header
		if(this.options.pager){
			var pagerPanel = new Element('tr');
			var pager = new Element('td');
			pager.setProperty('colspan',this.tHead.getElements('th').length);
			pager.className = 'tablePager';
			
			this.options.availablePages = []; 
	
			this.options.amountPages = (this.elements.length / this.options.itemsPerPage);

			if(this.options.amountPages > 1){
			
				var page = new Element('div');
				page.className = 'tablePageScroll';
				page.innerHTML = '< vorige';
				page.addEvent('click',this.slidePage.bind(this,['prev']));
				page.injectInside(pager);
				
				var pageDivider = new Element('div');
				pageDivider.className = 'tablePageDivider';
				pageDivider.innerHTML = '|';
				pageDivider.injectInside(pager);
						
				for(i=1;i<=Math.ceil(this.options.amountPages);i++){
					var page = new Element('div');
					if(i == 1){
						page.className = 'tablePageSel';
						this.options.currentSelected = page;
						this.options.currentNr = i;
					}else{
						page.className = 'tablePage';
					}
					page.addEvent('click',this.SelectPage.bind(this,[page]));
					
					page.innerHTML = i;
					page.injectInside(pager);
					this.options.availablePages.include(page); 
					
					var pageDivider = new Element('div');
					pageDivider.className = 'tablePageDivider';
					pageDivider.innerHTML = '|';
					pageDivider.injectInside(pager);
 			
				}
				
				var page = new Element('div');
				page.className = 'tablePageScroll';
				page.innerHTML = 'volgende >';
				page.addEvent('click',this.slidePage.bind(this,['next']));
				page.injectInside(pager);
				
				//this.SelectPage(this.options.currentSelected);
				pager.injectInside(pagerPanel);
				pagerPanel.injectTop(this.tHead);
				
			}
		}
		this.tHead.getElements('th').each(function(el,i){
			
			if(el.axis){
				el.addEvent('click', this.sort.bind(this,i));
				el.addEvent('mouseover', function(){
					el.addClass('tableHeaderOver');
				});
				el.addEvent('mouseout', function(){
					el.removeClass('tableHeaderOver');
				});
				el.getdate = function(str){
					// inner util function to convert 2-digit years to 4
					function fixYear(yr) {
						yr = +yr;
						if (yr<50) { yr += 2000; }
						else if (yr<100) { yr += 1900; }
						return yr;
					};
					var ret;
					//
					if (str.length>12){
						strtime = str.substring(str.lastIndexOf(' ')+1);
						strtime = strtime.substring(0,2)+strtime.substr(-2)
					}else{
						strtime = '0000';
					}
					//
					// YYYY-MM-DD
					if (ret=str.match(/(\d{2,4})-(\d{1,2})-(\d{1,2})/)) {
						return (fixYear(ret[1])*10000) + (ret[2]*100) + (+ret[3]) + strtime;
					}
					// DD/MM/YY[YY] or DD-MM-YY[YY]
					if (ret=str.match(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/)) {
						return (fixYear(ret[3])*10000) + (ret[2]*100) + (+ret[1]) + strtime;
					}
					return 999999990000; // So non-parsed dates will be last, not first
				};
				//
				el.findData = function(elem){
					var child = elem.getFirst();
					if(child){
						return el.findData(child);
					}else{
						return elem.innerHTML.trim();
					}
				};
				//
				el.compare = function(a,b){
					var1 = el.findData(a.getChildren()[i]);
					var2 = el.findData(b.getChildren()[i]);
					//var1 = a.getChildren()[i].firstChild.data;
					//var2 = b.getChildren()[i].firstChild.data;
					
					if(el.axis == 'number' || el.axis == 'Integer' || el.axis == 'ImmutableInteger'){
						var1 = parseFloat(var1);
						var2 = parseFloat(var2);
						
						if(el.sortBy == 'ASC'){
							return var1-var2;
						}else{
							return var2-var1;
						}
						
					}else if(el.axis == 'string' || el.axis == 'String' || el.axis == 'email' || el.axis == 'Email' ||
						el.axis == 'LinkPickerURL' || el.axis == 'Address' || el.axis == 'Zipcode' || el.axis == 'FixedSelect' ){
						var1 = var1.toUpperCase();
						var2 = var2.toUpperCase();
						
						if(var1==var2){return 0};
						if(el.sortBy == 'ASC'){
							if(var1<var2){return -1};
						}else{
							if(var1>var2){return -1};
						}
						return 1;
						
					}else if(el.axis == 'JoinedField'){
						var1 = var1.toUpperCase();
						var2 = var2.toUpperCase();
						
						if(var1==var2){return 0};
						if(el.sortBy == 'ASC'){
							if(var1<var2){return -1};
						}else{
							if(var1>var2){return -1};
						}
						return 1;
						
					}else if(el.axis == 'HtmlText'){
	
						var1 = var1.toUpperCase();
						var2 = var2.toUpperCase();
						
						if(var1==var2){return 0};
						if(el.sortBy == 'ASC'){
							if(var1<var2){return -1};
						}else{
							if(var1>var2){return -1};
						}
						return 1;
						
					}else if(el.axis == 'date' || el.axis == 'Date'){
						var1 = parseFloat(el.getdate(var1));
						var2 = parseFloat(el.getdate(var2));
						
						if(el.sortBy == 'ASC'){
							return var1-var2;
						}else{
							return var2-var1;
						}
						
					}else if(el.axis == 'currency'){
						var1 = parseFloat(var1.substr(1).replace(',',''));
						var2 = parseFloat(var2.substr(1).replace(',',''));
						
						if(el.sortBy == 'ASC'){
							return var1-var2;
						}else{
							return var2-var1;
						}
						
					}
					
				}
				
				if(i == this.options.sortOn){
					el.fireEvent('click');
				}
			}
		}, this);
		
		if(Browser.Engine.trident){
			this.table.setStyle('display','block');
		}else{
			this.table.setStyle('display','table');
		}
	},
	
	slidePage: function(slideDirection){
		if(slideDirection == 'next'){
			nextPage = (this.options.currentNr.toInt() + 1);
			if(nextPage <= this.options.availablePages.length){
				nextElement = this.options.availablePages[nextPage-1];
				this.SelectPage(nextElement);
			}
		}	
		if(slideDirection == 'prev'){			
			prevPage = this.options.currentNr.toInt() - 1;
			if(prevPage >= 1){
				prevElement = this.options.availablePages[prevPage-1];
				this.SelectPage(prevElement);
			}
		}
		
	
	},
	
	SelectPage: function(pageElement){
		this.options.currentSelected.className = 'tablePage';
		this.options.currentNr = pageElement.innerHTML;
		pageElement.className = 'tablePageSel';
		boundary1 = (pageElement.innerHTML * this.options.itemsPerPage) - this.options.itemsPerPage;
		boundary2 = (pageElement.innerHTML * this.options.itemsPerPage);
		for(i=0;i<this.elements.length;i++){

			if(i >= boundary1 && i < boundary2){
				if(Browser.Engine.trident){
					this.elements[i].setStyle('display','block');
				}else{
					this.elements[i].setStyle('display','table-row');
				}

			}else{
				this.elements[i].setStyle('display','none');
			}
		}
		this.options.currentSelected = pageElement;
		
		if(this.filtered){
			this.filteredAltRow();
		}else{
			this.altRow();
		}
	},
	
	sort: function(index){
		if(this.options.onStart){
			this.fireEvent('onStart');
		}
		//
		this.options.sortOn = index;
		var header = this.tHead.getElements('th');
		var el = header[index];
		
		header.each(function(e,i){
			if(i != index){
				e.removeClass('sortedASC');
				e.removeClass('sortedDESC');
			}
		});
		
		if(el.hasClass('sortedASC')){
			el.removeClass('sortedASC');
			el.addClass('sortedDESC');
			el.sortBy = 'DESC';
		}else if(el.hasClass('sortedDESC')){
			el.removeClass('sortedDESC');
			el.addClass('sortedASC');
			el.sortBy = 'ASC';
		}else{
			if(this.options.sortBy == 'ASC'){
				el.addClass('sortedASC');
				el.sortBy = 'ASC';
			}else if(this.options.sortBy == 'DESC'){
				el.addClass('sortedDESC');
				el.sortBy = 'DESC';
			}
		}
		//
		this.elements.sort(el.compare);
		this.elements.injectInside(this.tBody);
		//
		if(this.filtered){
			this.filteredAltRow();
		}else{
			this.altRow();
		}
		
		//
		if(this.options.onComplete){
			this.fireEvent('onComplete');
		}
		if(this.options.pager){
			if(this.options.amountPages > 1){
				this.SelectPage(this.options.currentSelected);
			}
		}
	},
	
	altRow: function(){
		this.elements.each(function(el,i){
			if(i % 2){
				el.removeClass('altRow');
			}else{
				el.addClass('altRow');
			}
		});
	},
	
	filteredAltRow: function(){
		this.table.getElements('.'+this.options.filterSelectedCls).each(function(el,i){
			if(i % 2){
				el.removeClass('altRow');
			}else{
				el.addClass('altRow');
			}
		});
	},
	
	filter: function(form){
		var form = $(form);
		var col = 0;
		var key = '';
		
		form.getChildren().each(function(el,i){
			if(el.id == 'column'){
				col = Number(el.value);
			}
			if(el.id == 'keyword'){
				key = el.value.toLowerCase();
			}
			if(el.type == 'reset'){
				el.addEvent('click',this.clearFilter.bind(this));
			}
		}, this);
		
		if(key){
		this.elements.each(function(el,i){
			if(this.options.filterHide){
				el.removeClass('altRow');
			}
			if(el.getChildren()[col].firstChild.data.toLowerCase().indexOf(key) > -1){
				el.addClass(this.options.filterSelectedCls);
				if(this.options.filterHide){
					el.removeClass(this.options.filterHideCls);
				}
			}else{
				el.removeClass(this.options.filterSelectedCls);
				if(this.options.filterHide){
					el.addClass(this.options.filterHideCls);
				}
			}
		}, this);
		if(this.options.filterHide){
			this.filteredAltRow();
			this.filtered = true;
		}
		}
	},
	
	clearFilter: function(){
		this.elements.each(function(el,i){
			el.removeClass(this.options.filterSelectedCls);
			if(this.options.filterHide){
				el.removeClass(this.options.filterHideCls);
			}
		}, this);
		if(this.options.filterHide){
			this.altRow();
			this.filtered = false;
		}
	}

});
sortableTable.implement(new Events);
sortableTable.implement(new Options);

/*************************************************************/

