/* auteur: Bernard Martin-Rabaud */

/* Date de création: 18/12/2003 */



/***********************************************************************************************************/

/*                                             CALENDRIER EN JAVASCRIPT                                    */

/***********************************************************************************************************/

var duree_jour = 24 * 60 * 60 * 1000;
var inputDateName = "" ;

date_jour = dateAMidi();
feries = null;


function cliquerOuPas(e) {
	
	if (document.all) { // Need to hard-code this to trap IE for error-handling
			var t = window.event.srcElement;
			while (t.parentElement != null) {
				if (t.id=="moui") {
					return true;
					}
				t = t.parentElement;
				}
			return false;
	}
	else
	{ // on suppose Gecko
		var t = e.originalTarget;
		while (t.parentNode != null) 
		{
			if (t.id=="moui") 
			{
				return true;
			}
			t = t.parentNode;
		}
		return false;
	}
	return false;
}

function ecrire() {

	// affiche le mois concernant la date demandée (en argument, facultative)

	this.joursFeries();
		
	html = "<DIV id='moui' style='position:absolute;VISIBILITY:hidden;'>" ;

	html += "<table id='calendrier' cellspacing='0' cellpadding='0' border='1' summary='calendrier'>";

	html += "<tr><td>";

	html += "<table id='calendrier-haut' cellspacing='0' cellpadding='0' border='0' summary='mois et année du calendrier'>";

	html += this.afficherEntete();

	html += "</table>";

	html += "</td></tr>";

	html += "<tr><td>";

	html += "<table id='calendrier-jours' cellspacing='0' cellpadding='0' border='0' summary='jour du mois'>";

	html += "</table>";

	html += "</td></tr>";

	html += "</table>";
	
	html += "</div>" ;

	document.write(html);
	
	document.onmouseup = check2HideCalendar ;
	
	this.afficherJoursSemaine();
  this.afficherJoursMois();

}

function check2HideCalendar(e) {
	if (!cliquerOuPas(e)) kill();
}

function afficher(elName,iDN) {
	this.inputDateName = iDN ;
	var el = document.getElementById(elName) ;
	var x = 0;
	var w = el.style.width ;	
	
	do { x += el.offsetLeft ; } while(el=el.offsetParent) ;
	el = document.getElementById(elName) ;
	var y = 0;	
	do { y += el.offsetTop ; } while(el=el.offsetParent) ;
	
	document.getElementById("moui").style.left = x + 50 ;
	document.getElementById("moui").style.top = y ;
	document.getElementById("moui").style.visibility = "visible" ;
	//document.getElementById("moui1").style.visibility = "visible" ;
}

function joursFeries() {

	// indique les jours fériés en fonction de l'année du calendrier

	var feries = this.date_jour.joursFeriesMobiles();

	this.feries = "|" + feries.join("|") + "|";

}



function afficherEntete() {

	// affiche le mois (en lettres) et l'année avec des flèches pour les incrémenter ou les décrémenter

	// affichage de 2 flèches prec 

	var html = "<tr><td class='calendrier-fleche'>";

	html += "<a href='javascript:anneePrecedente()' title='année précédente'><font color='#000000'>&lt;&lt;</font></a>";

	html += "</td>";

	html += "<td class='calendrier-fleche'>";

	html += "<a href='javascript:moisPrecedent()' title='mois précédent'><font color='#000000'>&lt;</font></a>";

	// affichage du mois avec son id qui permettra de modifier le contenu du <td>

	html += "<td id='calendrier-mois-an'>" + this.date_jour.moisLitteral() + " " + this.date_jour.getFullYear() + "</td>";

	// affichage de 2 flèches suiv 

	html += "</td>";

	html += "<td class='calendrier-fleche'>";

	html += "<a href='javascript:moisSuivant()' title='mois suivant'><font color='#000000'>&gt;</font></a>";

	html += "</td>";

	html += "<td class='calendrier-fleche'>";

	html += "<a href='javascript:anneeSuivante()' title='année suivante'><font color='#000000'>&gt;&gt;</font></a>";

	html += "</td></tr>";

	return html;

}



function afficherJoursSemaine() {

	// affiche les jours de la semaine sur une ligne

	var jours_sem = new Array("lun", "mar", "mer", "jeu", "ven", "sam", "dim");
	
	var racine = document.getElementById("calendrier-jours");
	var tTbody = racine.firstChild ;
	
	//Gecko don't append a tbody on a empty table. So firstChild is null.
	if (tTbody != null) racine.removeChild(tTbody);	
	tTbody = document.createElement("TBODY");
	racine.appendChild(tTbody);
	tTr = document.createElement("TR") ;
	tTbody.appendChild(tTr);

	for (var i=0;i<jours_sem.length;i++) {

		tTd = document.createElement("TD") ;
		if (i < 5)
		{
			tTd.className ='calendrier-sem' ;
			noeud_txt = document.createTextNode(jours_sem[i]);
			tTd.appendChild(noeud_txt);
		}
		else
		{
			tTd.className = 'calendrier-fin-sem';
			noeud_txt = document.createTextNode(jours_sem[i]);
			tTd.appendChild(noeud_txt);
		}
		tTr.appendChild(tTd);
	}
}



