// Version 2.04 4/3/09: Ajout gestion option debug

if(window.XMLHttpRequest)
	xhr_object = new XMLHttpRequest();
else
	if(window.ActiveXObject)
		var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
//	else
//		document.location = "http://syrte.obspm.fr/gen/heure_op_js";

chaine_dtrajet = null;
chaine_offset = null;
dtrajet_moyen = 0; // Temps trajet entre serveur et poste client (en ms)
offset_moyen = 0; // Offset moyen entre UTC poste client et heure UTC serveur (en ms)
tz_local = 0; // Difference UTC - poste client (en secondes) 
tz_France = 0; // Difference UTC - France (en secondes, fourni par le serveur)

var heure_UTC;





interval_sync = 180; // Synchro toutes les 180s
sync_OK = false;
str_h_sync = " "; // Heure derniere synchro
sync_en_cours = 0; // =1 si phase de synchro en cours

interval_affich = 150; // Temps entre maj affichage en ms
erreurs_ref_max = 10; // Nbr erreurs acceptees avant de relancer une synchro
nb_max_interval = 15; // Nbr d'interval avant RAZ du controle
h_ref_ctrl = 0; // Date prise comme ref pour controle chgt heure poste client
nb_interval_ctrl = 0; // Comptage interval lors controle
nb_erreurs_ref = 0;  // Comptage erreurs lors controle
h_force_sync = 0; // Prochaine heure ou on force une synchro (leap second, DST)
debug = 0; // mode debug (appel via url ?debug=on)

// Les pointeurs vers les timers
tmo_gt1 = null;
tmo_gt2 = null;
tmo_gt3 = null;
tmo_gt4 = null;
tmo_gt5 = null;
tmo_gt6 = null;
tmo_mo = null;
tmo_ev = null;
tmo_af = null;
tmp_ho = null;

// Conversion calendriers
a_mois = new Array();
a_mois[0] = "Jan";
a_mois[1] = "Feb";
a_mois[2] = "Mar";
a_mois[3] = "Apr";
a_mois[4] = "May";
a_mois[5] = "Jun";
a_mois[6] = "Jul";
a_mois[7] = "Aug";
a_mois[8] = "Sep";
a_mois[9] = "Oct";
a_mois[10] = "Nov";
a_mois[11] = "Dec";

f_mois = new Array();
f_mois[0] = "janvier";
f_mois[1] = "f&eacute;vrier";
f_mois[2] = "mars";
f_mois[3] = "avril";
f_mois[4] = "mai";
f_mois[5] = "juin";
f_mois[6] = "juillet";
f_mois[7] = "ao&ucirc;t";
f_mois[8] = "septembre";
f_mois[9] = "octobre";
f_mois[10] = "novembre";
f_mois[11] = "d&eacute;cembre";

a_jour = new Array();
a_jour[0] = "Sun,";
a_jour[1] = "Mon,";
a_jour[2] = "Tue,";
a_jour[3] = "Wed,";
a_jour[4] = "Thu,";
a_jour[5] = "Fri,";
a_jour[6] = "Sat,";

f_jour = new Array();
f_jour[0] = "Dimanche";
f_jour[1] = "Lundi";
f_jour[2] = "Mardi";
f_jour[3] = "Mercredi";
f_jour[4] = "Jeudi";
f_jour[5] = "Vendredi";
f_jour[6] = "Samedi";


Array.prototype.indexOf = function(value)
// Recherche chaine dans tableau de chaines
    {
    var t = this;
    for (var i = 0 ; i < t.length ; i++)
            if (t[i] == value )
                return i;
    return -1;
}

function AffCacheDiv( nom )
// Affiche ou cache une section 'div'
{
	var divID = nom;
	if ( document.getElementById && document.getElementById( divID ) ) // Pour les navigateurs recents
	{
		Pdiv = document.getElementById( divID );
		Pdiv.className = ( Pdiv.className == 'cachediv' ) ? '' : 'cachediv';
	}
	else if ( document.all && document.all[ divID ] ) // Pour les vieilles versions
	{
		Pdiv = document.all[ divID ];
		Pdiv.className = ( Pdiv.className == 'cachediv' ) ? '' : 'cachediv';
	}
}

