/**
 * Extensions de la classe String
 */  
String.prototype.capitalize_all = function() {
	return this.replace(/(\w+)/g, function(word){
    	return word.capitalize();
  	});
};
String.prototype.capitalize = function() {
  	return this.replace(/\w/, function(first_letter){
  	  return first_letter.toUpperCase();
  	});
};
String.prototype.isEmail = function() {
	return this.match(/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i) ? true : false;
};
String.prototype.trim = function() {
	return this.replace(/^\s*/,'').replace(/\s*$/,'');
};
if (typeof com == 'undefined') var com = {};
com.Twoexvia = {
	redirige:function(url) {
		window.location = url;
	}
};
// accordion.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
// 
// Accordion is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro: 
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//

/*-----------------------------------------------------------------------------------------------*/

if (typeof Effect == 'undefined') 
	throw("accordion.js requires including script.aculo.us' effects.js library!");

var accordion = Class.create();
accordion.prototype = {

	//
	//  Setup the Variables
	//
	showAccordion : null,
	currentAccordion : null,
	duration : null,
	effects : [],
	animating : false,
	
	//  
	//  Initialize the accordions
	//
	initialize: function(container, options) {
	  if (!$(container)) {
	    throw(container+" doesn't exist!");
	    return false;
	  }
	  
		this.options = Object.extend({
			resizeSpeed : 8,
			classNames : {
				toggle : 'accordion_toggle',
				toggleActive : 'accordion_toggle_active',
				content : 'accordion_content'
			},
			defaultSize : {
				height : null,
				width : null
			},
			direction : 'vertical',
			onEvent : 'click'
		}, options || {});
		
		this.duration = ((11-this.options.resizeSpeed)*0.15);

		var accordions = $$('#'+container+' .'+this.options.classNames.toggle);
		accordions.each(function(accordion) {
			Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false);
			if (this.options.onEvent == 'click') {
			  accordion.onclick = function() {return false;};
			}
			
			if (this.options.direction == 'horizontal') {
				var options = {width: '0px', display:'none'};
			} else {
				var options = {height: '0px', display:'none'};
			}
//			options.merge({display: 'none'});			
			
			this.currentAccordion = $(accordion.next(0)).setStyle(options);
		}.bind(this));
	},
	
	//
	//  Activate an accordion
	//
	activate : function(accordion) {
		if (this.animating) {
			return false;
		}
		
		this.effects = [];
	
		this.currentAccordion = $(accordion.next(0));
		this.currentAccordion.setStyle({
			display: 'block'
		});		
		
		this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive);

		if (this.options.direction == 'horizontal') {
			this.scaling = $H({
				scaleX: true,
				scaleY: false
			});
		} else {
			this.scaling = $H({
				scaleX: false,
				scaleY: true
			});			
		}
			
		if (this.currentAccordion == this.showAccordion) {
		  this.deactivate();
		} else {
		  this._handleAccordion();
		}
	},
	// 
	// Deactivate an active accordion
	//
	deactivate : function() {
		var options = $H({
		  duration: this.duration,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			queue: {
				position: 'end', 
				scope: 'accordionAnimation'
			},
			scaleMode: { 
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			},
			afterFinish: function() {
				this.showAccordion.setStyle({
          height: 'auto',
					display: 'none'
				});				
				this.showAccordion = null;
				this.animating = false;
			}.bind(this)
		});    
//    options.merge(this.scaling);

    this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
    
		new Effect.Scale(this.showAccordion, 0, options.update(this.scaling).toObject());
	},

  //
  // Handle the open/close actions of the accordion
  //
	_handleAccordion : function() {
		var options = $H({
			sync: true,
			scaleFrom: 0,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			scaleMode: { 
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			}
		});
		options.merge(this.scaling);
		
		this.effects.push(
			new Effect.Scale(this.currentAccordion, 100, options.update(this.scaling).toObject())
		);

		if (this.showAccordion) {
			this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
			
			options = $H({
				sync: true,
				scaleContent: false,
				transition: Effect.Transitions.sinoidal
			});
			options.merge(this.scaling);
			
			this.effects.push(
				new Effect.Scale(this.showAccordion, 0, options.update(this.scaling).toObject())
			);				
		}
		
    new Effect.Parallel(this.effects, {
			duration: this.duration, 
			queue: {
				position: 'end', 
				scope: 'accordionAnimation'
			},
			beforeStart: function() {
				this.animating = true;
			}.bind(this),
			afterFinish: function() {
				if (this.showAccordion) {
					this.showAccordion.setStyle({
						display: 'none'
					});				
				}
				$(this.currentAccordion).setStyle({
				  height: 'auto'
				});
				this.showAccordion = this.currentAccordion;
				this.animating = false;
			}.bind(this)
		});
	}
}
/**
 * +----------------------------------------------+
 *				outils.js
 *
 *	made by a javascript frogger: Benjamin[at]2exvia[dot]com
 *	
 * +----------------------------------------------+ 
 */      
