﻿$(document).ready(function(){
  // Submenu closing button behaviour
  $('.pager_js').pager({
    ExcludeFirstChild: true
  });

  // Submenu closing button behaviour
  $('.pager_intel_js').pager({
    targetTag: 'dl',
	  container: 'div',
	  numberByPages: 3
  });
});


/** 
 * Hooks Jquery to add the pager
 *
 * @author  Guillaume Pousseo
 */
jQuery.fn.pager = function(options) {
	// Make sure options exists
	options = options || {};
	
  // Number of element per pages
  options.numberByPages = options.numberByPages || 50;
  
  // Exclude first child (used for tables with title
  options.ExcludeFirstChild = options.ExcludeFirstChild || false;
  
  // Tags to treat as element 
  // (used so that it can be passed for further dev and other type of pages)
  options.targetTag = options.targetTag || 'tr';
  options.container = options.container || 'tbody';
  
  // Title preceding the pager, ie: if 'Page' -> Page < 1 2 3 ... 9 10 >
  options.pagerTitle = options.pagerTitle || '';
  
  // range of the pages to display so that the pager options appear form x to x+range 
  // ie:  options.range = 10 -> Page 5 6 ... 13 14
  options.range = options.range || 10;
  
  // Sets the navigation signs
  options.navigation = [];
  options.navigation['previous'] = options.previous || '<';
  options.navigation['next'] = options.next || '>';
  
  // Position of the pager
  options.pagerTop = options.pagerTop || true;
  options.pagerBottom = options.pagerBottom || true;

	this.each(function() {
		var element = this;
		new Pager(element, options);
	});

	// Don't break the chain
	return this;
}


/** 
 * Creates a pager
 *
 * @author  Guillaume Pousseo ... Yes! him again!
 */
