// -*- encoding: utf-8 -*-
//
// Librairie de fonctions jQuery/AJAX de recherche des tirages, communes
// à toutes les pages du domaine 'Photographies'.
// Dépend de jQuery 1.3.2+
//
// Noter que le flux d'exécution des formulaires de recherche est particulier:
// la recherche n'est pas exécutée lors de la soumission des formulaires, mais
// lors du chargement des pages qui incluent ce script. Cela permet de mettre
// à disposition les fonctions de recherche «in place» sur toutes les pages du
// domaine 'Photographies'. Détail de ce flux d'exécution:
//
//  * au chargement du formulaire, si des paramètres de recherche ont été spécifiés
//    dans l'URI, ce script déclenche automatiquement une recherche AJAX avec ces
//    paramètres et affiche les résultats dans le corps de la page.
//
//  * lors de la soumission d'un formulaire (simple/avancé), les valeurs des
//    champs sont simplement transcrites dans l'URI et la page est rechargée.
//    Cela permet d'inscrire les recherches dans l'historique du navigateur.
//
// (c) 2009 Le Petit Atelier de Génie logiciel, Olivier Lange
//
// Ce script est distribué selon les termes de le GNU General Public License
// (voir http://www.fsf.org/licensing/licenses/gpl.html et la notice qui suit).
//
// $Id$

// Classe dsySearchForm: constantes, propriétés et méthodes spécifiques au
// traitement des formulaires de recherche simple et avancée.
// @assert On suppose qu'il existe deux formulaires désignés 'simpleSearch'
// et 'advSearch' dans le corps de la page qui invoque les méthodes de cet objet.
var dsySearchForm = {
  // Constantes globales
  SEARCH_FORM_MODE_SIMPLE: "simple",  // Mode par défaut (déterminé par indicateur 'bModeSimple' ci-après)
  SEARCH_FORM_MODE_ADVANCED: "adv",
  SEARCH_FORM_SELECTOR_SIMPLE: "form#simpleSearch",
  SEARCH_FORM_SELECTOR_ADVANCED: "form#advSearch",

  // Propriétés
  bModeSimple: true,  // Indication du formulaire de recherche visible: simple (true) ou avancée (false)

  // Méthodes

  // Analyse les paramètres d'URI et initialise les champs des formulaires en
  // conséquence: pour tous les paramètres dont le nom commence par la lettre 'q'
  // («query parameter»), transcrit leurs valeurs dans le ou les champs de même nom;
  // si le nom du paramètre est 'mo' (mode), définit la propriété 'bModeSimple'
  // selon sa valeur: true s'il vaut 'simple', false sinon.
  populate: function( query) {
    if( query != undefined && query != "") {
      if( query.substring( 0, 1) == "?")  query = query.substring( 1);  // Supprime le '?' initial
      var params = query.split( "&");
      var tokens, paramName, paramNameGroup, paramValue, inputElt;
      for( var i = 0; i < params.length; i++) {
        tokens = params[ i].split( "=");
        if( tokens.length > 0) {
          paramValue = decodeURIComponent( tokens[ 1]);
          paramName = tokens[ 0].toLowerCase();
          paramNameGroup = paramName.substring( 0, 1);
          if( paramName == "locale" || paramNameGroup == "q") {
            // FIXME: traiter cas des checkbox 'qs' (qui peuvent être toutes deux actives)
            inputElt = $( "*[name=" + paramName + "]").each( function() {
              $( this).val( paramValue);
            });
          } else if( paramName == "mo") {
            dsySearchForm.bModeSimple = ( paramValue.toLowerCase() == dsySearchForm.SEARCH_FORM_MODE_SIMPLE);
          } // if-else
        } // if
      } // for
    } // if
  }, // populate

  // Commande le rechargement de la page avec les critères saisis dans le formulaire
  // de recherche qui a été soumis. Cela aura pour effet de déclencher indirectement
  // une recherche après rechargement de la page -- voir méthode 'doSearchOnLoad()'.
  //
  // @see méthode 'dsySearch.doSearch()' pour le détail des autres paramètres.
  handleSubmit: function() {
    var formSelector = dsySearchForm.bModeSimple
      ? dsySearchForm.SEARCH_FORM_SELECTOR_SIMPLE : dsySearchForm.SEARCH_FORM_SELECTOR_ADVANCED;
    var formElt = $( formSelector);
    var query = formElt.serialize();
    // Commande le rechargement de la page avec les nouveaux paramètres de recherche
    window.location.search = query;
  },

  // Affiche/masque les formulaires de recherche simple et avancée selon la
  // valeur de l'indicateur 'bModeSimple'; ce dernier vaut 'true' par défaut.
  //
  // @see parseURI()  permet d'initialiser l'indicateur 'bModeSimple' avec
  //   le paramètre d'URI 'mo' (si celui-ci est défini).
  setVisibility: function() {
    if( dsySearchForm.bModeSimple) {
      $( dsySearchForm.SEARCH_FORM_SELECTOR_ADVANCED).hide();
      $( dsySearchForm.SEARCH_FORM_SELECTOR_SIMPLE).show();
    } else {
      $( dsySearchForm.SEARCH_FORM_SELECTOR_ADVANCED).show();
      $( dsySearchForm.SEARCH_FORM_SELECTOR_SIMPLE).hide();
    };
  },

  // Affiche le formulaire de recherche avancée en masquant la recherche simple
  // et vice-versa à chaque nouvelle invocation
  toggleVisibility: function() {
    $( dsySearchForm.SEARCH_FORM_SELECTOR_ADVANCED).toggle();
    $( dsySearchForm.SEARCH_FORM_SELECTOR_SIMPLE).toggle();
    dsySearchForm.bModeSimple = !dsySearchForm.bModeSimple;
  } // toggle
}; //dsySearchForm

