if(!Calendar){var Calendar = new Object();}

function eResa_dispos()
{
    this.dispos = null;
    this.arrivalDates = null;
    this.specialDays = specialDays;
    this.nextDateDispo = null;


    this.init = function(offerCode, calendar) {
        var page = getBaseLink() + 'product/jsondispo/';

        var thisDispos = this;
        var thisCalendar = calendar;
        new Ajax.Request(
          page,
          {
              method:'post',
              parameters: $H({'code':offerCode}).toQueryString(),
              onCreate: function() {
                thisCalendar.disable();
              },
              onComplete:function(request){
                var dispoList = request.responseText.evalJSON();

                var dispoListSort = function (a,b) {return parseInt(a) - parseInt(b)};

                for (var i in dispoList) {
                    if (dispoList[i]) {
                        dispoList[i] = dispoList[i].concat(dispoList[i]).sort(dispoListSort).uniq();
                    } else {
                        dispoList[i] = dispoList[i];
                    }
                }

                thisDispos.dispos = dispoList;

                if(thisDispos.dispos){
                    thisDispos.arrivalDates = Object.keys(thisDispos.dispos).sort();
                }

                thisDispos.calculNextDateDispo();

                thisCalendar.initDateDefault();

                thisCalendar.enable();
              }
          }
        );
    }

    this.calculNextDateDispo = function() {

        var now = new Date();
        this.nextDateDispo = now;
        for (var date in this.dispos) {
            tabDate = date.split('-');
            dateDispo = new Date(Number(tabDate[0]), Number(tabDate[1])-1, Number(tabDate[2]));
            if(dateDispo > now) {
                this.nextDateDispo = dateDispo;
                break;
            }
        }
    }
}

