// la date de départ, la date de retour et la première date "possible"
var openDate = new Date(), openDateTime;

// le nombre d'heures minimum avant une réservation
var delaiMinimum = { mode: null, vp: null, vu: null, sp: null };

// pour gérer l'état à chaque changement d'agence
var daysClosed = null, openingHours = null;

// setHoraireMenu: liste à remplir, jour de la semaine et date du calendrier
function setHoraireMenu(lst, date)
{
	// si nous sommes aujourd'hui il faut limiter les heures affichées
	var d = new Date(date);
	d.setHours (0, 0, 0, 0);
	var h_start = (openDate.getTime() == d.getTime()) ? openDateTime.getHours() : 0;

	var old_val = (lst.selectedIndex >= 0) ? lst.options[lst.selectedIndex].value : "";
	if (!old_val.length)
		old_val = (lst.name == "h_depart") ? heureDepart : heureRetour;
	lst.options.length = 1;
	if (!(a = openingHours[date.getDay()]))
		return;

	// attention à faire une copie de l'objet date...
	for(var t=new Date(a[0]); t<=a[1]; t.setMinutes(t.getMinutes()+30))
	{
		if (!a[2] || !a[3] || t <= a[2] || t >= a[3])
		{
			if (h_start && t.getHours() < h_start) continue;
			h = t.getHours(); m = t.getMinutes();
			v = (h.toString().length > 1 ? "" : "0") + h + ":" + (m.toString().length > 1 ? "" : "0") + m;
			if (!old_val.length) old_val = v;
			lst.options[lst.options.length] = new Option (v, v, (v == old_val), (v == old_val));
		}
	}
	// sélectionner automatiquement les horaires pour le type "sp"
	if (currentType == 'sp' && lst.options.length > 1)
		lst.selectedIndex = 1;// (lst.name=='h_depart' ? 1 : lst.options.length-1);
}

// checkDateRetour
function checkDateRetour(d)
{
	var minOffset = (currentType == 'sp' ? (7 * 3600 * 24000): 0)
	return [((d.getTime() >= minOffset + $('#depart').datepicker('getDate').getTime()) && isBusinessDay(d)), ''];
}

// checkDateDepart : vérifie la validité de la date de départ
function checkDateDepart(d)
{
	return [(d.getTime() >= openDate.getTime() && isBusinessDay(d)), ''];
}

// doType : change le type de véhicule
function doType (val)
{
	// changer le type courant
	currentType = val;
	
	// modifier l'affichage pour le vhéicule sans permis'
	$('#div_sp_info').css('display', (val=='sp' ? 'block' : 'none'));
	$('#span_h_depart, #span_h_retour').css('display', (val=='sp' ? 'none' : 'inline'));
	if (val == 'el')
		$('body').addClass('green');
	else
		$('body').removeClass('green');

	// afficher les catégories correspondant au type de véhicule
	showCategory();

	// re-vérfiier les dates de départ et de retour
	if ($('#depart').val() && $('#retour').val() && setOpenDateTime())
		alert("Désolé, les dates sélectionnées ne sont pas valides pour ce type de véhicule.\nMerci de modifier votre sélection.");
}


// doAgence
function doAgence(id)
{
	$('#agence').empty();
	enableCalendarControls(false, 'chargement en cours');
	$.get('../xmlagenceinfo.php?id=' + id, function(xml)
	{ 
		var e = xml.documentElement;
		if (!e || !e.getAttribute("id"))
		{
			enableCalendarControls(false, 'agence inconnue');
			return;
		}
		
		$('#agence').attr('value', e.getAttribute('id'));
		if (currentZone != e.getAttribute('zone'))
		{
			currentZone = e.getAttribute('zone');
			showCategory ();
		}
		doHoraires(xml); 
		// vérifier si l'agence fait boîte aux lettres
		if (e && e.getAttribute('bal')=='1')
			$('#agence_bal').show();

		// vérifier que les dates de départ/retour sont toujours valides
		var err = [];
		$('#depart, #retour').each(function() { 
			if ((d = $(this).datepicker('getDate')) && !isBusinessDay(d)) { 
				this.empty(); 
				err.push('la date de ' + this.id + ' sélectionnée n\'est pas valide pour cette agence');
			}
		});
		if (err.length)
			alert('Désolé :\n' + err.join('\n') + ' Merci de modifier votre sélection.');
	});
}