function processRequest()
// Appelee par srv_gettime: evalue le temps de trajet, recupere l'heure + TZ du serveur et sauvegarde
{
	if ( debug == true )
	{
		document.getElementById("DBG_02").innerHTML = document.getElementById("DBG_02").innerHTML
		                                              + "#" + xhr_object.readyState
		                                              + "-" + xhr_object.status;
	}
	if(xhr_object.readyState == 4 && xhr_object.status == 200)
	{
		var date = new Date();
		var t_final = date.getTime();
		tz_local = date.getTimezoneOffset() * 60;
        	var t_finalUTC = date.getTime();
		var reponse = xhr_object.responseText;
		var tabreponse = reponse.split(" ");
		if ( debug == true )
		{
			document.getElementById("DBG_03").innerHTML = document.getElementById("DBG_03").innerHTML
			                                             + "#" + reponse;
		}
		var t_initialUTC = parseInt(tabreponse[0]);
		var t_serveurUTC = parseInt(tabreponse[1]);
		tz_France = parseInt(tabreponse[2]);
		h_force_sync = parseInt(tabreponse[3]);
		heure_UTC=tz_France/(-3600);
		
		var dtrajet = parseInt( Math.round(t_finalUTC - t_initialUTC) / 2 );
		var offset = t_serveurUTC - t_initialUTC - dtrajet; // negatif: avance H locale
		// Sauvegarder les 2 mesures dans des chaines de caracteres (pour moyennage ulterieur)
		if(chaine_dtrajet == null)
		{
			chaine_dtrajet = dtrajet;
			chaine_offset = offset;
		}
		else
		{
			chaine_dtrajet = chaine_dtrajet + "#" + dtrajet;
			chaine_offset = chaine_offset + "#" + offset;
		}
		if ( debug == true )
		{
			document.getElementById("DBG_04").innerHTML = chaine_dtrajet;
			document.getElementById("DBG_05").innerHTML = chaine_offset;
		}
	}
}

function srv_gettime()
// Effectue une requete http sur le serveur pour evaluer le temps de trajet et recuperer l'heure + TZ du serveur
{
        var date = new Date();
        var t_startUTC = date.getTime();
        url_time = "/gen/gettime.php?timer=" + t_startUTC;
	xhr_object.open("GET",url_time,true);
	xhr_object.setRequestHeader("Cache-Control","no-store,no-cache,must-revalidate");
	xhr_object.onreadystatechange=processRequest;
	xhr_object.send(null);
	if ( debug == true ) document.getElementById("DBG_01").innerHTML = document.getElementById("DBG_01").innerHTML + "#" + t_startUTC;
}

function moyenne_dtrajet()
// Moyennage du temps de trajet et de l'offset avec les mesures faites
{
	// calcul temps de trajet avec elements tableau
	if ( chaine_dtrajet != null )
	{
		// calcul delai trajet moyen avec elements tableau
		var tab_dtrajet = chaine_dtrajet.split("#");
		var nb_elements = tab_dtrajet.length;
		var sum = 0;
		for(var i = 0; i < nb_elements; i++)
		{
			sum = sum + parseInt(tab_dtrajet[i]);
		}
		dtrajet_moyen = sum/nb_elements;
		// calcul offset moyen avec elements tableau
		var tab_offset = chaine_offset.split("#");
		var nb_elements = tab_offset.length;
		var sum = 0;
		for(var i = 0; i < nb_elements; i++)
		{
			sum = sum + parseInt(tab_offset[i]);
		}
		offset_moyen = sum / nb_elements;
		sync_OK = true;
		document.getElementById("T_sync").innerHTML  = " ";
	}
	sync_en_cours = 0;
}

function check2Digits(i)
// Utilisee pour changer l'affichage de 9:8:5 a 09:08:05
{
	if (i<10)
	{
		i="0" + i;
	}
	return i;
}

function check1Digits(i)
// Utilisee pour changer l'affichage de la date de 03 mars en 3 mars
{
	if (i.substring(0,1) == "0")
	{
		i = i.substring(1,2);
	}
	return i;
}

