/*!
 * Gewusst-Wo Javascript Library
 * Copyright (C) 2009 TENSQUARE gmbh
 */

if (!$gw$ || !$ || !$gw$.ui)
  throw new Error ("Core libs missing");


(function ()
{
    /* Klassen- und Selector-Definitionen */
    var GW_CONTAINER_SELECTOR = "#gwo_searchbox";

   /* Namespace $gw$.searchbox erzeugen */
   var phrasesuggest = $gw$.getNamespace ("phrasesuggest");

   /**
    * autoComplete:
    * -------------
    * delay        : Verzögerung beim Aufklappen der Orte (in ms)
    * minChars     : Anzahl von Zeichen, ab derer die Ortsmöglichkeiten
    *                aufklappen
    * useMore      : true  => Bei Ortsmöglichkeiten > 10 wird "weitere Orte" mit
    *                         angezeigt.
    *                false => es werden alle Möglichkeiten angezeigt
    *                         (z.B. gefundene Sonderselektion bei einer
    *                          Ortssuche)
    * moreURL      : Die URL, welche nach Klick auf "weitere Orte" aufgerufen
    *                wird
    * moreParams   : Die Parameter, welche an die "moreURL" angehängt werden.
    *                Zusätzlich werden die folgenden Parameter an die URL
    *                gehängt:
    *                - alle zusätzlich zum Suchtypen angegebenen-Parameter
    *                  z.B "formNameReg", "formName", "action" und "context"
    *                - SB_CI_PARAM ("ci") mit aktuellem Wert des Ortsfeldes
    *                - alle Eingabewerte der Input-Felder inkl. Hiddenfields
    *                  (siehe getValues)
    * onChangeTerm : Callbackfunktion für das Wecheln der eingabe in dem Orts-
    *                Feld. Innerhalb dieser Funktion sollten die folgenden
    *                Properties im Objekt AutoCompleteOptions neu übergeben
    *                werden:
    *                - useMore => "weitere Orte" ja oder nein
    *
    */
   var DEFAULT_OPTIONS =
   {
        delay        : 200,
        minChars     : 1,
        selectParams : "",
        highlight    : false,
        onChangeTerm : null,
        onChangeValue : null
   }



   /*=======================================================================*/
   /* SearchboxHandler                                                           */
   /*=======================================================================*/

   /**
    * Vewaltet die Searchbox:
    *
    * <ul>
    *   <li> Event-Handling (OnClick)
    * </ul>
    *
    * @param  {Function} onClickFn  Callbackfunktion für das anklicken
    *         einer Suchoption. Hierbei sollte innerhalb der Callbackfunktion
    *         die Funktion setHTML aufgerufen werden um das neue HTML
    *         für die Searchbox zu übergeben.
    *         Interface: onClick(searchType, searchTypeInfos)
    *           {Object} searchType der angeklickte Suchtyp
    *           {Integer} lifeTime Lebenszeit des gesetzten HTMLs dieses
    *           Suchtyps
    *           {Boolean} filled Das HTML für diesen Suchtyp ist schon
    *           gesetzt
    *
    * @param  {Object} [sbOptions]  Optionen. Die Angabe ist optional. Fehlt
    *         der Parameter, werden die Default-Optionen verwendet. Das
    *         Objekt muss nur diejenigen Optionen enthalten, die von den
    *         Default-Vorgaben abweichen.
    * @param  {Object|String} [addParams]  Zusätzliche Parameter  für den
    *         Initial gesetzten Suchtypen in Objekt oder Query-String Notation.
    *         z.B "formNameReg", "formName", "action" und "context".
    *
    *
    * @constructor
    */
   function GWPhraseSuggesterHandler (autoCompleteId, options)
   {
      var self = this;
      var autoCompleter = null;
      var autoCompleteId = autoCompleteId;

      options = $.extend(DEFAULT_OPTIONS, options);
      this.options = options;

      /* ggf. AutoComplete-Optionen mit Default-Optionen mergen */
      if (options.minChars < 1)
         options.minChars = 1;

      /**
       * Initialisiert das Event-Handling dieses SearchboxHandlers.<p>
       *
       * Im Rahmen der Initialisierung werden folgende Aufgaben erledigt:
       * <ul>
       *   <li> Binding der Click-Events zum Wechseln der Suchoption
       *   <li> Binding der Events für die Spezialoption-Combobox.
       *   <li> Setzen des Initial-Typs: Wird anhand der Klasse SB_ACTIVE_CLASS
       *        bestimmt, welche dem entsprechenden List-Tag gegeben wurde.
       *   <li> Binding der DefaultTexte und AutoCompletes</li>
       * </ul>
       *
       * Die Methode sollte normalerweise innerhalb des DOMReady-Events
       * aufgerufen werden.
       */
      this.bindEvents = function ()
      {
         bindAutoCompleteField();
      }

      /**
       * Methode zum setzen der neuen AutoComplete-Daten und ggf. Optionen
       *
       * Hiermit kann bei jedem neuen setzen der Daten acOptions.data auch
       * z.B. über acOptions.useMore bestimmt werden, ob
       * "weitere Orte zeigen..." angezeigt wird.
       *
       * @param  {DOM-Objekt} item das entsprechende Input-Feld
       * @param  {String} term der zu diesen neuen Daten gehörende Value in
       *                       dem Input-Feld
       * @param  {Array}  data Die Ortsdaten als Array bestehen aus QueryStrings
       *                       ["name=PHRASE&count=COUNT"]
       *                   Beispiel.:
       *                   ["name=Auto&count=9297",
       *                    "name=Hotel&count=1200"]
       * @param  {Objekt} autoCompleteOptions die AutoComplete-Optionen
       */
      this.setAutoCompleteData = function (item, term, data)
      {
         var values = [];
         $.each( data, function(entryIndex,entry )
         {
             var idx = values.length;
             values[idx] = [];
             values[idx][values[idx].length] = entry['name'];
             values[idx][values[idx].length] = entry['count'];
             values[idx][values[idx].length] = entry['showcount'];
         });

         $(item).setData(values, term);
      }

      /**
       * Liefert alle in der Aktuellen Suchbox enthaltenden
       * Input-Werte inkl. Hiddenfields als Key-Value-Array
       *
       * Key   => Name des Input-Feldes
       * Value => Der wert des Input-Feldes
       *          (Bei Checkboxen nur, falls checked)
       */
      function getValues()
      {
         var result = [];
         var inputFields = $(GW_CONTAINER_SELECTOR + " input");
         for (var i=0; i<inputFields.length; i++)
         {
            var item = inputFields[i];

            if ($v$.tools.isCheckbox(item) && !item.checked)
               continue;

            result[item.name] = $(item).val();
         }
         return result;
      }

      /**
       * Die zur Übergabe an die AutoComplete-Felder nötigen
       * AutoComplete-Optionen werden gesetzt
       *
       * @param  {Objekt} autoCompleteOptions die Basis-AutoComplete-Optionen
       * @param  {Array}  data Die neuen Auswahlmöglichkeiten anhand der
       *                       aktuellen Orts-Feld-Eingabe
       */
      function buildAcOptions(autoCompleteOptions, data)
      {
          autoCompleteOptions = $v$.tools.getAsObject(autoCompleteOptions);

          var selectParams = $v$.tools.getAsObject(autoCompleteOptions.selectParams);

          var acOptions = $.extend({}, autoCompleteOptions);
          acOptions.selectParams = selectParams;
          acOptions.matchSubset = false;

          var addParams = [];
          acOptions.addParams = addParams;
          acOptions.cacheLength = 10000;
          acOptions.max=1000;
          acOptions.data = data;
          acOptions.width = 450;
          acOptions.scrollHeight = 200;

          return acOptions;
      }

      this.clearCache = function (item, term, data)
      {
         autoCompleter.flushCache();
      }
     /**
       * Bindet die Autocomplete-Funktion für die folgenden Typen und deren
       * definierten zugeordneten Typen (siehe "INPUTS")
       *
       */
      function bindAutoCompleteField()
      {
         if ($("#"+autoCompleteId).length == 0)
            return;

         var acOptions = buildAcOptions(self.options);

         var data = self.options.data;
         autoCompleter = $("#"+autoCompleteId).autocomplete(data, acOptions);

         $("body").bind ("click", self, function(){autoCompleter.hideResultsNow(true);});
      }
   }

   /*
    * Klassen und Funktionen im Namespace $gw$.phrasesuggest veröffentlichen.
    */
   phrasesuggest.GWPhraseSuggesterHandler = GWPhraseSuggesterHandler;
}());
