// Variables globales
var aGmap;
var aGmap_zoom_min = 1;
var aGmap_zoom_max_view = 9;
var pointIcon;
var pointIconBold;
var pointIconUltraBold;
var locIcon;
var excIcon;
var tooltip;
var showSVC = false;
var geocoder;
var tabAccuracy = new Array(
    2,
    4,
    6,
    10,
    12,
    13,
    16,
    16,
    17,
    17
);

continents = {
    'w/0': {
	'lat': 46.9202,
	'lng': 10.8984,
	'zoom': 3
    },
    'w/1': {
	'lat': 50.2893,
	'lng': -99.1406,
	'zoom': 2
    },
    'w/2': {
	'lat': 20.5505,
	'lng': -75.3222,
	'zoom': 4
    },
    'w/3': {
	'lat': 2.4601,
	'lng': 15.8203,
	'zoom': 2
    },
    'w/4': {
	'lat': -27.8390,
	'lng': 145.0195,
	'zoom': 3
    },
    'w/5': {
	'lat': -18.3128,
	'lng': -70.3125,
	'zoom': 2
    },
    'w/6': {
	'lat': 1.4061,
	'lng': 73.3007,
	'zoom': 2
    },
    'w/7': {
	'lat': 32.9902,
	'lng': 33.0468,
	'zoom': 3
    },
    'w/8': {
	'lat': 8.9284,
	'lng': 110.0390,
	'zoom': 3
    },
    'w/9': {
	'lat': 33.7243,
	'lng': 97.0312,
	'zoom': 2
    },
    'w/10': {
	'lat': 42.5530,
	'lng': 14.0625,
	'zoom': 1
    },
    'w/11': {
	'lat': 39.5040,
	'lng': 43.1542,
	'zoom': 4
    }
}


// Chargement de la carte
googleLoad.include('aGmap');
google.load('maps', '2.184');//2.184

// Initialisation une fois la carte prête
google.setOnLoadCallback(googleInit);

// Initialisation
function aGmapInit()
{
    initIcons();

    // Création de la carte
    aGmap = new google.maps.Map2($('aGmap'), {
	draggableCursor: 'pointer'
    });

    geocoder = new GClientGeocoder();

    // Positionnement initial de la carte
    if ('en' == 'en') {
	var point = new google.maps.LatLng(20, 280);
    } else {
	var point = new google.maps.LatLng(20, 5);
    }
    aGmap.setCenter(point, aGmap_zoom_min);

    // Taille des controles à afficher
    if (aGmap_size == 'small' || aGmap_size == 'ultrasmall') {
	aGmap.addControl(new GSmallMapControl());
    } else {
	aGmap.addControl(new GLargeMapControl());
    }

    // Type de carte
    aGmap.setMapType(aGmap_type);

    // Permettre le changement de type de carte
    aGmap.addControl(new GMenuMapTypeControl());
    aGmap.addMapType(G_PHYSICAL_MAP);

    // Affichage de l'échelle en bas à droite de la carte
    aGmap.addControl(new GScaleControl(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(5, 25)));

    // Préparation des tooltips
    tooltip = new Element('div', {
	'id' : 'tooltip',
	'style': 'position:relative;z-index:1;background-color:#FFFFFF;border:1px solid #000000;width:100px;font-size:10px;visibility:hidden;',
	'class': 'centrer'
    });
    tooltip.injectInside($('aGmap'));

    // Fonction à appeler en fonction du mode
    switch (aGmap_mode) {
	case 'search':
	    aGmapSearch();
	    break;
	case 'results':
	    aGmapResults();
	    break;
	case 'admin':
	    aGmapAdmin();
	    break;
	case 'view':
	    aGmapView();
	    break;
    }
}

function getLatLng() {
    var bounds = aGmap.getBounds();
    var southWest = bounds.getSouthWest();
    var northEast = bounds.getNorthEast();
    var lngSpan = northEast.lng() - southWest.lng();
    var latSpan = northEast.lat() - southWest.lat();
    var tabLatLng = new Array();
    tabLatLng.push(southWest.lat());
    tabLatLng.push(southWest.lat() + latSpan);
    tabLatLng.push(southWest.lng());
    tabLatLng.push(southWest.lng() + lngSpan);
    tabLatLng.push(aGmap.getZoom());

    /*if (tabLatLng[3] < tabLatLng[2]) {
	p('Longitude inversion !');
	var tmpLng = tabLatLng[2];
	tabLatLng[2] = tabLatLng[3];
	tabLatLng[3] = tmpLng;
    }*/

    return tabLatLng;
}

function getIcon(icon)
{
    switch (icon) {
	case 'pointIcon':
	    return pointIcon;
	    break;
	case 'pointIconBold':
	    return pointIconBold;
	    break;
	case 'pointIconUltraBold':
	    return pointIconUltraBold;
	    break;
	case 'excIcon':
	    return excIcon;
	    break;
	case 'locIcon':
	default:
	    return locIcon;
	    break;
    }
}

function initIcons()
{
    pointIcon = new GIcon(G_DEFAULT_ICON);
    pointIcon.image = baseUrl + '/images/gmap_light.png';
    pointIcon.iconSize = new GSize(3,3);
    pointIcon.shadowSize = new GSize(0,0);
    pointIcon.iconAnchor = new GPoint(0,0);
    
    pointIconBold = new GIcon(G_DEFAULT_ICON);
    pointIconBold.image = baseUrl + '/images/gmap_bold.png';
    pointIconBold.iconSize = new GSize(6,6);
    pointIconBold.shadowSize = new GSize(0,0);
    pointIconBold.iconAnchor = new GPoint(0,0);
    
    pointIconUltraBold = new GIcon(G_DEFAULT_ICON);
    pointIconUltraBold.image = baseUrl + '/images/gmap_ultrabold.png';
    pointIconUltraBold.iconSize = new GSize(8,8);
    pointIconUltraBold.shadowSize = new GSize(0,0);
    pointIconUltraBold.iconAnchor = new GPoint(0,0);
    
    locIcon = new GIcon(G_DEFAULT_ICON);
    locIcon.image = baseUrl + '/images/gmap_loc.png';
    locIcon.iconSize = new GSize(14,15);
    locIcon.shadowSize = new GSize(0,0);
    locIcon.iconAnchor = new GPoint(7,15);
    
    excIcon = new GIcon(G_DEFAULT_ICON);
    excIcon.image = baseUrl + '/images/gmap_loc.png';
    excIcon.iconSize = new GSize(14,15);
    excIcon.shadowSize = new GSize(0,0);
    excIcon.iconAnchor = new GPoint(7,15);
}

function posFromAddress(address, newMarker)
{
    if ($chk($('worldregion')) && $('worldregion').get('value') && $chk($('country')) && !$('country').get('value')) {
	posFromContinent();
    } else {
	address = address.replace(/\((.*)\)/g, '');
	if (aGmap_mode != 'admin' && $chk($('country'))) {
	    address += $('country').options[$('country').selectedIndex].text.replace(/\((.*)\)/g, '');
	}
	geocoder.getLocations(address, function(retdata)
	{
	    if (retdata.Status.code == 200) {
		aGmap.doMove = false;
		var place = retdata.Placemark[0];
		aGmap.setCenter(new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]), tabAccuracy[place.AddressDetails.Accuracy]);
		aGmap.doMove = true;
		if (newMarker) {
		    setMarker();
		}
	    } else {
		divAlert("We weren't able to locate your address. You can move the 'home' cursor manually on the map");
	    }
	});
    }
}

function posFromContinent()
{
    if ($chk($('worldregion')) && $('worldregion').get('value')) {
	var continent = $('worldregion').get('value');
	aGmap.setCenter(new GLatLng(continents[continent].lat, continents[continent].lng));
	aGmap.setZoom(continents[continent].zoom);
    }
}

function showTooltip(marker, nb) {
    nb = (nb <= 100) ? nb : '100+';
    tooltip.innerHTML = nb + ' ads';
    var point = aGmap.getCurrentMapType().getProjection().fromLatLngToPixel(aGmap.getBounds().getSouthWest(), aGmap.getZoom());
    var offset = aGmap.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(), aGmap.getZoom());
    var anchor = marker.getIcon().iconAnchor;
    var width = marker.getIcon().iconSize.width;
    var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point.x - anchor.x + width,- offset.y + point.y +anchor.y + 5));
    pos.apply(tooltip);
    tooltip.setStyle('visibility', 'visible');
}

function infoBulle(gmark, marker_infos) {
    GEvent.addListener(gmark, 'click', function() {
        $clear(timer);
	requestBulle(gmark, marker_infos);
    });
    GEvent.addListener(gmark, 'mouseover', function() {
        $clear(timer);
	var delayedFunction = function() {requestBulle(gmark, marker_infos)};
	timer = delayedFunction.delay(1000);
    });
    GEvent.addListener(gmark, 'mouseout', function() {
	$clear(timer);
    });
}

function requestBulle(gmark, marker_infos) {
    coordsBeforeInfoWindow = aGmap.getBounds().getCenter();
    var jSonRequest = new Request.JSON({
	url: baseUrl + '/ajax/get_aGmap_infoBulle.php',
	onComplete: function(retdata) {
	    iW++;
	    aGmap.doMove = false;
	    gmark.openInfoWindowHtml(retdata);
	}
    }).post({'rep': marker_infos.rep, 'id': marker_infos.id});
    if (!gmark.iW) {
	gmark.iW = true;
	GEvent.addListener(gmark, 'infowindowclose', function() {
	    iW--;
	    aGmap.setCenter(coordsBeforeInfoWindow);
	    if (!iW) {
		aGmap.doMove = true;
	    }
	});
    }
}
var viewzoom = 0;

//Initialisation du mode vue
function aGmapView()
{
    setMarker(curLat, curLng);
}

function setMarker(lat, lng)
{
    aGmap.clearOverlays();

    point = new GLatLng(lat, lng);

    aGmap.bounds = null;
    aGmap.bounds = new GLatLngBounds();
    aGmap.bounds.extend(point);

    var marker = new GMarker(point, {draggable: true, icon: getIcon('locIcon')});

    aGmap.addOverlay(marker);

    aGmap.setCenter(aGmap.bounds.getCenter());
    if (!viewzoom) {
	var newZoom = aGmap.getBoundsZoomLevel(aGmap.bounds);
	(newZoom > aGmap_zoom_max_view) ? aGmap.setZoom(aGmap_zoom_max_view) : aGmap.setZoom(newZoom);
    } else {
	aGmap.setZoom(viewzoom);
    }
}
window.addEvent('domready', init);