function affichage()
// Mise a jour de l'affichage de la page web
{
	// Heure du client
	var str_h_locale = new Date();
	var h_locale = str_h_locale.getTime();
	tz_local = str_h_locale.getTimezoneOffset() * 60; // Recalculee a chaque affichage (chgt du client?)

	// Heure corrigee du client
	var h_corr = h_locale + offset_moyen;
	var str_h_corr = new Date ( h_corr );

	// Force une synchro si près d'un saut de seconde ou passage ete/hiver - hiver/ete
	if ( Math.abs (h_force_sync - h_corr) < 500 )
	{
		h_ref_ctrl = 0;
		clearTimeout( tmo_ev );
		clearTimeout( tmo_af );
		sync_OK = false;
		tmo_ho = setTimeout ("horloge()",1100);
	}

	// Heure Francaise (pseudo-heure UTC decalee selon TZ)
	var tempDate = new Date();
	var str_h_France;
	var h_France = h_corr - (tz_France * 1000);
	tempDate.setTime( h_France );
	str_h_France=tempDate.toUTCString();
	// La date ressort sous la forme 'Thu, 27 Nov 2008 13:19:40 GMT' mais ce n'est pas GMT/UTC mais l'heure francaise!!
	var elem = str_h_France.split(' ');
	var elem2 = elem[4].split(':'); // Split de 13:19:40
	var tmp_JS_France = elem[0];
	var tmp_J_France = elem[1];
	var tmp_M_France = elem[2];
	var tmp_A_France = elem[3];
	var tmp_HH_France = elem2[0];
	var tmp_MM_France = elem2[1];
	var tmp_SS_France = elem2[2]; 
	// Conversion 'Thu,' en jour de la semaine en francais
	tmp_JS_France = f_jour [ a_jour.indexOf( tmp_JS_France ) ];
	// Conversion 'Nov,' en jour du mois en francais
	tmp_M_France = f_mois [ a_mois.indexOf( tmp_M_France ) ];

	if ( sync_OK == true)
	{
		if (h_ref_ctrl!= 0)
		{
			nb_interval_ctrl++;
			if ( Math.abs( h_locale - h_ref_ctrl) > ( interval_affich * nb_interval_ctrl * 1.5) )
			{
				// Comptage des erreurs (heure actuelle trop differente de celle attendue) -> chgt heure du PC?
				nb_erreurs_ref++;
			}
			if ( nb_erreurs_ref > erreurs_ref_max )
			{
				// Si trop d'erreur de pas: on repart a zero
				h_ref_ctrl = 0;
				clearTimeout( tmo_ev );
				clearTimeout( tmo_af );
				tmo_ho = setTimeout ("horloge()",0);
			}
			if ( nb_interval_ctrl > nb_max_interval )
			{
				h_ref_ctrl = 0;
			}
		}
		else
		{
			// Pas encore d'heure de reference pour les tests
			h_ref_ctrl = h_locale;
			nb_interval_ctrl =  0;
			nb_erreurs_ref = 0;
		}

		// Mise a jour de l'affichage

		// Heure locale client
		//document.getElementById("JS_client").innerHTML = f_jour[str_h_locale.getDay()];
		//document.getElementById("J_client").innerHTML  = str_h_locale.getDate()
		//document.getElementById("M_client").innerHTML  = f_mois[str_h_locale.getMonth()];
		//document.getElementById("A_client").innerHTML  = str_h_locale.getFullYear();
		document.getElementById("HH_client").innerHTML = check2Digits(str_h_locale.getHours());
		document.getElementById("MM_client").innerHTML = check2Digits(str_h_locale.getMinutes());
		document.getElementById("SS_client").innerHTML = check2Digits(str_h_locale.getSeconds());
		// Heure UTC client (avant correction)
		document.getElementById("JS_UTC_client").innerHTML = f_jour[str_h_locale.getUTCDay()];
		document.getElementById("J_UTC_client").innerHTML  = str_h_locale.getUTCDate();
		document.getElementById("M_UTC_client").innerHTML  = f_mois[str_h_locale.getUTCMonth()];
		document.getElementById("A_UTC_client").innerHTML  = str_h_locale.getUTCFullYear();
		document.getElementById("HH_UTC_client").innerHTML = check2Digits(str_h_locale.getUTCHours());
		document.getElementById("MM_UTC_client").innerHTML = check2Digits(str_h_locale.getUTCMinutes());
		document.getElementById("SS_UTC_client").innerHTML = check2Digits(str_h_locale.getUTCSeconds());
		// Heure UTC corrigee selon serveur
		document.getElementById("JS_UTC").innerHTML = f_jour[str_h_corr.getUTCDay()];
		document.getElementById("J_UTC").innerHTML  = str_h_corr.getUTCDate();
		document.getElementById("M_UTC").innerHTML  = f_mois[str_h_corr.getUTCMonth()];
		document.getElementById("A_UTC").innerHTML  = str_h_corr.getUTCFullYear();
		document.getElementById("HH_UTC").innerHTML = check2Digits(str_h_corr.getUTCHours());
		document.getElementById("MM_UTC").innerHTML = check2Digits(str_h_corr.getUTCMinutes());
		document.getElementById("SS_UTC").innerHTML = check2Digits(str_h_corr.getUTCSeconds());
		// Heure Francaise
		
		//document.getElementById("JS_France").innerHTML = tmp_JS_France;
		//document.getElementById("J_France").innerHTML  = check1Digits(tmp_J_France);
		//document.getElementById("M_France").innerHTML  = tmp_M_France;
		//document.getElementById("A_France").innerHTML  = tmp_A_France;
		document.getElementById("HH_France").innerHTML = tmp_HH_France;
		document.getElementById("MM_France").innerHTML = tmp_MM_France;
		document.getElementById("SS_France").innerHTML = tmp_SS_France;
		document.getElementById("heure_UTC").innerHTML = "UTC+"+heure_UTC;
		
		// Infos techniques: offset et delai
		document.getElementById("AFF_offset").innerHTML  = Math.round ( offset_moyen) / 1000;
		document.getElementById("AFF_delai").innerHTML  = Math.round ( dtrajet_moyen * 10 ) / 10;
		// Retour des TZ en heures et minutes
		var hh = Math.floor(-tz_local/3600);
		var mm = (-tz_local - (hh * 3600)) / 60;
		document.getElementById("TZ_client").innerHTML = hh + "h" + check2Digits(mm);
		hh = Math.floor(-tz_France/3600);
		mm = (-tz_France - (hh * 3600)) / 60;
		document.getElementById("TZ_France").innerHTML = hh + "h" + check2Digits(mm);

		// Affichage delai avant prochaine synchro (sauf si synchro en cours)
		if ( sync_en_cours != 1 )
		{
			var delai_sync = Math.round ( interval_sync - ( h_locale - str_h_sync.getTime() ) / 1000 );
			document.getElementById("T_sync").innerHTML = "(synchro dans " + delai_sync + " s)";
		}
	}
}

