/**
 * Fonctions liées à l'affichage
 * @author : Max
 * @date : 25/08/2011 15:51
 * @version : 1.0.0
 */
var Display = {};

/**
 * Ouverture de popup (div ou window)
 */
Display.Popup = Class.create( {

	/**
	 * constructeur de la classe
	 */
	initialize: function(options)
	{
		// Définition des paramètres
		this.mode			= 'window'; // window | div
		this.url			= ''; // adresse pour récupérer le contenu de la div
		this.contentHTML	= ''; // contenu HTML de la div
		this.haveCache		= true;
		this.cacheId		= 'cache-popup'; // id du cache de la div
		this.classCache		= 'cache';
		this.divId			= 'div-popup'; // id du div contenant du HTML
		this.classDiv		= null;
		this.loadingHTML	= 'Chargement ...';
		this.scrollTop		= false;
		this.cache			= null;
		this.div			= null;
		this.effectId		= null;
		this.autoClose		= false;
		this.durationOpen	= 3; // temps restant ouvert avant auto fermeture
		this.effectCloseId	= null;
		
		this.name			= 'popup'; 
		this.win			= null;
		this.pos			= 'center'; // postion centrée ou random
		this.width			= 500;
		this.height			= 500;
		this.scroll			= 'yes';
		this.resize			= 'yes';
		
		this.options		= {};

		Object.extend(this.options, options || {});
		
		// on affecte les propriétés des options
		for (var o1 in this) {
			for (var o2 in this.options) {
				if (o1==o2) {
					this[o1] = this.options[o2];
				}
			}
		}
		
		this.open();
		
	}, // fin du constructeur
	
	/**
	 * Ouverture de la popup
	 */
	open: function ()
	{		
		var obj = this;
		
		switch (this.mode) {
			
			case "window":
				
				var left;
				var top;
				var settings;
				if (this.pos == "random") {
					left = (screen.width) ? Math.floor(Math.random() * (screen.width - this.width)) : 100;
					top = (screen.height) ? Math.floor(Math.random() * ((screen.height - this.height) - 75)) : 100;
				} else if (this.pos == "center") {
					left = (screen.width) ? (screen.width - this.width) / 2 : 100;
					top = (screen.height) ? (screen.height - this.height) / 2 : 100;
				} else {
					left = 0;
					top = 20;
				}
				settings = 'width=' + this.width;
				settings+= ',height=' + this.height;
				settings+= ',top=' + top;
				settings+= ',left=' + left;
				settings+= ',scrollbars=' + this.scroll;
				settings+= ',location=no';
				settings+= ',directories=no';
				settings+= ',status=no';
				settings+= ',menubar=no';
				settings+= ',toolbar=no';
				settings+= ',resizable=' + this.resizable;
				
				this.win = window.open(this.url, this.name, settings);
				this.win.focus(this.name);
				
			break;
			
			case "div":
		
				// on se place en haut de la page
				if (this.scrollTop)
					self.scrollTo(0,0);
				
				if (this.haveCache) {
					// on créé un cache
					if ($(this.cacheId))
						$(this.cacheId).remove();
					
					this.cache = new Element('div', { id: this.cacheId, 'class': this.classCache } );
					$(document.body).insert( { top: this.cache } );
										
					var scrollOffsets = document.viewport.getScrollOffsets();
					if (scrollOffsets[1] > 0)
						this.cache.setStyle( { top: scrollOffsets.top + 'px', left: scrollOffsets.left + 'px' } );
			
					Event.observe(window, 'scroll', function() {
						scrollOffsets = document.viewport.getScrollOffsets();
						obj.cache.setStyle( { top: scrollOffsets.top + 'px', left: scrollOffsets.left + 'px' } );
					});				
					this.cache.show();
					
					this.cache.observe('click', function(event){
						obj.close();
					});
				}
				
				// on créé le div
				if ($(this.divId))
					$(this.divId).remove();
				this.div = new Element('div', { id: this.divId, 'class': this.classDiv } );
				$(document.body).insert( { top: this.div } );
				
				if (this.autoClose) {
					Event.observe(this.div, 'click', function(event) {
						obj.close();
					} );
				}
				
				Event.observe(window, 'scroll', function() {
					obj.center(true);
				});	
				
				this.div.show();
				this.div.setOpacity(0.5);
				
				
				if (this.url)
					this.div.update(this.loadingHTML);
				else if (this.contentHTML)
					this.div.update(this.contentHTML);
				
					
				// centrage de la popup
				this.center();
				
				// on cache les elements qui passent au dessus du div
				this.hideTags(1);
				
				new Effect.Opacity(this.div, {duration:0.5, fps:25, from:0.5, to:1.0, afterFinish: function() {
					if (obj.url) {
						obj.loadContent();
					} else {
						if (obj.options.onFinish)
							obj.options.onFinish();
					}
					if (obj.autoClose)
						obj.close(obj.durationOpen);
				}});
		
			break;
		} // fin du switch
		
	}, // fin de open
	
	loadContent: function()
	{
		var obj = this;
		
		new Ajax.Request(this.url, {
			method: 'get',
			onSuccess: function(transport) {
				obj.setContent(transport.responseText);
				if (obj.options.onFinish)
					obj.options.onFinish();
			}
		});
	},
	
	setContent: function(str) {
		this.contentHTML = str;
		this.div.update(str);
		this.center();
		this.center();
	},
	
	/**
	 * Fermeture de la popup
	 */
	close: function (delay)
	{		
		var obj = this;
		
		switch (this.mode) {
			
			case "window":
			
				this.win.close();	
					
			break;
			
			case "div":
				//form.update("");
				
				if (!delay)
					delay = 0;
				
				if (this.effectCloseId)
					this.effectCloseId.cancel();
				
				//new Effect.Shrink(formId, {duration: 0.7});
				this.effectCloseId = new Effect.Opacity(this.div, { delay: delay, duration:0.5, fps:25, from:1, to:0.5, afterFinish: function() {
					obj.div.remove();
					if (obj.haveCache)
						obj.cache.remove();					
					// on remet les elements effacés 
					obj.hideTags(0);		
				}});
			
			break;
			
		} // fin du switch
		
		if (obj.options.onClose)
			obj.options.onClose();
		
	}, // fin de close
	
	/**
	 * Centrage de la popup div
	 */
	center: function (move)
	{
		var dim = document.viewport.getDimensions();
		var screenH = dim.height;
		var screenW = dim.width;

		var scrollOffsets = document.viewport.getScrollOffsets();
		var posTop = (screenH / 2) - (this.div.getHeight() / 2) + scrollOffsets.top;
		var posLeft = (screenW / 2) - (this.div.getWidth() / 2) + scrollOffsets.left;
		
		if (move) {
			if (this.effectId)
				this.effectId.cancel();
			this.effectId = new Effect.Move(this.div, { duration: 0.5, x: posLeft, y: posTop, mode: 'absolute', transition: Effect.Transitions.Quint.easeInOut });
		} else {
			this.div.style.top = posTop + "px";
			this.div.style.left = posLeft + "px";
		}
	}, // fin de center
	
	/**
	 * Cachage ou affichage d'elements pour l'affichage d'une div en superposition
	 */
	hideTags: function (t)
	{
		if (Prototype.Browser.IE) {
			$$('applet', 'iframe', 'select', 'object', 'embed').each( function(el) {
				el.style.visibility = (t == 0) ? "visible" : "hidden";			
			} );
		}
	}
}); // fin de Popup