/**
 * Fonction d'initialisation appelée au domready
 */
function init()
{
    $('calDatas').set('html', '<img src="http://www.websideholidays.com/images/ajax-activity-small.gif" width="16" height="16" alt="Loading rates and availability calendar..." />');

    // Gestion des liens mois précédents / suivants
    $$('#prev, #next').addEvent('click', function(event)
    {
        var event = new Event(event);
        event.stop();
        $('pnloader').loader = new Loader($('pnloader'));
        tmpDate = debutDate;
        if (this.get('id') == 'next') {
            tmpDate.setMonth(tmpDate.getMonth() + 3);
            debutMois.setMonth(debutMois.getMonth() + 3);
            finMois.setMonth(finMois.getMonth() + 3);
        } else if (this.get('id') == 'prev') {
            tmpDate.setMonth(tmpDate.getMonth() - 3);
            debutMois.setMonth(debutMois.getMonth() - 3);
            finMois.setMonth(finMois.getMonth() - 3);
        }
        debutDate = tmpDate;
        var mois = (debutDate.getMonth()+1).toString();
        if (mois.length == 1) {
            mois = '0' + mois;
        }
        debut = debutDate.getFullYear() + '-' + mois;
        if (admin) {
            annule();
        }
        creerCalendrier();
    });

    // Initialisation du calendrier
    creerCalendrier();
}

/**
 * Créer un calendrier en effectuant un appel Ajax
 * Déplace ensuite les propriétés de chaque case dans le DOM, puis les colorise et ajoute les tooltip
 * Si nous sommes dans le mode admin, la fonction initadmin est appelée à la fin
 */
function creerCalendrier()
{
    // On sauvegarde dans la tableau calForm la liste des périodes du calendrier, afin de ne plus faire de requetes MySQL inutiles
    var calForm = new Array();
    if ($chk($('calForm')) && $('calForm').getChildren().length > 1) {
        $('calForm').getChildren().each(function(item, index){
            if ($(item).get('id').match(new RegExp(/^p(a)?[0-9]+$/))) {
                calForm.push($(item).get('id').replace('p', '') + '|' + $(item).get('value'));
            }
        });
    }

    var jSonRequest = new Request.JSON({
        url: baseUrl + '/ajax/calendrier.php',
        onComplete: function(retdata)
        {
            $('calDatas').setStyles({
                padding: 0
            });
            $('calDatas').set('html', retdata['aff']);
            if (navmois) {
                $('prev').set('html', retdata['divPrev']);
                $('next').set('html', retdata['divNext']);
            }
            if (admin && !calForm.length) {
                saison1 = retdata['bs'];
                saison2 = retdata['ms'];
                saison3 = retdata['hs'];
            }
            if (admin) {

                // Créer des champs input pour sauvegarder les périodes récupérées depuis la base de données
                comments = retdata['comments'];
                initPeriodes(retdata['periodes']);
            }

            // Sauvegarde dans le DOM et colorisation
            $$('[name=day]').each(function(el)
            {
                if (el.get('jour') && el.get('mois') && el.get('annee')) {
                    el.calJour = el.get('jour');
                    el.calMois = el.get('mois');
                    el.calAnnee = el.get('annee');
                }
                if (el.get('availg')) {
                    el.calAvailG = el.get('availg');
                }
                if (el.get('availd')) {
                    el.calAvailD = el.get('availd');
                }
                if (el.get('nightsming')) {
                    el.calNightsMinG = el.get('nightsming');
                }
                if (el.get('nightsmind')) {
                    el.calNightsMinD = el.get('nightsmind');
                }
                if (el.get('offerg')) {
                    el.calOfferG = el.get('offerg');
                }
                if (el.get('offerd')) {
                    el.calOfferD = el.get('offerd');
                }
                if (el.get('offeridg')) {
                    el.calOfferIdG = el.get('offeridg');
                }
                if (el.get('offeridd')) {
                    el.calOfferIdD = el.get('offeridd');
                }
                if (el.get('periodeg')) {
                    el.calPeriodeG = el.get('periodeg');
                }
                if (el.get('perioded')) {
                    el.calPeriodeD = el.get('perioded');
                }
                if (el.get('first')) {
                    el.calFirst = el.get('first');
                }
                if (el.get('last')) {
                    el.calLast = el.get('last');
                }
                if (el.get('occupeidg')) {
                    el.calOccupeG = el.get('occupeidg');
                }
                if (el.get('occupeidd')) {
                    el.calOccupeD = el.get('occupeidd');
                }
                el.removeProperties('jour', 'mois', 'annee', 'availg', 'availd', 'nightsming', 'nightsmind', 'offerg', 'offerd', 'offeridg', 'offeridd', 'periodeg', 'perioded', 'first', 'last', 'occupeidg', 'occupeidd');
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
                if (!admin && !adminview && el.calOccupeD ) {
                    el.removeProperty('title');
                }
            });

            // Création tooltip
            if (!admin) {
                pageTips = new Tips($$('.caltips'), {
                    fixed:true,
                    className:'calTooltip'
                });
            }

            // Si mode admin
            if (admin) {
                initadmin();
            }

            // Suppression des éventuels loader
            if ($defined($('pnloader').loader)) {
                $('pnloader').loader.destroy();
                $('pnloader').loader = null;
            }

        }
    }).post({'id': loc_id, 'nombre': nombre, 'debut': debut, 'calForm': calForm, 'admin': admin, 'from_currency': from_currency, 'to_currency': to_currency, 'adminview': adminview});
}

/**
 * Colorise une case du calendrier
 * Si color1 ou color2 sont passés en paramètre, ces couleurs sont forcées, sinon, les couleurs sont calculées en fonction des périodes
 */
function colorise(el, color1, color2, periode)
{
    var bg;
    var colorG;
    var colorD;

    switch(el.calAvailG) {
        case '0':
            colorG = 'gris';
            break;
        case '1':
            colorG = 'vert1';
            break;
        case '2':
            colorG = 'vert2';
            break;
        case '3':
            colorG = 'vert3';
            break;
        default:
            colorG = 'blanc';
    }
    switch(el.calAvailD) {
        case '0':
            colorD = 'gris';
            break;
        case '1':
            colorD = 'vert1';
            break;
        case '2':
            colorD = 'vert2';
            break;
        case '3':
            colorD = 'vert3';
            break;
        default:
            colorD = 'blanc';
    }

    // Période occupée
    if (el.calOccupeG || el.calOccupeD) {
        if (el.calOccupeG) {
            colorG = 'rouge';
        }
        if (el.calOccupeD) {
            colorD = 'rouge';
        }
    }

    // Promotion
    if (el.calOfferG || el.calOfferD) {
        if (el.calOfferG) {
            colorG = 'jaune';
        }
        if (el.calOfferD) {
            colorD = 'jaune';
        }
    }

    // Forcer une colorisation
    if (color1) {
        colorG = color1;
    }
    if (color2) {
        colorD = color2;
    }

    // Si le fond est uni
    if (colorG == colorD) {
        bg = baseUrl + '/ajax/calendrier_fond.php?c1=' + colorG;
        if (el.calPeriodeG != el.calPeriodeD || el.calOfferIdG != el.calOfferIdD || el.calOccupeG != el.calOccupeD) {
            bg += '&sepa=1';
        }
        return bg;
    }

    // Si c'est un mélange entre deux couleurs
    if (colorG != colorD) {
        bg = baseUrl + '/ajax/calendrier_fond.php?c1=' + colorG + '&c2=' + colorD;
        return bg;
    }

    return true;
}
// On initialise les périodes qu'une seule fois
var initP = false;
var periodes = new Array();
var sauvegarde = 'init';
var occupe = false;
var offer = false;

/**
 * selectMode : mode de sélection
 * 1 : date de début et date de fin + selection de période complète si survol d'une période occupée
 * 2 : selection de période complète réagissant seulement sur les périodes libres (appliquer / retirer promotion)
 */
var selectMode = 1;

/**
 * Lorsque l'utilisateur souhaite définir une nouvelle période, on utilise start et end
 */
var start;
var end;

var newstart;
var newend;
var newend_prec;

/**
 * Nous sert à savoir combien de périodes sont définies sur telle ou telle saison, afin de vérifier la présence des tarifs
 * correspondant aux périodes du calendrier
 */
var saison1;
var saison2;
var saison3;

/**
 * Objet contenant les libelles des periodes occupées disposant ou non d'un commentaire du locataire
 */
var comments;

/**
 * Variables de debug
 */
var inputType = 'hidden';


/**
 * Permet d'effectuer des actions d'initialisation
 * Cette fonction est déclenchée une fois le calendrier généré par calendrier.js
 */