// enableCalendarControls
function enableCalendarControls(enabled, info)
{
	$('#calendar :input').attr('disabled', !enabled);
	if (info) $('#calendar img.btn_cal').attr('title', info).attr('alt', info);
	if (!enabled) $('#agence_bal').hide();
}

// doHoraires : obtient les jours de fermeture et les heures d'ouvertures
// détermine la première heure possible pour la location
function doHoraires(xml)
{
	// obtenir les délais pour la zone 
	// 	sans objet pour les téléconseillers...
	if (document.cookie.indexOf("ADA001_TC_MODE=") == -1)
	{
		delaiMinimum.vp   = parseInt(xml.documentElement.getAttribute("vp_delai_min"));
		delaiMinimum.vu   = parseInt(xml.documentElement.getAttribute("vu_delai_min"));
		delaiMinimum.sp   = parseInt(xml.documentElement.getAttribute("sp_delai_min"));
		delaiMinimum.mode = xml.documentElement.getAttribute("delai_mode");
	}

	// jours de fermeture
	daysClosed = new Array(12);
	for (var i=0, lst=xml.getElementsByTagName("fermeture"); i<lst.length; i++)
	{
		// apparemment parseInt("08") = 0 sur FF....
		m = lst[i].getAttribute("mois") - 1;
		if (!daysClosed[m])
			daysClosed[m] = new Array();
		daysClosed[m].push(lst[i].getAttribute("jour"));
	}

	// heures d'ouverture
	openingHours = null;
	for (var i=0, lst=xml.getElementsByTagName("horaire"); i<lst.length; i++)
	{
		if (!openingHours) openingHours = new Array(7);
		// le jour (1-7, convertit en ISO 0-6)
		j = parseInt(lst[i].getAttribute("jour"));
		if (j == 7)
			j = 0;
		openingHours[j] = new Array(
			  makeTime(lst[i].getAttribute("ouverture"))
			, makeTime(lst[i].getAttribute("fermeture"))
			, makeTime(lst[i].getAttribute("pause_debut"))
			, makeTime(lst[i].getAttribute("pause_fin"))
			);
	}

	if (openingHours)
	{
		// vérification des dates et des heures
		enableCalendarControls(true, "ouvrir le calendrier");
		setOpenDateTime();
		doCheckIllimite();
	}
}
// setOpenDateTime : return 'true' si les dates changent
function setOpenDateTime()
{
	var hasChanged = false;
	// on doit avoir les heures d'ouveture d'une agence
	if (!openingHours || !openingHours.length) 
		return hasChanged;

	openDateTime = getOpenDateTime();
	openDate = new Date(openDateTime);
	openDate.setHours(0,0,0,0);

	// s'il y a déjà une date de départ et qu'elle est avant openDate...
	if (!(d = $('#depart').datepicker('getDate')) || !checkDateDepart(d))
	{
		d = nextBusinessDay(openDate, 0);
		$('#depart').datepicker('setDate', d);
		hasChanged = true;
	}
	// ajuster le menu des horaires
	setHoraireMenu (document.getElementById('h_depart'), d);

	// vérifier la date de retour
	if (!(d = $('#retour').datepicker('getDate')) || !checkDateRetour(d))
	{
		d = nextBusinessDay(openDate, (currentType=='sp' ? 7 : 1) );
		$('#retour').datepicker('setDate', d);
		hasChanged = true;
	}

	// ajuster le menu des horaires
	setHoraireMenu (document.getElementById('h_retour'), d);
	return hasChanged;
}