function sync_horloge()
// Evaluation/synchro de l'horloge (temps A/R client-serveur)
{
	str_h_sync = new Date();
	sync_en_cours = 1;
	if ( debug == true )
	{
		document.getElementById("DBG_01").innerHTML = "";
		document.getElementById("DBG_02").innerHTML = "";
		document.getElementById("DBG_03").innerHTML = "";
		document.getElementById("DBG_04").innerHTML = "";
		document.getElementById("DBG_05").innerHTML = "";
	}
	document.getElementById("T_sync").innerHTML  = "(synchro en cours)";
	chaine_dtrajet = null;
	chaine_offset = null;
	// Quelques A/R entre client et serveur
	tmo_gt1 = setTimeout("srv_gettime()",0);
	tmo_gt2 = setTimeout("srv_gettime()",400);
	tmo_gt3 = setTimeout("srv_gettime()",800);
	tmo_gt4 = setTimeout("srv_gettime()",1200);
	// Calcul moyenne offset et temps de trajet
	tmo_mo = setTimeout("moyenne_dtrajet()",2000);
}

function horloge( h_param )
{

	if ( h_param == "D" )
	{
		debug = true;
	}
	else
	{
		debug = false;
	}


	// Affichage ?? avant evaluation/synchro de l'horloge
	//document.getElementById("JS_client").innerHTML = "??";
	document.getElementById("HH_client").innerHTML = "??";
	document.getElementById("MM_client").innerHTML = "??";
	document.getElementById("SS_client").innerHTML = "??";
	//document.getElementById("J_client").innerHTML  = "??";
	//document.getElementById("M_client").innerHTML  = "??";
	//document.getElementById("A_client").innerHTML  = "??";

	//document.getElementById("JS_UTC_client").innerHTML = "??";
	document.getElementById("HH_UTC_client").innerHTML = "??";
	document.getElementById("MM_UTC_client").innerHTML = "??";
	document.getElementById("SS_UTC_client").innerHTML = "??";
	//document.getElementById("J_UTC_client").innerHTML  = "??";
	//document.getElementById("M_UTC_client").innerHTML  = "??";
	//document.getElementById("A_UTC_client").innerHTML  = "??";

	//document.getElementById("JS_UTC").innerHTML = "??";
	document.getElementById("HH_UTC").innerHTML = "??";
	document.getElementById("MM_UTC").innerHTML = "??";
	document.getElementById("SS_UTC").innerHTML = "??";
	//document.getElementById("J_UTC").innerHTML  = "??";
	//document.getElementById("M_UTC").innerHTML  = "??";
	//document.getElementById("A_UTC").innerHTML  = "??";

	//document.getElementById("JS_France").innerHTML = "??";
	document.getElementById("HH_France").innerHTML = "??";
	document.getElementById("MM_France").innerHTML = "??";
	document.getElementById("SS_France").innerHTML = "??";
	//document.getElementById("J_France").innerHTML  = "??";
	//document.getElementById("M_France").innerHTML  = "??";
	//document.getElementById("A_France").innerHTML  = "??";

	document.getElementById("AFF_offset").innerHTML = "??";
	document.getElementById("AFF_delai").innerHTML  = "??";
	document.getElementById("T_sync").innerHTML     = " ";
	document.getElementById("TZ_client").innerHTML  = "??";
	document.getElementById("TZ_France").innerHTML  = "??";

	// synchro/evaluation de l'horloge puis reevaluation/synchro toutes les X s
	sync_horloge();
	tmo_ev = setInterval("sync_horloge()", interval_sync * 1000);

	// MAJ de l'affichage toutes les X ms
	tmo_af = setInterval("affichage()", interval_affich);
}