function afficherJoursMois() {

	// affiche les jours du mois en fonction du mois et de l'année en cours

	// limites indique le début et la fin des jours visibles dans le calendrier

	// de façon à ce que le calendrier contienne le 1er du mois sur la 1ère ligne

	var limites = this.limitesMoisCalendrier();

	var jour = limites[0];

	var auj = dateAMidi();

	var col = 0;

	var ligne = 0;

	var racine = document.getElementById("calendrier-jours").firstChild ;
	tTr = document.createElement("TR");
	racine.appendChild(tTr);
	
	while (jour <= limites[1]) {
		if (col == 7) {
			tTr = document.createElement("TR");
			racine.appendChild(tTr);
			col = 0;
			ligne++;
		}

		tTd = document.createElement("TD");
		
		if (jour.memeJour(auj))
		{			
			tTd.className = 'calendrier-jour-auj' ;
		}
		else if (jour.dansLeMois(this.date_jour))
		{ 
			if (col < 5) tTd.className = 'calendrier-jour' ;
			else tTd.className = 'calendrier-jour-we';
		}
		else tTd.className = 'calendrier-jour-horsmois' ;
		
		var j = jour.getDate() ;
		if (j<10) j = "0"+j ;
		var m = (jour.getMonth()+1) ;
		if (m<10) m = "0"+m ;
		tLink = document.createElement("A");
		tHref = "javascript:write2form(\"" + j + "/"+ m + "/" + jour.getFullYear() + "\"); kill();"
		tLink.setAttribute("href",tHref);
		tText = document.createTextNode(jour.getDate());
		tLink.appendChild(tText);
		tTd.appendChild(tLink);
		tTr.appendChild(tTd);
		jour.jourSuivant();
		col++;
	}


	while (ligne < 5)
	{
		tTr = document.createElement("TR");
		racine.appendChild(tTr);

		for (col=0;col<7;col++)
		{
			tTd = document.createElement("TD");
			tText = document.createTextNode("&nbsp;");
			tTd.appendChild(tText);
			ligne++;
		}
	}		

	return html;

}



function limitesMoisCalendrier() {

	// détermine les limites du calendrier relatif au mois de la date en cours, de telle façon à ce que le 1er du mois

	// soit sur la 1ère ligne, que le dernier du mois sur la dernière ligne, 

	// et que le début du calendrier commence un lundi et la fin finisse un dimanche

	

	// on cherche la date du début du calendrier	
	var jour = new Date(this.date_jour.getTime());

	jour.debutMois(); // date du 1er du mois

	var jour_semaine = jour.getDay();

	jour_semaine = jour_semaine ? jour_semaine - 1 : 6;

	var debut_cal = new Date();

	debut_cal.setTime(jour.getTime() - jour_semaine * duree_jour);

	// puis la date de la fin du calendrier

	jour.finMois(); 

	jour_semaine = jour.getDay();

	jour_semaine = jour_semaine ? jour_semaine - 1 : 6;

	var fin_cal = new Date();

	fin_cal.setTime(jour.getTime() + (6 - jour_semaine)  * duree_jour);
	//alert("debut_cal="+debut_cal.getDate()+" && fin_cal="+fin_cal.getDate());
	

	var limites = new Array(debut_cal, fin_cal);

	return limites;

}



function moisSuivant() {

	// fait passer le calendrier au mois suivant

	// il faut modifier le jour courant du calendrier,

	// puis modifier le mois et éventuellement l'année en haut du calendrier

	// et les jours, tout ça via la structure du DOM

	this.date_jour.moisSuivant();

	this.joursFeries();

	this.majEntete();

	this.majJoursMois();

}



function moisPrecedent() {

	// fait passer le calendrier au mois suivant

	// il faut modifier le jour courant du calendrier,

	// puis modifier le mois et éventuellement l'année en haut du calendrier

	// et les jours, tout ça via la structure du DOM

	this.date_jour.moisPrecedent();

	this.joursFeries();

	this.majEntete();

	this.majJoursMois();

}



function anneeSuivante() {

	// fait passer le calendrier au mois suivant

	// il faut modifier le jour courant du calendrier,

	// puis modifier le mois et éventuellement l'année en haut du calendrier

	// et les jours, tout ça via la structure du DOM

	this.date_jour.anneeSuivante();

	this.joursFeries();

	this.majEntete();

	this.majJoursMois();

}



function anneePrecedente() {

	// fait passer le calendrier au mois suivant

	// il faut modifier le jour courant du calendrier,

	// puis modifier le mois et éventuellement l'année en haut du calendrier

	// et les jours, tout ça via la structure du DOM

	this.date_jour.anneePrecedente();

	this.majEntete();

	this.majJoursMois();

}



function majEntete() {

	// met à jour le mois et l'année en-tête du calendrier

	document.getElementById("calendrier-mois-an").lastChild.nodeValue = this.date_jour.moisLitteral() + " " + this.date_jour.getFullYear();

}