function initadmin()
{
    // On initialise le mode de selection
    changeSelectMode(selectMode);

    // Ainsi que la variable permettant de savoir si les modifs ont été ou non enregistrées
    if (sauvegarde == 'init') {
        calSauvegarde(true);
        window.onbeforeunload = unloadMess;
    }

    // On retire les évènements afin d'éviter le double déclenchement
    $('controle_promotion').removeEvents('click');
    $('controle_enregistrer').removeEvents('click');
    $$('[name=controle_annuler]').removeEvents('click');
    $('controle_periode_disponibilite').removeEvents('change');
    $('controle_appliquerPeriodeLibre').removeEvents('click');
    $('controle_appliquerPeriodeOccupee').removeEvents('click');
    $('controle_editerPeriodeOccupee').removeEvents('click');
    $('controle_libererPeriodeOccupee').removeEvents('click');
    //$('retour_passe').removeEvents('click');
    $$('[name^=bs],[name^=ms],[name^=hs]').removeEvents('change');
    $('controle_appliquerPromo').removeEvents('click');
    $('controle_editerPeriodePromotion').removeEvents('click');
    $('controle_libererPeriodePromotion').removeEvents('click');
    $('changeNbMois').removeEvents('change');

    // Et on affecte une action au bouton Appliquer une promotion, qui change le mode de sélection
    $('controle_promotion').addEvent('click', function(e)
    {
        var e = new Event(e);
        e.stop();
        changeSelectMode(2);
    });

    $('changeNbMois').addEvent('change', function()
    {
        if (!sauvegarde) {
            divAlert("Please save your changes before changing the number of months displayed.", "Close");
            this.selectedIndex = 0;
        } else {
            if (this.value) {
		var tmploc = $chk($('tmploc')) ? '&loc='+$('tmploc').value : '';
                window.location.href = "http://www.websideholidays.com/admin/locadmin/avail/" + loc_id + ".html?nbmois=" + this.value+tmploc;
            }
        }
    });

    /**
     * Ici on gère le clic sur le bouton Enregistrer les modifications
     * On récupère les prix et on les clone pour ensuite les injecter dans calForm, qui sera envoyé par Ajax
     * On vérifie que les prix ont bien été renseignés, et on injecte également l'ID de la location
     */
    $('controle_enregistrer').addEvent('click', function(e)
    {
        var e = new Event(e);
        e.stop();
        save();
    });
    $$('[name=dosave]').addEvent('click', function(e)
    {
        var e = new Event(e);
        e.stop();
        save();
    });

    // On affiche le texte générique du cadre de gauche
    $('texte_generique').setStyle('display', 'block');

    // Et on ajoute une action au bouton d'annulation du mode d'ajout de promotion. Il change le mode de sélection et replace le texte générique
    $$('[name=controle_annuler]').addEvent('click', annule);
    $('controle_periode_nuitsmin').setStyle('display', 'none');

    // Gestion des select lors de la création d'une nouvelle période
    $('controle_periode_disponibilite').addEvent('change', function()
    {
        if (this.get('value') > 0 && this.get('value') < 4) {
            $('texte_periode_occupee').setStyle('display', 'none');
            $('texte_periode_libre').setStyle('display', 'block');
            $('controle_periode_nuitsmin').setStyle('display', 'block');
        } else if (this.get('value') == '4') {
            $('texte_periode_libre').setStyle('display', 'none');
            $('texte_periode_occupee').setStyle('display', 'block');
        } else if (this.get('value') == '0') {
            $('texte_periode_occupee').setStyle('display', 'none');
            $('texte_periode_libre').setStyle('display', 'block');
            $('controle_periode_nuitsmin').setStyle('display', 'none');
        } else {
            $('texte_periode_occupee').setStyle('display', 'none');
            $('texte_periode_libre').setStyle('display', 'none');
            $('controle_periode_nuitsmin').setStyle('display', 'none');
        }
    });
    
    // On ajout l'évènement sur la modification d'un champ de tarif
    $$('#tarifs table input').addEvent('keyup', function(){
	calSauvegarde();
    });

    // Au clic sur Valider lors de l'ajout d'une période libre, on reset le formulaire et on créé la période demandée
    $('controle_appliquerPeriodeLibre').addEvent('click', function()
    {
        calSauvegarde(false);
        var avail = $('controle_periode_disponibilite').get('value');
        var nightsmin = $('controle_periode_nuitsmin').get('value');
        var promo = 0;
        if (!nightsmin) {
            nightsmin = 1;
        }
        creerPeriode(avail, nightsmin, promo, new Array());
        resetInputs();
        verifierTarifs(avail, nightsmin);
    });

    // Idem pour les périodes occupées, avec les attributs en plus
    $('controle_appliquerPeriodeOccupee').addEvent('click', function()
    {
        var error;
	var avail = $('controle_periode_disponibilite').get('value');
        var promo = 0;
        var nightsmin = 0;
        var attributes = new Array();
        $$('[id^=controle_attr]').each(function(el)
        {
            if (el.get('value')) {
		if (el.get('name') == 'email') {
		    var pattern = /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
		    if (pattern.test(el.get('value'))) {
			attributes.include(el.get('name') + '::' + el.get('value'));
		    } else {
			error = true;
		    }
		} else {
		    attributes.include(el.get('name') + '::' + el.get('value'));
		}
            }
        });
	if (error) {
	    divAlert("The e-mail address you have provided is invalid.");
	} else {
	    creerPeriode(avail, nightsmin, promo, attributes);
	    resetInputs();
	    calSauvegarde(false);
	}
    });

    // Demande de libération d'une période occupée
    $('controle_libererPeriodeOccupee').addEvent('click', function()
    {
        $(occupe).destroy();
        $$('[name=day]').each(function(el)
        {
            if (el.calOccupeG == occupe) {
                el.calOccupeG = null;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            }
            if (el.calOccupeD == occupe) {
                el.calOccupeD = null;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            }
        });
        if (!occupe.match(new RegExp(/^pa[0-9]+$/))) {
            var resaToDelete = $('resaToDelete').get('value').split(',');
            resaToDelete.include(occupe);
            resaToDelete.erase('');
            resaToDelete = resaToDelete.join(',');
            resaToDelete = resaToDelete.replace('p', '');
            $('resaToDelete').set('value', resaToDelete);
        }
        occupe = false;
        changeSelectMode(1);
        resetInputs();
        calSauvegarde(false);
    });

    // Editer une période occupée
    $('controle_editerPeriodeOccupee').addEvent('click', function()
    {
        if (this.get('value') == "Change Information") {
            this.set('value', "Save Changes");
            $$('[id^=controle_occupe_span_]').each(function(el) {
                el.setStyle('display', 'none');
            });
            $$('[id^=controle_occupe_attr_]').each(function(el) {
                el.setStyle('display', 'block');
            });            
        } else {
            var error;
	    var attributes = new Array();
            attributes.include('id::' + occupe.replace('p', ''));
            $$('[id^=controle_occupe]').each(function(el)
            {
                if (el.get('value') && !el.get('value').match(/(:){2}|(\$){2}/)) {
		    if (el.get('name') == 'email') {
			var pattern = /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
			if (pattern.test(el.get('value'))) {
			    attributes.include(el.get('name') + '::' + el.get('value'));
			} else {
			    error = true;
			}
		    } else {
			attributes.include(el.get('name') + '::' + el.get('value'));
		    }
                }
            });

	    if (error) {
		divAlert("The e-mail address you have provided is invalid.");
	    } else {
		attributes = attributes.join('$$');

		infosPeriode = retourneInfosPeriode(occupe);
		var value = infosPeriode[0] + '|' + infosPeriode[1] + '|' + infosPeriode[2] + '|' + infosPeriode[3] + '|' + infosPeriode[4] + '|' + attributes;
		$(occupe).set('value', value);

		occupe = false;
		changeSelectMode(1);
		resetInputs();
		calSauvegarde(false);
	    }
        }
    });

    // Ajouter une promotion
    $('controle_appliquerPromo').addEvent('click', function()
    {
        calSauvegarde(false);
        var avail = 5;
        var promo = $('controle_promo_select').get('value');
        var nightsmin = 0;
        var attributes = new Array();
        creerPeriode(avail, nightsmin, promo, attributes);
        resetInputs();
    });

    // Demande de suppression d'une promotion
    $('controle_libererPeriodePromotion').addEvent('click', function()
    {
        $(promo).destroy();
        $$('[name=day]').each(function(el)
        {
            if (el.calOfferIdG == promo) {
                el.calOfferIdG = null;
                el.calOfferG = null;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            }
            if (el.calOfferIdD == promo) {
                el.calOfferIdD = null;
                el.calOfferD = null;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            }
        });
        promo = false;
        changeSelectMode(1);
        resetInputs();
        calSauvegarde(false);
    });

    // Editer une promotion
    $('controle_editerPeriodePromotion').addEvent('click', function()
    {
        if (this.get('value') == "Change Special Offer") {
            this.set('value', "Save Special Offer");
            $('controle_editpromo_span').setStyle('display', 'none');
            $('controle_editpromo_select').setStyle('display', 'block');
        } else {
            infosPeriode = retourneInfosPeriode(promo);
            var value = infosPeriode[0] + '|' + infosPeriode[1] + '|' + infosPeriode[2] + '|' + $('controle_editpromo_select').get('value') + '|' + infosPeriode[4];
            $(promo).set('value', value);

            promo = false;
            changeSelectMode(1);
            resetInputs();
            calSauvegarde(false);
        }
    });

    /*$('retour_passe').addEvent('click', function()
    {
        window.location.href = "http://www.websideholidays.com/admin/locadmin/avail-passe/" + loc_id + ".html";
    });*/
    
}

/**
 * Gestion du survol de périodes complètes à partir d'une case
 * Voir haut de fichier pour la description des modes de selection
 */
function survolPeriode(el, color, over)
{
    periodeAvail = retournePeriodeAvail(el);
    var periode = periodeAvail[0];
    var avail = periodeAvail[1];
    var occupep = periodeAvail[2];
    var offernb = periodeAvail[3];
    var offerp = periodeAvail[4];

    if (selectMode == 1 || selectMode == 2) {
        if (!start && !end && occupep) {
            $$('[name=day]').each(function(current)
            {
                if (current.calOccupeG && current.calOccupeD && current.calOccupeG == current.calOccupeD && current.calOccupeG == occupep) {
                    current.setStyle('background', "url('" + colorise(current, color, color) + "') no-repeat top center");
                } else if (current.calOccupeG && current.calOccupeD && current.calOccupeG != current.calOccupeD && current.calOccupeG == occupep) {
                    current.setStyle('background', "url('" + colorise(current, color, 'rouge') + "') no-repeat top center");
                }  else if (current.calOccupeG && current.calOccupeD && current.calOccupeG != current.calOccupeD && current.calOccupeD == occupep) {
                    current.setStyle('background', "url('" + colorise(current, 'rouge', color) + "') no-repeat top center");
                } else if (current.calOccupeD == occupep) {
                    current.setStyle('background', "url('" + colorise(current, '', color) + "') no-repeat top center");
                } else if (current.calOccupeG == occupep) {
                    current.setStyle('background', "url('" + colorise(current, color) + "') no-repeat top center");
                }
            });
        } else if (!start && !end && offerp && offernb) {
            $$('[name=day]').each(function(current)
            {
                if (current.calOfferIdG && current.calOfferIdD && current.calOfferIdG == current.calOfferIdD && current.calOfferIdG == offerp) {
                    current.setStyle('background', "url('" + colorise(current, color, color) + "') no-repeat top center");
                } else if (current.calOfferIdG && current.calOfferIdD && current.calOfferIdG != current.calOfferIdD && current.calOfferIdG == offerp) {
                    current.setStyle('background', "url('" + colorise(current, color, 'jaune') + "') no-repeat top center");
                } else if (current.calOfferIdG && current.calOfferIdD && current.calOfferIdG != current.calOfferIdD && current.calOfferIdD == offerp) {
                    current.setStyle('background', "url('" + colorise(current, 'jaune', color) + "') no-repeat top center");
                } else if (current.calOfferIdD == offerp) {
                    current.setStyle('background', "url('" + colorise(current, '', color) + "') no-repeat top center");
                } else if (current.calOfferIdG == offerp) {
                    current.setStyle('background', "url('" + colorise(current, color) + "') no-repeat top center");
                }
            });
        } else if (!start && !end && !occupe && !el.calOfferIdD && !el.calOfferD) {
            overD(el, over);
        } else if (start && !end && !occupe && !el.calOfferIdG && !el.calOfferG) {
            overG(el, over);
        }
    }
}

