var Pagination = Class.create({
	initialize: function(json, root_id, observer) {
		this.json = json;
		this.observer = observer;
		this.begin = 0;
		this.end = 0;
		this.root_id = root_id;
		this.elem_per_page = 15;
		this.intervalle = 20;
		this.intervalles = new Array();
		this.current_intervalle = parseInt(this.intervalle) / 2;
		this.current_page = 1;
		this.indices = new Array();
		this.page_prev_template = new Template("<a href=\"javascript: #{instance}.prev();\" class='item_bleu' title='page précédente'><u><<</u></a>&nbsp;&nbsp;");
		this.page_next_template = new Template("&nbsp;&nbsp;<a href=\"javascript: #{instance}.next();\" class='item_bleu' title='page suivante'><u>>></u></a>");
		this.page_template = new Template("<a href=\"javascript:#{instance}.set_current_page(#{num_page});\" class='item_bleu'><u>#{num_page}</u></a>");
		this.page_template_unselected = new Template("#{num_page}");
		this.index_template = new Template("<a href=\"javascript:#{instance}.set_current_index(#{index});\" class='item_bleu'><u># #{index}</u></a>");
		this.index_template_unselected = new Template("# #{index}");
		this.info_template = new Template("Résultats : #{begin}-#{end} / #{total} &nbsp; Résultats par pages : <input style='display:inline;' type='text' onchange=\"javascript:#{instance}.set_page_size(this.value);\" value='#{page_size}' size='2' maxlength='2' name='elem_per_page_input'/>"); 
		this.info_empty_template = new Template("Résultats : 0 <br/> Résultats par pages : <input type='text' onchange=\"javascript:#{instance}.set_page_size(this.value);\" value='#{page_size}' size='2' maxlength='2' name='elem_per_page_input'/>");
		this.update();
	},

	update: function(){
		if(this.json){
			this.indices.clear();
			this.intervalles.clear();
			var o = new Object();
			var cpt = this.elem_per_page;

			if(cpt > this.json.length)
				cpt = this.json.length;

			//init des pages
			o.begin = 0;
			o.end = cpt;
			this.indices.push(o);
			while(cpt < this.json.length)
			{
				o = new Object();
				o.begin = cpt;
				if(parseInt(o.begin) + parseInt(this.elem_per_page) < parseInt(this.json.length))
					cpt = parseInt(o.begin) + parseInt(this.elem_per_page);
				else
					cpt = this.json.length;
				o.end = cpt;
				this.indices.push(o);
			}
			
			//init des intervalles
			var obj = new Object();
			obj.start = 1;
			obj.end = obj.start + (this.intervalle - 1);
			obj.index = this.intervalle/2;
			 
			while( obj.end < this.indices.length )
			{
				this.intervalles.push(Object.clone(obj));
				obj.start += this.intervalle;
				obj.index += this.intervalle;
				obj.end += this.intervalle;
			}
			
			obj.end = this.indices.length;
			obj.index = obj.start + Math.floor((obj.end - obj.start) / 2);
			this.intervalles.push(Object.clone(obj));
			
			this.current_page = 1;
			this.begin = this.indices[parseInt(this.current_page) - 1].begin;
			this.end = this.indices[parseInt(this.current_page) - 1].end;
			this.display();
			if(this.observer)
				this.observer.notify();
		}
	},
	
	set_page_size: function(size) {
		if(size > 0){
			this.elem_per_page = size;
			this.current_page = 1;
			this.update();
		}
	},

	set_current_page: function(page_num){
		if(page_num >= 1 && page_num <= this.indices.length) {
			this.current_page = page_num;
			this.begin = this.indices[this.current_page - 1].begin;
			this.end = this.indices[this.current_page - 1].end;
			this.display();

			if(this.observer)
				this.observer.notify();
		}
	},
		
	set_current_index: function(index_num){
		this.current_intervalle = index_num;
		var cur_index =  this.get_index();
		this.set_current_page(cur_index.index);
	},
	
	get_index: function() {
		var cur_index =  this.intervalles[0];
		var tmp_current_intervalle = this.current_intervalle;
		this.intervalles.each(function(e) { 
			if(e.index == tmp_current_intervalle)
				cur_index = e;
		});
		return cur_index;
	},

	/* page suivante */
	next: function()
	{
		var e = 0;
		var num_page = parseInt(this.current_page);
		var i = this.get_index();
		var next_intervalle = Math.ceil(num_page / this.intervalle);
		
		this.intervalles.each(function(elt){
			if( i.index == elt.index ){
				e = parseInt(elt.end);
				return;
			}
		});
		
		//si on est ds le bon intervalle, on change juste de page, sinon on change d'intervalle
		if( num_page < e ){
			this.set_current_page(num_page+1);
		} else {
			this.set_current_index(this.intervalles[next_intervalle].index);
			this.set_current_page(num_page+1);
		}
	},
	
	/* page précédente */
	prev: function()
	{
		var s = 0;
		var num_page = parseInt(this.current_page);
		var i = this.current_intervalle;
		var prev_intervalle = Math.ceil((num_page-1)/ this.intervalle);
		//alert(prev_intervalle);
		
		this.intervalles.each(function(elt){
			if( i == elt.index ){
				s = parseInt(elt.start);
				return;
			}
		});
		 
		//si on est ds le bon intervalle, on change juste de page, sinon on change d'intervalle
		if( num_page > s ){
			this.set_current_page(num_page-1);
		} else {
			this.set_current_index(this.intervalles[prev_intervalle-1].index);
			this.set_current_page(num_page-1);
		}
	},

	display: function()
	{
		var html = "";
		// liste des pages
		var i = 0;
		var cur_index =  this.get_index();
		
		//affichage du bouton précédent
		if(this.current_page != 1){
				var f = new Object();
				f.instance = this.observer.instance + ".pagination";
				html += this.page_prev_template.evaluate(f);
		}
		//pages
		for(i = cur_index.start - 1; i < cur_index.end; i++) {
			var o = new Object(); // attention à l'adressage de cet objet
			o.instance = this.observer.instance + ".pagination";
			o.num_page = i + 1;
			if(this.current_page == (i + 1))
				html += this.page_template_unselected.evaluate(o) + "&nbsp;";
			else
				html += this.page_template.evaluate(o)+ "&nbsp;";
		}
		// affichage du bouton suivant
		var b = new Object();
		b = this.intervalles.last();
		if(this.current_page != b.end ){
				var f = new Object();
				f.instance = this.observer.instance + ".pagination";
				html += this.page_next_template.evaluate(f);
		}
		// liste des indexes
		html+= "<br/>";
		var j = 0;
		//this.current_intervalle = this.get_index().index;

		/* on affiche les médiane seulement si il y a plus d'1 intervalle */
		if( this.intervalles.length > 1 ){
			for(j = 0; j < this.intervalles.length; j++) {
				var o = this.intervalles[j];
				o.instance = this.observer.instance + ".pagination";
				if(o.index == this.current_page)
					html += this.index_template_unselected.evaluate(o) + "&nbsp;";
				else
					html += this.index_template.evaluate(o)+ "&nbsp;";
			}
		}
		
		// infos (nb elmt / page)
		var o = new Object();	
		o.begin = parseInt(this.indices[this.current_page - 1].begin) + parseInt(1);
		o.end = this.indices[this.current_page - 1].end;
		o.total = this.json.length; // attention à l'adressage de cet objet
		o.instance = this.observer.instance + ".pagination";
		o.page_size = this.elem_per_page;

		if(o.total > 0)
			html += "<br/>" + this.info_template.evaluate(o);
		else
			html += "<br/>" + this.info_empty_template.evaluate(o);
		$(this.root_id).update(html);
	},

	set_json: function(json) {
		if(json){
			this.json = json;
			this.update();
		}
	}
});