// getOpenDateTime : renvoie la première date possible de réservation
function getOpenDateTime()
{
	// on arrondit à l'heure supérieure
	var dOpen = new Date();
	dOpen.setHours (dOpen.getHours() + 1, 0, 0, 0);

	// le délai minimum est soit en heures (C)alendaire soit en heures d'(O)uverture
	if (delaiMinimum.mode != 'O')
	{
		// pour les heures calendaires
		dOpen.setHours(dOpen.getHours() + delaiMinimum[currentType]);
		if 
		(
			!isBusinessDay(dOpen) 
			|| openingHours[dOpen.getDay()][1].getHours() < dOpen.getHours()
			|| (currentType=='sp' && dOpen.getHours() > openingHours[dOpen.getDay()][0].getHours()) // pour les sans permis on n'affiche pas l'heure, il faut que ce soti la première heure
		)
		{
			dOpen = nextBusinessDay (dOpen, 1);
			dOpen.setHours( openingHours[dOpen.getDay()][0].getHours() );
		}
		return dOpen;
	}
	
	// pour les heures d'ouvertures
	var h = delaiMinimum[currentType];
	if (!h) h = 1;
	var offset = (isBusinessDay(dOpen) && openingHours[dOpen.getDay()][1].getHours() > dOpen.getHours() ) ? 0 : 1;
	while (h > 0)
	{
		// on passe au jour suivant (sauf pour la première fois)
		dOpen = nextBusinessDay(dOpen, offset);
		if (offset)
			dOpen.setHours( openingHours[dOpen.getDay()][0].getHours() );
		else
			offset = 1;
		// on enlève le nombre d'heures ouvrables
		h -= openingHours[dOpen.getDay()][1].getHours() - dOpen.getHours();
	}
	dOpen.setHours(openingHours[dOpen.getDay()][1].getHours() + h, 0, 0, 0);
	return dOpen;
}

// nextBusinessDay
function nextBusinessDay(date, offset_days)
{
	var d = new Date(date), dayms = 24 * 3600 * 1000;
	d.setHours (3, 0, 0, 0);
	for(d.setTime(d.getTime() + offset_days * dayms);; d.setTime(d.getTime() + dayms))
		if (isBusinessDay(d))
			break;
	d.setHours (0, 0, 0, 0);
	return d;
}

// renvoie true si d est ouvert
function isBusinessDay(date) 
{
	// des jours de fermeture pour le mois indiqué ?
	if (daysClosed && daysClosed[date.getMonth()] != null)
		for (var x in daysClosed[date.getMonth()]) 
			if (daysClosed[date.getMonth()][x] == date.getDate())
				return false;

	// s'il n'y a aucuen heure d'ouverture renseignée, on arrête une boucle infinie
	if (!openingHours) 
		return true;
		
	// pas d'heures d'ouvertures ce jour-là
	if (!openingHours[date.getDay()])
		return false;

	return true;
}

// doCheckHoraireDepart : la date de départ change
function doCheckHoraireDepart() 
{
	var d = $('#depart').datepicker('getDate');
	setHoraireMenu (document.getElementById('h_depart'), d);
	if ($('#retour').datepicker('getDate').getTime() < d.getTime())
	{
		d = nextBusinessDay(d, (currentType == 'sp' ? 7 : 1));
		$('#retour').datepicker('setDate', d);
		doCheckHoraireRetour();
		return false;
	}
	doCheckIllimite();
	return false;
}

// doCheckHoraireRetour : appelé quand le champ texte contenant la date de retour change
function doCheckHoraireRetour() 
{
	setHoraireMenu (document.getElementById('h_retour'), $('#retour').datepicker('getDate'));
	doCheckIllimite();
}

// faut-il afficher les km illimités ?
// uniquement si moins de 2 jours
function doCheckIllimite()
{
	var days = 0;
	if ((d = $('#depart').datepicker('getDate')) && (r = $('#retour').datepicker('getDate')))
	{
		days = (r.getTime() - d.getTime()) / (3600 * 24000);
		if (r.getDay() == 1) 
			days--; // pour tenir compte du dimanche
	}
	
	var flag = (days < 2 && currentType != 'sp' && currentType != 'vp');
	$('#illimite_ctrl').css('display', flag ? 'block' : 'none');
	$('#illimite').attr('disabled', flag ? '' : 'Yes');
}