/**
 * Gestion du clic de périodes complètes ou de cases du calendrier
 * Voir haut de fichier pour la description des modes de selection
 */
function clicPeriode(el)
{
    periodeAvail = retournePeriodeAvail(el);
    var periode = periodeAvail[0];
    var avail = periodeAvail[1];
    var occupep = periodeAvail[2];
    var offernb = periodeAvail[3];
    var offerp = periodeAvail[4];

    infosPeriode = retourneInfosPeriode(periode);
    if (infosPeriode) {
        var pStart = infosPeriode[0];
        var pEnd = infosPeriode[1];
        pEnd = new Date(pEnd.split('-')[0], pEnd.split('-')[1] - 1, pEnd.split('-')[2]);
        pEnd.setDate(pEnd.getDate() + 1);
        pEnd = formatDateJsToMysql(pEnd);
    }

    if (selectMode == 1 || selectMode == 2) {
        if ((avail < 4 || !avail) && !start && !end && !occupe && !occupep && !offerp && !offernb) {
            start = el.get('id');
            el.precD = el.calAvailD;
            el.calAvailD = '0';
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            if (selectMode == 1) {
                $('controle_periode_start').set('html', formatDateMysqlToUser(start));
                $('texte_generique').setStyle('display', 'none');
                $('texte_periode').setStyle('display', 'none');
                $('texte_avant_periode').setStyle('display', 'block');
            } else if (selectMode == 2) {
                $('controle_promo_start').set('html', formatDateMysqlToUser(start));
                $('texte_avant_promo').setStyle('display', 'none');
                $('texte_entre_promo').setStyle('display', 'block');
            }
            overD(el, true);
        } else if ((el.calAvailG < 4 || !el.calAvailG) && start && !end && !occupe && (!occupep || !el.calOccupeG) && !el.calOfferIdG && !el.calOfferG) {
            end = el.get('id');
            $(start).setStyle('background', "url('" + colorise($(start)) + "') no-repeat top center");
            verifierDates(start, end);
        } else if (start && !end && !occupe && occupep && el.calOccupeG && !el.calOfferIdG && !el.calOfferG) {
            $(start).setStyle('background', "url('" + colorise($(start)) + "') no-repeat top center");
            divAlert("Vous ne pouvez inclure une période occupée dans votre sélection. Veuillez d'abord libérer les éventuelles périodes occupées.", "Close");
            annule(selectMode);
        } else if (start && !end && !occupe && (!occupep || !el.calOccupeG) && el.calOfferIdG && el.calOfferG) {
            $(start).setStyle('background', "url('" + colorise($(start)) + "') no-repeat top center");
            divAlert("Vous ne pouvez inclure une période en promotion dans votre sélection. Veuillez d'abord supprimer les éventuelles promotions.", "Close");
            annule(selectMode);
        } else if (!start && !end) {

            // Libérer ou éditer une période occupée / une promotion
            if (occupep) {
                editPeriodeOccupee(occupep);
            } else if (offerp && offernb) {
                editPeriodePromotion(offerp);
            }
        }
        if (start || end) {
            $$('[name=annule]').setStyle('display', 'block');
        }
    }
}

/**
 * Changement du mode de sélection
 * On retire tous les évènementq afin d'éviter d'éventuels double déclenchements
 */
function changeSelectMode(mode)
{
    $$('[name=day]').removeEvents('mouseover');
    $$('[name=day]').removeEvents('mouseout');
    $$('[name=day]').removeEvents('click');
    if (!start && !end) {
        $$('[name=annule]').setStyle('display', 'none');
        $('texte').getChildren('div').setStyle('display', 'none');
        $$('[class=centrer]').setStyle('display', 'block');
        $('texte_generique').setStyle('display', 'block');
        $$('[name=boutons]').setStyle('display', 'block');
        $('divNext').setStyle('visibility', 'visible');
        $('divPrev').setStyle('visibility', 'visible');
    }
    start = null;
    end = null;
    if (mode == 1 || mode == 2) {
        if (mode == 2) {
            $$('[name=annule]').setStyle('display', 'block');
            $('texte_generique').setStyle('display', 'none');
            $$('[name=boutons]').setStyle('display', 'none');
            $('texte_avant_promo').setStyle('display', 'block');
        }
        selectMode = mode;
        $$('[name=day]').setStyle('cursor', 'pointer');
        $$('[name=day]').addEvents({
            'mouseover': function(){
                survolPeriode(this, 'gris', true);
            },
            'mouseout': function(){
                survolPeriode(this, '');
            },
            'click': function(){
                $$('[name=boutons]').setStyle('display', 'none');
                $('divNext').setStyle('visibility', 'hidden');
                $('divPrev').setStyle('visibility', 'hidden');
                clicPeriode(this);
            }
        });
    }
}

/*
 * Fonction appelée une seule fois à l'initialisation du mode admin
 * Elle récupère les périodes renvoyées par MySQL et les place dans le formulaire calForm, qui sera ensuite utilisé pour enregistrer les modifications et pour éviter trop de requêtes d'affichage
 */
function initPeriodes(tabPeriodes)
{
    if (!initP) {
        $('calForm').empty();
        $each(tabPeriodes, function(value, periode){
            var value = tabPeriodes[periode]['start'] + '|' + tabPeriodes[periode]['end'] + '|' + tabPeriodes[periode]['availability'] + '|' + tabPeriodes[periode]['offer'] + '|' + tabPeriodes[periode]['nightsMin'];
            if (tabPeriodes[periode]['attributs']) {
                value += '|' + tabPeriodes[periode]['attributs'];
            }
            var input = new Element('input', {
                'type': inputType,
                'value': value,
                'readonly': 'readonly',
                'id': 'p' + periode,
                'name': 'periodes[]'
            }).inject($('calForm'));
        });
        var input = new Element('input', {
            'type': inputType,
            'value': '',
            'readonly': 'readonly',
            'id': 'resaToDelete',
            'name': 'resaToDelete'
        }).inject($('calForm'));
    }
    initP = true;
}

/*
 * Retourne l'identifiant de disponibilité d'une case (aucun, 1, 2, 3...)
 */
function retournePeriodeAvail(el)
{
    var retour = new Array();
    if (el.calFirst || el.calLast) {
        retour.push(el.calPeriodeD);
        retour.push(el.calAvailD);
    } else {
        retour.push(el.calPeriodeG);
        retour.push(el.calAvailG);
    }
    if (el.calOccupeD) {
        retour.push(el.calOccupeD);
    } else {
        retour.push('');
    }
    if (el.calOfferD && el.calOfferIdD) {
        retour.push(el.calOfferD);
        retour.push(el.calOfferIdD);
    } else {
        retour.push('');
        retour.push('');
    }
    return retour;
}

/*
 * Retourne les informations concernant une période
 * - date de début
 * - date de fin
 * - availability
 * - offer
 * - nightsmin
 * - attributs
 */
function retourneInfosPeriode(periode)
{
    if ($chk($(periode))) {
        var retour = new Array();
        retour.push($(periode).get('value').split('|')[0]);
        retour.push($(periode).get('value').split('|')[1]);
        retour.push($(periode).get('value').split('|')[2]);
        retour.push($(periode).get('value').split('|')[3]);
        retour.push($(periode).get('value').split('|')[4]);
        retour.push($(periode).get('value').split('|')[5]);
        return retour;
    } else {
        return '';
    }
}

/*
 * Supprime une période d'après son identifiant, à la fois du calendrier et de calForm, et met a jour le compteur de saisons du calendrier
 */
function supprimePeriode(periode)
{
    calSauvegarde(false);
    infosPeriode = retourneInfosPeriode(periode);
    if (infosPeriode[1] >= "2010-09-01") {
	switch(infosPeriode[2]) {
	    case '1':
		saison1--;
		break;
	    case '2':
		saison2--;
		break;
	    case '3':
		saison3--;
		break;
	    default:
	}
    }
    $(periode).destroy();
    $$('[name=day]').each(function(el) {
        if (el.calPeriodeG && el.calPeriodeD && el.calPeriodeG == el.calPeriodeD && el.calPeriodeG == periode) {
            el.calAvailG = el.calNightsMinG = el.calPeriodeG = null;
            el.calAvailD = el.calNightsMinD = el.calPeriodeD = null;
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
        } else if (el.calFirst && el.calPeriodeD == periode) {
            el.calAvailD = el.calNightsMinD = el.calPeriodeD = null;
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
        } else if (el.calLast && el.calPeriodeG == periode) {
            el.calAvailG = el.calNightsMinG = el.calPeriodeG = null;
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
        }
    });
}

/*
 * Lorsqu'une nouvelle période chevauche une période déjà présente, on modifie cette dernière en la réduisant ou en la coupant en deux
 */
