/*
 * TablePagination script
 * 2007 by Martin Kleinhans
 *
 * creates a pagination bar for a table and handles switching pages
 * uses tableloader and tablesort if available
 */
 
	var TablePagination = {
		counter: 0,
		instances: [],
		
		isManaged: function(id) {
			return (TablePagination.getTablePaginationById(id)?true:false);
		},
		
		getTablePagination: function(number) {
			return TablePagination.instances[number];
		},
		
		getTablePaginationById: function(id) {
			var instance = undefined;
      TablePagination.instances.each(function(o) {
				if(o.getId() == id) {
					instance = o;
					throw $break;
				}
			});
			return instance;
		},
		
		create: function(id,options) {
			var table = $(id);
			if(!table || !(table.tagName == 'table' || table.tagName == 'TABLE')) {
				return;
			}
		
			if (options) {
	      options = new Hash(options);
	    } else {
	      options = $H();
	    }
	    var pos = TablePagination.counter;
      var object = TablePagination.getTablePaginationById(id);
      if(object) {
        pos = object.getNumber();
      } 
      
			TablePagination.instances[pos] = new TablePaginationInstance(id, options);
			if(TablePagination.instances[pos].isLoadable()) {
				TableLoader.getTableLoaderById(id).onPaginationCreated();
    	}
      
      if(!object) {
        TablePagination.counter++;
      }
		},
		
		handleAction: function(number,action,result) {
			if(action == 'click') {
        return TablePagination.getTablePagination(number).onClick(result);
			}
			if(action == 'prev' || action == 'prev2' || action == 'next' || action == 'next2') {
				return TablePagination.getTablePagination(number).onSpecialClick(action);
			}
		}
		
	};
	
	var TablePaginationInstance = Class.create();

	TablePaginationInstance.prototype = {
		options_default : $H({
	      id: '',
	      currentPage: 0,
	      rowsPerPage: 10,
	      buttons: 10,
	      total: 0,
	      activeliClass: 'active',
	      liClass: 'page',
	      ulClass: 'pagination',
        paginationLinkTitle: "View page #{pagenr}",
        prevTitle: '<',
        beginTitle: '|<',
        nextTitle: '>',
        endTitle: '>|'
    }),
	    
		options : $H({
    }),
    
    isSortable: function() {
			if(typeof(SortableTable) == 'object' && SortableTable.isManaged(this.getId())) {
				return true;
			}
			return false;
		},
		
		isLoadable: function() {
			if(typeof(TableLoader) == 'object' && TableLoader.isManaged(this.getId())) {
				return true;
			}
			return false;
		},
		
		getPages: function() {
			return Math.max(1, Math.ceil(this.getTotal() / this.options['rowsPerPage']));
		},
		
		getTotal: function() {
			var total = this.options['total'];
			if(total <= 0) {
				var rows = this.getTableRows();
				total = rows.length;
			}
			return total;
		},
    
    getId: function() {
    	return this.options['id'];
    },
    
    getNumber: function() {
    	return this.options['number'];
    },
    
		getCurrentPage: function() {
    	return this.options['currentPage'];
		},

		getTableRows: function() {
	    var rows = [];
	    var tbl = $(this.getId());
	    
	    var tbody = tbl.getElementsByTagName('tbody');
	
	    if(tbody && tbody.length) {
		    tbody = tbody[0];
		    rows = tbody.getElementsByTagName('tr');
	    } else {
				var tmp = tbl.getElementsByTagName('tr');
				for(var i = tmp.length; i--;) {
				        if(tmp[i].getElementsByTagName('th')) continue;
				        rows[rows.length] = tmp[i];
				};
	    };
	    return rows;
		},
        
    initialize: function(id, opt) {
			this.options = Object.clone(this.options_default);
			this.options['id'] = id;
			this.options['number'] = TablePagination.counter;
			if (opt.values().length>0) {
        this.options.merge(opt);
      }
      
       // check if a column / order is already defined
      if(this.isLoadable()) {
	    	var loader = TableLoader.getTableLoaderById(id);
	    	if(!opt['currentPage'] && loader.getCurrentPage() != 0) {
	    		this.options['currentPage'] = loader.getCurrentPage();
	    	}
      }
      
      this.createPageinationList();
      this.setCurrentPage(this.options['currentPage'],true);
		},
		
		createPageinationList: function() {
    	var tbl = $(this.getId());
       
      var ul = $('paginateList-'+ this.getId());
      if(!ul) {
				ul = document.createElement("ul");
				ul = $(ul);
				ul.className = this.options['ulClass'];
				ul.id = "paginateList-" + this.getId();
			}
			
			var total = this.getTotal();
			var currentPage = this.options['currentPage'];
			var rowsPerPage = this.options['rowsPerPage'];
			var pages = Math.max(1, Math.ceil(total / rowsPerPage));
			
			
			
			var buttons = this.options['buttons'];
			var firstPage = 0;
			var lastPage = pages;
			
			if(pages > buttons) {
				firstPage = currentPage-(buttons/2);
				if(firstPage <0) {
					firstPage = 0;
				}
				lastPage = currentPage+(buttons/2);
				if(lastPage-firstPage < buttons) {
					lastPage = firstPage + buttons;
				}
				if(lastPage >= pages) {
					lastPage = pages;
				}
			}
		  
      if(firstPage + 1 == lastPage) {
        ul.hide();
        return;
      } else {
        ul.show();
      }
      
			// check if the list needs to be updated
			if(this.options['firstPage'] == firstPage && 
				this.options['lastPage'] == lastPage) {
				var firstPage = this.options['firstPage'];
				
        var i = 0;
        var child;
        while(ul.childNodes[i]) {
        	child = $(ul.childNodes[i]);
        	if(child.down().id == 'paginateList-' + this.getNumber() + '-a-' + currentPage) {
	        	child.className = this.options['activeliClass'];
	        } else {
	        	child.className = this.options['liClass'];
	        }
	        i++;
        };
        return;
			}
			
			this.options['firstPage'] = firstPage;
			this.options['lastPage'] = lastPage;
			
			// clear the list
			ul.innerHTML = '';
			
			var number = this.getNumber();
			
			// page buttons
			for(var i = firstPage; i < lastPage; i++) {
				li = document.createElement("li");
				li.className = this.options['specialliClass'];
				a  = document.createElement("a");
				a.id = 'paginateList-'+number+'-a-'+i;
			  a.href = "";     
        var titleTemplate = new Template(this.options['paginationLinkTitle']);
        var templateData = {pagenr: (i + 1)}
			  a.title = titleTemplate.evaluate(templateData);
			  a.appendChild(document.createTextNode(i+1));
			  
			  a.onclick = function() {
			  	var element = this;
			  	var page = element.id.replace("paginateList-"+number+"-a-", "");
			  	TablePagination.handleAction(number,'click',page);
          return false;
			  };
			  
			 	li.appendChild(a);
        if(i == currentPage) {
        	li.className = this.options['activeliClass'];
				}
        ul.appendChild(li);
			};
			
			// special buttons
			var li, a;
			var specialbuttons = [['<',0,'prev',this.options['prevTitle']],['|<',0,'prev2',this.options['beginTitle']],['>',1,'next',this.options['nextTitle']],['>|',1,'next2',this.options['endTitle']]];
			
			for(var i = 0;i < specialbuttons.length;i++) {
				li = document.createElement("li");
				li.className = this.options['liClass'];
				a  = document.createElement("a");
				a.id = 'paginateList-'+number+'-a-'+specialbuttons[i][2];
			  a.href = "";     
			  a.title = specialbuttons[i][3];
			  a.appendChild(document.createTextNode(specialbuttons[i][0]));
			  
			  a.onclick = function() {
			  	var element = this;
			  	var action = element.id.replace("paginateList-"+number+"-a-", "");
			  	TablePagination.handleAction(number,action);
          return false;
			  };
			  
			 	li.appendChild(a);
			 	
			 	
			 	if(specialbuttons[i][1] == 0) {
			 		ul.insertBefore(li,ul.down());
			 	} else {
			 		ul.appendChild(li);
				}
			}
			if(tbl.nextSibling) {
				tbl.parentNode.insertBefore(ul, tbl.nextSibling);
			} else {
				tbl.parentNode.appendChild(ul);
			};
		},
		
		onClick: function(page) {    
				this.setCurrentPage(page);
					
        return false;
		},
		
		onSpecialClick: function(action) {
			var page = this.getCurrentPage();
			if(action == 'prev') {
				page = page - 1;
			} else if(action == 'prev2') {
				page = 0;
			} else if(action == 'next') {
				page = page + 1;
			} else if(action == 'next2') {
				page = parseInt(this.getTotal()/this.options['rowsPerPage']);
			}
			this.setCurrentPage(page);
			return false;
		},
		
		setCurrentPage: function(page,oncreate,force) {
			if(this.isLoadable()) {
				if(TableLoader.getTableLoaderById(this.getId()).isLoading()) {
					return;
				}
			}

			page = typeof page == "undefined" ? this.getCurrentPage() : page;
			
			var total = this.getTotal();
			
			// validate page
			if(this.getPages() <= page) {
				page = this.getPages()-1;
			}
			if(page < 0) {
				page = 0;
			}
			
			if(!force && this.getCurrentPage() == page && !oncreate) {
				return;
			}
			
			// set page
			this.options['currentPage'] = Number(page);
      
      // update pagination
      this.createPageinationList();
      
      if(this.isLoadable()) {
      	if(!oncreate) {
      		TableLoader.getTableLoaderById(this.getId()).load();      		
      	}
			} else {
				var tbl = $(this.getId());
				var rowsPerPage = this.options['rowsPerPage'];
				var min = rowsPerPage * page;
				var max = Number(min) + Number(rowsPerPage);
				var cnt = 0;
				var rows = this.getTableRows();
				var len = rows.length;
				
				for(var i = 0; i < len; i++) {
	        rows[i].style.display = (i >= min && i < max) ? "" : "none";
	        
				};
			}   
			return true;      
		}
	};