if (typeof ZoomImage == 'undefined') {
	var ZoomImage = Class.create({
		/**
		 * ============================		
		 * Group: UI
		 * ============================		 
		 */			 
		overlay:null,
		box:null,
		boxContent:null,
		/**
		 * ============================		
		 * Group: Private properties
		 * ============================		 
		 */
		_aData:[],
		_bInit:false,
		_nIntImage:null,
		_image:null,
	  	/**
		 * ============================		
		 * Group: Public methods
		 * ============================	
		 * 
		 * Constructor: initialise	
		 * 	 		 		 	 		 	 
		 */
		initialize: function() {},
		/**
		 * Method: void ajoute 
		 * Ajout d'elements a ecouter  
		 *		 
		 * Parameters
		 *  - Object 
		 *  	 {
		 *  	 	HtmlElement element, 
		 *  	 	String label, 
		 *  	 	String srcZoom
		 *  	 }
		 */		 		 
		ajoute:function(valeur) {
			if (valeur.element == null) return;
			this._aData.push({element:valeur.element, label:valeur.label, srcZoom:valeur.srcZoom});
		},
		/**
		 * ============================		
		 * Group: Private methods
		 * ============================	
		 * 
		 * Method: void demarre
		 *		 		 		 		 		 	 
		 */
		demarre:function() {
			if (!this._bInit) {
				this._createOverlay();
				this._createBox();
				this.overlay.hide();
				this.box.hide();
				this._bInit = true;
			}
			this._addEventListeners();
		},
		/**	
		 * Method: void _createOverlay
		 */
		_createOverlay:function() {
			if (this.overlay == null) {
				this.overlay = new Element('div', {
					id:'ZoomImage__overlay'
				}).setStyle({
					zIndex:1000,
					position:'absolute',
					top:0,
					left:0,
					backgroundColor:'#000000',
					width:document.viewport.getDimensions().width+'px',
					height:document.viewport.getDimensions().height+'px'
				});
				$(document.body).insert({'top':this.overlay});
			}
		},
		/**	
		 * Method: void _createBox
		 */
		_createBox:function() {
			if (this.box == null) {
				this.box = new Element('div', {
					id:'ZoomImage__box'
				}).setStyle({
					zIndex:1001,
					position:'absolute',
					backgroundColor:'#FFFFFF',
					width:'1px',
					height:'1px'
				});
				this.overlay.insert({'after':this.box});
			}
		},
		/**	
		 * Method: void _addEventListeners
		 * Ajout des ecouteurs de clic et du stage		 
		 */
		_addEventListeners:function() {
			var INSTANCE = this;
			this._aData.each(function(oZoom) {
				// == Memorisation de <oZoom> dans le scope du sujet
				oZoom.element.oZoom = oZoom;
				Event.stopObserving(oZoom.element, 'click', INSTANCE._handlerClick.bindAsEventListener(INSTANCE));
				Event.observe(oZoom.element, 'click', INSTANCE._handlerClick.bindAsEventListener(INSTANCE));
				oZoom.element.setStyle({cursor:'pointer'});
				oZoom.element.title = "Zoom !";
			});
			Event.stopObserving(window, 	'resize',	INSTANCE._handlerResize.bindAsEventListener(INSTANCE));
			Event.stopObserving(this.box, 	'click',	INSTANCE._close.bindAsEventListener(INSTANCE));
			Event.stopObserving(window, 	'scroll',	INSTANCE._handlerResize.bindAsEventListener(INSTANCE));
			Event.observe(window, 		'resize', 	INSTANCE._handlerResize.bindAsEventListener(INSTANCE));
			Event.observe(this.box,		'click', 	INSTANCE._close.bindAsEventListener(INSTANCE));
			Event.observe(window, 		'scroll', 	INSTANCE._handlerResize.bindAsEventListener(INSTANCE));
		},
		_handlerClick:function(event) {
			this._open(event.target.oZoom);
		},
		_redimensionne:function(MAX_LARGEUR, MAX_HAUTEUR) {
			var MAX_LARGEUR = MAX_LARGEUR;
			var MAX_HAUTEUR = MAX_HAUTEUR;
			var nRatioL = this._image.width / MAX_LARGEUR;
			var nRatioH = this._image.height / MAX_HAUTEUR;
			var nRatio = (nRatioL > nRatioH) ? nRatioL : nRatioH;
			return {nLargeur:Math.round(this._image.width/nRatio), nHauteur:Math.round(this._image.height/nRatio)};
		},
		_handlerResize:function(event) {
			var INSTANCE = this;
			if (this.overlay != null && this.box != null && this._image != null) {
				if (this._image.height > document.viewport.getHeight() || this._image.width > document.viewport.getWidth()) {
					// == Reduction de l'image
					var oDim = this._redimensionne(document.viewport.getWidth()-20, document.viewport.getHeight()-20);
					this.box.setStyle({width:oDim.nLargeur+'px', height:oDim.nHauteur+'px'});
					this.content.setStyle({width:oDim.nLargeur+'px', height:oDim.nHauteur+'px'});
				} else {
					this.box.setStyle({width:this._image.width+'px', height:this._image.height+'px'});
					this.content.setStyle({width:this._image.width+'px', height:this._image.height+'px'});
				}
				this.overlay.setStyle({
					width:document.viewport.getDimensions().width+'px',
					height:document.viewport.getScrollOffsets().top+document.viewport.getDimensions().height+'px'
				});
				var nMarginLeft = parseInt(this.box.getStyle('marginLeft').substr(0, this.box.getStyle('marginLeft').length-2), 10);
				var nMarginTop = parseInt(this.box.getStyle('marginTop').substr(0, this.box.getStyle('marginTop').length-2), 10);
				new Effect.Tween(
					this.box, 
					nMarginLeft, 
					document.viewport.getDimensions().width/2-this.content.width/2, 
					{duration:.5, transition: Effect.Transitions.sinoidal}, 
					function(value) { INSTANCE.box.setStyle({marginLeft:value+'px'}); }	
				);
				new Effect.Tween(
					this.box, 
					nMarginTop, 
					document.viewport.getScrollOffsets().top+document.viewport.getDimensions().height/2-this.content.height/2,
					{duration:.5, transition: Effect.Transitions.sinoidal}, 
					function(value) { INSTANCE.box.setStyle({marginTop:value+'px'}); }	
				);
			} 
		},
		_close:function(event) {
			var INSTANCE = this;
			Effect.Fade(this.content, {duration:.5, from:1, to:0,
				afterFinish:function() {
					Effect.Shrink(INSTANCE.box, {duration:.5});
					Effect.Fade(INSTANCE.overlay, {
						duration:.5,
						from:INSTANCE.overlay.getStyle('opacity'),
						to:0
					});
				}
			});	
		},
		/**	
		 * Method: void _open
		 * 
		 * Parameters:
		 *  - Object oZoom (voir <ZoomImage.ajoute>)
		 */
		_open:function(oZoom) {
			var INSTANCE = this;
			this.overlay.setStyle({
				width:document.viewport.getDimensions().width+'px',
				height:document.viewport.getScrollOffsets().top+document.viewport.getDimensions().height+'px'
			});
			if (this._nIntImage != null) clearInterval(this._nIntImage);
			this._image = new Image();
			this._image.src = oZoom.srcZoom;
			this._nIntImage = setInterval(function() {
				if (INSTANCE._image.complete) {
					if (INSTANCE.overlay != null)
						Effect.Appear(INSTANCE.overlay, {duration:.5, from:0, to:.5});
					clearInterval(INSTANCE._nIntImage);
					INSTANCE._onLoadImage(oZoom);
				}
			}, 50);
		},
		/**
		 * Method: _onLoadImage	 
		 */	 		 		
		_onLoadImage:function(oZoom) {
			var INSTANCE = this;
			this.box.hide();
			this.box.setStyle({
				width:INSTANCE._image.width+'px',
				height:INSTANCE._image.height+'px',
				marginLeft:document.viewport.getDimensions().width/2-INSTANCE._image.width/2+'px',
				marginTop:document.viewport.getScrollOffsets().top+document.viewport.getDimensions().height/2-INSTANCE._image.height/2+'px'
			});
			Effect.Grow(this.box, {
				afterFinish:function() {
					INSTANCE.box.update("<img style=\"position:absolute;\" id=\"ZoomImage__ImageTag\" title=\""+oZoom.label+"\" src=\""+INSTANCE._image.src+"\" />");
					INSTANCE.content = $('ZoomImage__ImageTag');
					INSTANCE.content.setStyle({opacity:0});
					Effect.Appear(INSTANCE.content, {duration:.5, from:0, to:1});
					// !! 		FIX IE			!!
					INSTANCE.box.setStyle({top:'0px', left:'0px'});
					// !! 		eof FIX IE		!!
				}
			});
		}
	});
}
if (typeof print_r == 'undefined') {
	function print_r(a, n) {
		var s = "";
		if(!n) n = 0;
		var sEspace = "";
		for (var j = 0; j < n + 1; j++) sEspace += "    ";
		if (typeof(a) == 'object') {
	 		for (var item in a) {
	  			var value = a[item];
	  			if (typeof(value) == 'object') {
	   				s += sEspace+"'"+item+"' ...\n";
	   				s += print_r(value, n+1);
	  			} else {
	   				s += sEspace+"'"+item+"' => \""+value+"\"\n";
	  			}
	 		}
		} else {
	 		s = "==> "+a+" <== ("+typeof(a)+")";
		}
		return s;
	}
}
if (typeof ResizingTextArea == 'undefined') {
	/*  ResizeableTextarea for the Prototype JavaScript framework, version 0.2
	 *  (c) 2006 Bermi Ferrer <info -a-t bermi org>
	 *
	 *  ResizeableTextarea is freely distributable under the terms of an MIT-style license.
	 *
	 *  Requirements: Prototype JS framework http://prototypejs.org/
	 *  Ussage: Add this attribute to the textarea you want to resize 
	 *
	 *    onfocus="new ResizeableTextarea(this);"
	 *
	/*--------------------------------------------------------------------------*/
	var ResizingTextArea = Class.create();
	ResizingTextArea.prototype = {
	    defaultRows: 1,
	    initialize: function(field)
	    {
	        this.defaultRows = Math.max(field.rows, 1);
	        this.resizeNeeded = this.resizeNeeded.bindAsEventListener(this);
	        Event.observe(field, "click", this.resizeNeeded);
	        Event.observe(field, "keyup", this.resizeNeeded);
	    },
	    resizeNeeded: function(event)
	    {
	        var t = Event.element(event);
	        var lines = t.value.split('\n');
	        var newRows = lines.length;// + 1;
	        var oldRows = t.rows;
	        for (var i = 0; i <lines.length; i++)
	        {
	            var line = lines[i];
	            if (line.length>= t.cols) newRows += Math.floor(line.length / t.cols);
	        }
	        if (newRows> t.rows) t.rows = newRows;
	        if (newRows <t.rows) t.rows = Math.max(this.defaultRows, newRows);
	    }
	}
}
if (typeof popUp == 'undefined') {
	/**
	 * Function: popUp
	 * 
	 * Parameters:
	 *  - String url a appeler
	 *  - String id de la fenetre
	 *  - Number largeur
	 *  - Number hauteur
	 *  - Int 1 pour afficher la scrollbar, sinon 0
	 */	 	 	
	var popUp = function(sUrl, sId, nLargeur, nHauteur, nScrollBar) {
		var nX = (screen.availWidth) ? Math.round(screen.availWidth/2 - nLargeur/2) : 0;
	  	var nY = (screen.availHeight) ? Math.round(screen.availHeight/2 -nHauteur/2) : 0;
	  	var sOptions = 'width='+nLargeur+',height='+nHauteur+',left='+nX+',top='+nY+',scrollbars='+nScrollBar+',resizable=no';
	  	fenetreFocus = window.open(sUrl, sId, sOptions);
	  	try {
	  		if (fenetreFocus.window.focus) fenetreFocus.window.focus();
	  		return fenetreFocus;
		} catch(e) {} 
	};
}
if (typeof JSClient == 'undefined') {
	/**
	 * Object: JSClient
	 * Recuperation du "innerWidth" et "innerHeight" (initialisation automatique), 
	 * actualisation auto des valeurs lors du redimensionnement du client
	 * 
	 * 	Usage:
	 * 	 JSClient.nLARGEUR pour recuperer la largeur en Number
	 * 	 JSClient.nLARGEUR pour recuperer la hauteur en Number	 
	 */	 
	var JSClient = {INSTANCE:null};
	JSClient.initialise = function() {
		if (JSClient.INSTANCE == null) {
			JSClient.INSTANCE = this;
			JSClient.nLARGEUR = 0;
			JSClient.nHAUTEUR = 0;
			JSClient.actualiseDimensions();
			Event.observe(window, 'resize', function(event) { 
				JSClient.actualiseDimensions(); 
			});
		}
	};
	JSClient.actualiseDimensions = function() {
		if (typeof(window.innerWidth) == 'number') {
		    JSClient.nLARGEUR = window.innerWidth;
		    JSClient.nHAUTEUR = window.innerHeight;
		} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
			// IE 6+ en 'standards compliant mode'
			JSClient.nLARGEUR = document.documentElement.clientWidth;
			JSClient.nHAUTEUR = document.documentElement.clientHeight;
		} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
			// IE 4 compatible
			JSClient.nLARGEUR = document.body.clientWidth;
			JSClient.nHAUTEUR = document.body.clientHeight;
		}
	};
	JSClient.initialise();
}
if (typeof MEService == 'undefined') {
	/**
	 * Class: MEService
	 * Mode ajax des includes Master Edit
	 */	 	 	 	
	var MEService = {	
		_sURL:"",
		sAJAX_REQUEST:'Ajax.Request',
		sAJAX_UPDATER:'Ajax.Updater',
		/**
		 * Method: setURL
		 * 
		 * Parameters:
		 *  - String url du controleur
		 */		 		
		setURL:function(valeur) {
			this._sURL = valeur;
		},
		/**
		 * Method: appelle
		 * Effectue un Ajax.Request
		 * 
		 * Parameters:
		 *  - String classe
		 *  - String methode
		 *  - * parametres
		 *  - Ecouteurs de la reponse : surSucces, surErreur 		 		 		 		 		 
		 */		 		 		
		appelle:function(sClasse, sMethode, parametres, oEcouteur) {			
			var oParametres = {
				sClasse:sClasse, 
				sMethode:sMethode, 
				sType:MEService.sAJAX_REQUEST,
				sJson:Object.toJSON(parametres)
			};
			new Ajax.Request(this._sURL, {
				parameters:oParametres, 
				onComplete:function(event) {
					var reponse = (event.responseText.isJSON()) ? event.responseText.evalJSON() : event.responseText;
					if (typeof oEcouteur.surSucces == 'function') {
						oEcouteur.surSucces.apply(oEcouteur, [reponse]);
					}
				},
				onFailure:function(event) {
					Event.stop(event);
					if (typeof oEcouteur.surErreur == 'function') {
						oEcouteur.surErreur.apply(oEcouteur, [event]);
					}
				}
			})
		},
		/**
		 * Method: affiche
		 * Effectue un Ajax.Updater
		 * 
		 * Parameters:
		 *  - String id de l'element html de destination
		 *  - String classe
		 *  - String methode
		 *  - * parametres
		 *  - Ecouteurs de la reponse : surSucces	 		 		 		 		 		 		 
		 */
		affiche:function(sBoiteReponse, sClasse, sMethode, parametres, oEcouteur) {
			var oParametres = {
				sClasse:sClasse, 
				sMethode:sMethode, 
				sType:MEService.sAJAX_UPDATER,
				sJson:Object.toJSON(parametres)
			};
			new Ajax.Updater(sBoiteReponse, this._sURL, {
				evalScripts:true,
				parameters:oParametres, 
				onComplete:function(event) {
					if (typeof oEcouteur.surSucces == 'function') {
						oEcouteur.surSucces.apply(oEcouteur, [event.responseText]);
					}
				}
			});
		}
	};
}
if (typeof Fenetre == 'undefined') {
	/**
	 * Class: Fenetre
	 * Boites de dialogues modales
	 */	
	var Fenetre = {
		_aEcouteurs:[],
		_delegue:function(i) {
			if (typeof this._aEcouteurs[i].callback == 'function') this._aEcouteurs[i].callback();
		},
		_verifieHtml:function(s) {
			if (s.indexOf('<') != 0) {
				s = "<span>"+s+"</span>";
			}
			return s;
		},
		alerte:function(sTitre, sHtml, fCallbackFermeture) {
			Modalbox.show(this._verifieHtml(sHtml), {overlayClose:true, title:sTitre, afterHide:function() {
				if (typeof fCallbackFermeture == 'function') fCallbackFermeture();
			}});
		},
		/**
		 * Method: void questionne
		 *
		 * Parametres:
		 *  - String question a poser
		 *  - Array de la forme 
		 * 	[ 
		 *		{
		 *			libelle:'libelle du bouton', 
		 *			callback:function() { alert('fonction invoquee lors du clic sur le bouton...'); }; 
		 *		}, 
		 *		... 
		 *	] 		  		 
		 */		 		 		 		
		questionne:function(sQuestion, aEcouteurs) {
			var sHtml = "";
			this._aEcouteurs = aEcouteurs || [];
			this._aEcouteurs.each(function(oEcouteur, i) {
					sHtml += "<input type=\"button\" value=\""+oEcouteur.libelle+"\" onclick=\"Fenetre._delegue("+i+");\" />&nbsp;";
			});
			sHtml = "<div style=\"text-align:center;\">"+sHtml+"</div>";
			Modalbox.show(sHtml, {overlayClose:true, evalScripts:true, title:sQuestion});
		},
		/**
		 * Method: void ferme
		 * Demande de fermeture de la fenetre modale
		 *
		 * Parameters:
		 *  - [int nDelai] delai de fermeture en ms
		 *    Si le delai est renseigne, de&sactivation de "l'overlayClose"		 	 		 
		 */		 		 		 		
		ferme:function(nDelai) {
			if (nDelai != undefined && nDelai != 0) {
				Modalbox.options.overlayClose = false;
				setTimeout(function() {
					Modalbox.hide();
				}, nDelai);
			} else if (nDelai == undefined) {
				Modalbox.hide();
			} else if (nDelai == 0) {
			
			}
		}
	};
}
/**
 * =============================================
 * Class: Infobulle
 * Dependant de JSClient 
 *  v 0.1
 * ============================================= 
 */ 