function reduitPeriode(periode)
{
    infosPeriode = retourneInfosPeriode(periode);
    var startMonth = new Date(infosPeriode[0].split('-')[0], infosPeriode[0].split('-')[1]-1, infosPeriode[0].split('-')[2]);
    var endMonth = new Date(infosPeriode[1].split('-')[0], infosPeriode[1].split('-')[1]-1, infosPeriode[1].split('-')[2]);

    $(periode).destroy();

    // On regarde si la période à modifier est affichée entièrement à l'écran, où si elle débute avant le premier mois affiché,
    // où se termine après le dernier mois affiché
    var outDeb = false;
    var outFin = false;
    if ((startMonth.getMonth() < debutMois.getMonth() && startMonth.getFullYear() == debutMois.getFullYear()) || startMonth.getFullYear() < debutMois.getFullYear()) {
        outDeb = true;
    }
    if ((endMonth.getMonth() > finMois.getMonth() && endMonth.getFullYear() == finMois.getFullYear()) || endMonth.getFullYear() > finMois.getFullYear()) {
        outFin = true;
    }

    var start;
    var end;
    var p;

    if (!outDeb || !outFin) {
        $$('[name=day]').each(function(el)
        {
            if (el.calPeriodeD == periode && el.calPeriodeG != el.calPeriodeD) {
                p = 'p' + rand();
                el.calPeriodeD = p;
                el.calFirst = true;
                start = el.get('id');
            } else if (el.calPeriodeG == periode && el.calPeriodeG != el.calPeriodeD && start) {
                el.calPeriodeG = p;
                el.calLast = true;
                avail = (el.calAvailG) ? el.calAvailG : 0;
                offer = 0;
                nightsmin = (el.calNightsMinG) ? el.calNightsMinG : 0;
                end = new Date(el.get('id').split('-')[0], el.get('id').split('-')[1]-1, el.get('id').split('-')[2]);
                end.setDate(end.getDate() - 1);
                end = formatDateJsToMysql(end);
                var value = start + '|' + end + '|' + avail + '|' + offer + '|' + nightsmin;
                var input = new Element('input', {
                    'type': inputType,
                    'value': value,
                    'readonly': 'readonly',
                    'id': p,
                    'name': 'periodes[]'
                }).inject($('calForm'));
            } else if (el.calPeriodeG && el.calPeriodeD && el.calPeriodeG == el.calPeriodeD && el.calPeriodeG == periode && start) {
                el.calPeriodeG = el.calPeriodeD = p;
                el.calFirst = el.calLast = false;
            }
        });
    }

    if (!outDeb && outFin) {
        end = new Date(infosPeriode[1].split('-')[0], infosPeriode[1].split('-')[1]-1, infosPeriode[1].split('-')[2]);
        end = formatDateJsToMysql(end);
        avail = ($(start).calAvailD) ? $(start).calAvailD : 0;
        offer = 0;
        nightsmin = ($(start).calNightsMinD) ? $(start).calNightsMinD : 0;
        var value = start + '|' + end + '|' + avail + '|' + offer + '|' + nightsmin;
        var input = new Element('input', {
            'type': inputType,
            'value': value,
            'readonly': 'readonly',
            'id': periode,
            'name': 'periodes[]'
        }).inject($('calForm'));
    } else if (outDeb && !outFin) {
        start = new Date(infosPeriode[0].split('-')[0], infosPeriode[0].split('-')[1]-1, infosPeriode[0].split('-')[2]);
        start = formatDateJsToMysql(start);
        $$('[name=day]').each(function(el)
        {
            if (el.calPeriodeG == periode && el.calPeriodeG != el.calPeriodeD && start) {
                avail = (el.calAvailG) ? el.calAvailG : 0;
                offer = 0;
                nightsmin = (el.calNightsMinG) ? el.calNightsMinG : 0;
                end = new Date(el.get('id').split('-')[0], el.get('id').split('-')[1]-1, el.get('id').split('-')[2]);
                end.setDate(end.getDate() - 1);
                end = formatDateJsToMysql(end);
            }
        });
        var value = start + '|' + end + '|' + avail + '|' + offer + '|' + nightsmin;
        var input = new Element('input', {
            'type': inputType,
            'value': value,
            'readonly': 'readonly',
            'id': periode,
            'name': 'periodes[]'
        }).inject($('calForm'));
    } else if (outDeb && outFin && infosPeriode[2] < 4) {
        end = new Date(newstart.split('-')[0], newstart.split('-')[1]-1, newstart.split('-')[2]);
        end.setDate(end.getDate() - 1);
        end = formatDateJsToMysql(end);
        start = new Date(newend.split('-')[0], newend.split('-')[1]-1, newend.split('-')[2]);
        start.setDate(start.getDate() + 1);
        start = formatDateJsToMysql(start);
        periodes.erase(periode);
        p = rand();
        ajouterPeriode('p' + p, infosPeriode[0], end, infosPeriode[2], infosPeriode[3], infosPeriode[4], new Array());
        p = rand();
        ajouterPeriode('p' + p, start, infosPeriode[1], infosPeriode[2], infosPeriode[3], infosPeriode[4], new Array());
    }
}

/*
 * Modifie l'état du calendrier : sauvegardé ou non, et affiche un message en conséquence
 */
function calSauvegarde(bool)
{
    if (sauvegarde == 'init') {
        sauvegarde = true;
        //$$('[name=save]').setStyle('visibility', 'hidden');
    } else {
        sauvegarde = bool;
        if (!sauvegarde) {
            $$('[name=sauvegarde]').fade('show');
            $$('[name=sauvegarde]').setStyle('display', 'block');
            $$('[name=sauvegarde]').setStyle('color', '#DF1D22');
	    $$('[name=sauvegarde]').setStyle('margin-top', '6px');
            $$('[name=sauvegarde]').set('html', "Your changes have not been saved.");
            $$('[name=save]').setStyle('visibility', 'visible');
        } else {
            $$('[name=sauvegarde]').fade('show');
            $$('[name=sauvegarde]').setStyle('display', 'block');
            $$('[name=sauvegarde]').setStyle('color', '#08a2e0');
	    $$('[name=sauvegarde]').setStyle('margin-top', '6px');
            $$('[name=sauvegarde]').set('html', "Your changes have been saved.");
            //$$('[name=save]').setStyle('visibility', 'hidden');
        }
    }
}

/*
 * Gestion du survol dans le cas du choix d'une date de début de période
 * On ne colorise que les parties droites des cases, et on ne le fait pas sur les périodes occupées, qui peuvent cependant être sélectionnées pour être libérées
 * la fonction overG fait de même, mais pour le choix d'une date de fin
 */
function overD(el, over)
{
    if (!el.calOccupeD && over) {
        var bg = el.getStyle('background-image').replace('url(', '');
        bg = bg.replace(')', '');
        if (bg == 'undefined') {
            bg = baseUrl + '/ajax/calendrier_fond.php?c1=blanc';
        }
        bg = bg.replace(/\bc2=[a-z0-9]+\b/, '');
        bg = 'url(' + bg + '&c2=gris)';
        bg = bg.replace('&&', '&');
        el.setStyle('background-image', bg);
    } else if (!over) {
        el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
    }
}

function overG(el, over)
{
    if (!el.calOccupeG && over) {
        var bg = el.getStyle('background-image').replace('url(', '');
        bg = bg.replace(')', '');
        bg = bg.split('?');
        if (bg[1]) {
            bg = bg[1].split('&');
            if (bg[0]) {
                bg[0] = bg[0].replace('c1=', '');
            }
            if (bg[1] && bg[1] != 'sepa=1') {
                bg[1] = bg[1].replace('c2=', '');
            } else if (bg[1] && bg[1] == 'sepa=1') {
                bg[1] = 'jaune';
            }
            if (bg[0] == bg[1] || (bg[0] && !bg[1])) {
                bg = bg[0];
            } else {
                bg = bg[1];
            }
        } else {
            bg = 'blanc';
        }
        bg = 'url(' + baseUrl + '/ajax/calendrier_fond.php?c1=gris&c2=' + bg + ')';
        el.setStyle('background-image', bg);
    } else if (!over) {
        el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
    }
}

/**
 * Lorsque l'utilisateur a sélectionné une date de début et de fin, on vérifie leur exactitude
 * - La date de fin ne doit pas être antèrieure à la date de début
 * - Aucune période occupée ne doit se trouver entre la date de début et la date de fin
 */
function verifierDates(start, end)
{
    var resa = false;
    var promo = false;
    var nc = false;
    periodes = new Array();
    var end_prec = end;
    end = end.split('-');
    end = new Date(end[0], end[1]-1, end[2]);
    startdiff = new Date(start.split('-')[0], start.split('-')[1]-1, start.split('-')[2]);
    var nuits = Math.ceil((end.getTime()-startdiff.getTime())/(1000*60*60*24));
    end.setDate(end.getDate() - 1);
    end = formatDateJsToMysql(end);
    if (end < start) {
        divAlert("The end date cannot be before the start date.", "Close");
        annule();
        return false;
    }

    $$('[name=day]').each(function (el) {
        if (el.get('id') >= start && el.get('id') <= end && (el.calOccupeG || el.calOccupeD) && (el.calOccupeG && el.calOccupeD && el.calOccupeG == el.calOccupeD)) {
            resa = true;
        } else if (el.get('id') >= start && el.get('id') <= end && (el.calofferIdG || el.calOfferIdD) && (el.calOfferIdG && el.calOfferIdD && el.calOfferIdG == el.calOfferIdD)) {
            promo = true;
        } else if (el.get('id') >= start && el.get('id') <= end && selectMode == 2 && (!el.calAvailD || (el.calAvailD == 0 && !el.precD))) {
            nc = true;
        } else if (el.get('id') >= start && el.get('id') <= end && (el.calAvailG || el.calAvailD)) {
            periodeAvail = retournePeriodeAvail(el);
            if (periodeAvail[0]) {
                periodes.include(periodeAvail[0]);
            }
        }
    });

    if (resa) {
        divAlert("Vous ne pouvez inclure une période occupée dans votre sélection. Veuillez d'abord libérer les éventuelles périodes occupées.", "Close");
        annule(selectMode);
        return false;
    }
    if (promo) {
        divAlert("Vous ne pouvez inclure une période en promotion dans votre sélection. Veuillez d'abord supprimer les éventuelles promotions.", "Close");
        annule(selectMode);
        return false;
    }
    if (nc) {
        divAlert("Une promotion ne peut pas être appliquée sur une période non renseignée.", "Close");
        annule(selectMode);
        return false;
    }

    // Les dates sont correctes, on demande les propriétés à l'utilisateur
    // Colorisation temporaire
    $$('[name=day]').setStyle('cursor', 'default');
    $$('[name=day]').each(function (el) {
        if (el.get('id') > start && el.get('id') < end_prec) {
            el.precG = el.calAvailG;
            el.precD = el.calAvailD;
            el.calAvailG = el.calAvailD = '0';
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            el.calAvailG = el.precG;
            el.calAvailD = el.precD;
            el.precG = el.precD = null;
        } else if (el.get('id') == start) {
            el.calAvailD = '0';
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            el.calAvailD = el.precD;
            el.precD = null;
        } else if (el.get('id') == end_prec) {
            el.precG = el.calAvailG;
            el.calAvailG = '0';
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            el.calAvailG = el.precG;
            el.precG = null;
        }
    });

    if (selectMode == 1) {
        $('controle_periode_startd').set('html', formatDateMysqlToUser(start));
        $('controle_periode_endd').set('html', formatDateMysqlToUser(end_prec));
        if (nuits > 1) {
            $('controle_periode_nuits').set('html', nuits + ' ' + "nights");
        } else {
            $('controle_periode_nuits').set('html', nuits + ' ' + "night");
        }
        $('texte_avant_periode').setStyle('display', 'none');
        $('texte_periode').setStyle('display', 'block');
        $('controle_periode_nuitsmin').getChildren('option').each(function(option) {
            option.setStyle('display', 'none');
            if (option.value <= nuits) {
                option.setStyle('display', 'block');
            }
        });
    } else if (selectMode == 2) {
        $('controle_promo_startd').set('html', formatDateMysqlToUser(start));
        $('controle_promo_endd').set('html', formatDateMysqlToUser(end_prec));
        if (nuits > 1) {
            $('controle_promo_nuits').set('html', nuits + ' nuits');
        } else {
            $('controle_promo_nuits').set('html', nuits + ' nuit');
        }
        $('texte_entre_promo').setStyle('display', 'none');
        $('texte_promo').setStyle('display', 'block');
    }

    // On créer la période en prenant en compte les periodes à scinder / fusionner
    newstart = start;
    newend = end;
    newend_prec = end_prec;
    highlight('texte');
}