// Classe dsySearch: regroupe constantes et méthodes pour la recherche des
// tirages au sein du repository Daisy et l'affichage client des résultats.
var dsySearch = {
  // Constante globales
  DSY_SEARCH_BASE_URI: "/daisy/ht/ext/search/portraits.html", // URI du service de recherche des portraits
  RANDOM_SEARCH_NAMES: [ "B", "C", "D", "E", "F", "M", "N", "P", "R", "S", "T", "V", "W"], // Premières lettres de noms pour lesquels on a plus de 10 résultats
  DSY_LOCALE_DEFAULT: "fr",

  // Détermine si les paramètres d'URI contiennent un paramètre de recherche
  // des tirages au moins ou non.
  //
  // @param query  chaîne de caractères contenant un fragment d'URI avec
  //   ou sans paramètres de recherche des tirages.
  //
  // @return  true si le fragment d'URI contient un paramètre de recherche
  //   des tirage au moins, false sinon.
  hasSearchParams: function( query) {
    var bHasParam = false;
    if( query != undefined && query != "")
      bHasParam = ( query.indexOf( "qn") != -1) ||( query.indexOf( "qd") != -1)
        ||( query.indexOf( "qs") != -1) ||( query.indexOf( "ql") != -1)
        ||( query.indexOf( "locale") != -1);
    return bHasParam;
  },

  // Lance une recherche sur les noms d'après une première lettre au hasard,
  // parmi celles qui retournent plus de 10 noms de personnalités correspondantes.
  // @param targetSelector  identique à celui de la méthode doSearch().
  doSearchRandom: function( targetSelector) {
    var i = Math.floor( Math.random() * dsySearch.RANDOM_SEARCH_NAMES.length);
    var query = "locale=" + dsySearch.DSY_LOCALE_DEFAULT
      + "&qn=" + dsySearch.RANDOM_SEARCH_NAMES[ Number( i)];
    dsySearch.doSearch( query, targetSelector);
  },

  // Lance une recherche selon les critères communiqués et affiche les résultats
  // dans le corps de la page, à l'emplacement de l'élément désigné par le
  // sélecteur passé en paramètre.
  //
  // @param query  chaîne de caractères contenant les paramètres de la recherche,
  //   sous la forme d'une URI (p.ex. 'param1=val1&param2=val2&...')
  //
  // @param targetSelect  chaîne de caractères contenant un sélecteur jQuery
  //   qui désigne l'élément dont le contenu doit être remplacé par les
  //   résultats de recherche.
  doSearch: function( query, targetSelector) {
    if( targetSelector == undefined || targetSelector == "")
      throw "dsySearch.doSearch(): le paramètre 'targetSelector' doit être spécifié.";
    if( query == undefined) {
      throw "dsySearch.doSearch(): le paramètre 'query' doit être spécifié."
    } else {
      if( query.substring( 0, 1) == "?")  query = query.substring( 1);  // Supprime le '?' initial
      // TODO: traduction i18n
      var targetSelectorNorm = ""+targetSelector;
      $(targetSelectorNorm).empty().append( "<p class='ajaxSearching'>Recherche en cours, veuillez patienter...</p>");
      $.get(
        dsySearch.DSY_SEARCH_BASE_URI + "?" + query,
        {},
        function( data) {
          $( targetSelectorNorm).empty().append( data);
          $( "a.popupTirage[behavior*=fancybox]").fancybox({ 'frameWidth': 620, 'frameHeight': 400, 'padding':25, hideOnContentClick:false });
        },
        "html"
      );
    }; // if-else
  } // doSearch
}; // dsySearch

// On document ready
$( function() {
  // FIXME: déplacer tout ce qui suit dans 'jquery.xpg.js', cela concerne certes
  // seulement les pages du domaine 'Photographies', mais pas la recherche et je
  // voudrais que 'jquery.htap.js' soit centré sur les fonctions de recherche.

  // Mise en évidence des labels des champs de recherche sur focus
  // FIXME: déplacer dans plugin 'jquery.xpg.js', mécanisme générique
  $("input[behavior*=labelover],select[behavior*=labelover]").each( function() {
    var inputElt = $(this);
    var labelElt = $( "label[for*=" + inputElt.attr( "id") + "]");
    if( labelElt != undefined)
      inputElt
        .focus( function() { labelElt.addClass("selectedLabel"); })
        .blur( function() { labelElt.removeClass("selectedLabel"); });
  });

  // Champ recherche simple
  // FIXME: ne pourrait-on pas utiliser classe 'selectedLabel', afin d'utiliser
  // mécanisme 'behavior="labelover"' et déplacer dans 'jquery.xpg.js'? demander à DR
  $("#simpleSearch input#name")
    .focus( function() { $("p.photos_f_05").addClass("photos_f_05_selected"); })
    .blur( function() { $("p.photos_f_05").removeClass("photos_f_05_selected"); });

  // Fake checkboxes
  // FIXME: pas bien compris à quoi cela servait; conserver? demander à DR
  // FIXME: déplacer dans 'jquery.xpg.js', mécanisme générique
  $("input:checkbox").each( function() {
    // check for what is/isn't already checked and match it on the fake ones
    (this.checked) ? $("#fake"+this.id).addClass('fakechecked') : $("#fake"+this.id).removeClass('fakechecked');
  });

  $(".fakecheck").click( function(){
    // function to 'check' the fake ones and their matching checkboxes
    ($(this).hasClass('fakechecked')) ? $(this).removeClass('fakechecked') : $(this).addClass('fakechecked');
    $(this.hash).trigger("click");
    return false;
  });
});

// eof