/**
 * Scroller de contenu (automatique + pagination)
 * Exemple : new Display.Scroller('scroller-container', { itemClassName: 'scroller-item', bulletClassName: 'scroller-page', colWidth: 974, pagination: true, transition: 'fade', paginationOverMode: 'image', paginationOverSuffix: '-on' } );
 */
Display.Scroller = Class.create( {

	/**
	 * constructeur de la classe
	 */
	initialize: function(idScroller, options) {
		
		// Définition des paramètres
		this.currentPage			= 0;
		this.previousPage			= -1;
		this.nbPage					= 0;
		this.nbCol					= 0; 
		this.nbColPage				= 1; // nb de colonne par page
		this.colWidth				= 100;
		this.isBlocked				= false;
		this.autoStart				= true;
		this.idScroller				= idScroller;
		this.itemClassName			= "box-item";
		this.bulletClassName		= "box-bullet";
		this.idBtnPrev				= null;
		this.idBtnNext				= null;
		this.duration				= 1;
		this.timer 					= true;
		this.timerDuration			= 5;
		this.pe						= null;
		this.pagination				= true;
		this.paginationId			= 'img-pagination';
		this.paginationOverMode		= 'opacity'; // opacity | image
		this.paginationOverSuffix	= '-on'; // suffixe de l'image en cas de paginationOverMode "image"
		this.transitionMode			= 'move'; // move | fade
		this.transition				= Effect.Transitions.sinoidal;
		this.mouseWheelEnabled		= true;
		this.onChange				= Prototype.emptyFunction;
		this.currentItem			= null;
		this.options				= {};
		
		Object.extend(this.options, options || {});
		
		// on affecte les propriétés des options
		for (var o1 in this) {
			for (var o2 in this.options) {
				if (o1==o2) {
					this[o1] = this.options[o2];
				}
			}
		}

		if (!$(idScroller))
			alert(idScroller + " introuvable !");
		else
			if (this.autoStart)
				this.start();

	}, // fin du constructeur

	/**
	 * Initialisation du scroller
	 */
	start: function ()
	{
		var obj = this;
		
		$(this.idScroller).observe("mouseover", this.scrollerOver.bindAsEventListener(this));
		$(this.idScroller).observe("mouseout", this.scrollerOut.bindAsEventListener(this));
		
		if ($(obj.idScroller).style.position != "absolute")
			$(obj.idScroller).style.position = "absolute";
		
		// on compte le nb d'élément du scroller
		$$("." + this.itemClassName).each(function(el) {
			el.id = obj.itemClassName + obj.nbCol;
			obj.nbCol ++;
		});
		if (this.pagination) {
			var cpt = 0;
			$$("." + this.bulletClassName).each(function(el) {
				el.id = obj.bulletClassName + cpt;
				el.observe("click", obj.clickPageBullet.bindAsEventListener(obj));
				cpt ++;
			});
		}
		if (this.nbCol % this.nbColPage == 0)  {
			this.nbPage = Math.floor(this.nbCol / this.nbColPage);
		} else {
			//this.nbPage = Math.floor(this.nbCol / this.nbColPage);
			this.nbPage = (Math.floor(this.nbCol / this.nbColPage) + 1);
		}
		
		switch (this.transitionMode) {
			case "move":
				$(this.idScroller).style.width = "10000px";
			break;
			case "fade":			
				$(this.idScroller).style.position = "absolute";
				var cpt = 0;
				$$("." + this.itemClassName).each(function(el) {
					el.style.position = "absolute";
					el.style.zIndex = obj.nbPage - cpt;
					cpt ++;
				});
			break;
		}	
		
		if (this.mouseWheelEnabled) {
			// mozilla
			Event.observe(this.idScroller, 'DOMMouseScroll', this.mouseWheel.bindAsEventListener(this));	
			// IE/Opera
			Event.observe(this.idScroller, 'mousewheel', this.mouseWheel.bindAsEventListener(this));	
		}
		
		if (!$(this.paginationId))
			this.pagination = false;
		
		this.managePagination();
		
		if (this.idBtnPrev && $(this.idBtnPrev))
			Event.observe(this.idBtnPrev, 'click', this.prevPage.bindAsEventListener(this));
		
		if (this.idBtnNext && $(this.idBtnNext))
			Event.observe(this.idBtnNext, 'click', this.nextPage.bindAsEventListener(this));
		
		if (this.timer && this.nbPage > 1)
			this.pe = new PeriodicalExecuter(this.nextPage.bind(this), this.timerDuration);
		
		this.changePage(0);
		
	}, // fin de start
	
	/**
	 * Initialisation du scroller
	 */
	managePagination: function ()
	{
		var obj = this;

		if (this.pagination) {
			// bullets
			$$("." + this.bulletClassName).each(function(el) {
				switch (obj.paginationOverMode) {
					case "opacity":
						el.setOpacity(0.5);
					break;
					case "image":
						var regExp = new RegExp(obj.paginationOverSuffix);
						el.src = el.src.replace(regExp,"");
					break;
				}
				el.style.cursor = "pointer";
			});
			// current
			switch (this.paginationOverMode) {
				case "opacity":
					$(this.bulletClassName + this.currentPage).setOpacity(1);
				break;
				case "image":
					var src = $(this.bulletClassName + this.currentPage).src;
					var ext = src.substring(src.lastIndexOf('.'));
					var prefix = src.substring(0, src.length - ext.length);
					$(this.bulletClassName + this.currentPage).src = prefix + this.paginationOverSuffix + ext;
				break;
			}
			$(this.bulletClassName + this.currentPage).style.cursor = "auto";
		}
		
	}, // fin de managePagination
	
	mouseWheel: function(event)
	{
		if (!this.isBlocked && this.pagination) {
			var delta = 0;
			if (!event) /* For IE. */
				event = window.event;
			if (event.wheelDelta) { /* IE/Opera. */
				delta = event.wheelDelta/120;
				/** In Opera 9, delta differs in sign as compared to IE. */
				if (window.opera)
					delta = -delta;
			} else if (event.detail) { /** Mozilla case. */
				/** In Mozilla, sign of delta is different than in IE.
				* Also, delta is multiple of 3.
				*/
				delta = -event.detail/3;
			}
			if (delta) {
				if (delta > 0)
					this.nextPage();
				else
					this.prevPage();
					
				if (this.timer && this.pe != null ) {
					this.pe.stop(); this.pe = null;
					this.pe = new PeriodicalExecuter(this.nextPage.bind(this), this.timerDuration);	
				}
			}
	
			if (event.preventDefault)
				event.preventDefault();
			
			event.returnValue = false;
		}
	}, // fin de mouseWheel
	
	/**
	 * Click sur une page
	 */
	clickPageBullet: function(event)
	{
		if (!this.isBlocked) {
			var el = event.findElement();
			var page = parseFloat(el.id.replace(this.bulletClassName, ""));
			this.previousPage = this.currentPage;
			this.currentPage = page;
			this.changePage(page - this.previousPage);
			el.blur();
			this.managePagination();
			
			if (this.timer && this.pe != null) {
				this.pe.stop(); this.pe = null;
				this.pe = new PeriodicalExecuter(this.nextPage.bind(this), this.timerDuration);	
			}
		}
	},  // fin de clickPageBullet
	
	/**
	 * Changement de page
	 */
	changePage: function(index)
	{
		if (!this.isBlocked) {
			var delta = - this.nbColPage * this.colWidth;
			this.isBlocked = true;
			var obj = this;
			var cpt = 0;
			var prevItem = null;
			this.currentItem = null;
			
			$$("." + this.itemClassName).each(function(el) {
				if (obj.previousPage == cpt) {
					prevItem = el;
				} else if (obj.currentPage == cpt) {
					obj.currentItem = el;
				}
				cpt ++;
			});
	
			switch (this.transitionMode) {
				case "move":
					new Effect.Move(this.idScroller, { duration: this.duration , x: index * delta, transition: this.transition, afterFinish: function(el) { obj.isBlocked = false; }} );
				break;
				case "fade":
					$$("." + this.itemClassName).each(function(el) {
						if (obj.currentItem == el || prevItem == el)
							el.show();
						else
							el.hide();
					});
					obj.currentItem.style.zIndex = 1;
					if (prevItem) {
						prevItem.style.zIndex = 2;						
						new Effect.Fade(prevItem, { duration: obj.duration / 2, transition: obj.transition,  afterFinish: function() {
							obj.isBlocked = false;
						}} );
					} else {
						obj.isBlocked = false;
					}
				break;
			}
			
			this.onChange();		
		}
	},  // fin de changePage
	
	/**
	 * Page suivante
	 */
	nextPage: function()
	{
		if (!this.isBlocked) {
			this.previousPage = this.currentPage;
			this.currentPage += 1;
			if (this.currentPage > this.nbPage - 1) {
				this.currentPage = 0;
			} else if (this.currentPage < 0) {
				this.currentPage = this.nbPage - 1;
			}
			this.changePage(this.currentPage - this.previousPage);
			this.managePagination();
		}
	},  // fin de nextPage
	
	/**
	 * Page précédente
	 */
	prevPage: function()
	{
		if (!this.isBlocked) {
			this.previousPage = this.currentPage;
			this.currentPage -= 1;
			if (this.currentPage > this.nbPage - 1) {
				this.currentPage = 0;
			} else if (this.currentPage < 0) {
				this.currentPage = this.nbPage - 1;
			}
			this.changePage(this.currentPage - this.previousPage);
			this.managePagination();
		}
	},  // fin de prevPage
	
	/**
	 * Mouse Over scroller
	 */
	scrollerOver: function()
	{
		if (this.timer && !this.isBlocked && this.pe != null) {
			this.pe.stop(); this.pe = null;
		}
	},  // fin de scrollerOver
	
	/**
	 * Mouse Over scroller
	 */
	scrollerOut: function()
	{
		if (this.timer && !this.isBlocked && this.pe == null)
			this.pe = new PeriodicalExecuter(this.nextPage.bind(this), this.timerDuration);
	} // fin de scrollerOut
	
} ); // fin de Display.Scroller



