/* JS Document pour les pages du Parlement europeen [createur Pellichero Olivier] */
/* Scripts permettant la creation et la gestion du calendrier ouvert en pop up */

/* ======================================================================================================== */
/* ACTIVATION DES SCRIPTS ================================================================================= */
/* ======================================================================================================== */
	var calendarfunction_js			= true;

/* ======================================================================================================== */
/* Calendar =============================================================================================== */
/* ======================================================================================================== */

	// Creation de l'objet calendrier
	function CalendarWidget(Lang, CSS, CSSMoving, NumberWeek, ModePopUp, ModeWeek, Limits, SpecialDays){
		// Parametres autorises lors de la creation de la classe JS:
			// 	Lang						:Object			>> objet reprenant tous les textes et valeurs linguistiques
			//	CSS							:Object			>> objet reprenant toutes les classes css a utiliser
			//	CSSMoving					:Object			>> objet reprenant les classes css a utiliser pour le positionnement
			//	NumberWeek					:Boolean		>> affichage des numeros de semaines dans le calendrier
			//	ModePopUp					:Boolean		>> affichage du calendrier en pop up ou independant
			//	ModeWeek					:Boolean		>> selection de semaine ou de jour
			//	Limits						:Object			>> objet reprenant les dates minimum et maximum pour la navigation dans le calendrier
			//	SpecialDays					:Array			>> liste d'objets contenant les dates speciales a traiter dans le calendrier
		// Parametres autorises lors de l'ouverture JS (display):
			// 	Parent						:String/Object	>> id de la balise "parent" cible ou reference directe de la balise
			// 	MainContainer				:String/Object	>> id de la balise dans laquelle le calendrier peut s'afficher visuellement
			// 	Index						:Array			>> liste des balises dont l'index devra etre modifie pour l'affichage du calendrier
			// 	Value						:String			>> date (texte) a selectionner
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Listing des textes demandes
			// 	Lang.week					>> info bulle affichee sur l'abbreviation "semaine"
			// 	Lang.shortweek				>> abbreviation "semaine"
			// 	Lang.day					>> info bulle affichee sur l'abbreviation des jours de la semaine
			// 	Lang.shortday				>> abbreviation des jours de la semaine
			// 	Lang.close					>> libelle du bouton de fermeture
			// 	Lang.selected				>> texte a utiliser pour le jour selectionne
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Listing des noms de CSS demandes
			// 	CSS.hidden					>> Style pour les textes caches
			// 	CSS.popup					>> classe pour le pop up (mode popup)
			// 	CSS.shadow					>> classe pour l'ombre portee (mode popup)
			// 	CSS.calendarday				>> classe pour le calendrier en mode selection par jour
			// 	CSS.calendarweek			>> classe pour le calendrier en mode selection par semaine
			// 	CSS.month					>> classe pour l'abbreviation du mois dans l'entete du pop up
			// 	CSS.linkprev				>> classe pour les boutons de navigation precedent
			// 	CSS.linknext				>> classe pour les boutons de navigation suivants
			// 	CSS.linkmonth				>> Style pour le bouton de changement de mois
			// 	CSS.linkyear				>> Style pour le bouton de changement d'annee
			// 	CSS.linklabel				>> classe pour le libelle cache des boutons de navigation
			// 	CSS.tableblock				>> classe pour le conteneur du tableau
			// 	CSS.ceilweek				>> classe pour les cellules contenant les numeros de semaine
			// 	CSS.ceilday					>> classe pour les cellules contenant les numeros de jour
			// 	CSS.ceilwkend				>> classe pour les cellules contenant les valeurs relatives au week end
			// 	CSS.rowhover				>> classe pour l'effet de survol d'un lien "jour" ou "semaine"
			// 	CSS.ceilselected			>> classe pour la selection d'une cellule (mode jour)
			// 	CSS.rowselected				>> classe pour la selection d'une rangee de cellules (mode semaine)
			// 	CSS.close					>> classe pour la zone du bouton de fin de boite
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Listing des noms de CSS demandes pour le positionnement (si l'objet est nul, les styles seront ajoutés directement)
			// 	CSSMoving.topleft			>> classe pour afficher le pop up en haut a gauche du bouton
			// 	CSSMoving.topright			>> classe pour afficher le pop up en haut a droite du bouton
			// 	CSSMoving.bottomleft		>> classe pour afficher le pop up en bas a gauche du bouton
			// 	CSSMoving.bottomright		>> classe pour afficher le pop up en bas a droite du bouton
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Listing des parametres chaque objet demandant l'ajout d'un marqueur
			//	SPECIALDAY.min				>> objet contenant la reference du jour de debut {day:valeur, month:valeur, year:valeur}
			//	SPECIALDAY.max				>> objet contenant la reference du jour de debut {day:valeur, month:valeur, year:valeur}
			//	SPECIALDAY.css				>> classe CSS a assigner aux jours concernes
			//	SPECIALDAY.text				>> titre/nom de l'evenement
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Classe utilisee
			// HTManager					>> htmanager.js
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Exemple d'utilisation
			// Creation du widget
			//	var s = new CalendarWidget("Objet linguistique", 
			//							   "Objet de style", "Objet de style pour le positionnement", 
			//							   "Affichage ou non des semaines", 
			//							   "Mode d'affichage", "Mode de selection", 
			//							   {min:limite/date minimale, max:limite/date maximale}, 
			//							   ["Liste d'objet des jours speciaux {}"]);
			// Affichage/Ouverture
			//	s.display("ID du parent", "ID du conteneur de visibilite", 
			//			  ["Id des balises dont l'index doit etre mis a jour"], 
			//			  "fonction a appeler lors de la selection", "date au format texte a afficher"){
			// Disparition/Fermeture
			//	s.hide();
			// Suppression du widget
			//	s.remove();
		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Variables
		var authorize_access		= false;
		var authorize_addEvent		= false;
		var authorize_open			= false;
		var This;
		var Html;
		var Current;
		var Data;
		var Tags;
		var Lang;
		// =======================================================================
		// INITIALISATION ========================================================
		// =======================================================================
			// Initialisation : Fonction creant le widget avec les parametres demandes
			this.init = function(){
				if(typeof(htmanager_js) == "boolean" && htmanager_js){
					// Autorisation d'acces aux fonctionnalites
					authorize_access				= true;
					// Sauvegarde des references
					This							= this;
					Html							= new HTManager();
					// Initialisation des objets utiles
					Tags							= new Object();	// Conteneur de balises
					Data							= new Object();	// Parametrage general du widget
					Current							= null;			// Conteneur des donnees relatives au calendrier ouvert
					// Recuperation des parametres transmis
						// Textes linguistiques
						Lang						= (typeof(Lang)	== "object")? 	Lang : 	new Object();
						if(typeof(Lang.shortdays)	!= "object") Lang.shortdays =	new Array();
						if(typeof(Lang.days)		!= "object") Lang.days 		=	new Array();
						// Liste des classes CSS a utiliser
						Data.css					= (typeof(CSS)			== "object")? 	CSS 		: 	new Object();
						// Affichage du numero des semaines
						Data.numberweek				= (typeof(NumberWeek)	== "boolean"	&& NumberWeek);
						// Affichage du calendrier en pop up
						Data.popup					= (typeof(ModePopUp)	== "boolean"	&& ModePopUp);
						// Liste des classes CSS a utiliser pour le positionnement
						if(typeof(CSSMoving)	== "object" && CSSMoving != null && Data.popup){
							if(	typeof(CSSMoving.topleft) 		!= "string" || CSSMoving.topleft 		== null ||
								typeof(CSSMoving.topright) 		!= "string" || CSSMoving.topright 		== null ||
								typeof(CSSMoving.bottomleft)	!= "string" || CSSMoving.bottomleft 	== null ||
								typeof(CSSMoving.bottomright) 	!= "string" || CSSMoving.bottomright 	== null){
								Data.cssmoving		= null;
							}else{
								Data.cssmoving		= CSSMoving;
							}
						}else Data.cssmoving		= null;
						// Selection de semaine au lieu de jour
						Data.modeweek				= (typeof(ModeWeek)		== "boolean"	&& ModeWeek);
						// Liste des nombres de jour par mois (janvier > decembre)
						Data.monthdays				= new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
						// Initialisation de la decoupe des formats
						Data.format					= new Object();
						Data.format.day				= init_dayformat();
						Data.format.week			= init_weekformat();
						// Dates minimales et maximales autorisees
						if(typeof(Limits) == "object" && Limits != null){
							Data.dmin				= convert_date2object(Limits.min);
							Data.dmax				= convert_date2object(Limits.max);
						}else{
							Data.dmin				= null;
							Data.dmax				= null;
						}
					// Ajout des actions JS sur toute la page pour faire disparaitre le calendrier
					if(Data.popup){
						if(window.addEventListener)			window.addEventListener("click", 	function(e){	This.windowhide(e); }, false);
						else if(document.addEventListener) 	document.addEventListener("click", 	function(e){	This.windowhide(e); }, false);
						else if(document.attachEvent)		document.attachEvent("onclick",		function(e){	This.windowhide(e); });
					}
					// Creations des balises
					Tags.validate					= false;
					Tags							= create_inittags();
					// Activation des acces
					authorize_access				= true;
					authorize_open					= true;
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Initialisation : Fonction identifiant l'ordre d'affichage des donnees selon le format transmis (jour)
			function init_dayformat(){
				var o								= new Object();
				// Analyse de l'ordre des donnees
				var id								= String(Lang.formatday).indexOf("DD");
				var im								= String(Lang.formatday).indexOf("MM");
				var iy								= String(Lang.formatday).indexOf("YYYY");
				var s;
				var e;
				switch(true){
					case (id < im < iy):		// Jour Mois Annee
						o							= {day:0, month:1, year:2};
						s							= id + 2;
						e							= im;
						break;
					case (id < iy < im):		// Jour Annee Mois
						o							= {day:0, month:2, year:1};
						s							= id + 2;
						e							= iy;
						break;
					case (iy < id < im):		// Annee Jour Mois
						o							= {day:1, month:2, year:0};
						s							= id + 2;
						e							= im;
						break;
					case (im < id < iy):		// Mois Jour Annee
						o							= {day:1, month:0, year:2};
						s							= im + 2;
						e							= id;
						break;
					case (iy < im < id):		// Annee Mois Jour
						o							= {day:2, month:1, year:0};
						s							= im + 2;
						e							= id;
						break;
					case (im < iy < id):		// Mois Annee Jour
						o							= {day:2, month:0, year:1};
						s							= im + 2;
						e							= iy;
						break;
				}
				// Identification du separateur
				o.separator							= String(Lang.formatday).substring(s, e);
				// Envoi du decoupage
				return(o);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Initialisation : Fonction identifiant l'ordre d'affichage des donnees selon le format transmis (semaine)
			function init_weekformat(){
				var o								= new Object();
				// Objet utile
				var m								= new Array();
					m[0]							= {ref:"week", 	text:"{ww}", 	length:4};
					m[1]							= {ref:"start", text:"{start}", length:7};
					m[2]							= {ref:"end", 	text:"{end}", 	length:5};
				// Analyse de l'ordre des donnees
				var t								= String(Lang.formatweek).toLowerCase();
				var w								= t.indexOf("{ww}");
				var s								= t.indexOf("{start}");
				var e								= t.indexOf("{end}");
				// Analyse de l'ordre des informations
				var t1;	var t2;	var t3;
				if(w < s && w < e){
					t1								= 0;
					if(s < e){	t2 = 1; t3 = 2; }else{ t2 = 2; t3 = 1; }
				}else if(s < w && s < e){
					t1								= 1;
					if(w < e){	t2 = 0; t3 = 2; }else{ t2 = 2; t3 = 0; }
				}else if(e < s && e < w){
					t1								= 2;
					if(s < w){	t2 = 1; t3 = 0; }else{ t2 = 0; t3 = 1; }
				}
				// Decoupe du format
				var i								= {min:-1, max:0};
				for(var j = 0; j < 3; j++){
					i.max							= t.indexOf(m[j].text);
					o["text" + j]					= Lang.formatweek.substring(i.min, i.max);
					o[m[j].ref]						= j;
					i.min							= i.max + m[j].length;
				}
				o.text3								= (i.min < Lang.formatweek.lenght)? Lang.formatweek.substring(i.min, Lang.formatweek.length) : "";
				// Envoi du decoupage
				return(o);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Initialisation : Fonction lancant la suppression du calendrier
			this.remove = function(){
				// Ajout des actions JS sur toute la page pour faire disparaitre le calendrier
				if(Data.popup){
					if(window.removeEventListener)			window.removeEventListener("click", 	function(e){	This.windowhide(e); }, false);
					else if(document.removeEventListener) 	document.removeEventListener("click", 	function(e){	This.windowhide(e); }, false);
					else if(document.detachEvent)			document.detachEvent("onclick",			function(e){	This.windowhide(e); });
				}
				// Suppression du calendrier s'il est affiche
				This.hide();
				// Nettoyage des objets
				Html								= null;
				Data								= null;
				Current								= null;
				Tags								= null;
				Lang								= null;
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Initialisation : Appel automatique de l'initialisation lors de la creation de l'instance
			this.init();
		
		// =======================================================================
		// AFFICHAGE =============================================================
		// =======================================================================
			// Affichage : Fonction lancant l'affichage du calendrier
			this.display = function(Parent, MainContainer, Index, Callback, Value){
				if(authorize_access && authorize_open){
					// Ciblage de la balise servant de conteneur
					Parent							= (typeof(Parent) == "string")? document.getElementById(Parent) : Parent;
					// Verification des donnees
					if(Html.check(Parent) && typeof(Callback) == "function"){
						// Blocage de l'autorisation d'ouverture
						authorize_open				= false;
						// Analyse des donnees
						if(typeof(Index) == "object"){
							var m					= Index.length;
							for(var i = 0; i < m; i++){ Index[i] = (typeof(Index[i]) == "string")? document.getElementById(Index[i]) : Index[i]; }
						}else Index					= null;
						// Sauvegarde des donnees
						Current						= new Object();
						Current.parent				= Parent;
						Current.index				= Index;
						Current.callback			= Callback;
						Data.currentparent			= Parent;
						// Analyse du conteneur principal
						MainContainer				= (typeof(MainContainer) == "string")? document.getElementById(MainContainer) : MainContainer;
						Current.bodycontent			= (Html.check(MainContainer))? MainContainer : null;
						// Sauvegarde de l'initialisation pour debloquer le premier "clic"
						Current.firstclic			= true;
						// Analyse de la date
						var D;
						if(!Data.modeweek) 	D		= get_validateday(Value);
						else				D		= get_validateweek(Value);
						// Date selectionnee
						Current.dselect				= D.selected;
						// Remise a zero de la date affichee (instance initialisee lors du remplissage)
						Current.ddisplay			= null;
						// Lancement du remplissage du calendrier
						fillingup(D.display);
						// Assignation des effets d'ouverture en decallage pour laisser le temps au script de fermeture d'autres panneaux de s'executer
						setTimeout(function(){ This.add_widget(); }, 5);
					}
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Affichage : Fonction integrant le calendrier dans la page
			this.add_widget = function(){
				if(!authorize_open && Current != null){
					if(Html.check(Current.parent)){
						// Deplacement temporaire du pop up
						if(Data.popup) Tags.popup.style.left	= "-100000px";
						// Ajout de l'index pour l'ouverture
						setIndex(Current.index, true);
						// Integration du calendrier dans la balise designee
						Current.parent.appendChild(Tags.main);
						// Calcul des dimensions de la fenetre
						if(Data.popup) Tags.main.style.left		= "";
						adaptivedesign();
					}
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Affichage : Fonction gerant l'ajout et la suppression des index
			function setIndex(L, Add){
				// Deblocage de l'action de fermeture
				if(typeof(L) == "object"){
					var m								= L.length;
					for(var i = 0; i < m; i++){ L[i].style.zIndex	= (Add)? 10000 : "";	}
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Affichage : Fonction lancant la suppression du calendrier
			this.hide = function(){
				// Deblocage de l'action de fermeture
				if(authorize_access && Current != null && !authorize_open){
					if(Html.check(Current.parent)){
						// Deblocage de l'autorisation d'ouverture
						authorize_open					= true;
						// Vidage du calendrier
						fillingup_clear();
						// Suppression du calendrier
						Current.parent.removeChild(Tags.main);
						// Nettoyage de l'index
						setIndex(Current.index, false);
						// Nettoyage de l'objet
						Current							= null;
					}else  Current.firstclic			= false;
				}
			};
			this.windowhide = function(e){
				if(authorize_access && Current != null && !authorize_open){
					var b																	= false;
					// Identification de la balise en fonction du type de navigateur
					if(e.target){
						if(!String(e.target.id).match("widgetcalendar_idtag_"))  		b 	= true;
					}else if(!String(e.srcElement.id).match("widgetcalendar_idtag_")) 	b 	= true;
					if(b) (!Current.firstclic)? This.hide() : Current.firstclic = false;
				}
			}
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Affichage : Fonction changeant le mois ou l'annee affichee
			this.change = function(month, year){
				if(authorize_access && Current != null && (month == -1 || month == 0 || month == 1) && (year == -1 || year == 0 || year == 1)){
					var m					= Current.ddisplay.month + month;
					var y					= Current.ddisplay.year + year;
					if(m > 12){			m 	= 1;	y++;
					}else if(m < 1){	m 	= 12;	y -- }
					fillingup({day:0, month:m, year:y});
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
			// Affichage : Fonction affichant l'effet de survole sur les jours du calendrier
			this.hover = function(hover, ceilweek){
				if(authorize_access && !authorize_open){
					var t;
					// Nettoyage des semaines
					for(var i = 0; i < 6; i++){
						t			= Tags.ceils[i];
						if(typeof(t) == "object") t.tr.className = String(t.tr.className).replace(Data.css.rowhover + " ", "").replace(Data.css.rowhover, "");
					}
					// Surlignage de la semaine
					if(hover && ceilweek >= 0 && ceilweek < 6){
						t			= Tags.ceils[ceilweek];
						if(typeof(t) == "object") t.tr.className = Data.css.rowhover + " " + t.tr.className;
					}
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
			// Affichage : Fonction analysant les dimensions et repositionnant le calendrier
			function adaptivedesign(){
				// Suppression des contraintes des donnees ajoutees
				Tags.main.className					= Data.css.popup;
				Tags.main.style.top					= "";
				Tags.main.style.bottom				= "";
				Tags.main.style.left				= "";
				Tags.main.style.right				= "";
				Tags.popup.style.width				= "";
				Tags.content.style.width			= "";
				Tags.shadow.style.width				= "";
				// Suppression des contraintes de tailles définies
				Tags.content.style.width			= Tags.table.offsetWidth + "px";
				Tags.popup.style.width				= Tags.content.offsetWidth + "px";
				// Etirement de l'ombre portee
				Tags.shadow.style.width				= Tags.content.offsetWidth + "px";
				Tags.shadow.style.height			= Tags.content.offsetHeight + "px";
				// Calcul de la zone disponible pour afficher le calendrier
				if(Current.bodycontent != null){
					var c							= Html.getRealOffset(Tags.main, Current.bodycontent);
					var p							= Html.getRealOffset(Current.parent, Current.bodycontent);
					if(c != null && p != null){
						if(Data.cssmoving == null){
							Tags.main.className			= Data.css.popup;
							// Verification que le calendrier ne sorte par de la page par la gauche
							if(c.left < 0){
								Tags.main.style.left 	= (5 - p.left) + "px";
								Tags.main.style.right 	= "auto";
							}
							// Verification que le calendrier ne sorte par de la page par le haut
							if(c.top < 0){
								Tags.main.style.top 	= "5px";
								Tags.main.style.bottom 	= "auto";
							}
							// Verification que le calendrier ne sorte par de la page par la droite
							var m						= Current.bodycontent.offsetWidth;
							if(c.left + Tags.main.offsetWidth > m){
								Tags.main.style.left 	= (m - (c.left + Tags.main.offsetWidth)) + "px";
								Tags.main.style.right 	= "auto";
							}
							// Verification que le calendrier ne sorte par de la page par le bas
							m							= Math.max(Current.bodycontent.offsetHeight, Current.bodycontent.scrollHeight);
							if(c.top + Tags.main.offsetHeight > m){
								Tags.main.style.top		= (m - (c.top + Tags.main.offsetHeight)) + "px";
								Tags.main.style.bottom 	= "auto";
							}
						}else{
							var positionV				= "";
							var positionH				= "";
							// Verification que le calendrier ne sorte par de la page par le bas
							var m						= Math.max(Current.bodycontent.offsetHeight, Current.bodycontent.scrollHeight);
							positionV	= (c.top + Tags.main.offsetHeight > m)? 	"top" 		: "bottom";
							// Verification que le calendrier ne sorte par de la page par le haut
							positionV	= (c.top < 0)? 								"bottom" 	: "top";
							// Verification que le calendrier ne sorte par de la page par la droite
							m							= Current.bodycontent.offsetWidth;
							positionH	= (c.left + Tags.main.offsetWidth > m)? 	"right"		: "left";
							// Verification que le calendrier ne sorte par de la page par la gauche
							positionH	= (c.left < 0)? 							"left"		: "right";
							// Assignation de la classe
							Tags.main.className			= Data.css.popup + " " + Data.cssmoving[positionV + "" + positionH];
						}
					}
				}
			};
		
		// =======================================================================
		// ENVOI =================================================================
		// =======================================================================
			// Envoi : Fonction envoyant le choix de date par jour
			this.send_day = function(day, week, month, year){
				// Verification de la date envoyee
				if(!isNaN(day) && !isNaN(month) && !isNaN(year)){
					// Appel de la fonction choisie
					Current.callback({data:{day:day, week:(isNaN(week))? null : week, month:month, year:year}, text:convert_date2string(day, month, year)});
				}
				// Fermeture du calendrier
				This.hide();
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Envoi : Fonction envoyant le choix de date par semaine
			this.send_week = function(day, week, month, year){
				// Verification de la date envoyee
				if(!isNaN(day) && !isNaN(week) && !isNaN(month) && !isNaN(year)){
					// Identification de la semaine
					var w				= get_limitweek({day:day, month:month, year:year});
					// Ajout du numero de semaine dans les donnees
					w.real.dmin.week	= week;
					w.real.dmax.week	= week;
					// Appel de la fonction choisie
					Current.callback({data:{min:w.real.dmin, max:w.real.dmax}, text:convert_week2string(week, w.real.dmin, w.real.dmax)});
				}
				// Fermeture du calendrier
				This.hide();
			};
		
		// =======================================================================
		// CREATION ==============================================================
		// =======================================================================
			// Creation : Fonction construisant les balises HTML du tableau du calendrier (vide) et de l'affichage en popup
			function create_inittags(){
				var c;
				var t;
				var i;
				var d;
				// Objet contenant les references des tags
				var o							= new Object();
				// Creation du tableau principal vide
					o.table						= Html.createNode("table", {id:"widgetcalendar_idtag_table"});
					// Creation de l'entete
					c 							= Html.createNode("thead", {id:"widgetcalendar_idtag_thead"});
					o.table.appendChild(c);
					t							= Html.createNode("tr", {id:"widgetcalendar_idtag_tr0"});
					c.appendChild(t);
					c							= t;
					// Creation de l'entete >> numero de semaine
					if(Data.numberweek){
						t						= Html.createNode("abbr", {title:String(Lang.week), id:"widgetcalendar_idtag_abbrweek"}, String(Lang.shortweek));
						t						= Html.createNode("th", {className:Data.css.ceilweek, id:"widgetcalendar_idtag_thweek"}, t);
						c.appendChild(t);
					}
					// Creation de l'entete >> jour (lundi au vendredi)
					for(i = 1; i < 6; i++){
						t						= Html.createNode("abbr", {title:String(Lang.days[i]), id:"widgetcalendar_idtag_abbr" + i}, String(Lang.shortdays[i]));
						t						= Html.createNode("th", {id:"widgetcalendar_idtag_th" + i}, t);
						c.appendChild(t);
					}
					// Creation de l'entete >> jour (week end)
					t							= Html.createNode("abbr", {title:String(Lang.days[6]), id:"widgetcalendar_idtag_abbr6"}, String(Lang.shortdays[6]));
					t							= Html.createNode("th", t, {className:Data.css.ceilwkend, id:"widgetcalendar_idtag_th6"});
					c.appendChild(t);
					t							= Html.createNode("abbr", {title:String(Lang.days[0]), id:"widgetcalendar_idtag_abbr0"}, String(Lang.shortdays[0]));
					t							= Html.createNode("th", t, {className:Data.css.ceilwkend, id:"widgetcalendar_idtag_th0"});
					c.appendChild(t);			
					// Creation du corps
					c 							= Html.createNode("tbody", {id:"widgetcalendar_idtag_tbody"});
					o.table.appendChild(c);
					o.ceils						= new Array();
					for(i = 0; i < 6; i++){
						d						= new Object();
						// Creation de la rangee
						d.tr					= Html.createNode("tr", {id:"widgetcalendar_idtag_tr" + i});
						c.appendChild(d.tr);
						// Creation de la cellule reprenant le numero de la semaine
						d.tdweek				= Html.createNode("td", {className:Data.css.ceilweek, id:"widgetcalendar_idtag_tr" + i + "tdweek"});
						if(Data.numberweek) d.tr.appendChild(d.tdweek);
						// Creation des cellules des jours
						d.tddays				= new Array();
						for(j = 0; j < 7; j++){
							t					= Html.createNode("td", {className:Data.css.ceilday, id:"widgetcalendar_idtag_tr" + i + "td" + j});
							d.tddays.push(t);
							d.tr.appendChild(t);
						}
						// Ajout des styles pour le week end
						d.tddays[0].className	= Data.css.ceilwkend;
						d.tddays[6].className	= Data.css.ceilwkend;
						// Deplacement de la cellule de dimanche a la fin de la rangee
						d.tr.removeChild(d.tddays[0]);
						d.tr.appendChild(d.tddays[0]);
						// Ajout de la rangee dans la liste des balises
						o.ceils.push(d);
					}
				// Creation des balises utiles pour le pop up si demande
				if(Data.popup){
					// Creation des blocs principaux
					o.popup						= Html.createNode("div", {className:Data.css.popup});
					o.shadow					= Html.createNode("div", {className:Data.css.shadow});
					o.popup.appendChild(o.shadow);
					o.content					= Html.createNode("div", {className:(Data.modeweek)? Data.css.calendarweek : Data.css.calendarday, id:"widgetcalendar_idtag_cont"});
					o.popup.appendChild(o.content);
					// Creation de l'entete
						// Nom du mois affiche
						o.month					= Html.createNode("div", {className:Data.css.month, title:"", id:"widgetcalendar_idtag_month"}, " ");
						o.content.appendChild(o.month);
						// Liens de navigation
						o.linkprev				= Html.createNode("div", {className:Data.css.linkprev, id:"widgetcalendar_idtag_linkp"});
						o.content.appendChild(o.linkprev);
						o.linknext				= Html.createNode("div", {className:Data.css.linknext, id:"widgetcalendar_idtag_linkn"});
						o.content.appendChild(o.linknext);
					// Integration du tableau de contenu
					t							= Html.createNode("div", {className:Data.css.tableblock, id:"widgetcalendar_idtag_tableblock"}, o.table);
					o.content.appendChild(t);
					// Creation du pied de calendrier
					t							= Html.createNode("a", {href:"#calendarclose", id:"widgetcalendar_idtag_close"}, String(Lang.close));
					Html.addEvent(t, "click", function(){ This.hide(); }, true);
					t							= Html.createNode("div", {className:Data.css.close, id:"widgetcalendar_idtag_footer"}, t);
					o.content.appendChild(t);
					// Sauvegarde de la balise principale
					o.main						= o.popup;
				}else{
					// Sauvegarde de la balise principale
					o.main						= o.table;
				}
				// Validation de la creation de balises
				o.validate						= true;
				// Envoi du resultat
				return(o);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Creation : Fonction construisant les balises HTML du menu de navigation
			function create_navigation(month, year){
				if(Data.popup){
					var t;
					var m;
					var y;
					// Encodage du nom du mois en cours
					Tags.month.innerHTML= Lang.shortmonths[month -1] + " " + year;
					Tags.month.title	= Lang.months[month -1] + " " + year;
					// Recuperation des donnees de la date limite
					if(Data.dmin != null){
						m				= Data.dmin.month;
						y				= Data.dmin.year;
					}else{
						m				= null;
						y				= null;
					}
					// Bouton "annee precedente"
					t					= null;
					if(Data.dmin == null || (year == y +1 && month >= m) || (year > y +1)){
						t				= Html.createNode("span", {className:Data.css.linklabel, id:"widgetcalendar_idtag_spanyp"}, Lang.year_labelprev);
						t				= Html.createNode("a", {href:"calendar_yearprev", className:Data.css.linkyear, title:Lang.year_titleprev, id:"widgetcalendar_idtag_ayp"}, t);
						Html.addEvent(t, "click", function(){ This.change(0, -1); }, true);
						Tags.linkprev.appendChild(t);
					}
					// Bouton "mois precedent"
					t					= null;
					if(Data.dmin == null || (month > m || year > y)){
						t				= Html.createNode("span", {className:Data.css.linklabel, id:"widgetcalendar_idtag_spanmp"}, Lang.month_labelprev);
						t				= Html.createNode("a", {href:"calendar_monthprev", className:Data.css.linkmonth, title:Lang.month_titleprev, id:"widgetcalendar_idtag_amp"}, t);
						Html.addEvent(t, "click", function(){ This.change(-1, 0); }, true);
						Tags.linkprev.appendChild(t);
					}
					// Recuperation des donnees de la date limite
					if(Data.dmax != null){
						m				= Data.dmax.month;
						y				= Data.dmax.year;
					}else{
						m				= null;
						y				= null;
					}
					// Bouton "mois suivant"
					t					= null;
					if(Data.dmax == null || (month < m || year < y)){
						t				= Html.createNode("span", {className:Data.css.linklabel, id:"widgetcalendar_idtag_spanyn"}, Lang.month_labelnext);
						t				= Html.createNode("a", {href:"calendar_monthnext", className:Data.css.linkmonth, title:Lang.month_titlenext, id:"widgetcalendar_idtag_ayn"}, t);
						Html.addEvent(t, "click", function(){ This.change(1, 0); }, true);
						Tags.linknext.appendChild(t);
					}
					// Bouton "annee suivant"
					t					= null;
					if(Data.dmax == null || (year == y -1 &&  month <= m) || (year < y -1)){
						t				= Html.createNode("span", {className:Data.css.linklabel, id:"widgetcalendar_idtag_spanmn"}, Lang.year_labelnext);
						t				= Html.createNode("a", {href:"calendar_yearnext", className:Data.css.linkyear, title:Lang.year_titlenext, id:"widgetcalendar_idtag_amn"}, t);
						Html.addEvent(t, "click", function(){ This.change(0, 1); }, true);
						Tags.linknext.appendChild(t);
					}
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Creation : Fonction construisant les balises HTML de la cellule "jour"
			function create_day(textStart, day, textEnd){
				var s							= Html.createNode("span", {className:Data.css.hidden}, textStart);
				var e							= Html.createNode("span", {className:Data.css.hidden}, textEnd);
				var l							= Html.createNode("span", {id:"widgetcalendar_idtag_days" + day}, String(day));
					l							= Html.createNode("a", {href:"#calendarday", id:"widgetcalendar_idtag_daya" + day}, s, l, e);
				// Envoi du resultat
				return(l);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Creation : Fonction construisant les balises HTML de la cellule "numero de semaine"
			function create_numberweek(textStart, numberweek, textEnd){
				var s							= Html.createNode("span", {className:Data.css.hidden}, textStart);
				var e							= Html.createNode("span", {className:Data.css.hidden}, textEnd);
				var l							= Html.createNode("span", {id:"widgetcalendar_idtag_weeks" + numberweek}, String(numberweek));
				if(!Data.modeweek) 	l			= Html.createNode("span", {id:"widgetcalendar_idtag_weeka" + numberweek}, s, l, e);
				else				l			= Html.createNode("a", {href:"#calendarweek", id:"widgetcalendar_idtag_weeka" + numberweek}, s, l, e);
				// Envoi du resultat
				return(l);
			};
		
		// =======================================================================
		// REMPLISSAGE ===========================================================
		// =======================================================================
			// Remplissage : Fonction integrant les donnees correspondant au mois demande
			function fillingup(D){
				if(Current != null && Tags.validate){
					// Nettoyage du tableau
					fillingup_clear();
					// Identification des valeurs utiles pour l'affichage du mois
						// Recuperation du nombre de jours dans le mois
						var length					= get_daysbymonth(D.month, D.year);
						// Identification du numero de la premiere semaine
						var w						= 0;
						if(Data.numberweek) w = get_numberweek({day:1, month:D.month, year:D.year});
						// Identification du type d'annee -> la premiere semaine de l'annee comprend-t-elle le 1er janvier ?
						var firstwyear				= (w < 52);
						// Ciblage du premier jour du mois a afficher
						var dayMonth				= new Date(D.year, D.month -1, 1);
						// Identification du type d'annee -> la derniere semaine de l'annee comprend-t-elle le 31 decembre ?
						var lastwyear				= false;
						if(Data.numberweek && D.month == 12){
							var lastweek			= get_numberweek(D.year, D.month, 31);
							lastwyear				= (lastweek > w);
							// Calcul de la derniere semaine du mois a afficher
							lastweek				= (dayMonth.getDay() == 0)? 7 : dayMonth.getDay();
							if(!lastwyear) lastweek	= Math.ceil((31 + lastweek-1)/7) -1;
						}
					// Analyse du jour selectionne
					var selected					= 0;
					if(Current.dselect != null){
						if(!Data.modeweek){
							if(Current.dselect.month == D.month && Current.dselect.year == D.year) selected = Current.dselect.day;
						}else{
							if(Current.dselect.view.dmin.month == D.month && Current.dselect.view.dmin.year == D.year) selected = Current.dselect.view.dmin.day;
						}
					}
					// Sauvegarde de la date affichee
					Current.ddisplay				= {day:1, month:D.month, year:D.year};
					// Remplissage du tableau
					var i;
					var r							= 0;					// Ligne du tableau
					var c							= dayMonth.getDay();	// Cellule du tableau
					var h							= -1;					// Identification de la ligne en cours
					var n							= -1;					// Numero de la semaine
					for(i = 1; i <= length; i++){
						// Verification de la semaine (rangee) a traiter
						if(r < 6){
							// Ciblage de la cellule
							c						= (c >= 7)? 0 : c;
							// Ajout du numero de la semaine
							if(h != r){
								// Correction affichage (courcircuitage de la numerotation) : Gestion des annees ne finissant pas par le 31 decembre
								if(!lastwyear && r == lastweek){
									lastwyear		= true;
									w				= 1 - r;
								}
								// Integration des balises du numero de semaine
								h					= r;
								n					= w + r;
								fillingup_numberweek(n, D.month, D.year, r, (c == 1 && i == selected), i);
								// Correction affichage (retour a la numerotation normale) : Gestion des annees ne commencant pas par le 1 janvier
								if(!firstwyear){
									firstwyear		= true;
									w				= 0;
								}
							}
							// Integration des balises gerant le jour
							fillingup_day(i, n, D.month, D.year, r, c, length, (i == selected));
							// Modification des valeurs pour le jour suivant
							if(c == 0) r++;
							c++;
						}
					}
					// Ajout de la navigation
					create_navigation(D.month, D.year);
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Remplissage : Fonction vidant le tableau pre existant
			function fillingup_clear(){
				if(Tags.validate){
					// Nettoyage du menu de navigation
					if(Data.popup){
						Tags.month.innerHTML		= "";
						Tags.month.title			= "";
						Tags.linkprev.innerHTML		= "";
						Tags.linknext.innerHTML		= "";
					}
					// Nettoyage du tableau des jours
					var c;
					var m							= Tags.ceils.length;
					for(var i = 0; i < m; i++){
						c							= Tags.ceils[i];
						// Suppression de la classe de selection par semaine
						c.tr.className				= "";
						// Suppression du numero de semaine
						c.tdweek.innerHTML			= "<span id=\"widgetcalendar_idtag_weeks" + i + "\"></span>";
						// Suppression des jours
						for(var j = 0; j < 7; j++){
							c.tddays[j].innerHTML	= "<span id=\"widgetcalendar_idtag_days" + i + "" + j + "\"></span>";
							c.tddays[j].className	= Data.css.ceilday;
						}
						// Reinitialisation de la classe du week end
						c.tddays[6].className		= Data.css.ceilwkend;
						c.tddays[0].className		= Data.css.ceilwkend;
					}
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Remplissage : Fonction remplissant la cellule "jour" du tableau
			function fillingup_day(day, week, month, year, tr, td, daymax, selected, weekselect){
				if(Tags.validate){
					// Reference a la cellule parente
					var c							= Tags.ceils[tr].tddays[td];
						c.innerHTML					= "";
					// Creation du texte cache de selection
					var t							= "";
					if(selected && !Data.modeweek){
						t							+= " " + Lang.selected;
						c.className					+= " " + Data.css.ceilselected;
					}
					// Ajout de la ponctuation cachee
					t								+= (day >= daymax)? "." : ", ";
					// Creation du lien
					var l							= create_day(Lang.days[td] + " ", day, t);
					// Ajout de fonctionnalite au lien
					if(!Data.modeweek) 	Html.addEvent(l, "click", function(){ This.send_day(day, week, month, year); }, true);
					else				Html.addEvent(l, "click", function(){ This.send_week(day, week, month, year); }, true);
					Html.addEvent(l, "focus", 		function(){ This.hover(true, 	tr); }, true);
					Html.addEvent(l, "mouseover", 	function(){ This.hover(true, 	tr); }, true);
					Html.addEvent(l, "blur", 		function(){ This.hover(false, 	tr); }, true);
					Html.addEvent(l, "mouseout", 	function(){ This.hover(false, 	tr); }, true);
					// Integration dans la cellule
					c.appendChild(l);
				}
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Remplissage : Fonction remplissant la cellule "numero de semaine" du tableau
			function fillingup_numberweek(week, month, year, tr, selected, daymin){
				if(Tags.validate){
					// Reference a la cellule parente
					var c							= Tags.ceils[tr].tdweek;
						c.innerHTML					= "";
					// Creation du texte cache de selection
					var t							= ", ";
					if(Data.modeweek && selected){
						t							= " " + Lang.selected + ", ";
						Tags.ceils[tr].tr.className	= Data.css.rowselected;
					}
					// Creation du lien
					var l							= create_numberweek(Lang.week + " ", week, t);
					// Ajout de fonctionnalite au lien
					if(Data.modeweek){
						Html.addEvent(l, "click", 		function(){ This.send_week(daymin, week, month, year); }, true);
						Html.addEvent(l, "focus", 		function(){ This.hover(true, 	tr); }, true);
						Html.addEvent(l, "mouseover", 	function(){ This.hover(true, 	tr); }, true);
						Html.addEvent(l, "foblur", 		function(){ This.hover(false, 	tr); }, true);
						Html.addEvent(l, "mouseout", 	function(){ This.hover(false, 	tr); }, true);
					}
					// Integration dans la cellule
					c.appendChild(l);
				}
			};
			
		// =======================================================================
		// OUTILS ================================================================
		// =======================================================================
			// Outils : Fonction convertissant la date (jour) transmise en objet
			function convert_date2object(g){
				var s;
				// Analyse du type de donnees transmises
				if(g != null){
					if(typeof(g) == "object"){					// Objet de donnees
						if(!isNaN(Number(g.day)) && !isNaN(Number(g.month)) && !isNaN(Number(g.year))){		// >> Objet de donnees conforme
							s	= g;
						}else if(g.length == 3){															// >> Tableau de donnees [DD, MM, YYYY]
							s	= {day:Number(g[0]), month:Number(g[1]), year:Number(g[2])};
						}
					}else if(typeof(g) == "string"){			// Version textuelle
						// Recuperation de l'information
						s		= String(g).split(Data.format.day.separator);
						s		= (s.length == 3)? {day:Number(s[Data.format.day.day]), month:Number(s[Data.format.day.month]), year:Number(s[Data.format.day.year])} : null;
					}else{
						s		= null;
					}
					// Ajout de la reference de la semaine
					if(s != null) s.week	= 0;
				}else 	s		= null;
				// Envoi du resultat
				return(s);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction convertissant la date (jour) transmise en texte
			function convert_date2string(day, month, year){
				// Reformatage de la date
				var a							= new Array(3);
					a[Data.format.day.day]		= (String(day).length 	< 2)? "0" + day 	: day;
					a[Data.format.day.month]	= (String(month).length < 2)? "0" + month 	: month;
					a[Data.format.day.year]		= year;
				// Envoi du resultat
				return(a.join(Data.format.day.separator));
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction convertissant la date (semaine) transmise en texte
			function convert_week2string(week, datestart, dateend){
				// Reformatage de la date
				var a								= new Array(7);
					a[0]							= Data.format.week.text0;
					a[2]							= Data.format.week.text1;
					a[4]							= Data.format.week.text2;
					a[6]							= Data.format.week.text3;
					a[Data.format.week.week*2 +1]	= week;
					a[Data.format.week.start*2 +1]	= convert_date2string(datestart.day, datestart.month, datestart.year);
					a[Data.format.week.end*2 +1]	= convert_date2string(dateend.day, dateend.month, dateend.year);
				// Envoi du resultat
				return(a.join(""));
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction verifiant que la date transmise est dans les limites autorisees
			function check_datelimit(g){
				var okmin				= false;
				var okmax				= false;
				if(Data.dmin == null)	okmin	= true;
				else 					okmin	= ((g.year > Data.dmin.year) || (g.year == Data.dmin.year && g.month >= Data.dmin.month));
				if(Data.dmax == null)	okmax	= true;
				else 					okmax	= ((g.year < Data.dmax.year) || (g.year == Data.dmax.year && g.month <= Data.dmax.month));
				// Envoi du resultat
				return((okmin && okmax));
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
			// Outils : Fonction identifiant si l'annee est bissextile ou non
			function is_leapyear(y){
				// Analyse de l'annee. Une annee est bissextile si elle est divisible par 4 mais pas par 100 sauf si elle est divisible par 400
				if((y%4 == 0 && y%100 != 0) || y%400 == 0){ return(true); }else{ return(false); }
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction envoyant le nombre de jour du mois designe
			function get_daysbymonth(month, year){
				// Recuperation du nombre de jours dans le mois
				var m					= Data.monthdays[month -1];
				// Identification du type "bissextile" de l'annee
				if(month == 2 && is_leapyear(year)) m = 29;
				// Envoi du resultat
				return(m);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction envoyant la date actuelle au bon format
			function get_today(){
				var d					= new Date();
				// Envoi du resultat
				return({day:(d.getDay() +1), month:(d.getMonth() +1), year:d.getFullYear()});
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction envoyant la date (jour) valide apres analyse : conformite et limite
			function get_validateday(v){
				// Convertion de la date au bon format
				v								= convert_date2object(v);
				// Verification que la date n'est pas hors des limites autorisees
				if(v != null) v 				= (check_datelimit(v))? v : null;
				// Sauvegarde de la date choisie si elle existe
				var s							= v;
				// Assignation de la date (mois et annee) actuelle si elle n'est pas definie
				if(v == null){
					v							= get_today();
					if(!check_datelimit(v)) v	= Data.dmax;
				}
				// Envoi du resultat
				return({selected:s, display:{day:0, week:0, month:v.month, year:v.year}});
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction envoyant la date (semaine) valide apres analyse : conformite et limite
			function get_validateweek(v){
				var s						= null;
				// Analyse du format de date envoyee
				if(typeof(v) == "string"){
					// Verification de la conformite du format par rapport au format linguistique
					var i					= new Array();
					i[0]					= v.indexOf(Data.format.week.text0);
					i[1]					= v.indexOf(Data.format.week.text1, i[0] + Data.format.week.text0.length);
					i[2]					= v.indexOf(Data.format.week.text2, i[1] + Data.format.week.text1.length);
					i[3]					= v.indexOf(Data.format.week.text3, i[2] + Data.format.week.text2.length);
					if(0 <= i[0] <= i[1] <= i[2] <= i[3]){
						// Recuperation d'une des dates
						v					= v.substring(i[Data.format.week.start] + Data.format.week["text" + Data.format.week.start].length, i[Data.format.week.start +1]);
					}else v					= null;
				}else v						= null;
				// Convertion et validation de la date obtenue
				v							= get_validateday(v);
				// Calcul de la semaine selectionnee si le jour demande est correct
				if(v.selected != null) s	= get_limitweek(v.selected);
				// Envoi du resultat
				return({selected:s, display:v.display});
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction envoyant la date actuelle au bon format
			function get_numberweek(d){
				var nw						= -1;
				if(!isNaN(d.day) && !isNaN(d.month) && !isNaN(d.year)){
					// Fonction calculant theoriquement le numero de la semaine
					function getWeek(day){
						// Calcul du nombre de jour total entre le 1 janvier et le jour demande
							var days									= 0;
							// Ajout des jours des mois passes
							for(var i = 1; i < day.month; i++){	days	+= get_daysbymonth(i, day.year);	}
							// Ajout du nombre de jours d'ecart entre le premier du mois et le jour demande
							days										+= day.day;
						// Analyse de la position du premier janvier dans la semaine
							var newyear									= 0;
							// Recuperation du numero du jour du premier janvier
							var date									= new Date(day.year, 0, 1);
							newyear										= date.getDay();
							// Correction de la valeur dimanche (0 >> 7)
							if(newyear == 0) newyear					= 7;
						// Calcul du nombre de semaines	
							// Calcul du nombre de jours de la premiere semaine
							days										-= (8 - newyear);
							// Initialisation du compteur de semaine
							var weeks									= 1;
							// Calcul du nombre de semaines completes
							weeks										+= Math.floor(days/7);
							// Ajout de la semaine en cours si elle est entammee
							if(days%7 != 0) weeks++;
						// Envoi du resultat
						return(weeks);
					}
					// - - - - - - - - - - - - - - - -
					// Calcul theorique du numero de semaine du jour demande
					nw						= getWeek(d);
					// Recuperation de la position du premier janvier dans l'annee demandee
					var firstday			= new Date(d.year, 0, 1);
					firstday				= firstday.getDay();
					// Correction du numero de la semaine si le premier janvier est au dela de jeudi
					if(firstday == 0 || firstday > 4) nw--;
					// Verification du numero de la semaine si le mois demande est janvier 
					if(d.month == 1 && nw <= 0){
						// Identification de la position du 1er janvier precedent
						firstday			= new Date(d.year -1, 0, 1);
						firstday			= firstday.getDay();
						// Calcul du nombre de semaine
						nw					= (firstday == 4 || (is_leapyear(d.year -1) && firstday == 3))? 53 : 52;
					// Verification du numero de la semaine si le mois demande est decembre 
					}else if(d.month == 12){
						// Identification de la position du dernier jour du mois
						firstday			= new Date(d.year, 11, 31);
						firstday			= firstday.getDay();
						// Analyse de la longueur de la semaine : a-t-elle les 4 jours indispensables pour pouvoir etre comptabilisee
						if(firstday > 0 && firstday < 4){
							// Recherche du numero du lundi de cette semaine
							firstday		= 31 - (firstday -1);
							// Correction du numero de la semaine si le jour demande se trouve dans cette semaine
							if(d.day >= firstday && d.day <= 31) nw = 1;
						}
					}
				}
				// Envoi du numero de la semaine
				return(nw);
			};
			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
			// Outils : Fonction envoyant les dates (debut/fin) de la semaine englobant la date
			function get_limitweek(v){
				var s						= new Object();
				var d						= new Object();
				// Recuperation de la position du jour dans la semaine
				var r						= new Date(v.year, v.month -1, v.day);
				var c						= r.getDay();
				// Recherche de la date debutant la semaine
					var n					= (c == 0)? 6 : c -1;
					// Recuperation de la date effective
					if(v.day - n > 0){
						s.dmin				= {day:v.day - n, month:v.month, year:v.year};
					}else if(v.month -1 > 0){
						s.dmin				= {day:get_daysbymonth(v.month -1, v.year) + v.day - n, month:v.month -1, year:v.year};
					}else{
						s.dmin				= {day:get_daysbymonth(12, v.year) + v.day - n, month:12, year:v.year -1};
					}
					// Recuperation de la date minimale affichee
					d.dmin					= {day:Math.max(1, v.day - n), month:v.month, year:v.year};
				// Recherche de la date finissant la semaine
					n						= (c == 0)? c : 7 - c;
					// Recuperation de la date effective
					if(v.day + n < get_daysbymonth(v.month, v.year)){
						s.dmax				= {day:v.day + n, month:v.month, year:v.year};
					}else if(v.month +1 < 12){
						s.dmax				= {day:v.day - get_daysbymonth(v.month, v.year) + n, month:v.month +1, year:v.year};
					}else{
						s.dmax				= {day:v.day - get_daysbymonth(1, v.year +1) + n, month:1, year:v.year +1};
					}
					// Recuperation de la date minimale affichee
					d.dmax					= {day:Math.min(get_daysbymonth(v.month, v.year), v.day + n), month:v.month, year:v.year};
				// Envoi des dates
				return({real:s, view:d});
			};
	};
	
