/**
 *  @singleton
 *  Search Manager
 *  Manager qui va permettre de gérer à la fois la recherche simple et la recherche avancé.
 *  C'est par lui que passerons les demandes de chargement des flux
 *  Si un flux est déjà chargé il renverra son contenu, sinon il ira le chercher dans le cache
 **/

var SearchManager = {
  initSearch : 0,
  //options
  /**
   * dataOptions :
   * options des flux à charger pour l'ensembles des objets concernant la recherche.
   * on peut hors de ce fichier mettre à jour ces options objets de flux via la methode
   * cf. addDatasOptions, une explication est intégrée
   */
  datasOptions : {
    /**
     * searchCurl du fichier de configuration de la recherche
     */
    searchConfig : {
      type:'json'
    },
    searchDatasSimple : { //flux pour le moteur de recherche simple
      type:'json'
    },
    searchDatas : { //flux de chargement d'origine pour le moteur de recherche avancé
      //url:'/search/flux/searchdatas.js',
      type:'json'
    },
    templates : { //fichier contenant tous les templates HTML
      //url:'/search/flux/templates.xml',
      type:'xml'
    }
  },
  searchQuery : {//searchQuery : objet contenant les données de recherche, ces données sont mises à jour dès qu'un input est mis à jour
        searchId : null, //id de recherche, n'est utilisée que sur la recherche avancée
        travelType:'', //type de sejour, voyage, vols secs, sejours...
         departurePlace:'', //endroit de depart, ville de depart en principe
        destinationPlace:'', //destination d'arrivée, c'est un pays ici
        destinationCity:'', //ville d'arrivee
        departureDate:'', //date de depart, format JJ/MM/AAAA
        nbAdults:0, //nb adultes
        nbEnfants:0, //nb enfants
        budget:0, //budget (min-max)
        confort:1 //confort 1 à 4
      },

  datas : {
    searchConfig  : null, //objet contenant le flux js quand il sera chargé, cet objet est à nul tant que le flux n'est pas chargé
    searchDatas    : null //objet de searchs datas
  },

  datasRequested : [], /*liste des datas qui ont déjà été demandées, on se sert de ce tableau,
              cela permet d'éviter des soucis si on se base sur l'objet datas,
              surtout si les datas on déjà été demandées mais qu'elles n'ont pas été chargées
             */
  currentQueries : [], //tableau des requetes en cours, contient les dataNames, et la callback

  /**
   * recupére les datas via ajax en fonction de la liste passée en paramètre, quand toutes les datas sont chargée la callback est éxécutée
   * @param {Array} dataNames tableau contenant la liste des datas à récupérer pour l'objet en question, ex : ['searchConfig', 'templates']
   * @param {Function} callback fonction exécutée après que toutes les "datas" aient été chargées.
   */
  getDatas : function(dataNames, callback) {
    var _this = this;


    //creation query
    var query = {
      dataNames : dataNames,
      callback : callback,
      datasRemaining : dataNames.slice()
    };

    //ajout query
    this.currentQueries.push(query);
    for (var i=0; i<query.dataNames.length; i++) {
      var n = query.dataNames[i];
      if (this.datasRequested.indexOf(n)<0) {
        this.datasRequested.push(n);
        this.getData(n);
      } else {
        query.datasRemaining.splice(i,1);
      }
    }
  },


  /**
   * récupère 1 data, cette methode est appelée par la methode principale getDatas
   * @param {Object} n  Objet data déclaré dans datasOptions
   */
  getData : function(n) {
    var _this = this;
    var o = this.datasOptions[n];
    if(o.url) {
      $.ajax({
        type    : "GET",
        url      : o.url,
        dataType  : o.type,
        data    : o.getParams ? o.getParams() : "",
        success    : function(msg){
          _this.datas[n] = msg;
          //console.info('query loaded :', n);
          _this.checkQueries(n);
        },
        error    : function(XMLHttpRequest, textStatus, errorThrown) {
          if(window.console) {
            console.info('error :', n, ':', XMLHttpRequest, textStatus, errorThrown);
          }
        }
      });
    } else {
      _this.datas[n] = o.fromvar;
      _this.checkQueries(n);
    }
  },

  /**
   * Quand une data est chargée cette methode est appelée pour checker si toutes les datas liées à une query sont chargées,
   * dans ce cas on éxécute la callback associé à la "query"
   * @param {Object} name    Nom de la data qui vient d'être chargée.
   */
  checkQueries : function(name) {
    var _this = this;
    
    this.currentQueries = this.currentQueries.filter(function(query){
      
      for (var i=0; i<query.datasRemaining.length; i++) {
        var n  = query.datasRemaining[i];
        if (_this.datas[n]!=null) {
          query.datasRemaining.splice(i,1);
        }
      }
      
      //console.log(name,'query.datasRemaining :', query.datasRemaining);
      if(query.datasRemaining.length==0) {
        //console.log(name,'datasremainer aquels to zero, now call callback');
        var datas = {};
        for (var i=0; i<query.dataNames.length; i++) {
          var n  = query.dataNames[i];
          datas[n] = _this.datas[n];
        }
        //console.log('callback', query.dataNames, query.datasRemaining, datas);
        query.callback(datas);
        return false;
      }
      
      //console.log(name, 'des datas restes : ',query.datasRemaining)
      return true;
    });
    
    
    //console.log(this.currentQueries);
  },

  /**
   * Cette méthode permet de surcharger ou rajouter des objets composants les flux ou déclarer les bonnes urls de flux depuis le serveur
   * Cette methode peut être appelée depuis les pages HTML au début de la page.
   * @param {Object} datasOptions objet contenant les options des flux
   *
   * ex :
   *
   *
     <script type="text/javascript">
    SearchManager.addDatasOptions({
      searchConfig : {
        url:'/search/flux/searchConfig.js'
      },
      searchDatas : {
        url:'/search/flux/searchdatas.php?lang=FR&var1=foo',
      }
    })
      </script>

  */
  addDatasOptions : function(datasOptions) {
    for (var i in datasOptions) {
      if (!this.datasOptions[i]) this.datasOptions[i]={};
      for (var j in datasOptions[i])
        this.datasOptions[i][j] = datasOptions[i][j];
    }
    this.initSearch = 1;
  }

}