// makeTime
function makeTime(tm)
{
	if (tm == null || !tm.toString().length)
		return null;
	a = tm.toString().split(":");
	return new Date(0, 0, 0, a[0], a[1], 0);
}

// doCheckNumber
function doCheckNumber(fld)
{
	if (!fld.value.match(/\d+/))
	{
		fld.style.backgroundColor = "#ff7777";
		fld.select();
	}
	else
	{
		fld.style.backgroundColor = "";
	}
}

// doCheck
function doCheck(frm, with_fix)
{
	var err = "", 
		d = $('#depart').datepicker('getDate'),
		r = $('#retour').datepicker('getDate');
	if (!frm.agence.value.length)
		err += "\n- L'agence indiquée est invalide";
	if (!validateSelect(frm.categorie))
		err += "\n- Vous devez indiquer la catégorie du véhicule";
	if (!validateSelect(frm.h_depart))
		err += "\n- Vous devez indiquer l'heure de départ";
	if (d && r && d.getTime() > r.getTime())
		err += "\n- La date de départ ne peut être postérieure à la date de retour";
	if (!validateSelect(frm.h_retour))
		err += "\n- Vous devez indiquer l'heure de retour";
	var days = (r && d) ? (r.getTime() - d.getTime()) / (1000 * 60 * 60 * 24) : 0, 
		max_days = (currentType=='vp' ? 21 : (currentType=='vu' ? 14 : 28));
	if (days > max_days && currentType != 'sp')
		err += "\n- La durée de la location demandée est trop élevée pour une réservation en ligne";
	if (currentType=='sp' && days < 7)
		err += "\n- Pour une location d'un véhicule sans permis inférieure à 7 jours, merci de contacter directement votre agence";
	if (days == 0 && frm.h_retour.selectedIndex <= frm.h_depart.selectedIndex)
		err += "\n- L'heure de départ doit être antérieure à l'heure du retour";
	if (!validateSelect(frm.age))
		err += "\n- Vous devez indiquer votre age";
	if (currentType != 'sp' && !validateSelect(frm.permis))
		err += "\n- Vous devez indiquer votre nombre d'années de permis";
	if (frm.distance.value.length && !frm.distance.value.match(/^\d*$/))
		err += "\n- La distance à parcourir est invalide";
	if (err.length)
	{
		alert("Attention !\n" + err);
		return false;
	}
	// message d'avertissement avant modification des dates pour les véhicules "sans permis"
	if (currentType == 'sp' && days > max_days && !with_fix)
	{
		alert("La durée de réservation en ligne maximum est d'un mois, le tarif affiché correspond au premier mois de location, au delà le paiement s'effectue en agence");
		r = nextBusinessDay(d, 28); 
		$('#retour').datepicker('setDate', r);
		setHoraireMenu (document.getElementById('h_retour'), r);
		return doCheck (frm, true);
	}
	return true;
}

// showCategory
function showCategory()
{
	// mémoriser la valeur précédente
	var lst = document.getElementById("categorie"), val = (lst.selectedIndex > 0) ? lst.options[lst.selectedIndex].value : currentCat;
	if (e = document.getElementById("cat_" + val))
		e.style.display = 'none';

	// vider le menu des catégories
	lst.options.length = 1;
	msg = "Choisissez d'abord une agence";
	if (currentType && currentZone)
	{
		// le remplir en fonction du type et de la zone
		var zone = currentZone;
		if (!mnuCategory[zone + '-' + currentType])
			zone = "fr";
		// remplir la liste des catégories
		for(var a=mnuCategory[zone + '-' + currentType], n=a?a.length:0, i=0; i<n; i++)
		{
			v = a[i].split('-');
			lst.options.add (new Option(v[1], v[0], (v[0]==val), (v[0]==val)));
		}
		// afficher la catégorie
		var divType = document.getElementById('cat_' + zone + '-' + currentType);
		if (!divType.innerHTML.length)
			$.get("../lib.categorie.php?zone=" + zone + '&type=' + currentType, function(html) { divType.innerHTML = html; selectCategory(); });
		else
			selectCategory();
		msg = (i > 0) ? "Choisissez un véhicule" : "Erreur: pas de catégories pour cette zone";
	}
	else
		selectCategory(); // pour afficher l'image par défaut
	lst.options[0].text = "--- " + msg + " ---";
	doCheckIllimite();
}