Pager = function(element, options) {
  // Elements that are not to be set
  var total = 0;
  var element = element;
  var pages = 0;
  var currentPage = 1;
  var targetTag = $(options.targetTag, element);

  // Count all the tags to treat as elements
  setTotal();

	// First determine the number of pages
	setPages(); 

	// Only continues if the number of pages is above 1  
  if(pages > 1){    
  	// Only displays the current page content
  	buildStructure();    	
  	
  	// Only displays the current page content
  	displayPageContent();
  	
    // Display the pager
  	if(options.pagerTop){
  	  element.parentNode.insertBefore(buildPager(), element);
  	}
  	
  	if(options.pagerBottom){
  	  element.parentNode.insertBefore(buildPager(), element.nextSibling);
  	}         	
  }	
  
  // Gets the total number of rows
  function setTotal()
  {	
  	total = targetTag.length - addStart();
  }
  
  // Returns the numbers of row to escape on top 
  // Useful for tables where the header th has to be escaped
  function addStart(){
    return options.ExcludeFirstChild ? 1 : 0;
  }
  
  // Generates the total number of pages
  function setPages()
  {	
  	pages = Math.ceil(total / options.numberByPages);
  }

  // Generates the containers corresponding to each of the pages
  function buildStructure(){
  	for(var i = 1; i <= pages; i++){
	  	// first create the thead
	  	var container = document.createElement(options.container);
	  	container.id = 'js_pager_page_'+ i;
	  	container.className = 'js_pagers';
	  	element.appendChild(container);
	  	moveContainerChilds(container, i);		
  	}
  }
  
  // Move the rows into their corresponding page container
  function moveContainerChilds(container, value){ 
  	var end = value * options.numberByPages;
  	var start = end - options.numberByPages + addStart();

  	for(var i = start; i <= end; i++){
  		if(targetTag[i]) container.appendChild(targetTag[i]); 
  	}    
  }  	if(currentPage > 1){
  	  parent.insertBefore(buildPagerNavigationButton('previous'), parent.firstChild);
  	}
  
  // Show or hide the page according to the user browsing
  function displayPageContent(){	
  	var containers = $(element).children('.js_pagers');
    
  	for(var i = 1; i <= pages; i++){
  		if(i == currentPage){
  			containers[i-1].style.display = "";
  		}
  		else{
  		  containers[i-1].style.display = "none";
  		}
  	}
  }
  
  // Initialise the pagers navigation
  function buildPager(){
  	// Create the pager container
  	var div = document.createElement('UL');
  	div.className = 'js_pager_menu pager';	
  	
  	// Add a pager title
  	if(options.pagerTitle){
  	  buildPagerTitle(div);
  	}
  	
  	// Create the start
  	var end = (pages >= options.range) ? options.range : pages;
  	
  	// Create each element of the menu
  	for(var i = 1; i <= end; i++){
  		buildPagerElement(i, div);
  	}
  	
  	// Get the navigation marks
  	buildPagerNavigation(div);
  	
  	return div;  	
  } 
  
  // Creates a title for the pager navigation if the option.pagerTitle had a value
  function buildPagerTitle(parent){
  	// Create the pager title container
  	var li = document.createElement('LI');    var liTxt = document.createTextNode(options.pagerTitle);
    
    li.appendChild(liTxt);
  	parent.insertBefore(li, parent.firstChild);
  } 
  
  // Include each page number in the pager navigation
  function buildPagerElement(i, parent){
  	// Create the pager container
  	var li = document.createElement('LI');
  	var tag = (currentPage == i) ? 'SPAN' : 'A';
  	var href = document.createElement(tag);
  	var hrefTxt = document.createTextNode(i);
  	
  	href.appendChild(hrefTxt);
  	li.appendChild(href);
  	parent.appendChild(li);
  	
  	if(tag == 'A'){
  		href.onclick = function(e){ changePage(this); }
    }
  }
  
  // Checks wether a previous or next element should be generated in the pager navigation
  function buildPagerNavigation(parent){
  	if(currentPage > 1){
  	  parent.insertBefore(buildPagerNavigationButton('previous'), parent.firstChild);
  	}
  	
  	if(currentPage < pages){
  	  parent.appendChild(buildPagerNavigationButton('next'));
  	}
  }   
  
  // Displays the pager navigation previous or next elements
  function buildPagerNavigationButton(type){
  	// Create the pager container
  	var li = document.createElement('LI');
  	li.className = 'pager_'+ type;
  	var tag = 'A';
  	var href = document.createElement(tag);
  	var hrefTxt = document.createTextNode(options.navigation[type]);
  	
  	href.appendChild(hrefTxt);
  	li.appendChild(href);
  	
  	if(tag == 'A'){
  		href.onclick = function(e){ changePage(this); }
  	}
  	
  	return li;
  }  
  
  // Callback function called when a pager navigation element is clicked
  function changePage(element){	
    // Set the current page according to the element clicked
    if($(element).text() == options.navigation['next']){
      currentPage++;
    }
    else if($(element).text() == options.navigation['previous']){
      currentPage--;
    }
    else{
      currentPage = parseInt(element.innerHTML);
    }

  	// Empty the pager
  	var parent = element.parentNode.parentNode.parentNode;
  	$('.js_pager_menu', parent).each(
  	  function(){
				this.innerHTML = '';
				
				// Sets the pager according to the range option
				var start = (currentPage <= Math.ceil(options.range/2)) ? 1 : currentPage - Math.ceil(options.range/2);
				var end;
				if(currentPage < Math.ceil(options.range/2)){
				  end = (pages >= options.range) ? options.range : pages;
				}
				else{
				  end = (currentPage < pages - Math.floor(options.range/2)) ? currentPage +  Math.floor(options.range/2) : pages;
        }
        
				// Create each element of the menu
				for(var i = start; i <= end; i++){
					buildPagerElement(i, this);
				} 
				
				// Get the navigation marks
				buildPagerNavigation(this); 
				
				// Add a pager title
				if(options.pagerTitle){
					buildPagerTitle(this);
				}  		  
  	  }
  	);
  	
  	// Only displays the current page content
  	displayPageContent();
  }
}  