/**
 * On créer ici une nouvelle période
 * Si cette nouvelle période recouvre une ou plusieurs autres périodes, on les réduits, on les découpe ou on les supprime (si la période
 * est entièrement recouverte)
 */
function creerPeriode(avail, nightsmin, promo, attributes)
{
    var p = rand();
    if (avail == 4) {
        attributes.include('id::' + p);
    }
    ajouterPeriode('p' + p, newstart, newend, avail, promo, nightsmin, attributes);

    if (periodes.length && avail < 4) {
        var tabPeriodes = new Object();
        periodes.each(function(item, index) {
            tabPeriodes[item] = $(item).get('value');
            infosPeriode = retourneInfosPeriode(item);
            if (infosPeriode[0] >= newstart && infosPeriode[1] <= newend) {
                supprimePeriode(item);
            } else if ((infosPeriode[0] >= newstart || infosPeriode[1] <= newend) || (infosPeriode[0] < newstart && infosPeriode[1] > newend)) {
                reduitPeriode(item);
            }
        });
    }

    start = null;
    end = null;
    if (promo) {
        changeSelectMode(2);
    } else {
        changeSelectMode(1);
    }
}

/**
 * Enfin, après avoir créé la période, on l'ajoute au calendrier et à calForm
 */
function ajouterPeriode(periode, start, end, avail, offer, nightsmin, attributes)
{
    end_prec = new Date(end.split('-')[0], end.split('-')[1]-1, end.split('-')[2]);
    end_prec.setDate(end_prec.getDate() + 1);
    end_prec = formatDateJsToMysql(end_prec);
    
    if (avail > 0) {
        if (!attributes || !attributes.length) {
            var value = start + '|' + end + '|' + avail + '|' + offer + '|' + nightsmin;
        } else {
            var value = start + '|' + end + '|' + avail + '|' + offer + '|' + nightsmin + '|' + attributes.join('$$');
        }
        var input = new Element('input', {
            'type': inputType,
            'value': value,
            'readonly': 'readonly',
            'id': periode,
            'name': 'periodes[]'
        }).inject($('calForm'));

	if (end >= "2010-09-01") {
	    switch(avail) {
		case '1':
		    saison1++;
		    break;
		case '2':
		    saison2++;
		    break;
		case '3':
		    saison3++;
		    break;
		default:
	    }
	}
    }

    $$('[name=day]').each(function(el)
    {
        if (el.precG) {
            el.precG = null;
        }
        if (el.precD) {
            el.precD = null;
        }

        if (avail < 4) {
            if (el.get('id') > start && el.get('id') < end_prec) {
                if (avail > 0) {
                    el.calAvailG = el.calAvailD = avail;
                    el.calPeriodeG = el.calPeriodeD = periode;
                    el.calNightsMinG = el.calNightsMinD = nightsmin;
                } else {
                    el.calAvailG = el.calAvailD = null;
                    el.calFirst = el.calLast = null;
                    el.calPeriodeG = el.calPeriodeD = null;
                }
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
                //el.set('title', '');
            } else if (el.get('id') == start) {
                if (avail > 0) {
                    el.calAvailD = avail;
                    el.calFirst = true;
                    el.calPeriodeD = periode;
                    el.calNightsMinD = nightsmin;
                } else {
                    el.calAvailD = null;
                    el.calFirst = null;
                    el.calNightsMinD = null;
                    el.calPeriodeD = null;
                }
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
                //el.set('title', '');
            } else if (el.get('id') == end_prec) {
                if (avail > 0) {
                    el.calAvailG = avail;
                    el.calLast = true;
                    el.calPeriodeG = periode;
                    el.calNightsMinG = nightsmin;
                } else {
                    el.calAvailG = null;
                    el.calLast = null;
                    el.calNightsMinG = null;
                    el.calPeriodeG = null;
                }
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
                //el.set('title', '');
            }
        } else if (avail == 4) {
            if (el.get('id') > start && el.get('id') < end_prec) {
                el.calOccupeG = el.calOccupeD = periode;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            } else if (el.get('id') == start) {
                el.calOccupeD = periode;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            } else if (el.get('id') == end_prec) {
                el.calOccupeG = periode;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            }
        } else if (avail == 5) {
            if (el.get('id') > start && el.get('id') < end_prec) {
                el.calOfferG = el.calOfferD = offer;
                el.calOfferIdG = el.calOfferIdD = periode;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            } else if (el.get('id') == start) {
                el.calOfferD = offer;
                el.calOfferIdD = periode;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            } else if (el.get('id') == end_prec) {
                el.calOfferG = offer;
                el.calOfferIdG = periode;
                el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
            }
        }
    });
}

/**
 * Lorsqu'elle est appelée, cette fonction annule toute opération en cours et revient au mode de sélection de base en faisant réapparaitre
 * le texte générique
 */
function annule(promo)
{
    if (selectMode == 1 || selectMode == 2) {
        start = null;
        end = null;
        $$('[name=day]').each(function(el)
        {
            if (el.precG) {
                el.calAvailG = el.precG;
                el.precG = null;
            } else if (el.calAvailG == '0') {
                el.calAvailG = null;
            }
            if (el.precD) {
                el.calAvailD = el.precD;
                el.precD = null;
            } else if (el.calAvailD == '0') {
                el.calAvailD = null;
            }
            el.setStyle('background', "url('" + colorise(el) + "') no-repeat top center");
        });
    }
    
    if (promo && promo == 2) {
        changeSelectMode(2);
    } else {
        changeSelectMode(1);
    }
    resetInputs();
    
    occupe = false;
}

/**
 * Fonction remettant à zéro les select et les champs input du cadre contextuel
 * Appelé lors de l'annulation ou de la validation d'un formulaire
 */
function resetInputs()
{
    $('controle_periode_disponibilite').selectedIndex = 0;
    $('controle_periode_nuitsmin').selectedIndex = 0;
    $('controle_promo_select').selectedIndex = 0;
    $('texte_periode_libre').setStyle('display', 'none');
    $('texte_periode_occupee').setStyle('display', 'none');
    $('controle_periode_nuitsmin').setStyle('display', 'none');
    $$('[class=itext]').set('value', '');
    $$('[class=stext]').set('html', 'Not given');
    $('controle_editerPeriodeOccupee').set('value', "Change Information");
    $('controle_editerPeriodePromotion').set('value', "Change Special Offer");
    $$('[id^=controle_occupe_span_]').each(function(el) {
        el.setStyle('display', 'block');
    });
    
    $$('[id^=controle_occupe_attr_]').each(function(el) {
        el.setStyle('display', 'none');
    });
    
    $('controle_editpromo_span').setStyle('display', 'block');
    $('controle_editpromo_select').setStyle('display', 'none');
}

/**
 * Gestion des attributs pour les périodes occupées
 */
function attributs(periode)
{
    var retour = '';
    var infosPeriode = retourneInfosPeriode(periode);
    if (infosPeriode[4] > 1) {
        retour += "Minimum Stay : " + infosPeriode[4] + ' nights<br />';
    } else if (infosPeriode[4] == 1) {
        retour += "Minimum Stay : " + infosPeriode[4] + ' night<br />';
    }
    if (infosPeriode[3] > 0) {
        retour += "Special Offer : " + infosPeriode[3] + '%<br />';
    }
    if (infosPeriode[5]) {
        attributs = infosPeriode[5].split('$$');
        attributs.each(function(item, index) {
            item = item.split('::');
            switch(item[0]) {
                case 'fname':
                    retour += "Renter's First Name : " + item[1] + '<br />';
                    break;
                case 'lname':
                    retour += "Renter's Last Name : " + item[1] + '<br />';
                    break;
                case 'email':
                    retour += "E-mail Address : " + item[1] + '<br />';
                    break;
                case 'resa_comments':
                    retour += "Comments : " + item[1] + '<br />';
                    break;
                default:
                    break;
            }
        });
    }
    return retour;
}

/**
 * 
 */
function editPeriodeOccupee(periode)
{
    occupe = periode;
    //$('loc_comment').set('html', comments[occupe.replace('p', '')]);
    $$('[name=day]').each(function(el)
    {
        if (!el.calOccupeD && !el.calOfferIdD) {
            el.setStyle('cursor', 'default');
        }
    });
    resetInputs();
    $('texte').getChildren('div').setStyle('display', 'none');
    $$('[class=centrer]').setStyle('display', 'block');
    $('texte_occupe').setStyle('display', 'block');    
    $$('[name=annule]').setStyle('display', 'block');
    $$('[id^=controle_occupe_attr_]').setStyle('display', 'none');
    
    infosPeriode = retourneInfosPeriode(periode);

    var end = new Date(infosPeriode[1].split('-')[0], infosPeriode[1].split('-')[1]-1, infosPeriode[1].split('-')[2]);
    end.setDate(end.getDate() + 1);
    startdiff = new Date(infosPeriode[0].split('-')[0], infosPeriode[0].split('-')[1]-1, infosPeriode[0].split('-')[2]);
    var nuits = Math.ceil((end.getTime()-startdiff.getTime())/(1000*60*60*24));
    end = formatDateJsToMysql(end);

    $('controle_occupe_start').set('html', formatDateMysqlToUser(infosPeriode[0]));
    $('controle_occupe_end').set('html', formatDateMysqlToUser(end));
    if (nuits > 1) {
        $('controle_occupe_nuits').set('html', nuits + ' nuits');
    } else {
        $('controle_occupe_nuits').set('html', nuits + ' nuit');
    }

    if (infosPeriode[5]) {
        infosPeriode[5] = infosPeriode[5].split('$$');
        infosPeriode[5].each(function(item, index) {
            if (item) {
                item = item.split('::');
                if (item[0] != 'id') {
                    item[1] = item[1].replace('//UPDATE', '');
                    $('controle_occupe_attr_' + item[0]).set('value', item[1]);
                    $('controle_occupe_span_' + item[0]).set('html', item[1]);
                }
            }
        });
    }

    highlight($('texte'));
}

