/**
 * triTable plugin
 *
 */
(function($){
   $.triTable = function(jEl,param) {
      var param = $.extend({
         nbLignes :20,
         choixOrd : new Array(),
         sauvLigne : new Array(),
         jTbody : $("tbody", jEl),
         listeTrExecpt : new Array(),
         listeTrActu : null,
         tr_action : null
      },param);
      $("tbody tr", jEl).each(function(){ param.sauvLigne.push( $(this).clone() ); });

      var nbTr = $("tbody tr", jEl).length;
      if ( nbTr == 0 )
         jEl.append('<div class="rechercheVide">Aucun résultat ne correspond aux critères de recherche</div>');
      else if ( nbTr > 4 ){
         ajoutModulePag ();
         ajoutModuleRech();
         initTri();
         initOrd();
         initDat();      
         affichageLigne(1, true, true);
      }
      else if ( param.tr_action != null )
         $("tbody tr", jEl).css('cursor', 'pointer').click(function(){
            param.tr_action( $(this) );
         });
      
         
   
      /**
       * @name ajoutModulePag
       * @desc ajoute sous le tableau de quoi changer le numéro de la page
       */
      function ajoutModulePag () {
         jEl.append('<div class="rechercheVide">Aucun média ne correspond aux critères de recherche</div>\
                        <div class="pagination">\
                            <span class="pageInf">.</span>\
                            <input class="numPage" type="text" size="1" /> /  <input class="nbPage" type="text" size="1" readonly="readonly" />\
                            <span class="pageSup">.</span>\
                        </div>');
      
         $(".pageInf", jEl).click(function(){  affichageLigne(parseInt( $(".numPage", jEl).val() ) - 1, false, false); });
         $(".pageSup", jEl).click(function(){ affichageLigne(parseInt( $(".numPage", jEl).val() ) + 1, false, false); });
         $(".numPage", jEl).change(function(){ affichageLigne(parseInt( $(".numPage", jEl).val() ), false, false); });
      }
      /**
       * @name ajoutModuleRech
       * @desc ajoute au dessus du tableau de quoi faire une recherche sur les mots du tableau
       */
      function ajoutModuleRech () {
         $('<div class="motCles">Recherche <input id="motCle" type="text" size="30" /></div>').insertBefore( $("table", jEl) );
         
         
         $("#motCle", jEl).keyup(function(){
            var listeMot = $.triTable.TransfoPourComparaison($(this).val()).split(' ');
            param.listeTrExecpt['rech'] = new Array();
            for( var i in param.sauvLigne )
               for   (var j in listeMot){
                  var reg = new RegExp('>[^<]*' + listeMot[j].toLowerCase() + '[^>]*<');
                  if ( !reg.test(param.sauvLigne[i].html().toLowerCase()) ){
                     param.listeTrExecpt['rech'].push(i);
                     break;
                  }
               }
            affichageLigne(1, true, true);
         });
      }
      /**
       * @name initTri
       * @desc ajoute les modules de tri et les actions sur les elements de tri
       */
      function initTri(){      
         $('th.tri', jEl).each(function(){
            var numCol = $('> table > thead > tr > th', jEl).index( $(this)[0] );
            var triCol = new Array();
            param.listeTrExecpt[numCol] = new Array();
            
            $('> table > tbody tr', jEl).each(function(){
               var temp = $("td", $(this) ).eq(numCol).text().split(', ');
               for (var j in temp){
                  if ( !in_array(temp[j], triCol) )
                     triCol.push(temp[j]);
               }                        
            });
            
			var lSel = parseInt($("colgroup col").eq(numCol).attr('width'));
			var lSel = isNaN(lSel) ? 'auto' : lSel - 10;
            var f = $('<div></div>');
			var t = $('<select style="width:'+ lSel +'px"><option selected="selected" value="Tous">Tous</option></select>');
            triCol.sort();
            for ( var j in triCol)
               t.append('<option value="'+triCol[j]+'">'+triCol[j]+'</option>');
            f.append(t);
            $(this).append(f);

			$("select", $(this)).change(function(){
               param.listeTrExecpt[numCol] = new Array();
               if ( $(this).val() != 'Tous' )
                  for( var i in param.sauvLigne ){
                     var chpOrd = $("td", param.sauvLigne[i]).eq(numCol).text();
                     var reg = new RegExp('^(.*, )*' + $(this).val() + '(, .*)*');
                     if ( !reg.test(chpOrd) )
                        param.listeTrExecpt[numCol].push(i);
                  }
               affichageLigne(1, true, true);
            });
         });
		 $("option[@value='Tous']", $("th.tri div")).attr('selected', 'selected');
      }
      /**
       * @name initOrd
       * @desc defini la première colonne comme ordonné et defini les actions liée
       */
      function initOrd(){   
         $("th.dat", jEl).addClass('ord');
         $("th.ord", jEl).each(function(){ 
            $(this).html('<span>'+$(this).text()+'</span>'); 
            if ( $("th.ord", jEl).index($(this)[0]) == 0 ){
               $(" > span", $(this)).attr('class', 'asc');
               param.choixOrd = [$("> th", $(this).parent()).index( $(this)[0] ), 'asc'];
            }            
         });
         
         $("th.ord", jEl).click(function(){
            var nvClass = $(" > span", $(this)).attr('class') == 'asc' ? 'desc' : 'asc';
            $(" > span", $("th.ord", jEl)).attr('class', '');
            $(" > span", $(this)).attr('class', nvClass);
            param.choixOrd = [$("> th", $(this).parent()).index( $(this)[0] ), nvClass];
            affichageLigne(1, false, true);
         });
      }
      /**
       * @name initDat
       * @desc initialisation des élements et actions sur un tri de type date
       */
      function initDat(){   
         $("th.dat", jEl).each(function(){
            dtMini = null;
            var numCol = $("> table > thead > tr > th", jEl).index( $(this)[0] );
            
            $("> table >tbody tr", jEl).each(function(){
               temp1 = $("td", $(this)).eq(numCol).text().replace(/^([0-9]{2})\/([0-9]{2})\/([0-9]{4}).*$/, "$3$2$1");
               if ( dtMini == null || dtMini > temp1 ) dtMini = temp1;
            });
            $(this).append('<div class="cdCalendrier">\
                             du <span>'+ dtMini.replace(/([0-9]{4})([0-9]{2})([0-9]{2})$/, "$3/$2/$1") +'</span> au ...\
                           <div class="calendrier"></div>\
                        </div>');
            param.listeTrExecpt[numCol] = new Array();

            $(".calendrier", $(this)).calendrier({
               listeDate : dtMini,
               action_valide : function(jCal, date) { 
                  jCal.hide().prev().text(date.replace(/([0-9]{4})([0-9]{2})([0-9]{2})$/, "$3/$2/$1"));
                  $(" > span", $("th.ord", jEl)).attr('class', '');
                  $(" > span", jCal.parent().parent()).attr('class', 'asc');
                  param.choixOrd = [numCol, 'asc'];                  
                  
                  param.listeTrExecpt[numCol] = new Array();
                  if ( date != dtMini )
                     for( var i in param.sauvLigne ){
                        var j = $("td", param.sauvLigne[i]).eq(numCol).text().replace(/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/g, "$3$2$1").split(', ');
                        if ( !in_array(date, j, 'sup' ) )
                           param.listeTrExecpt[numCol].push(i);
                     }
                  affichageLigne(1, true, true);
               }
            });
         });
         $("th.dat .cdCalendrier", jEl).click(function(){ 
            $(".calendrier", $(this)).show() ; 
            return false; 
         }).mouseout(function(){  $(".calendrier", $(this)).hide() ; });
         $("th.dat .calendrier", jEl).mouseover(function(){  $(this).show() ; });
      }
      /**
       * @name affichageLigne
       * @desc affiche les lignes correspondantes au num de la page, des critères de tri et d'ordre
       */      
      function affichageLigne(numPage, modifTri, modifOrd){
         
         if ( modifTri || param.listeTrActu == null ){
            var tabExcept = new Array();
            param.listeTrActu = new Array();
            for (var i in param.listeTrExecpt)
               tabExcept = tabExcept.concat(param.listeTrExecpt[i]);
            for( var i in param.sauvLigne )
               if ( !in_array(i, tabExcept) )
                  param.listeTrActu.push(i);
         }
         if ( modifOrd ){
            var listeTrTri = new Array();
            var typDat = $("> table > thead > tr > th", jEl).eq(param.choixOrd[0]).attr('class').indexOf('dat') != -1;
            for ( var i in param.listeTrActu ){
               var chpOrd = $("td", param.sauvLigne[param.listeTrActu[i]]).eq(param.choixOrd[0]).text().replace(/\s*/g, '');
			   if ( param.choixOrd[1] == 'asc')
                  listeTrTri.push( (!typDat ? chpOrd.toLowerCase() : chpOrd.replace(/^([0-9]{2})\/([0-9]{2})\/([0-9]{4}).*/, "$3$2$1")) +'[/]'+ param.listeTrActu[i]);
               else
			      listeTrTri.push( (!typDat ? chpOrd.toLowerCase() : chpOrd.replace(/^.*([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/, "$3$2$1")) +'[/]'+ param.listeTrActu[i]);
			}
            listeTrTri.sort();
            if ( param.choixOrd[1] == 'desc' ) listeTrTri.reverse();
            
            param.listeTrActu = new Array();
            for ( var i in listeTrTri )
               param.listeTrActu.push( listeTrTri[i].split('[/]')[1] );
         }         
         
         $("tr", param.jTbody).remove();
         if ( param.listeTrActu.length > 0 ){
            $(".rechercheVide", jEl).hide();
            var nbPage = Math.floor(param.listeTrActu.length / param.nbLignes) + ( param.listeTrActu.length % param.nbLignes == 0 ? 0 : 1 );
            if ( nbPage == 1 ) numPage = 1;
            if ( numPage > nbPage ) numPage = nbPage;
            
            for (i = (numPage-1)*param.nbLignes; i <= (numPage)*param.nbLignes - 1; i++){
               if ( i < param.listeTrActu.length){
                  var temp = param.sauvLigne[param.listeTrActu[i]].clone();
                  if ( i%2 == 1 ) temp.addClass('color');
                  param.jTbody.append(temp);
               }
            }
            if ( param.tr_action != null ){
               $("tr", param.jTbody).css('cursor', 'pointer').click(function(){
                  param.tr_action( $(this) );
               });
            }
            if ( nbPage > 1 ){
               $(".pageInf", jEl).css('visibility', numPage != 1 ? 'visible' : 'hidden');
               $(".pageSup", jEl).css('visibility', numPage != nbPage ? 'visible' : 'hidden');
               $(".numPage", jEl).val(numPage);
               $(".nbPage", jEl).val(nbPage);
               $(".pagination", jEl).show();
            }
            else
               $(".pagination", jEl).hide();
         }
         else {
            $(".rechercheVide", jEl).show();
            $(".pagination", jEl).hide();
         }
      }
      /**
       * @name in_array
       * @desc 
       */   
      function in_array(mot, tab, typ){
         for (var i in tab)
            if ( typ == 'sup' && mot <= tab[i] )
               return true;
            else if ( typ == null && mot == tab[i] )
               return true;
            
         return false;
      }
    };
   /**
    * @name $.triTable.TransfoPourComparaison
    * @desc retourne une expression en minuscule en placant des regex sur les lettrse accentuables
    */   
   $.triTable.TransfoPourComparaison = function(mot) {
      mot = mot.toLowerCase();
      mot = mot.replace(/^ +(.*) +$/, '$1');
      mot = mot.replace(/[âàäa]/g, '[âàäa]');
      mot = mot.replace(/[éèëêe]/g, '[éèëêe]');
      mot = mot.replace(/[îïi]/g, '[îïi]');
      mot = mot.replace(/[ôöo]/g, '[ôöo]');
      mot = mot.replace(/[ùûüu]/g, '[ùûüu]');
      return mot;
   };
      
   $.fn.triTable = function(param) {
      return this.each(function() {
         new $.triTable( $(this), param);   
      });
   };
})(jQuery)