var Infobulle = Class.create();
Infobulle.prototype = {
	/**
	 * ====================================
	 * GROUP: Methodes publiques
	 * ====================================	 	 
	 *	 	
	 * Method: initialize
	 *
	 * Parameters:
 	 *  
	 */	 
	initialize: function() {
		if ($('__infobulle') == null) {
			this.bAffAGauche = false;
			this.MARGE_CURSEUR = 10;
			new Insertion.Top('body', "<div id='__infobulle' style='position:absolute; display:none;'></div>");
			$('__infobulle').setStyle({
				zIndex: 10001,
				position: 'absolute',
				backgroundColor: '#fff',
				margin: 0,
				padding: '5px',
				top: 0,
				left: 0,
				font: '11px Verdana, Arial, Geneva',
				border: '1px solid #ccc'
			});
		}
	},
	setStyle: function(o) {
		$('__infobulle').setStyle(o);
	},
	/**
	 * Method: affiche
	 *
	 * Parameters:
	 * 	- sHtml, String le contenu (html ou non) de l'infobulle	 	 
	 */	 	 	
	affiche: function(sHtml, bAffAGauche) {
		this.initialize();
		this.bAffAGauche = bAffAGauche;
		Event.observe(document, 'mousemove', this._bouge.bindAsEventListener(this));
		$('__infobulle').update(sHtml);
		$('__infobulle').setStyle({position:'absolute', display:'inline'});
	},
	/**
	 * Method: masque
	 *  Masque l'infobulle	 
	 */	
	masque: function() {
		if ($('__infobulle') != null) {
			Event.stopObserving(document, 'mousemove', this._bouge.bindAsEventListener(this));
			$('__infobulle').setStyle({position:'absolute', display:'none'});
			$('__infobulle').remove();
		}
	},
	/**
	 * ====================================
	 * GROUP: Methodes privees
	 * ====================================	 	 
	 *	 	
	 * Method: _bouge
	 *
	 * Parameters:
 	 *  MouseEvent e
	 */
	_bouge: function(e) {
		if ($('__infobulle') != null) {
			$('__infobulle').style.top = (Event.pointerY(e) + 7) + "px";
			if (Event.pointerX(e) + $('__infobulle').getWidth() + 40 > JSClient.LARGEUR) {
				$('__infobulle').style.left = (JSClient.LARGEUR - $('__infobulle').getWidth() - 80)+"px";
			} else {
				$('__infobulle').style.left = Event.pointerX(e) + ((this.bAffAGauche) ? -this.MARGE_CURSEUR-$('__infobulle').getWidth() : this.MARGE_CURSEUR) + "px";
			}
		}
	}
};





