(function($){
  
  EventCalendar = function(){
    this.calendarDatasElt = $('#content_agenda');
    this.calendarContainer = $('#contenu_agenda');
    this.currentDayBtn = null;
    
    this.canPrevious = true; //on peut naviguer vers la précédente
    this.canNext = true; // on peu naviguer vers la suivante

    this.addLoader();
    
    this.isOpen = false;
    this.datas = calendarDatas;
    this.canChange = false; // si false : on est en train de rechercher des données
    this.hasEvts = false;
    this.currentWeekIds = {month:null, week:null, mday:null, wday:null, year:null};
    this.initCurrentWeek();
    
    
    this.initCalendarArea();
    this.initCurrentDay(true);

    this.initListeners.call(this);
  };
  // end EventCalendar()
  
  
  EventCalendar.prototype = {
    
    /*
     *
     *  initialisation des éléments
     *
     */
     
     TYPE_PREVIOUS : 1,
     TYPE_NEXT : 2,
     
     
     initCalendarArea : function(){
     var day = this.currentWeekIds.mday+7;
       $('#nav_agenda li a').each(function(index, elt){
         var currentDay = parseInt($(this).data("day"),10);
         if(!isNaN(currentDay) && currentDay > day ){
           $(this).text("");
           $(this).data('day', 0);
           $(this).parent().addClass("inactive");
         }
       });
     },
    
    
    initListeners : function(){
      var self = this;
      
      this.calendarDatasElt.click(function(evt){
        evt.preventDefault();
        if(self.hasEvts && !self.isOpen){
          self.isOpen = true;
          self.openInfos.call(self);
        }
      });
      
      $('#button_agenda').click(function(evt){ 
        evt.preventDefault();
        
        if(!self.hasEvts){
          return 0;
        }
        
        if(self.isOpen){
          self.closeInfos.call(self);
        }else{
          self.isOpen = true;
          self.openInfos.call(self);
        }
      });
      
      $("#nav_agenda li.close").click(function(evt){
        evt.preventDefault();
        
        if(!self.hasEvts){
          return 0;
        }
        
        if(self.isOpen){
          self.closeInfos.call(self);
        }else{
          self.isOpen = true;
          self.openInfos.call(self);
        }
      });
      
      this.initDayz.call(this);
    },
    
    
    
    initDayz : function(){
      var self = this;
      
      $("#nav_agenda li a").each(function(index, elt){
        
        $(this).click(function(evt){ 
          evt.preventDefault();
          if($(this).attr("id") == 'calendar_btn_previous'){
            if(self.canPrevious){
              self.canNext = true;
              self.displayPreviousWeek.call(self);
            }
          }else if($(this).attr("id") == 'calendar_btn_next'){
            if(self.canNext){
              self.canPrevious = true;
              self.displayNextWeek.call(self);
            } 
          }else{
            if($(this).data('day') == '0' || $(this).data('day') == ''){
              return;
            }
            self.changeCurrentDayBtn.call(self, $(this));
            self.displayDay.call(self, $(this).data('day'));
          }
        });
        
      });
      
    },
    
    
    displayDay : function(day){
      this.removeCurrentDay();
      this.currentWeekIds.mday = day;
      this.initCurrentDay();
    },
    
    
    /*
     * 
     * fonctions d'affichage
     * 
     */
    addLoader : function(){
      this.calendarDatasElt.addClass("loader");
    },
    
    removeLoader : function(){
       this.calendarDatasElt.removeClass("loader");
    },
    
    removeCurrentDay : function(){
      this.calendarDatasElt.children().remove();
      this.addLoader();
    },
    
    
    /**
     *  changement du style du bouton du jour sur lequel on était (passe en non selectionné) + on pointe sur le nouveau bouton actif
     */
    changeCurrentDayBtn : function(newDayBtn){ 
      if(!this.currentDayBtn){
        return 0;
      }
      this.currentDayBtn.text(this.currentDayBtn.data('day'));
      this.currentDayBtn.parent().removeClass("active");
      this.currentDayBtn = newDayBtn;
      this.currentDayBtn.parent().addClass("active");
      this.currentDayBtn.text(this.currentDayBtn.data('day_libelle') +'. '+ this.currentDayBtn.data('day'));
    },
    
    
    /**
     *  affichage de la semaine précédente : on selectionne le 1er jour dispo pour le mois en cours / si on change de mois, penser à changer l'intitulé
     */
    displayPreviousWeek : function(){
      this.canChange = false;
      this.removeCurrentDay();
      var self = this;
      var weekDays = this.getPreviousWeekDayz();
      
      if(!weekDays){
        return 0;
      }
      
      var cpt = 0;
      var firstBtnIsInit = false;
      var monthLibelle = Utilities.getMonth(this.currentWeekIds.month);
      $('.gcwt-table h4').text(monthLibelle+' '+this.currentWeekIds.year);
      $("#nav_agenda li a").each(function(index, elt){
        if($(this).attr("id") == 'calendar_btn_previous' || $(this).attr("id") == 'calendar_btn_next'){
          return;
        }

        if(weekDays[cpt] == 0){
          $(this).text('');
          $(this).data("day", '');
          $(this).parent().addClass("inactive");
        }else{
          $(this).parent().removeClass("inactive");
          $(this).text(weekDays[cpt]);
          $(this).data("day", weekDays[cpt]);
        }
        
        if(weekDays[cpt] != 0 && !firstBtnIsInit){
           self.changeCurrentDayBtn($(this));
           self.displayDay(weekDays[cpt]);
           firstBtnIsInit = true;
        }
        cpt++;
      });
      
      return 1;
    },
    
    
    
      /**
     *  affichage de la semaine suivante : on selectionne le 1er jour dispo pour le mois en cours
     */
    displayNextWeek : function(){
      this.canChange = false;
      this.removeCurrentDay();
      var self = this;
      var weekDays = this.getNextWeekDayz();
      
      if(!weekDays){
        return 0;
      }
      
      var cpt = 0;
      var firstBtnIsInit = false;
      var monthLibelle = Utilities.getMonth(this.currentWeekIds.month);
      $('.gcwt-table h4').text(monthLibelle+' '+this.currentWeekIds.year);
      $("#nav_agenda li a").each(function(index, elt){
        if($(this).attr("id") == 'calendar_btn_previous' || $(this).attr("id") == 'calendar_btn_next'){
          return;
        }

        if(weekDays[cpt] == 0){
          $(this).text('');
          $(this).data("day", '');
          $(this).parent().addClass("inactive");
        }else{
          $(this).text(weekDays[cpt]);
          $(this).data("day", weekDays[cpt]);
          $(this).parent().removeClass("inactive");
        }
        
        if(weekDays[cpt] != 0 && !firstBtnIsInit){
           self.changeCurrentDayBtn($(this));
           self.displayDay(weekDays[cpt]);
           firstBtnIsInit = true;
        }
        cpt++;
      });
      
      return 1;
    },
    
    
      
    /**
     * ouvrir les infos
     */
    openInfos : function(){
      this.calendarContainer.addClass("open");
      return 0;
      
      this.calendarContainer.animate({
        'margin-left':'-429px',
        'width':'670px'
      },{
        easing:'easeInOutCubic',
        duration:1000,
        step : function(){

        },
       complete:function(){
          $(this).addClass('open');
       } 
      });
    },




    /**
     * fermer les infos
     */
    closeInfos: function(){
       this.isOpen = false;
      this.calendarContainer.removeClass("open");
      
      return 0;
      
      var self = this;
      $('#content_agenda li p').css({"display":'none'});
      
      this.calendarContainer.animate({
        'margin-left':'0px',
        'width':'241px'
      },{
        easing:'easeInOutCubic',
        duration:1000,
        step : function(){

        },
       complete:function(){
        $('#content_agenda li p').css({"display":''});
         self.isOpen = false;
          $(this).removeClass('open');
       } 
      });
    },
    
    
   
   
   
    /*
     * 
     * 
     * traitement des données
     * 
     */
    
    
    
      /**
       *  si on est à la première donnée de la lsite, on bloque la nav previous
       */
     setCanPrevious : function(){
        for(var month in this.datas){
          if(this.currentWeekIds.month == month && this.currentWeekIds.week == 0){
            this.canPrevious = false;
            break;
          }
          break;
        }
      },
    
    
    /**
     *  check si on peut avancer à la semaine suivante, bloque si pas possible
     */
    setCanNext : function(){
        for(var lastMonth in this.datas);

        if(this.currentWeekIds.month == lastMonth && !this.datas[lastMonth][this.currentWeekIds.week+1]){
            this.canNext = false;
        }
        
      },
    
    
    /**
     * récupération des jours composants la semaine précédente
     * On ne prend que les jours du mois en cours
     */
    getPreviousWeekDayz : function(){
      
      this.currentWeekIds.week--;
      var week = [];
      var i;
      // cas le plus simple : on a trouvé une semaine dans notre mois courrant
      if(this.currentWeekIds.week >=0 && this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
        var datasLength = this.datas[this.currentWeekIds.month][this.currentWeekIds.week].length;
        var cpt = Utilities.getSizeOfObject(this.datas[this.currentWeekIds.month][this.currentWeekIds.week]);
        
        if(cpt < 7){
          for(i = cpt; i < 7; i++){
            week.push(0);
          }
        }
        for(i in this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
          week.push(i);
        }
      }else{
        // on n'a plus de semaine dans le mois courrant, on tente le mois précédent
        this.currentWeekIds.month--;
        if(this.currentWeekIds.month == 0){
          this.currentWeekIds.month = 12;
          this.currentWeekIds.year--;
        }
        
        if(this.currentWeekIds.month > 0 && this.datas[this.currentWeekIds.month]){
          var searchWeekPos = 0;
          for(i in this.datas[this.currentWeekIds.month]){
            searchWeekPos = i;//this.datas[this.currentWeekIds.month][i];
          }
          this.currentWeekIds.week = searchWeekPos;
          if(this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
              var j = 0;
              for(i in this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
                week.push(i);
                j++;
              }
              
              if(j < 7){
                for(cpt = j; cpt < 7; cpt++){
                  week.push(0);
                }
              }
          }
        }else{
          return null;
        }
      }
      
      this.setCanPrevious();

      return week;
    },
    
    
    /**
     *  récupération des jours composants la semaine suivante
     */
    getNextWeekDayz : function(){
      this.currentWeekIds.week++;
      var week = [];
      var i,cpt;
      // cas le plus simple : on a trouvé une semaine dans notre mois courrant
      if(this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
        cpt = 0;
        for(i in this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
          week.push(i);
          cpt++;
        }
        
        if(cpt < 7){
          for(i = cpt; i < 7; i++){
            week.push(0);
          }
        }
        
      }else{
        // on n'a plus de semaine dans le mois courrant, on tente le mois précédent
        this.currentWeekIds.month++;
        if(this.currentWeekIds.month > 12){
          this.currentWeekIds.month = 1;
          this.currentWeekIds.year++;
        }
        
        if(this.datas[this.currentWeekIds.month] && this.datas[this.currentWeekIds.month][0]){
          this.currentWeekIds.week = 0;
          if(this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
             cpt = Utilities.getSizeOfObject(this.datas[this.currentWeekIds.month][this.currentWeekIds.week]);
             if(cpt < 7){
                for(i = cpt; i < 7; i++){
                  week.push(0);
                }
              }
              for(i in this.datas[this.currentWeekIds.month][this.currentWeekIds.week]){
                week.push(i);
              }
          }
        }else{
          return null;
        }
      }
      
      this.setCanNext();
      
      return week;
    },
    
    
    /**
     *  sur le load : on récupère la semaine actuelle dans notre tas de données
     */
    initCurrentWeek : function(){
        
      var currentDate = new Date();
      this.currentWeekIds.month = currentDate.getMonth()+1;
      this.currentWeekIds.wday = currentDate.getDay();
      this.currentWeekIds.mday = currentDate.getDate();
      this.currentWeekIds.year = currentYear;
      
      var found = false;
      for(var i in this.datas[this.currentWeekIds.month]){
        for(var j in this.datas[this.currentWeekIds.month][i]){
          if(j == this.currentWeekIds.mday){
             this.currentWeekIds.week = parseInt(i, 10);
             found = true;
             break;
          }
        }
        
        if(found){
          break;
        }
      }
    },
    
    
    /**
     *  une fois la semaine et le mois fixés, on peu récupérer les données du jour et tout afficher
     */
    initCurrentDay : function(isInit){
      var self = this;
      if(!this.currentWeekIds.month || this.currentWeekIds.week === null || !this.currentWeekIds.mday || !this.datas){
        if(!isInit){
          this.canPrevious = false;
          this.canNext = false;
        }
        this.removeLoader();
        this.calendarDatasElt.append("<p>Aucun événement n'a lieu ce jour</p>");
        
        $('#nav_agenda li a').each(function(index, elt){
          if($(this).data("day") == self.currentWeekIds.mday){
            self.currentDayBtn = $(this);
          }
        });
        
        return 0;
      }

      this.removeCurrentDay();
      $('#nav_agenda li a').each(function(index, elt){
        if($(this).data("day") == self.currentWeekIds.mday){
          self.currentDayBtn = $(this);
        }
      });
      
      var datasForToday = this.datas[this.currentWeekIds.month][this.currentWeekIds.week][this.currentWeekIds.mday];
      
      
      var contentLength = datasForToday.length;
      if(!contentLength){
        this.hasEvts = false;
        this.calendarDatasElt.append("<p>Aucun événement n'a lieu ce jour</p>");
      }else{
        for(var i=0; i < contentLength; i++){
            var contentElt = $('<li>');
            var contentPlace = "";
            if(datasForToday[i].location != ""){
                var contentPlace = $('<p class="place">'+datasForToday[i].location+'</p>');
            }
            var contentTitle = "";
            if(datasForToday[i].title != ""){
                var contentTitle = $('<h3>'+datasForToday[i].title+'</h3>');
            }
            var contentDesc = "";
            if(datasForToday[i].description!=""){
                contentDesc = $('<p>'+datasForToday[i].description+'</p>');
            }
            contentElt.append(contentPlace);
            contentElt.append(contentTitle);
            contentElt.append(contentDesc);
           
            if(contentElt.html() != ""){
                this.calendarDatasElt.append(contentElt);
            }
           
           
        }
        this.hasEvts = true;
      }
      this.canChange = true;
      this.removeLoader();
    }
    
    
    
  };
  // end EventCalendar.prototype 
  
  
})(jQuery);





(function(){
 
 
     Utilities = {
       
       months : [
         'Janvier',
         'Février',
         'Mars',
         'Avril',
         'Mai',
         'Juin',
         'Juillet',
         'Août',
         'Septembre',
         'Octobre',
         'Novembre',
         'Décembre',
       ],
       
       getMonth : function(monthId){
         
         return this.months[monthId-1];
         
       },
       
       getSizeOfObject : function(obj){
         var cpt = 0;
         for(var i in obj){
           cpt++;
         }

         return cpt;
      }
     };
 
})();