/**
 * 
 */
function editPeriodePromotion(periode)
{
    promo = periode;
    $$('[name=day]').each(function(el)
    {
        if (!el.calOccupeD && !el.calOfferIdD) {
            el.setStyle('cursor', 'default');
        }
    });
    resetInputs();
    $('texte').getChildren('div').setStyle('display', 'none');
    $$('[class=centrer]').setStyle('display', 'block');
    $('texte_editpromo').setStyle('display', 'block');
    $$('[name=annule]').setStyle('display', 'block');
    infosPeriode = retourneInfosPeriode(periode);

    var end = new Date(infosPeriode[1].split('-')[0], infosPeriode[1].split('-')[1]-1, infosPeriode[1].split('-')[2]);
    end.setDate(end.getDate() + 1);
    startdiff = new Date(infosPeriode[0].split('-')[0], infosPeriode[0].split('-')[1]-1, infosPeriode[0].split('-')[2]);
    var nuits = (end.getTime()-startdiff.getTime())/(1000*60*60*24);
    end = formatDateJsToMysql(end);

    $('controle_editpromo_start').set('html', formatDateMysqlToUser(infosPeriode[0]));
    $('controle_editpromo_end').set('html', formatDateMysqlToUser(end));
    if (nuits > 1) {
        $('controle_editpromo_nuits').set('html', nuits + ' nuits');
    } else {
        $('controle_editpromo_nuits').set('html', nuits + ' nuit');
    }

    $('controle_editpromo_span').set('html', infosPeriode[3] + '%');
    $('controle_editpromo_select').selectedIndex = ((infosPeriode[3] / 5) - 1);
    highlight($('texte'));
}

/**
 * Vérifie que les tarifs entrés sont cohérents (bs < ms < hs)
 */
function verifierTarifs(saison, duree)
{
    var retour = true;
    if (!saison && !duree) {
        for (var id = 0; id <= 4; id++) {
            var bs = ($$('[name^=bs]')[id].get('value')) ? $$('[name^=bs]')[id].get('value').toInt() : 0;
            var ms = ($$('[name^=ms]')[id].get('value')) ? $$('[name^=ms]')[id].get('value').toInt() : 0;
            var hs = ($$('[name^=hs]')[id].get('value')) ? $$('[name^=hs]')[id].get('value').toInt() : 0;
            if (bs || ms || hs) {
                if (bs && ms && bs >= ms) {
                    retour = false;
                }
                if (bs && hs && bs >= hs) {
                    retour = false;
                }
                if (ms && hs && ms >= hs) {
                    retour = false;
                }
            }
        }
        if (retour) {
            return true;
        } else {
            divAlert("Please check that your rates are consistent. The Low, Mid, and High Season rates must be progressive.", "Close");
            return false;
        }
    } else if (saison && duree) {
        var id;
        switch(saison) {
            case '1':
                saison = 'bs';
                break;
            case '2':
                saison = 'ms';
                break;
            case '3':
                saison = 'hs';
                break;
            default:
                return true;
        }
        switch(duree) {
            case '1':
                id = 0;
                break;
            case '2':
                id = 1;
                break;
            case '7':
                id = 2;
                break;
            case '15':
                id = 3;
                break;
            case '30':
                id = 4;
                break;
            default:
                return true;
        }
        if (!$$('[name^=' + saison + ']')[id].get('value')) {
            retour = false;
        }
        if (retour) {
            return true;
        } else {
            divAlert("We recommend that you enter the rate corresponding to the length of stay.", "Close");
            return true;
        }
    }
}

/**
 * Génération d'un nombre aléatoire
 * Cette fonction est utilisée pour donner des ID aux nouvelles périodes, et éventuellement pour réaffecter des ID
 * à une période coupée en deux
 */
function rand()
{
    var now = new Date().getTime() / 1000;
    now = now.toInt();
    var rand = Math.round(Math.random() * 10000000000);
    rand = rand.toString();
    return 'a' + now + rand;
}

/**
 * Met une cadre en surbrillance durant une seconde
 */
function highlight(div)
{
    $(div).setStyle('background-color', '#fefee2');
    (function()
    {
        $(div).highlight('#fefee2', '#eeeeee');
    }).delay(500);
}

/**
 * Message d'avertissement si l'utilisateur veut fermer la fenêtre sans avoir enregistré ses modifications
 */
function unloadMess()
{
    if (!sauvegarde) {
	var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
        mess = (is_chrome)
	    ? "Warning, your changes have not been saved."
	    	    : "Warning: your changes have not been saved. \n>>> Cancel: return to the page\n>>> OK: quit without saving (your changes will be lost)";
        return mess;
    }
}

/**
 * Sauvegarde le calendrier
 */
function save()
{
    if (!verifierTarifs()) {
        return false;
    }
    var bs = false;
    var ms = false;
    var hs = false;
    $$('[name^=bs],[name^=ms],[name^=hs]').each(function(input)
    {
        var clone = input.clone();
        clone.clone = true;
        clone.inject($('calForm'));
        if (clone.get('value') && clone.get('name') == 'bs[]' && !bs) {
            bs = true;
        } else if (clone.get('value') && clone.get('name') == 'ms[]' && !ms) {
	    ms = true;
        } else if (clone.get('value') && clone.get('name') == 'hs[]' && !hs) {
            hs = true;
        }
    });

    // On vérifie que les prix renseignés correspondent bien aux saisons, sinon on demande au propriétaire de remplir
    // les tarifs manquant
    if ((bs && saison1 || !saison1) && (ms && saison2 || !saison2) && (hs && saison3 || !saison3)) {
        var input = new Element('input', {
            'type': 'hidden',
            'value': loc_id,
            'readonly': 'readonly',
            'id': 'loc_id',
            'name': 'loc_id'
        }).inject($('calForm'));
        var inputMod = new Element('input', {
            'type': 'hidden',
            'value': mod,
            'readonly': 'readonly',
            'id': 'mod',
            'name': 'mod'
        }).inject($('calForm'));
        $('calForm').set('send', {
            url: baseUrl + '/ajax/calendrier_enregistrement.php',
            method: 'post',
            onComplete: function(retdata) {
		if (!mod) {
		    //window.opener.location.reload();
		}
                retdata = JSON.decode(retdata);
                if (retdata['more']) {
                    divAlert(retdata['more']);
                }
                if (retdata['error']) {
                    return false;
                }
                $('resaToDelete').set('value', '');
                if (retdata['resa_updated']) {
                    retdata['resa_updated'].each(function(item, index) {
                        var value = $('p' + item).get('value');
                        value = value.replace(/(id::)[0-9]+(\$){0,2}/, '');
                        value = value.replace(/(\|)$/, '');
                        $('p' + item).set('value', value);
                    });
                }
                if (retdata['resa_inserted']) {
                    retdata['resa_inserted'].each(function(item, index) {
                        prevp = item.split('|')[0];
                        newp = item.split('|')[1];
                        $('p' + prevp).set('id', 'p' + newp);
                        var value = $('p' + newp).get('value');
                        value = value.replace(/(id::a)[0-9]+(\$){0,2}/, '');
                        value = value.replace(/(\|)$/, '');
                        $('p' + newp).set('value', value);
                        $$('[name=day]').each(function(el)
                        {
                            if (el.calOccupeG == 'p' + prevp) {
                                el.calOccupeG = 'p' + newp;
                            }
                            if (el.calOccupeD == 'p' + prevp) {
                                el.calOccupeD = 'p' + newp;
                            }
                        });
                    });
                }
                input.destroy();
                inputMod.destroy();
                calSauvegarde(true);
            }
        });
        $('calForm').send();
    } else {
        champs = new Array();
        if (saison1 && !bs) {
            champs.include("Low Season");
        }
        if (saison2 && !ms) {
            champs.include("Mid Season");
        }
        if (saison3 && !hs) {
            champs.include("High Season");
        }
        divAlert("In order to save your calender, please fill in at least one rate for the following seasons:<br />" + champs.join(', '), "Close");
    }
    $$('[name^=bs],[name^=ms],[name^=hs]').each(function(input)
    {
        if (input.clone == true) {
            input.destroy();
        }
    });
    genTitles();
}

/**
 * Génération d'un nouveau title pour les cases dans le cas d'un enregistrement,
 * afin que tout reste cohérent
 */
function genTitles()
{
    var periode;
    var saison;
    var nightsMin;
    var price;
    var title;
    $$('[name=day]').each(function(el)
    {
        if (el.calPeriodeD) {
            periode = el.calPeriodeD;
            periode = retourneInfosPeriode(periode);
            switch (periode[2]) {
                case '1':
                    saison = 'Basse saison';
                    price = $$('[name^=bs]');
                    break;
                case '2':
                    saison = 'Moyenne saison';
                    price = $$('[name^=ms]');
                    break;
                case '3':
                    saison = 'Haute saison';
                    price = $$('[name^=hs]');
                    break;
                default:
                    return false;
            }
            if (periode[4] == 1) {
                /*  */
                nightsMin = periode[4] + ' night minimum';
            } else {
                /*  */
                nightsMin = periode[4] + ' nights minimum';
            }
            price = (price[0]) ? price[0].get('value') :
                (price[1]) ? price[1].get('value') :
                    (price[2]) ? price[2].get('value') :
                        (price[3]) ? price[3].get('value') :
                            (price[4]) ? price[4].get('value') : 'N.C.';
            title = saison + ', ' + price + '  / night, ' + nightsMin;
            el.set('title', title);
        }
    });
}

/* Pushup
 * Copyright (c) 2008 Nick Stakenburg (www.nickstakenburg.com)
 *
 * License: MIT-style license.
 * Website: http://www.pushuptheweb.com
 *
 */