/////////////////////////////////
// DEPRECIE (passage par soap pour retrocompatibilite pronight)
/////////////////////////////////
if (typeof JService == 'undefined') {
	/**
	 * Class: JService
	 * Utililisation du package jservice
	 */	 	 	 	
	var JService = {	
		_sServeur:"",
		/**
		 * Method: setServeur
		 * 
		 * Parameters:
		 *  - String url du serveur		 		 		 
		 */		 		
		setServeur:function(valeur) {
			this._sServeur = valeur;
		},
		/**
		 * Method: appelle
		 * Effectue un Ajax.Request
		 * 
		 * Parameters:
		 *  - String classe
		 *  - String methode
		 *  - * parametres
		 *  - Function de callback si succes
		 *  - Function de callback si erreur		 		 		 		 		 		 		 
		 */		 		 		
		appelle:function(sClasse, sMethode, parametres, fCallbackSucces, fCallbackErreur) {
			var oParametres = {
				sServeur:this._sServeur,
				sClasse:sClasse, 
				sMethode:sMethode, 
				sJson:Object.toJSON(parametres)
			};
			new Ajax.Request('site/httpservices/jservice.php', {
				parameters:oParametres, 
				onComplete:function(event) {
					var reponse = event.responseText.evalJSON();
					if (reponse.JService_erreur != undefined) {
						if (typeof fCallbackErreur == 'function') fCallbackErreur(reponse.JService_erreur);
					} else {
						if (typeof fCallbackSucces == 'function') fCallbackSucces(reponse);
					}
				}
			});
		},
		/**
		 * Method: affiche
		 * Effectue un Ajax.Updater
		 * 
		 * Parameters:
		 *  - String id de l'element html de destination
		 *  - String classe
		 *  - String methode
		 *  - * parametres
		 *  - Function de callback si succes	 		 		 		 		 		 		 
		 */
		affiche:function(sBoiteReponse, sClasse, sMethode, parametres, fCallbackSucces) {
			var oParametres = {
				sServeur:this._sServeur,
				sClasse:sClasse, 
				sMethode:sMethode, 
				sJson:Object.toJSON(parametres)
			};
			new Ajax.Updater(sBoiteReponse, 'site/httpservices/jservice.php', {
				evalScripts:true,
				parameters:oParametres, 
				onComplete:function(event) {
					if (typeof fCallbackSucces == 'function') fCallbackSucces(event.responseText);
				}
			});
		}
	};
}
/**
 * =======================================================================================
 *
 * Class: CompteurNumerique
 *  v 0.2
 */ 