/**
 * Affichage d'une liste d'autocomplete sur un champ texte
 * Exemple : new Display.AutoComplete("search", {cssClass: "alert"});
 */
Display.AutoComplete = Class.create( {

	/**
	 * constructeur de la classe
	 */
	initialize: function(id, options) {
		
		// Définition des parametres
		this.id_container 	= id + '_container';
		this.id_id		 	= id + '_id';
		this.id_value		= id + '_value';
		this.id_loading		= id + '_loading';
		this.cssClass 		= 'autocomplete';
		this.url			= '_ajax/autoComplete.php';
		this.params 		= ''; // &param1=1&param2=2 ...
		this.minChars 		= 2;
		this.pe 			= null;
		this.index 			= -1;
		this.current 		= null;
		this.duration		= 0.25; // duree d'affichage (en sec)
		this.delaySearch	= 0.5; // temps maximum entre deux recherche
		this.peDelaySearch 	= null;
		this.appearContainer= null;
		this.onSearch		= Prototype.emptyFunction;
		this.onSelect		= Prototype.emptyFunction;
		this.options		= {};
		
		Object.extend(this.options, options || {});
		
		// on affecte les propriétés des options
		for (var o1 in this) {
			for (var o2 in this.options) {
				if (o1==o2) {
					this[o1] = this.options[o2];
				}
			}
		}

		this.elt = $(id);
		this.container = $(this.id_container);

		this.elt.observe('keyup', this.keyEvent.bind(this));
		this.elt.observe('focus', this.focusEvent.bind(this));
		this.elt.observe('blur',  this.blurEvent.bind(this));
		
		// on bloque la soumission du formulaire s'il y en a un	
		if (this.elt.up('form')) {
			var obj = this;			
			this.elt.up('form').observe('submit', function(event) {
				if (obj.container.visible()) {
					Event.stop(event);
				}
			});
		}

	}, // fin du constructeur

	/**
	 * 
	 */
	focusEvent: function(event)
	{
		this.search();
	},
	blurEvent: function(event)
	{
		if (this.current) {
			this.select(this.current.readAttribute("ac_id"), this.current.readAttribute("ac_value"));
			this.close();
		}
		
		this.pe = new PeriodicalExecuter(this.peEvent.bind(this), 0.15);
	},
	peEvent: function(pe)
	{
		this.close();
		this.pe = pe;
		this.pe.stop();
	},
	keyEvent: function(event)
	{
		switch (event.keyCode) {
			case Event.KEY_DOWN:
				this.upDown(1);
			break;
			case Event.KEY_UP:
				this.upDown(-1);
			break;
			case Event.KEY_RETURN:
				if (this.current) {
					this.select(this.current.readAttribute("ac_id"), this.current.readAttribute("ac_value"));
					this.close();
				}
			break;
			default:
				if (this.delaySearch != 0) {
					// on lance le delay entre 2 keydown
					if (this.peDelaySearch != null) {
						this.peDelaySearch.stop();
					}
					this.peDelaySearch = new PeriodicalExecuter(this.peDelaySearchEvent.bind(this), this.delaySearch);
				} else {
					this.search();
				}
		}
	},
	peDelaySearchEvent: function(pe)
	{
		this.search();
		this.peDelaySearch.stop();
		this.peDelaySearch = null;
	},

	upDown: function(cpt)
	{
		this.index += cpt;
		var cResult = this.container.select("a");
		if (this.index > cResult.size() -1 ) {
			this.index --;
		} else if (this.index < 0) {
			this.index = 0;
		}
		if (this.current) {
			this.current.removeClassName("current");
		}
		this.current = cResult.toArray()[this.index];
		this.current.addClassName("current");

		//this.select(this.current.readAttribute("ac_id"), this.current.readAttribute("ac_value"));
	},
	search: function()
	{
		if (this.options.onSearch) {
			this.params = this.options.onSearch();
		}
		
		if (this.pe) { this.pe.stop(); this.pe = null; }
		if ($(this.id_id)) { $(this.id_id).value = ""; }
		
		var s = this.elt.value;
		var obj = this;
		if (s.length >= this.minChars) {
			var url = this.url +  '?' + this.elt.id + '=' + encodeURIComponent(s) + this.params;
			//alert(url);
			if ($(this.id_loading)) { new Effect.Appear(this.id_loading, {duration: this.duration}); }
			new Ajax.Request(url, {
				method: 'get',
				asynchronous: false,
				onSuccess: function(transport) {
					obj.container.show();
					obj.container.update(transport.responseText);
					if ($(obj.id_loading)) { new Effect.Fade(obj.id_loading, {duration: obj.duration}); }
					
					// on compte le nb de résultats
					var cResult = obj.container.select("a");
					if (cResult.size() > 0) {
						var first = cResult.toArray()[0];
						if (cResult.size() == 1) {
							obj.index = 0;
							obj.upDown(0);
						}
						cResult.each( function(o) {
							o.observe('click',  obj.clickItem.bindAsEventListener(obj, o));
						});
					}
					
					// nb de lignes
					/*var cLine = this.container.select("div");
					var h = cLine.toArray()[0].getHeight();
					this.container.style.height = (cLine.size() * h) + "px";*/
					
					if (obj.appearContainer) { obj.appearContainer.cancel(); }					
					obj.appearContainer = new Effect.Opacity(obj.container, {from:0, to:1, duration: obj.duration, afterFinish: function() { obj.appearContainer = null; } });
					//this.container.show();
				}
			});			
			
		} else {
			this.close();
		}
	},
	clickItem: function(event)
	{
		if (this.pe) { this.pe.stop(); this.pe = null; }
		var data = $A(arguments);
		data.shift();
		var a = data[0];
		this.select(a.readAttribute('ac_id'), a.readAttribute('ac_value'));
		this.close();
	},
	select: function(id, value)
	{
		if (this.pe) { this.pe.stop(); this.pe = null; }
		if ($(this.id_id)) { $(this.id_id).value = id; }
		this.elt.value = value;
		if (this.options.onSelect) {
			this.options.onSelect();
		}
	},
	close: function()
	{
		new Effect.Fade(this.container, {duration: this.duration});//container.hide();
		this.index = -1;	
		this.current = null;
	}
	
} ); // fin de Display.AutoComplete