var Pushup = {
  Version: '1.0.3',
  options: {
    appearDelay: .5,
    fadeDelay: 6,
    images: '/images-pushup/',
    message: "An important update is available for your browser",
    reminder: {
      hours: 6,
      message: "Remind me in #{hours}"
    },
    skip: false
  },
  updateLinks: {
    IE: 'http://www.microsoft.com/windows/downloads/ie/',
    Firefox: 'http://www.getfirefox.com',
    Safari: 'http://www.apple.com/safari/download/',
    Opera: 'http://www.opera.com/download/'
  },
  Browser: {
    IE: !!(window.attachEvent &&
      navigator.userAgent.indexOf('Opera') === -1),
    Firefox: navigator.userAgent.indexOf('Firefox') > -1,
    Safari: navigator.userAgent.indexOf('AppleWebKit/') > -1 &&
      /Apple/.test(navigator.vendor),
    Opera: navigator.userAgent.indexOf('Opera') > -1
  }
};

Pushup.conditions = {
  IE: (function(agent) {
    var version = /MSIE ([\d.]+)/.exec(agent);
    return version && parseFloat(version[1]) < 7;
  })(navigator.userAgent),
  Firefox: Pushup.Browser.Firefox &&
    parseFloat(navigator.userAgent.match(/Firefox[\/\s](\d+)/)[1]) < 3,
  Safari: Pushup.Browser.Safari &&
    parseFloat(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) < 500,
  Opera: Pushup.Browser.Opera && (!window.opera.version ||
    parseFloat(window.opera.version()) < 9.5)
};

(function() {
// find current browser and check if it needs an update
for (var browser in Pushup.Browser)
  if (Pushup.Browser[browser]) Pushup._browserUsed = browser;
Pushup._updateBrowser = Pushup.conditions[Pushup._browserUsed] &&
  Pushup._browserUsed;

// stop if no update is required and we want to skip build
if (!Pushup._updateBrowser && Pushup.options.skip) return;

function Extend(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
}

Extend(Pushup, {
  start: function() {
    // get the image directory
    if (/^(https?:\/\/|\/)/.test(this.options.images))
      this.images = this.options.images;
    else {
      var srcMatch = /pushup(?:-[\w\d.]+)?\.js(.*)/,
       scripts = document.getElementsByTagName('script');
      for (var i = 0, l = scripts.length; i < l; i++) {
        var s = scripts[i];
        if (s.src && s.src.match(srcMatch))
          this.images = s.src.replace(srcMatch, '') + this.options.images;
      }
    }
    if (Pushup._updateBrowser) this.show();
  },

  build: function() {
    this.pushup = document.createElement('div');
    Opacity.set(this.pushup, 0);
    this.pushup.id = 'pushup';

    this.messageLink = this.pushup.appendChild(document.createElement('a'));
    this.messageLink.className = 'pushup_messageLink';
    this.messageLink.target = '_blank';

    this.messageLink.appendChild(this.icon = document.createElement('div'));
    this.icon.className = 'pushup_icon';

    this.messageLink.appendChild(this.message = document.createElement('span'));
    this.message.className = 'pushup_message';
    this.message.innerHTML = this.options.message;

    // reminder message if cookies are enabled
    var hours = this.options.reminder.hours;
    if (hours && Pushup.cookiesEnabled) {
      this.pushup.appendChild(this.reminder = document.createElement('a'));
      this.reminder.href = '#';
      this.reminder.className = 'pushup_reminder';
      this.pushup.className = 'withReminder';
      //var H = hours + " hour" + (hours > 1 ? 's' : ''),
      var H = hours + " " + ((hours == 1) ? "hour" : "hours");
       message = this.options.reminder.message.replace('#{hours}', H);
      this.reminder.innerHTML = message;
    }

    // Older Opera doesn't handle float correctly
    if (Pushup.Browser.Opera &&
       (!window.opera.version || parseFloat(window.opera.version()) < 9.25)) {
      this.messageLink.style.cssFloat = 'none';
      this.reminder.style.cssFloat = 'none';
    }

    Pushup.setBrowser(Pushup._updateBrowser);
    document.body.appendChild(this.pushup);
    Pushup.addEvents();
  },

  addEvents: function() {
    if (this.reminder) {
      Event.add(this.reminder, 'click', function(event) {
        Event.stop(event);
        Pushup.setReminder(Pushup.options.reminder.hours);
        Pushup.fade();
      });
    }
    Event.add(this.pushup, 'mouseover', Pushup.clearFade);
    Event.add(this.pushup, 'mouseout', function() {
      Pushup.fade({ delay: Pushup.options.fadeDelay })
    });
  },

  setBrowser: function(browser) {
    browser = browser || 'IE';
    setPngBackground(this.icon, this.images + browser.toLowerCase() + '.png');
    this.messageLink.href = this.updateLinks[browser];
  },

  show: function() {
    // default to IE if no browser was detected
    var browser = typeof arguments[0] == 'string' ?
      arguments[0] : Pushup._browserUsed || 'IE',
     options = arguments[browser ? 1 : 0] || {};

    if (options.resetReminder) Pushup.resetReminder();

    // show if not blocked by cookie
    if (!options.ignoreReminder && Pushup.cookiesEnabled &&
      Cookie.get('_pushupBlocked')) return;

    if (!Pushup.pushup) Pushup.build();
    Opacity.set(Pushup.pushup, 0);
    Pushup.pushup.style.display = 'block';
    if (browser) Pushup.setBrowser(browser);
    this.appear({ fadeAfter: true, delay: Pushup.options.appearDelay });
  },

  appear: function(delay) {
    Pushup.clearFade();
    var options = arguments[0] || {};
    return window.setTimeout(function() {
      Appear(Pushup.pushup, { afterFinish: function() {
        if (options.fadeAfter)
          Pushup.fade({ delay: Pushup.options.fadeDelay });
      }});
    }, (options.delay || 0.01) * 1000);
  },

  clearFade: function() {
    if (Pushup._fadeTimer) {
      window.clearTimeout(Pushup._fadeTimer);
      Pushup._fadeTimer = null;
    }
  },

  fade: function() {
    var options = arguments[0] || {};
    Pushup._fadeTimer = window.setTimeout(function() {
      Fade(Pushup.pushup);
    }, (options.delay || 0.01) * 1000);
  },

  setReminder: function(hours) {
    Cookie.set('_pushupBlocked', 'blocked', { duration: 1 / 24 * hours })
  },

  resetReminder: function() { Cookie.remove('_pushupBlocked') }
});

// Opacity adapted from the Prototype JavaScript framework
// http://www.prototypejs.org
var Opacity = {
  set: function(element, value) {
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
  },

  get:  function(element) {
    var opacity = element.style.opacity;
    return opacity ? parseFloat(opacity) : 1.0;
  }
};

if (Pushup.Browser.IE) {
  Opacity.get = function(element) {
    var opacity = element.style.opacity;
    if (!opacity && element.currentStyle) opacity = element.currentStyle[opacity];

    if (opacity = (element.style.filter || '').match(/alpha\(opacity=(.*)\)/))
      if (opacity[1]) return parseFloat(opacity[1]) / 100;
    return 1.0;
  };

  Opacity.set = function(element, value) {
    function stripAlpha(filter) {
      return filter.replace(/alpha\([^\)]*\)/gi,'')
    }
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;
    var filter = element.style.filter,
     style = element.style;
    if (value == 1 || value === '') (filter = stripAlpha(filter)) ?
      style.filter = filter : style.filter = '';
    else style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
  };
}

function Appear(element) {
  var current = Opacity.get(element),
   options = arguments[1] || {};
  if (element.style.display != 'block')
    element.style.display = 'block';
  if (current < 1) {
    setTimeout(function() {
      Opacity.set(element, current += 0.05);
      Appear(element, options);
    }, 0.01);
  }
  else {
    if (Pushup.Browser.IE && element.style.filter)
      element.style.removeAttribute('filter');
    if (options.afterFinish) options.afterFinish.call();
  }
}

function Fade(element) {
  var current = Opacity.get(element),
   options = arguments[1] || {};
  if (current > 0) {
    setTimeout(function() {
      Opacity.set(element, current -= 0.05);
      Fade(element, options);
    }, 0.01);
  }
  else {
    element.style.display = 'none';
    if (options.afterFinish) options.afterFinish.call();
  }
}

function setPngBackground(element, url) {
  var options = Extend({
    align: 'top left',
    repeat: 'no-repeat',
    sizingMethod: 'crop',
    backgroundColor: ''
  }, arguments[2] || {});

  Extend(element.style, arguments.callee.IEBelow7 ? {
    filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' +
      url + '\'\', sizingMethod=\'' + options.sizingMethod + '\')'
  } : {
    background: options.backgroundColor + ' url(' + url + ') ' +
      options.align + ' ' + options.repeat
  });
}
setPngBackground.IEBelow7 = Pushup.Browser.IE &&
  parseFloat(/MSIE ([\d.]+)/.exec(navigator.userAgent)[1]) < 7;

// Based on the work of Peter-Paul Koch - http://www.quirksmode.org
var Cookie = {
  set: function(name, value) {
    var expires = '', options = arguments[2] || {};
    if (options.duration) {
      var date = new Date();
      date.setTime(date.getTime() + options.duration * 1000 * 60 * 60 * 24);
      value += '; expires=' + date.toGMTString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
  },

  remove: function(name) { this.set(name, '', -1) },

  get: function(name) {
    var cookies = document.cookie.split(';'), nameEQ = name + "=";
    for (var i = 0, l = cookies.length; i < l; i++) {
      var c = cookies[i];
      while (c.charAt(0) == ' ')
        c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0)
        return c.substring(nameEQ.length, c.length);
    }
    return null;
  }
};

// check if cookies are enabled
Pushup.cookiesEnabled = (function(test) {
  if (Cookie.get(test)) return true;
  Cookie.set(test, 'test', { duration: 15 });
  return Cookie.get(test);
})('_pushupCookiesEnabled');

var Event = {
  add: function(obj, type, fn) {
    if (obj.attachEvent) {
      obj['e' + type + fn] = fn;
      obj[type + fn] = function(){ obj['e' + type +fn](window.event) };
      obj.attachEvent('on' + type, obj[type + fn]);
    }
    else obj.addEventListener(type, fn, false);
  },

  stop: function(event) {
    if (Pushup.Browser.IE) {
      event.cancelBubble = true;
      event.returnValue = false;
    }
    else {
      event.preventDefault();
      event.stopPropagation();
    }
  }
};

Event.add(window, 'load', function() { Pushup.start() });
})();