var CompteurNumerique = Class.create();
CompteurNumerique.prototype = {
	/**
	 * ====================================
	 * GROUP: Methodes publiques
	 * ====================================	 	 
	 *	 	
	 * Method: initialize
	 *
	 * Parameters:
 	 *  - String sId, id du champ texte de qte	 
	 */	 	 	
	initialize: function(sId) {
		this.MIN = 1;
		this.MAX =  999;
		this.INCREMENT = 1;
		this.oChampNumerique = $(sId);
		if (this.oChampNumerique.value.length == 0) this.oChampNumerique.value = this.MIN;
		this.btPlus = $(sId+'_plus');
		this.btMoins = $(sId+'_moins');
		this.oChampNumerique.onkeyup = this.verifieSaisie.bind(this);
		this.btPlus.onclick = this.incremente.bind(this);
		this.btMoins.onclick = this.decremente.bind(this);
		
	},
	/**
	 * Method: incremente
	 *
	 *  Incrementation de la quantite	 
	 */	
	incremente: function() {
		if (parseInt(this.oChampNumerique.value) < this.MAX) {
			this.oChampNumerique.value = parseInt(this.oChampNumerique.value) + this.INCREMENT;
		}
	},
	/**
	 * Method: decremente
	 *
	 *  Decrementation de la quantite	 
	 */	
	decremente: function() {
		if (parseInt(this.oChampNumerique.value) > this.MIN) {
			this.oChampNumerique.value = parseInt(this.oChampNumerique.value) - this.INCREMENT;
		}
	},
	/**
	 * Method: verifieSaisie
	 *
	 *  Verification de la saisie, format numerique obligatoire	 
	 */
	verifieSaisie: function() {
		if (this.oChampNumerique.value.length == 0) {
			this.oChampNumerique.value = this.MIN;
		}
		if (!this.verifieEntier(this.oChampNumerique.value)) {
			this.oChampNumerique.value = this.MIN;
		}
	},
	/**
	 * Method: verifieEntier
	 *
	 *  Parameters:
	 *   type non connu valeur
	 *   
	 *  Returns:
	 * 	 Boolean, true si valeur est un entier 	  
	 */
	verifieEntier: function(valeur) {
		return !isNaN(Number(valeur));
	},
	/**
	 * ====================================
	 * GROUP: Setters
	 * ====================================	 	 
	 *	 	
	 * Method: changeIncrement
	 *
	 * Parameters:
 	 *  Int increment de base, si 6 alors 6,12,18,24,etc 
	 */
	changeIncrement: function(nIncrement) {
		this.INCREMENT = nIncrement;
	},
	/**
	 * Method: changeValeurMin
	 *
	 */	 	 	
	changeValeurMin: function(nMin) {
		this.MIN = nMin;
	},
	/**
	 * Method: changeValeur
	 *
	 */	
	changeValeur: function(nValeur) {
		this.oChampNumerique.value = nValeur;
	}
};
/**
 * =======================================================================================
 *
 * Class: Calendrier
 *  v 0.2 
 *   
 * =============================
 *  GROUP: Constantes
 * ============================= 
 * 
 * Var VERSION
 *  Version du Calendrier   
 */ 