function eResa_calendar(eltDateIn, eltDateOut, fieldIn, fieldOut, eltContainer)
{
    this.enabled = true;

    this.dayNames = new Array();
    this.dateCells = new Array();
    this.today = new Date();
    this.dayNamesPositions = new Array();
    this.datesPositions = new Array();

    this.calendarIdList = new Array();
    this.calendarReferentDates = new Array();

    this.firstLoad = true;
    this.calendarToLoad = null;

    this.eltCallCalendar = null;

    this.dispos = null;

    this.fieldIn = fieldIn;
    this.fieldOut = fieldOut;

    this.eltDateIn = eltDateIn;
    this.eltDateOut = eltDateOut;

    this.eltContainer = eltContainer;

    this.title = '&nbsp;';

    this.handlerDateIn = null;
    this.handlerDateOut = null;
    this.handlerDateError = null;

    this.durationDefault = 7;

    this.init = function(offerCode, defaultDuration)
    {
        this.initDuration(defaultDuration);

        this.dateInCalendrier(eltDateIn);
        this.dateOutCalendrier(eltDateOut);

        this.dispos = new eResa_dispos();
        this.dispos.init(offerCode, this);
    }

    this.initDuration = function(defaultDuration)
    {
        if(defaultDuration && defaultDuration > 0) {
            this.durationDefault = defaultDuration;
        }
        else
        {
            if('undefined' != typeof eresa_duration_default) {
                this.durationDefault = eresa_duration_default;
            }
        }
    }

    this.disable = function()
    {
        $(this.fieldIn).disable();
        $(this.fieldOut).disable();
        this.enabled = false;
    }

    this.enable = function()
    {
        $(this.fieldIn).enable();
        $(this.fieldOut).enable();
        this.enabled = true;
    }

    this.isEnabled = function()
    {
        return this.enabled;
    }

    // init le listener sur l'élément du calendrier pour la date d'arrivee
    this.dateInCalendrier = function(elt){
        if(elt){
            var thisCalendar = this;
            Event.observe(
                elt,
                'click',
                function(){
                    if(thisCalendar.isEnabled())
                    {
                        thisCalendar.calendarToLoad = 'in';
                        thisCalendar.eltCallCalendar = elt;

                        if(thisCalendar.firstLoad){

                            thisCalendar.firstLoad = false;

                            thisCalendar.initCalendar();
                        }
                        else{
                            thisCalendar.showCalendar();
                        }
                    }
                }
            );
        }
    }

    // init le listener sur l'élement du calendrier pour la date de depart
    this.dateOutCalendrier = function(elt){
        if(elt){
            var thisCalendar = this;
            Event.observe(
                elt,
                'click',
                function(){
                    if(thisCalendar.issetDateIn()) {
                        if(thisCalendar.isEnabled())
                        {
                            thisCalendar.calendarToLoad = 'out';
                            thisCalendar.eltCallCalendar = elt;

                            if(thisCalendar.firstLoad){
                            
                                thisCalendar.firstLoad = false;

                                thisCalendar.initCalendar();
                            }
                            else{
                                thisCalendar.showCalendar();
                            }
                        }
                    } else {
                        fireEvent(thisCalendar.eltDateIn, 'click');
                    }
                }
            );
        }
    }

    this.issetDateIn = function()
    {
        var dateIn = getStrToDate($(this.fieldIn).value);
        if(dateIn == null) {
            return false;
        } else {
            return true;
        }
    }

    this.initDateDefault = function()
    {
        if('undefined' != typeof eresa_date_default) {
            this.calendarReferentDates[0] = eresa_date_default;
            this.onSelectDateIn(eresa_date_default);
        }
    }

    // initialisation du calendrier, appelee lors du premier chargement uniquement
    this.initCalendar = function(){

        if($('calendrier')){
            if($('REcalendarFirstPanel')){
                this.calendarIdList[0] = 'REcalendarFirstPanel';
                if(!this.calendarReferentDates[0]){
                    this.calendarReferentDates[0] = this.dispos.nextDateDispo;
                }

            }

            if($('REcalendarSecondPanel')){
                this.calendarIdList[1] = 'REcalendarSecondPanel';
                if(this.calendarReferentDates[0]){
                    this.calendarReferentDates[1] = this.getNextMonthDate(this.calendarReferentDates[0]);
                }
            }

            for(var i=0; i< this.calendarIdList.length; i++){
                this.dayNames[i] = $(this.calendarIdList[i]).select('th.dayname');
                this.writeDaynames(this.dayNames[i]);
                this.dateCells[i] = $(this.calendarIdList[i]).select('td.days');
                this.datesPositions[i] = new Array();
            }
            
            this.initNavigation();
            
            this.showCalendar();
        }
    }

    // Ecrit le nom abbrege des jours
    this.writeDaynames = function(daynamesCells){

        if(daynamesCells){
            for(var i=0; i< daynamesCells.length; i++){
                daynamesCells[i].innerHTML = Calendar._SDN[i+1];
            }
        }

        this.dayNamesPositions = [6, 0, 1, 2, 3, 4, 5];
    }

    // affiche le calendrier sur la page
    this.showCalendar = function(){

        dateIn = getStrToDate($(this.fieldIn).value);

        if(dateIn !== null){
            this.calendarReferentDates[0] = new Date(dateIn.getFullYear(), dateIn.getMonth(), 1);
            this.calendarReferentDates[1] = this.getNextMonthDate(this.calendarReferentDates[0]);
        }

        for(var i=0; i< this.calendarIdList.length; i++){
            this.writeCalendar(i, this.calendarReferentDates[i]);
        }

        this.updateCalendarView();

        $('titreCalendrier').innerHTML = this.title;

        var position = this.getAbsolutePos(this.eltCallCalendar);
        var positionContainer = this.getAbsolutePos(this.eltContainer);
        var newYPos = position.y - positionContainer.y;
        var newXPos = position.x - positionContainer.x + this.eltCallCalendar.offsetWidth + 5;

        $('calendrier').style.position = "absolute";
        $('calendrier').style.zIndex = 3000;
        $('calendrier').style.top = newYPos+'px';
        $('calendrier').style.left = newXPos+'px';
        $('calendrier').style.display = "block";
    }

    // Nettoie puis ecrit le calendrier
    this.writeCalendar = function(numCalendar, startDate){
        if($(this.calendarIdList[numCalendar])){
            this.cleanCalendar(numCalendar);
            this.dateCells[numCalendar] = $(this.calendarIdList[numCalendar]).select('td.days');
            this.writeDates(startDate, numCalendar);
        }
    }

    // Ecrit les dates dans le tableau
    this.writeDates = function(startDate, numCalendar){

        var calendarMonth = startDate.getMonth();
        var calendarYear = startDate.getFullYear();

        var monthName = $(this.calendarIdList[numCalendar]).select('p.mois')[0];
        if(monthName){
            monthName.innerHTML = Calendar._MN[calendarMonth] + " " + calendarYear;
        }

        var nbDaysinMonth = startDate.getMonthDays();
        var dayOne = new Date(startDate.getFullYear(), startDate.getMonth(), 1);
        var firstDayOfMonth = Number(this.dayNamesPositions[dayOne.getDay()]);

        for(var i=0; i<nbDaysinMonth; i++)
        {
            var newDate = new Date(this.calendarReferentDates[numCalendar].getFullYear(), this.calendarReferentDates[numCalendar].getMonth(), Number(i+1));

            if(newDate <= this.today)
            {
                this.dateCells[numCalendar][firstDayOfMonth+i].innerHTML = '<span>'+(i+1)+'</span>';
                this.dateCells[numCalendar][firstDayOfMonth+i].addClassName('inactif');
            }
            else
            {
                this.dateCells[numCalendar][firstDayOfMonth+i].innerHTML = '<span>'+(i+1)+'</span>';

                if(newDate.getDay() == 0 || newDate.getDay() == 6){
                    this.dateCells[numCalendar][firstDayOfMonth+i].addClassName('weekEnd');
                }
            }

            this.datesPositions[numCalendar][i] = {},
            this.datesPositions[numCalendar][i].cell = this.dateCells[numCalendar][firstDayOfMonth+i];
            this.datesPositions[numCalendar][i].date = calendarYear + "-" + calendarMonth + "-" + (i+1);
        }

        // si le mois est sur 6 semaines, on affiche la derniere ligne
        if((firstDayOfMonth+i) > 35)
        {
             var lastRow = $(this.calendarIdList[numCalendar]).select('tr.lastRow')[0];
             if(lastRow){
                lastRow.style.display = "";
             }
        }

        // Ajout de la classe 'inactif' au début et a la fin du tableau
        for(var i = 0; i < firstDayOfMonth; i++){
             this.dateCells[numCalendar][i].innerHTML = '--';
             this.dateCells[numCalendar][i].addClassName('inactif');
        }

        for(var i = (nbDaysinMonth+firstDayOfMonth); i < this.dateCells[numCalendar].length; i++){
             this.dateCells[numCalendar][i].innerHTML = '--';
             this.dateCells[numCalendar][i].addClassName('inactif');
        }
    }

    // une fois les dates ecrites, on met a jour l'affichage avec les jours feries, les vacances et les dispos
    this.updateCalendarView = function(numCalendar){
        for(var numCalendar=0; numCalendar< this.calendarIdList.length; numCalendar++)
        {
            if(numCalendar == 0){
                var today = new Date();
                if(this.calendarReferentDates[0] <= today){
                    if($('cal_previousButton')) $('cal_previousButton').up().style.visibility = "hidden";
                }
                else{
                    if($('cal_previousButton')) $('cal_previousButton').up().style.visibility = "visible";
                }
            }

            if(this.dispos.specialDays)    // PROBLEM
            {
                // Affichage des jours feries
                if(this.dispos.specialDays.daysOff)
                {
                    if(this.dispos.specialDays.daysOff[this.calendarReferentDates[numCalendar].getFullYear()])
                    {
                        if(this.dispos.specialDays.daysOff[this.calendarReferentDates[numCalendar].getFullYear()][(this.calendarReferentDates[numCalendar].getMonth()+1)])
                        {
                            var currentSpecialDays = this.dispos.specialDays.daysOff[this.calendarReferentDates[numCalendar].getFullYear()][(this.calendarReferentDates[numCalendar].getMonth()+1)];

                            var thisCalendar = this;
                            currentSpecialDays.each(function(specialDay){
                                if(thisCalendar.datesPositions[numCalendar][specialDay-1])
                                {
                                    if(!thisCalendar.datesPositions[numCalendar][specialDay-1].cell.hasClassName('inactif'))
                                        thisCalendar.datesPositions[numCalendar][specialDay-1].cell.addClassName('holidays2');
                                }
                            });
                        }
                    }
                }

                // Affichage des vacances scolaires
                if(this.dispos.specialDays.holidays)
                {
                    if(this.dispos.specialDays.holidays[this.calendarReferentDates[numCalendar].getFullYear()])
                    {
                        if(this.dispos.specialDays.holidays[this.calendarReferentDates[numCalendar].getFullYear()][this.calendarReferentDates[numCalendar].getMonth()+1])
                        {
                            var currentSpecialDays = this.dispos.specialDays.holidays[this.calendarReferentDates[numCalendar].getFullYear()][this.calendarReferentDates[numCalendar].getMonth()+1];

                            var thisCalendar = this;
                            currentSpecialDays.each(function(specialDay)
                            {
                                if(thisCalendar.datesPositions[numCalendar][specialDay-1])
                                {
                                    if(!thisCalendar.datesPositions[numCalendar][specialDay-1].cell.hasClassName('inactif'))
                                        thisCalendar.datesPositions[numCalendar][specialDay-1].cell.addClassName('holidays');
                                }
                            });
                        }
                    }
                }
            }

            // Affichage des dates d'arrivee possibles dans la cas du calendrier  pour la date d'arrivee
            if(this.calendarToLoad == 'in')
            {
                if(this.dispos.arrivalDates)
                {
                    for(var i=0; i< this.dispos.arrivalDates.length; i++){
                        var arrivalDate = this.dispos.arrivalDates[i];
                        var arrivalYear = arrivalDate.split('-')[0];
                        var arrivalMonth = arrivalDate.split('-')[1];
                        var arrivalDay = Number(arrivalDate.split('-')[2]);

                        if(this.calendarReferentDates[numCalendar].getFullYear() == arrivalYear && this.calendarReferentDates[numCalendar].getMonth()+1 == arrivalMonth){
                            if(!this.datesPositions[numCalendar][arrivalDay-1].cell.hasClassName('inactif')){
                                this.datesPositions[numCalendar][arrivalDay-1].cell.innerHTML = '<a href="#" title="'+arrivalYear+'-'+arrivalMonth+'-'+arrivalDay+'">'+ arrivalDay + '</a>';
                            }
                        }
                    }

                    // Init des listeners sur les dates cliquables
                    var clickableDates = $(this.calendarIdList[numCalendar]).select('tbody')[0].select('a');

                    if(clickableDates)
                    {
                        var thisCalendar = this;
                        clickableDates.each(function(dateLink){
                            Event.observe(
                                dateLink,
                                'click',
                                function(evt){
                                    Event.stop(evt);
                                    var params = dateLink.title.split('-');
                                    thisCalendar.onSelectDateIn(new Date(params[0], Number(params[1]-1), Number(params[2])));
                                }
                            );
                        })
                    }
                }

                dateIn = getStrToDate($(this.fieldIn).value);
                if(dateIn !== null)
                {
                    if(this.calendarReferentDates[numCalendar].getFullYear() == dateIn.getFullYear() && this.calendarReferentDates[numCalendar].getMonth() == dateIn.getMonth()){
                        this.datesPositions[numCalendar][dateIn.getDate()-1].cell.addClassName('REselectedLink');
                    }
                }
            }
            // cas du calendrier pour la date de depart
            else if(this.calendarToLoad == 'out')
            {
                var dateIn = getStrToDate($(this.fieldIn).value);
                var dateOut = getStrToDate($(this.fieldOut).value);

                if(dateOut !== null)
                {
                    if(this.calendarReferentDates[numCalendar].getFullYear() == dateOut.getFullYear() && this.calendarReferentDates[numCalendar].getMonth() == dateOut.getMonth()){
                        this.datesPositions[numCalendar][dateOut.getDate()-1].cell.addClassName('REselectedLink');
                    }
                }

                var departureDates = '';

                if(this.dispos.arrivalDates){
                    //departureDates = eResa_dispos.dispos[dateIn.print(Calendar._TT["JSON_DATE_FORMAT"])];
                    departureDates = this.dispos.dispos[dateIn.print('%Y-%m-%d')];
                    for(var i= 0; i< departureDates.length; i++){
                        var nextDateTime = dateIn.getTime() + (Number(departureDates[i])*Date.DAY);
                        var nextDate = new Date();
                        nextDate.setTime(nextDateTime);
                        if(this.calendarReferentDates[numCalendar].getFullYear() == nextDate.getFullYear() && this.calendarReferentDates[numCalendar].getMonth() == nextDate.getMonth()){
                            this.datesPositions[numCalendar][nextDate.getDate()-1].cell.innerHTML = '<a href="#" title="'+nextDate.getFullYear()+'-'+nextDate.getMonth()+'-'+nextDate.getDate()+'">'+ nextDate.getDate() + '</a>';
                        }
                    }
                }

                // Init des listeners sur les dates de depart cliquables
                var clickableDatesOut = $(this.calendarIdList[numCalendar]).select('tbody')[0].select('a');
                if(clickableDatesOut){
                    thisCalendar = this;
                    clickableDatesOut.each(function(dateLink){
                        Event.observe(
                            dateLink,
                            'click',
                            function(evt){
                                Event.stop(evt);
                                var params = dateLink.title.split('-');
                                thisCalendar.onSelectDateOut(new Date(params[0], Number(params[1]), Number(params[2])));
                            }
                        );
                    })
                }
            }
        }

        var maxDispoDate = this.dispos.arrivalDates[this.dispos.arrivalDates.length-1];
        var maxArrivalYear = maxDispoDate.split('-')[0];
        var maxArrivalMonth = maxDispoDate.split('-')[1];

        if(this.calendarReferentDates[1].getFullYear() == maxArrivalYear && this.calendarReferentDates[1].getMonth()+1 == maxArrivalMonth){
            if($('cal_nextButton')) $('cal_nextButton').up().style.display = "none";
        }
        else{
            if($('cal_nextButton')) $('cal_nextButton').up().style.display = "block";
        }
    }

    // Efface le contenu du calendrier et enleve les classes CSS eventuelles (inactif, holidays, holidays2, weekEnd, REselectedLink)
    this.cleanCalendar = function(numCalendar){
        for(var i=0; i<this.dateCells[numCalendar].length; i++){
            this.dateCells[numCalendar][i].innerHTML = '';
            this.dateCells[numCalendar][i].removeClassName('inactif');
            this.dateCells[numCalendar][i].removeClassName('weekEnd');
            this.dateCells[numCalendar][i].removeClassName('holidays2');
            this.dateCells[numCalendar][i].removeClassName('holidays');
            this.dateCells[numCalendar][i].removeClassName('REselectedLink');
            var lastRow = $(this.calendarIdList[numCalendar]).select('tr.lastRow')[0];
            if(lastRow){
                lastRow.style.display = "none";
            }
        }
        this.datesPositions[numCalendar] = new Array();
        this.dateCells[numCalendar] = new Array();
    }

    // Initialise les evenements sur les boutons de navigation
    this.initNavigation = function(){
        if($('cal_nextButton')){
            thisCalendar = this;
            Event.observe(
                $('cal_nextButton'),
                'click',
                function(evt){
                    Event.stop(evt);

                    thisCalendar.calendarReferentDates[0] = thisCalendar.getNextMonthDate(thisCalendar.calendarReferentDates[0]);
                    thisCalendar.calendarReferentDates[1] = thisCalendar.getNextMonthDate(thisCalendar.calendarReferentDates[0]);

                    for(var i=0; i< thisCalendar.calendarIdList.length; i++){
                        thisCalendar.writeCalendar(i, thisCalendar.calendarReferentDates[i]);
                    }

                    thisCalendar.updateCalendarView();
                }
            );
        }

        if($('cal_previousButton')){
            thisCalendar = this;
            Event.observe(
                $('cal_previousButton'),
                'click',
                function(evt){
                    Event.stop(evt);

                    thisCalendar.calendarReferentDates[0] = thisCalendar.getPreviousMonthDate(thisCalendar.calendarReferentDates[0]);
                    thisCalendar.calendarReferentDates[1] = thisCalendar.getNextMonthDate(thisCalendar.calendarReferentDates[0]);

                    for(var i=0; i< thisCalendar.calendarIdList.length; i++){
                        thisCalendar.writeCalendar(i, thisCalendar.calendarReferentDates[i]);
                    }

                    thisCalendar.updateCalendarView();
                }
            );
        }

        if($('cal_closeButton')){
             Event.observe(
                $('cal_closeButton'),
                'click',
                function(evt){
                    Event.stop(evt);
                    $('calendrier').style.display = "none";
                }
            );
        }
    }

    // Renvoie le prochaine date de reference
    this.getNextMonthDate = function(currentDate){
        var currentMonth = currentDate.getMonth();
        var currentYear = currentDate.getFullYear();

        if(currentMonth == 11){
            var nextMonth = 0;
            var nextYear = currentYear + 1;
        }
        else{
            var nextMonth = currentMonth +1;
            var nextYear = currentYear;
        }

        var nextDate = new Date(nextYear, nextMonth, 1);
        return nextDate;
    }

    // Renvoie la precedente date de reference
    this.getPreviousMonthDate = function(currentDate){
        var currentMonth = currentDate.getMonth();
        var currentYear = currentDate.getFullYear();

        if(currentMonth == 0){
            var nextMonth = 11;
            var nextYear = currentYear - 1;
        }
        else{
            var nextMonth = currentMonth -1;
            var nextYear = currentYear;
        }

        var nextDate = new Date(nextYear, nextMonth, 1);
        return nextDate;
    }

    // actions lors du choix de la date d'arrivee
    this.onSelectDateIn = function(selectedDate){

        //this.initDuration();
        if(this.checkDispoDateIn(selectedDate)) {

            $(this.fieldIn).value = selectedDate.print('%d/%m/%Y');

            var newDateOut = this.checkDispoDateOut(selectedDate, this.durationDefault);
            if(newDateOut !== null) {
                $(this.fieldOut).value = newDateOut.print('%d/%m/%Y');
            }
        }

        $('calendrier').style.display = "none";

        if(this.handlerDateIn != null) {
            eval(this.handlerDateIn);
        }
    }

    this.checkDispoDateIn = function(date) {
        if(this.dispos.arrivalDates.include(date.print('%Y-%m-%d'))) {
            return (date > this.today);
        } else {
            return false;
        }
    }
    
    this.checkDispoDateOut = function(dateIn, duration) {
        var listDuration = this.dispos.dispos[dateIn.print('%Y-%m-%d')].reverse();

        var dateOut = null;
        if(listDuration.include(duration)) {
            dateOut = new Date(dateIn.getTime() + (Date.DAY * duration));
        } else {
            var newDuration  = 0;
            for (data in listDuration) {
                if(listDuration[data] <= duration) {
                    newDuration = listDuration[data];
                    break;
                }
            };
            if(newDuration > 0) {
                dateOut = new Date(dateIn.getTime() + (Date.DAY * newDuration));
            }
        }
        return dateOut;
    }

    // actions lors du choix de la date de depart
    this.onSelectDateOut = function(selectedDate){
        //this.initDuration();
        selectedDate.setMonth(selectedDate.getMonth());
        $(this.fieldOut).value = selectedDate.print('%d/%m/%Y');
        
        $('calendrier').style.display = "none";

        if(this.handlerDateOut != null) {
            eval(this.handlerDateOut);
        }
    }

    this.getAbsolutePos = function(el) {
        var SL = 0, ST = 0;
        var is_div = /^div$/i.test(el.tagName);
        if (is_div && el.scrollLeft)
            SL = el.scrollLeft;
        if (is_div && el.scrollTop)
            ST = el.scrollTop;
        var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
        if (el.offsetParent) {
            var tmp = this.getAbsolutePos(el.offsetParent);
            r.x += tmp.x;
            r.y += tmp.y;
        }
        return r;
    }

    this.setTitle = function(title) {
        this.title = title;
    }

    this.addHandlerDateIn = function(handlerFunction) {
        this.handlerDateIn = handlerFunction;
    }

    this.addHandlerDateOut = function(handlerFunction) {
        this.handlerDateOut = handlerFunction;
    }

    this.addHandlerError = function(handlerFunction) {
        this.handlererror = handlerFunction;
    }
}