// sélectionne une catégorie
function selectCategory()
{
	for (var lst=document.getElementById("categorie"), i=0; i<lst.options.length; i++)
		if (e = document.getElementById("cat_" + lst.options[i].value))
			e.style.display = lst.options[i].selected ? 'block' : 'none';
	if(lst.options[lst.selectedIndex].value)
	{
		var $img = $('#cat_'+lst.options[lst.selectedIndex].value+' img.cat_med')
		if($img.length)
		{
			var img = $img.attr('class').replace(/(.+\s)*([^\s]+)$/, '$2');
			if(img!='cat_med')
				$('#cat_visu').attr('src', '../'+img);
		}
	}
	
	if(!img)
		$('#cat_visu').attr('src','../img/cat_flotte_' + currentType + '.png');
}

/* intialise le formulaire de réservation */
function setupReservation()
{
	// les calendriers
	$.datepicker.setDefaults ({
		dateFormat: 'dd-mm-yy',
		firstDay: 1,
		dayNamesMin: ['di','lu','ma','me','je','ve','sa'],
		monthNames: ['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre']
		});

	$('#depart').datepicker( {onSelect: doCheckHoraireDepart, beforeShowDay: checkDateDepart} );
	$('#retour').datepicker( {onSelect: doCheckHoraireRetour, beforeShowDay: checkDateRetour} );
	$('#calendar img.btn_cal').css('cursor', 'pointer').click(function() { $('#' + this.id.replace('btn_', '')).datepicker('show'); });
	$('#calendar input').attr('autocomplete', 'off').attr('readonly', true);

	// type : on force le type pour assurer la cohérence en cas de rafraichissement de la page
	$('#radio_'+currentType).attr('checked','checked');
	
	// agence / ville
	 $('#autocomplete').tagdragon({
		'field': 'ville',
		'url': '../json.agences.php',
		'max': 30,
		'charMin': 3,
		'delay': 100,
		'onSelectedItem': function(val) { if (val.id) doAgence(val.id); },
		'onLoadedList': function(results) {
			len = (results && results.length > 0);
			$('#ville_ok').css('display', len ? "block" : "none");
			$('#ville_ko').css('display',!len ? "block" : "none");
		}
	});

	// agence sélectionnée
	if (id = $('#agence').val())
	{
		doAgence(id);
	}
	else
	{
		enableCalendarControls(false);
		doCheckIllimite();
	}
	// vérifier le bon affichage
	doType(currentType);

	// affichage de l'iamge de categorie
	$("#cat_details img.cat_med").live("click", function(){
		$('#cat_visu').attr('src', '../'+$(this).attr('class').replace(/(.+\s)*([^\s]+)$/, '$2') );
		return false;
	});
	// btn des galleries des categories
	$("#cat_details .galerie .next, .cat_details .galerie .prev").live("click", function(){
		var $band = $(this).parent().find('.band');
		var direction = $(this).hasClass('prev') ? 1 : -1;
		moveBand($band, direction);
		return false;
	});
};

function moveBand($band, direction)
{
	var mask_band_width = $band.parent().width();
	var band_width = $band.width();
	var band_left = (direction == 1) ? 0 : mask_band_width - band_width;
	$band.animate(
		 {left: band_left+'px'}
		,500
		,function(){
			$band.parent().parent().find('.next').toggle();
			$band.parent().parent().find('.prev').toggle();
		}
	);
}