Calendrier.VERSION = "0.2"; 
/**
 * Var: _INSTANCE
 *  Numero du calendrier en cours
 */ 
Calendrier._INSTANCE = 0;
/**
 * Var: aMoisFr
 *  Les mois en Francais
 */  
Date.aMoisFr = [
	'Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 
	'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Decembre'
];
/**
 * Var: aJoursFeries
 *  Les jours feries Francais
 */  
Date.aJoursFeries = [
	'01/01', '01/05', '08/05', '14/07', '15/08', '01/11', 
	'11/11', '25/12'
];
/**
 * ==================================
 * GROUP: Tools pour le Calendrier
 * ==================================
 * 
 * Method: renvoieJoursDansMois
 *  
 * Returns:
 *  Int le nombre de jour dans le mois (pour un objet de type date)
 */  
Date.prototype.renvoieJoursDansMois = function () {
	var dDateTmp = new Date(this.getFullYear(), this.getMonth(), 1);
	var nJours = 0;
	for (var i = 27; i <= 32; i++) {
		dDateTmp.setDate(i);
		if (dDateTmp.getMonth() != this.getMonth()) {
			nJours = i - 1;
			break;
		}
	}
	return nJours;
};
/**
 * Method: estFerie
 * 
 * Returns:   
 *  Boolean true si ferie (pour un objet de type date) 
 */ 
