OSS = function (options) {
  
  this.opt = options || {};
    
  this.opt.searchField = $(this.opt.searchField) || $('#search');
  this.opt.settings    = this.opt.settings    || {};
  this.opt.templates   = this.opt.templates   || {};
  this.opt.varName     = this.opt.varName     || 'oss';
  this.opt.userId      = this.opt.userId      || null;
  this.opt.key         = this.opt.key         || null;
  this.opt.url         = this.opt.url         || null;
  this.opt.minChars    = this.opt.minChars    || 2;
  
  if(!this.opt.search){
	  this.opt.search = {enabled: false}
  }
  else{
	  this.opt.search.enabled      = this.opt.search.enabled || false;
	  this.opt.search.template     = this.opt.search.template || {};
	  this.opt.search.templateInfo = this.opt.search.templateInfo || {};
	  this.opt.search.resource     = this.opt.search.resource || null;
	  this.opt.search.query        = this.opt.search.query || {};
  }
  
  if(!this.opt.suggest){
	  this.opt.suggest = {enabled: false}
  }
  else{
	  this.opt.suggest.enabled     = this.opt.suggest.enabled || false;
	  this.opt.suggest.template    = this.opt.suggest.template || {};
	  this.opt.suggest.resource    = this.opt.suggest.resource || null;
	  this.opt.suggest.query       = this.opt.suggest.query || {};
  }
  
  this.init = function() {   
	if(this.opt.suggest.enabled){
	  // Autovervollstaendigung des Suchfelds ausschalten
	  this.opt.searchField.attr("autocomplete", "off");
	    
	  // Click-Event Handler
	  this.opt.searchField.keyup($.proxy(function (event) {
	    this.searchFieldKeyPressed(event, this.opt.searchField);
	  },this));
	    
	  // FocusOut-Event Handler
	  this.opt.searchField.focusout($.proxy(function (event) {
	     this.searchFieldFocusOut(event, this.opt.searchField);   
	  },this));
	}	  
	
	// Form submit des Suchfelds umleiten
    var form = this.opt.searchField.parents('form:first');
    form.submit($.proxy(function () {
        return this.searchFieldEnterPressed(this.opt.searchField);
    },this));
	
	if(this.opt.search.enabled){	    
    	// Pruefen ob Parameter search bereits vorhanden ist um eine Suche durchzufuehren
	    var searchParam = decodeURI($(document).getUrlParam("search_"+this.opt.varName));
	    
	    if(searchParam &&  searchParam  != "null" && searchParam.length > 0){
	        this.opt.searchField.val(searchParam);
	        searchParam = searchParam.replace(/\+/g," ");
	        this.sendSearchRequest(searchParam, this.opt.search.query,
	                               this.showSearchResults);
	    }
	}
  },
  
  /**
   * Wird aufgerufen wenn eine Taste im Suchfeld gedrueckt wurde
   * @param {Event} Klickevent
   * @param {Inputfield} Das betroffene Feld
   */
  this.searchFieldKeyPressed = function(event, field){
    
    if (event.keyCode == '13') {
        // Beim druecken von Enter soll nichts unternommen werden
    }
    else if(event.keyCode == '40'){
        var item = $("#suggest ul li.suggest_hover_js");
        if(item.length == 0){
            $("#suggest ul:first li:first-child").toggleClass("suggest_hover_js");
        }else{
          item.toggleClass("suggest_hover_js");
          
          if(item.next().length == 0){
            $(item.closest("ul").nextAll("ul:first").find("li:first-child").toggleClass("suggest_hover_js"));
          }else{
            $(item.next()).toggleClass("suggest_hover_js");  
          }  
        }
    }
    else if (event.keyCode == '38'){
        var item = $("#suggest ul li.suggest_hover_js");
        if(item.length == 0){
            $("#suggest ul:last li:last-child").toggleClass("suggest_hover_js");
        }else{
            item.toggleClass("suggest_hover_js");
            
            if(item.prev().length == 0){
              $(item.closest("ul").prevAll("ul:first").find("li:last-child").toggleClass("suggest_hover_js"));
            }else{
              $(item.prev()).toggleClass("suggest_hover_js");  
            } 
        }
    }
    else{
    	if(this.opt.search.enabled){
    		// Pruefen ob man sich auf der Suchseite befindet um ggf.
            // statt einer Suggest-Suche eine Instant-Suche durchzufuehren
            var searchParam = decodeURI($(document).getUrlParam("search_"+this.opt.varName));
        
            if(searchParam &&  searchParam  != "null" && searchParam.length > 0){
              // Instant-Suche
              this.opt.search.query.standard.start = 0;
              this.sendSearchRequest(field.val(), this.opt.search.query, this.showSearchResults);
              return;
            }
    	}
        
        // Suggest-Suche
        this.sendSearchRequest(field.val(), this.opt.suggest.query,
                                   this.showSuggestWindow, this.hideSuggestWindow);
    }
  },

  /**
   * Wurd aufgerufen wenn das Suchfeld nicht mehr im Focus ist
   * @param {Event} Klickevent
   * @param {Inputfield} Das betroffene Feld
   */
  this.searchFieldFocusOut = function(event, field){
      setTimeout(this.hideSuggestWindow, 500);
  },

  /**
   * Wird aufgerufen wenn im Suchfeld Enter gedrueckt wurde
   * @param {Input field} field
   */
  this.searchFieldEnterPressed = function(field){
      var link = "";
      
      // Pruefen ob ein Suggest-eintrag markiert ist
      var item = $("#suggest ul li.suggest_hover_js a");    
      
      if(item.length != 0){
          link = item.attr('href');
          window.location.href = link;
          return false;
      }else if(field.val().length > 0 && this.opt.search.enabled){
          // Pruefen ob Feld Text enthaelt und Seite auf Suchseite umleiten
          link = "/search/searchOss.html?search_" + this.opt.varName + "=" + encodeURI(field.val().replace(/ /g,"+"));
          window.location.href = link;
          return false;
      }else{
    	  return true;
    	  //this.opt.searchField.parents('form:first').submit();
      }
  },


  /**
   * Suggest-Suche absenden
   * @param {String} Suchtext
   */
  this.sendSearchRequest = function(text, requestJson, onDocsFound, onNoDocsFound){
    
	  if(text == null || text == "" || text.length < this.opt.minChars){
		  this.hideSuggestWindow();
		  return;
	  }
	  
      // Suchtext in Einstelungen hinterlegen
      $.each(requestJson, function(index, value) { 
        value.searchText = text; 
      });
  
      // Pfad fuer Suggest-Ressource festlegen
      var path = "user/" + this.opt.userId + "/products/search.jsonp";
         
      $.ajax({
          url: this.opt.url + path + "?key=" + this.opt.key,
          data: { data: $.toJSON(requestJson)},
          dataType: "jsonp",
          jsonp: "callback",
          timeout: 5000,
          scriptCharset: "utf-8",
          success: $.proxy(function(data){
              if(data.statusCode != 0){
                  //console.log(data);
              }
              else{
                var docsFound = false;
                
                $.each(data.data, function(index, value) { 
                  if(value.documents){
                    if(value.documents.length >0){
                      docsFound = true;
                    }  
                  }
                  else if(value.groupResults && value.groupResults.length > 0){
                      docsFound = true;  
                  }
                });
                
                if(docsFound){
                   onDocsFound.call(this,data);
                }else{
                   onNoDocsFound.call(this);
                }
              }
          },this),
          error: function(){
              //console.log("Timeout");
          }
      });
  },
  
  /**
   * Blendet das Suggest-Fenster aus
   */
  this.hideSuggestWindow = function(){
      if($("#suggest").length){
          $("#suggest").remove();    
      }   
  },
  
  /**
   * Zeigt die Suchergebnisse an
   * @param {} data
   */
  this.showSearchResults = function(data){
      // Daten fuer die Templates bestimmen
      var templateData = $.extend({}, data.data, {"options": this.opt.search.templateInfo}, {"resource": this.opt.search.resource}, {"instance": this.opt.varName});
      
      // Templates laden
      ejsSearch = new EJS({url: this.opt.search.template}).render(templateData);    
      
      // Vor dem Ersetzen unsichtbar schalten
      $('#searchresults').hide();
      
      // Jeweilige Bereiche auf der Seite ersetzen
      $('#searchresults').html(ejsSearch);    
                  
      // Wieder sichtbar schalten
      $('#searchresults').show();
  },
  
  /**
   * Suggest-Fenster anzeigen
   * @param {JSON} Suchergebnis
   */
  this.showSuggestWindow = function(data){
      // Bisheriges Suggestfenster entfernen
      if($("#suggest").length){
          $("#suggest").remove();    
      }   
      
      // Daten fuer die Templates bestimmen
      var templateData = $.extend({}, data.data, {"resource": this.opt.suggest.resource}, {"instance": this.opt.varName});
      
      // Template fuer Suggest laden
      ejsSuggest = new EJS({url: this.opt.suggest.template}).render(templateData);
    
      
      // An das Ende des Content-Bereichs einfuegen
      $(ejsSuggest).insertAfter($('#frame'));
      
      // Position der Suchbox ermitteln
      var pos = this.opt.searchField.offset();  
      var height = this.opt.searchField.height();
      
      // Suggest-Fenster an die Position des Suchfensters setzen
      $("#suggest").css( { "left": pos.left + "px", "top":(pos.top + height) + "px" } );
      $("#suggest").show();
  },
  
  /**
   * Wechselt die Seite
   * @param {integer} Seitennummer auf die gewechselt werden soll
   */
  this.changePage = function(pageNo){
      // Neue Seite in den Einstellungen setzen
      var requestJson = this.opt.search.query;
      
      requestJson.standard.start = requestJson.standard.results * (pageNo-1);
      
      // Vorheriges Suchtext ermitteln
      var searchText = this.opt.search.query.standard.searchText;
      
      if(searchText && searchText.length > 0){
          // Anfrage senden
          this.sendSearchRequest(searchText, requestJson, this.showSearchResults);
      }
  },
  
  /**
   * Aendert die Sortierung
   * @param {integer} Nummer der in den Einstellungen definierte Sortierung
   */
  this.changeSorting = function(sortNo){
      // Neue Sortierung in den Einstellungen hinterlegen
      var requestJson = this.opt.search.query;
      requestJson.standard.sortFields = new Array(this.opt.search.templateInfo.sortFields[sortNo]);
      requestJson.standard.start = 0;
      
      // Vorheriges Suchtext ermitteln
      var searchText = this.opt.search.query.standard.searchText;
      
      if(searchText && searchText.length > 0){
          // Anfrage senden
          this.sendSearchRequest(searchText, requestJson, this.showSearchResults);
      }
  }  
}