function majJoursMois() {
	// met à jour les jours du mois
  afficherJoursSemaine();
  afficherJoursMois();  
}



function estFerie(jour) {

	// détermine si un jour est férié (rajouter la date de Pâques plus tard)

	var ch_date = rajoute0(jour.getDate()) + "/" + rajoute0(jour.getMonth()+1);

 	if (this.feries.indexOf("|" + ch_date + "|") == -1) return false;

 	else return true;

}





// FONCTIONS UTILITAIRES





Date.prototype.dansLeMois = function(date_ref) {

	// indique si la date en cours et date_ref sont du même mois et de la même année

	if ((this.getMonth() == date_ref.getMonth()) && (this.getFullYear() == date_ref.getFullYear()))

		return true;

	else return false;

}



Date.prototype.jourSuivant = function() {

	// incrémente le jour de la date en fonction du nombre de jours en argument (si pas d'argument, l'incrément = 1)

	// p. ex. var jour = new Date(2004, 0, 1) (soit 01/01/2004), jour.jourSuivant() donnera le 02/01/2004

	// et jour.jourSuivant(31) donnera le 01/02/2004

	if (arguments.length) var increment = parseInt(arguments[0]);

	else var increment = 1;

	this.setDate(this.getDate() + increment);

}



Date.prototype.moisSuivant = function() {

	// passe le jour au mois suivant

	if (this.getMonth() < 11) this.setMonth(this.getMonth() + 1);

	else {

   		this.setMonth(0);

   		this.setFullYear(this.getFullYear() + 1);

 	}

}



Date.prototype.moisPrecedent = function() {

	// passe le jour au mois précédent

	if (this.getMonth()) this.setMonth(this.getMonth() - 1);

	else {

   		this.setMonth(11);

   		this.setFullYear(this.getFullYear() - 1);

 	}

}



Date.prototype.anneeSuivante = function() {

	// passe le jour à l'année suivante

	this.setFullYear(this.getFullYear() + 1);

}



Date.prototype.anneePrecedente = function() {

	// passe le jour à l'année précédente

	this.setFullYear(this.getFullYear() - 1);

}



Date.prototype.debutMois = function() {

	// met la date en cours au premier du mois

	this.setTime(this.getTime() - (this.getDate() - 1) * duree_jour); 

}



Date.prototype.finMois = function() {

	// met la date en cours à la fin du mois

	this.moisSuivant();

 	this.setDate(1);

 	this.setTime(this.getTime() - duree_jour);

}



Date.prototype.memeJour = function(une_date) {

	// si la date courante est le même jour que une_date, retourne "true", sinon retourne "false"

	var diff = Math.abs(this.getTime() - une_date.getTime());

	if (diff < 60*60*1000) return true;

	else return false;

}



Date.prototype.moisLitteral = function() {

	var nom_mois = new Array("janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre");

	return nom_mois[this.getMonth()];

}



Date.prototype.joursFeriesMobiles = function() {

	// ajoute aux jours fériés fixes les jours fériés mobiles : lundi de Pâques, Ascension et lundi de Pentecôte

	var jours_feries = new Array("01/01", "01/05", "14/07", "15/08", "01/11", "11/11", "25/12");

	var jour = paques(this.getFullYear());

	// lundi de Pâques

	jour.jourSuivant();

	jours_feries.splice(1, 0, jour.afficherJourMois());

	// ascension

	jour.jourSuivant(38);

	if (jour.getMonth() > 3) jours_feries.splice(3, 0, jour.afficherJourMois());

	else jours_feries.splice(2, 0, jour.afficherJourMois());

	// lundi de Pentecôte

	jour.jourSuivant(11);

	jours_feries.splice(4, 0, jour.afficherJourMois());

	return jours_feries;

}

	

Date.prototype.afficherJourMois = function() {

	return rajoute0(this.getDate()) + "/" + rajoute0(eval(this.getMonth() + 1));

}



function dateAMidi() {

	// crée une date à midi (12h 0mn 0sec)

	if (arguments.length) ladate = arguments[0];

	else ladate = new Date();

	ladate.setHours(12);

	ladate.setMinutes(0);

	ladate.setSeconds(0);

	return ladate;

}

	

function rajoute0(valeur) {

	return (valeur < 10) ? "0" + valeur : valeur;

}



function paques(annee) {

    // retourne une date Javascript, qui est la date de Pâques en fonction de l'année

    annee = parseInt(annee);

    var date_paques = null;

    var b = annee - 1900;

    var c = annee % 19;

    var d = Math.floor((7*c+1)/19);

    var e = (11*c+4-d) % 29;

    var f = Math.floor(b/4);

    var g = (b+f+31-e) % 7;

    var avril = 25-e-g;

    if (avril > 0) date_paques = new Date(annee, 3, avril);

    else date_paques = new Date(annee, 2, avril + 31);

    return date_paques;

}

function kill() {
	document.getElementById("moui").style.visibility = "hidden" ;
	//document.getElementById("moui1").style.visibility = "hidden" ;
}

function write2form(date2write) {
	document.getElementById(this.inputDateName).value = date2write ;
}

ecrire();