Date.prototype.estFerie = function (j, m) {
	for (var i = 0; i < Date.aJoursFeries.length; i++) {
		if (Date.aJoursFeries[i].substring(0, 2) == j && Date.aJoursFeries[i].substring(3, 5) == m)
			return true;
	}
	return false;
};
/**
 * Method: renvoiePremierJourDuMois
 * 
 * Returns:   
 *  Int premier jour du mois (pour un objet de type date) 
 */ 
Date.prototype.renvoiePremierJourDuMois = function () { // (ou 0 est dimanche)
	var dDateTmp = new Date(this.getFullYear(), this.getMonth(), 1);
	return (dDateTmp.getDay() == 0) ? 7 : dDateTmp.getDay();
};
/**
 * Method: combleDate
 * 
 * Returns:   
 *  String sur deux caracteres (pour un type nombre) 
 */ 
Number.prototype.combleDate = function () {
	return (this < 10) ? "0"+this : this;
};
/**
 * ==================================
 * Class: Calendrier
 * ==================================
 *  
 * Constructor: Calendrier 
 *  
 */ 
function Calendrier(oAction, oDate, oRestrictions) {
	this._nINSTANCE = ++Calendrier._INSTANCE;
	this._initialise(oAction, oDate, oRestrictions);
};
/**
 * Method: _initialise
 *  Init. du calendrier, a invoquer aussi avant une mise a jour de l'affichage
 *  Dans la fonction de callback, le parametre oEvent contient une representation 
 *  de l'objet date {annee:aaaa, mois:mm, jour:jj } et l'objet cible target  
 *  
 * Parameters:   
 *  oAction: Objet contenant Object scope et String callback
 *  oDate: Object contenant Number annee, Number mois (1 a 12), Number jour
 *  oRestrictions 
 */  
Calendrier.prototype._initialise = function(oAction, oDate, oRestrictions) {
	this._oAction 			= oAction;
	this._oDate 			= oDate;
	this._oRestrictions 	= (oRestrictions == undefined) ? {MIN:{}, MAX:{}} : oRestrictions;
	this._dDate 			= new Date(oDate.annee, oDate.mois-1, oDate.jour);
	this._nJours 			= this._dDate.renvoieJoursDansMois();
	this._nPremierJour 		= this._dDate.renvoiePremierJourDuMois();
	this._sCalque 			= null;
	this._sNomCalque 		= "";
	this._sHtml 			= "";
};
/**
 * Method: affiche
 *  Affichage du calendrier
 *  
 * Parameters:
 *  sNomCalque, String le nom du calque de destination   
 */ 
Calendrier.prototype.affiche = function(sNomCalque) {
	var _THIS_ = this;
	var aJours = [];
	var i = 0, j = 0, k = 0, l = 0, nMoisMin = 0, nMoisMax = 0, nAnneeMin = 0, nAnneeMax = 0;
	var bCliquable;
	if (this._oRestrictions.INTERDITS == undefined) { this._oRestrictions.INTERDITS = []; }
	// Borne des annees
	nAnneeMin = (this._oRestrictions.MIN.annee != undefined) ? this._oRestrictions.MIN.annee : new Date().getFullYear();
	nAnneeMax = (this._oRestrictions.MAX.annee != undefined) ? this._oRestrictions.MAX.annee : new Date().getFullYear() + 100;
	if (nAnneeMin > nAnneeMax) {
		nAnneeMin = new Date().getFullYear();
		nAnneeMax = new Date().getFullYear() + 100;
	}
	// Borne des mois
	nMoisMin = (this._oRestrictions.MIN.mois != undefined && this._dDate.getFullYear() == this._oRestrictions.MIN.annee) ? this._oRestrictions.MIN.mois-1 : 0;
	nMoisMax = (this._oRestrictions.MAX.mois != undefined && this._dDate.getFullYear() == this._oRestrictions.MAX.annee) ? this._oRestrictions.MAX.mois : Date.aMoisFr.length;
	if (nMoisMin > nMoisMax) {
		nMoisMin = 0;
		nMoisMax = Date.aMoisFr.length;
	}
	// !!!!!!!!  Cas particuliers  !!!!!!!!
	if (nMoisMin == this._oRestrictions.MIN.mois-1 && nMoisMin > this._dDate.getMonth()) {
		this._initialise(this._oAction, {annee:this._dDate.getFullYear(), mois:this._oRestrictions.MIN.mois, jour:1}, this._oRestrictions);
		this.affiche(sNomCalque);
	}
	if (nMoisMax == this._oRestrictions.MAX.mois && this._dDate.getMonth() > nMoisMax-1) {
		this._initialise(this._oAction, {annee:this._dDate.getFullYear(), mois:this._oRestrictions.MAX.mois, jour:1}, this._oRestrictions);
		this.affiche(sNomCalque);
	}
	//
	// Borne des jours
	if (this._oRestrictions.MIN.annee == this._dDate.getFullYear() && this._oRestrictions.MIN.mois-1 == this._dDate.getMonth() && this._oRestrictions.MIN.jour != undefined) {
		for (i = 1; i <= this._oRestrictions.MIN.jour; i++) {
			this._oRestrictions.INTERDITS.push({annee:this._dDate.getFullYear(), mois:this._dDate.getMonth(), jour:i});	
		}
	}
	if (this._oRestrictions.MAX.annee == this._dDate.getFullYear() && this._oRestrictions.MAX.mois-1 == this._dDate.getMonth() && this._oRestrictions.MAX.jour != undefined) {
		for (i = this._oRestrictions.MAX.jour+1; i <= this._nJours; i++) {
			this._oRestrictions.INTERDITS.push({annee:this._dDate.getFullYear(), mois:this._dDate.getMonth(), jour:i});
		}
	}
	//
	var nJours7 = this._nJours + this._nPremierJour - 1;
	while (nJours7%7 != 0 && nJours7 <= 50) nJours7++;
	this._sNomCalque = sNomCalque;
	this._sCalque = $(this._sNomCalque);
	this._sCalque.update("");
	this._sHtml = "";
	this._sHtml += "<table class=\"calendrierTableau\">\n"; 
	this._sHtml += "	<tr>\n";
	this._sHtml += "		<td colspan=\"7\" class=\"calendrierLigneFormulaire\">\n";
	this._sHtml += "			<select id=\"selectMois"+this._nINSTANCE+"\">\n";
	for (i = nMoisMin; i < nMoisMax; i++) {
		this._sHtml += "				<option value=\""+i+"\""+((this._dDate.getMonth() == i) ? " selected=\"selected\"" : "")+">"+Date.aMoisFr[i].substr(0, 3)+"</option>";
	}
	this._sHtml += "			</select>\n";
	this._sHtml += "			<select id=\"selectAnnee"+this._nINSTANCE+"\">\n";
	for (i = nAnneeMin; i <= nAnneeMax; i++) {
		this._sHtml += "				<option value=\""+i+"\""+((this._dDate.getFullYear() == i) ? " selected=\"selected\"" : "")+">"+i+"</option>";
	}
	this._sHtml += "			</select>&nbsp;\n";
	this._sHtml += "		</td>\n";
	this._sHtml += "	</tr>\n";
	this._sHtml += "	<tr>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Lu</td>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Ma</td>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Me</td>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Je</td>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Ve</td>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Sa</td>\n";
	this._sHtml += "		<td class=\"calendrierEnteteJour\">Di</td>\n";
	this._sHtml += "	</tr>\n";
	for (var i = 1; i <= nJours7; i++) {
		if (i == 1 || (i-1) % 7 == 0) this._sHtml += "	<tr>\n";
		if(i >= this._nPremierJour && j < this._nJours) {
			k = ++j;
			this._sHtml += "		<td class=\"calendrierColonneJour\">\n"; 
			bCliquable = true;
			for (l = 0; l < this._oRestrictions.INTERDITS.length; l++) {
				if (this._oRestrictions.INTERDITS[l].annee == this._dDate.getFullYear() && this._oRestrictions.INTERDITS[l].mois == this._dDate.getMonth() && this._oRestrictions.INTERDITS[l].jour == k) {
					bCliquable = false;
					break;	
				}
			}
			if (bCliquable) {
				this._sHtml += "			<p><a class=\"calendrierLien\" id=\"jour_"+this._nINSTANCE+"_"+i+"\" href=\"javascript:void(0);\">"+k.combleDate()+"</a></p>";
				aJours.push({
					id:'jour_'+this._nINSTANCE+'_'+i, 
					oDate:{annee:this._oDate.annee, mois:this._oDate.mois.combleDate(), jour:k.combleDate()}
				});	
			} else {
				this._sHtml += "			<p class=\"jourInterdit\">"+k.combleDate()+"</p>";
			}
			this._sHtml += "		</td>\n";
			
		} else {
			this._sHtml += "		<td class=\"calendrierColonneJour\">&nbsp;</td>\n";
		}
		if (i % 7 == 0 || i == nJours7) 
			this._sHtml += "	</tr>\n";
	}
	this._sHtml += "</table>\n";
	this._sCalque.update(this._sHtml);
	for (i = 0; i < aJours.length; i++) {
		$(aJours[i].id).i = i;
		$(aJours[i].id).onclick = function() {
			var oArguments = aJours[this.i].oDate;
			oArguments.target = _THIS_;
			_THIS_._oAction.scope[_THIS_._oAction.callback](oArguments);
		};
	}
	$('selectMois'+this._nINSTANCE).onchange = function() {
		var sNomCalque = _THIS_._sNomCalque;
		var oDate = {annee:_THIS_._oDate.annee, mois:Number(this.value)+1, jour:1};
		_THIS_._initialise.apply(_THIS_, [_THIS_._oAction, oDate, _THIS_._oRestrictions]);
		_THIS_.affiche.apply(_THIS_, [sNomCalque]);
	};
	$('selectAnnee'+this._nINSTANCE).onchange = function() {
		var sNomCalque = _THIS_._sNomCalque;
		var oDate = {annee:this.value, mois:_THIS_._oDate.mois, jour:1};
		_THIS_._initialise.apply(_THIS_, [_THIS_._oAction, oDate, _THIS_._oRestrictions]);
		_THIS_.affiche.apply(_THIS_, [sNomCalque]);
	};	
};
/**
 * ==================================
 * GROUP: Specialisation du calendrier
 * ==================================
 *  
 * Method: Calendrier 
 *  A appeler a partir de l'evenement oEvent.target
 */
Calendrier.prototype.ferme = function() {
	this._sCalque.hide();
};
/**
 * Method: toggle
 *  Meme fonctionnement que toggle de prototype (afficher/masquer n fois)
 */  
Calendrier.prototype.toggle = function(sCalque) {
	this.affiche(sCalque);
	$(sCalque).toggle();
}
