/*
  Fully object oriented FactFinder suggest function
  for multiple suggest fields
*/

function FFSuggest()
{
  // Vars
  this.pDebug = false;
  this.pInstanceName = '';
  this.pSearchURL = '';
  this.pqueryParamId = '';
  this.pForm = '';
  this.pFormname = '';
  this.pLayerName = '';
  this.pQueryInput;
  this.pSuggest = new Array();
  this.pLastQuery;
  this.submitted = false;
  this.pShowImages = false;

  this.pSuggestImageClass = 'suggestImage';
  this.pSuggestQueryClass = 'suggestTextQuery';
  this.pSuggestTypeClass = 'suggestTextType';
  this.pSuggestAmountClass = 'suggestTextAmount';
  this.pSuggestQueryTypedClass = 'suggestTextQueryTyped';
  this.pSuggestFooterClass = 'suggestFooter';
  this.pSuggestHeaderClass = 'suggestHeader';
  this.pSuggestRowClass = 'suggestRow';
  this.pSuggestHighlightClass = 'suggestHighlight';

  this.ptranslation;
  this.currentAjaxRequest;


  this.init = function (searchURL, formname, queryParamId, divLayername, instanceName, debugMode, channelParamName, channel, showImages)
  {
    this.pSearchURL = searchURL;
    this.pFormname = formname;
    this.pqueryParamId = queryParamId;
    this.pChannelParamName = channelParamName;
    this.pChannel = channel;
    this.pLayerName = divLayername;
    this.pInstanceName = instanceName;
    this.pDebug = debugMode;
    this.pShowImages = showImages;
    if (this.pSearchURL == '')
    {
      if (this.pDebug) console.log('no searchurl defined');
      return null;
    }
    else if (this.pInstanceName == '')
    {
      if (this.pDebug) console.log('no instancename defined');
      return null;
    }
    else if (this.pFormname == '')
    {
      if (this.pDebug) console.log('no formname defined');
      return null;
    }
    else if (this.pqueryParamId == '')
    {
      if (this.pDebug) console.log('no queryParamId defined');
      return null;
    }
    else if (this.pLayerName == '')
    {
      if (this.pDebug) console.log('need a layer for output');
    }
    this.pQueryInput = jq('#' + this.pqueryParamId);
    this.pForm = jq('form[name=' + this.pFormname + ']');
    this.pQueryInput.keyup({FFSuggest: this}, this.handleKeyPress);
    this.pQueryInput.focus({FFSuggest: this}, this.showLayer);
    this.pQueryInput.blur({FFSuggest: this}, this.hideLayer);
    this.pForm.submit({FFSuggest: this}, this.handleSubmit);
    jq(document).mousedown({FFSuggest: this}, this.hideLayer);
  }

  this.addInputToForm = function(name, value)
  {
    var element = document.createElement('input');
    element.name = name;
    element.type = 'hidden';
    element.value = value;
    this.pForm.append(element);
  }

  this.handleSubmit = function(evt)
  {
    var FFSuggest = evt.data.FFSuggest;
    var id = jq('tr.' + FFSuggest.pSuggestHighlightClass).attr("id");
    if (id != undefined)
    {
      var id = jq('tr.' + FFSuggest.pSuggestHighlightClass).attr("id");
      var query;
      for (var i = 0; i < FFSuggest.pSuggest.length; i++)
      {
        if (FFSuggest.pSuggest[i].search(id) == 0)
        {
          query = FFSuggest.pSuggest[i].substring(id.length);
          break;
        }
      }
      var userInput = FFSuggest.pQueryInput.val();
      FFSuggest.addInputToForm('userInput', userInput);
      FFSuggest.pQueryInput.val(query);
      FFSuggest.addInputToForm('queryFromSuggest', 'true');
    }
  }

  this.handleClick = function (evt)
  {
    var FFSuggest = evt ? evt.data.FFSuggest : this;
    FFSuggest.pForm.submit();
  }

  this.handleMouseOver = function (id)
  {
    this.unmarkAll();
    jq('#' + this.pLayerName + ' tr[id="' + id + '"]').removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
  }

  this.handleMouseOut = function (id)
  {
    jq('#' + this.pLayerName + ' tr[id="' + id + '"]').removeClass(this.pSuggestHighlightClass).addClass(this.pSuggestRowClass);
  }

  this.handleKeyPress = function(evt)
  {
    var FFSuggest = evt.data.FFSuggest;
    evt = (evt) ? evt : ((event) ? event : null);
    var keyCode = evt.keyCode;
    if (keyCode == 38)
    {
      FFSuggest.moveUp();
    }
    else if (keyCode == 27)
    {
      FFSuggest.hideLayer();
    }
    else if (keyCode == 40)
    {
      FFSuggest.moveDown();
    }
    else
    {
      if (FFSuggest.pQueryInput.val() == '')
      {
        FFSuggest.hideLayer();
        FFSuggest.pLastQuery = '';
        return null;
      }
      if (FFSuggest.pLastQuery != FFSuggest.pQueryInput.val())
      {
        FFSuggest.getSuggestions();
      }
      FFSuggest.pLastQuery = FFSuggest.pQueryInput.val();
    }
  }


  this.moveUp = function()
  {
    if (jq('tr.' + this.pSuggestHighlightClass).length == 0)
    {
      jq('tr.' + this.pSuggestRowClass + ':last').removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
    }
    else
    {
      if (jq('tr.' + this.pSuggestHighlightClass).prev('tr.' + this.pSuggestRowClass).length == 0)
      {
        jq('tr.' + this.pSuggestHighlightClass).removeClass(this.pSuggestHighlightClass).addClass(this.pSuggestRowClass);
        jq('tr.' + this.pSuggestRowClass + ':last').removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
      }
      else
      {
        jq('tr.' + this.pSuggestHighlightClass).removeClass(this.pSuggestHighlightClass).addClass(this.pSuggestRowClass).prev('tr.' + this.pSuggestRowClass).removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
      }
    }
  }

  this.moveDown = function()
  {
    if (jq('tr.' + this.pSuggestHighlightClass).length == 0)
    {
      jq('tr.' + this.pSuggestRowClass + ':first').removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
    }
    else
    {
      if (jq('tr.' + this.pSuggestHighlightClass).next('tr.' + this.pSuggestRowClass).length == 0)
      {
        jq('tr.' + this.pSuggestHighlightClass).addClass(this.pSuggestRowClass).removeClass(this.pSuggestHighlightClass);
        jq('tr.' + this.pSuggestRowClass + ':first').removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
      }
      else
      {
        jq('tr.' + this.pSuggestHighlightClass).addClass(this.pSuggestRowClass).removeClass(this.pSuggestHighlightClass).next('tr.' + this.pSuggestRowClass).removeClass(this.pSuggestRowClass).addClass(this.pSuggestHighlightClass);
      }
    }
  }

  this.getSuggestions = function()
  {
    var FFSuggest = this;
    
    // kill all pending requests
    if( FFSuggest.currentAjaxRequest )
    {
      FFSuggest.currentAjaxRequest.abort();
    }
    
    var query = jq('input[id=' + FFSuggest.pqueryParamId + ']').attr('value');
    // check if the same query was asked before
    if (FFSuggest.pLastQuery == query)
    {
      return;
    }
    else
    {
      FFSuggest.pLastQuery = query;
    }

    var requestURL = FFSuggest.pSearchURL + '&query=' + encodeURIComponent(query) + '&' + FFSuggest.pChannelParamName + '=' + FFSuggest.pChannel + '&format=json';
    
    FFSuggest.currentAjaxRequest = jq.ajax(
    {
      type: "GET",
      url: requestURL,
      contentType: "application/x-www-form-urlencoded; charset=UTF-8",
      success: function (json, textStatus)
      {
        var jsonObj = eval(json);
        if (jsonObj.length > 0)
        {
          //create output text
          var outputText = '<table cellpadding="0" cellspacing="0" class="suggestLayer ' + FFSuggest.pLayerName + '" width="100%" border="0" onMouseDown="' + FFSuggest.pInstanceName + '.handleClick();">';
          outputText += '<tr class="' + FFSuggest.pSuggestHeaderClass + '" ><td nowrap="nowrap" colspan="' + (3 + FFSuggest.pShowImages) + '">' + FFSuggest.ptranslation['recommendations'] + '</td></tr>';

          FFSuggest.pSuggest = new Array();
          for (var i = 0; i < jsonObj.length; i++)
          {
            var suggestQuery = jsonObj[i].query;
            var suggestCount = jsonObj[i].hitCount;
            if (suggestCount == 0)
            {
              suggestCount = '';
            }
            else if (suggestCount == 1)
            {
              suggestCount = FFSuggest.ptranslation['singleproduct'];
            }
            else
            {
              var temp = suggestCount;
              suggestCount = '{0} ' + FFSuggest.ptranslation['products'];
              suggestCount = suggestCount.replace(/\{0\}/, temp);
            }
            var suggestType = FFSuggest.ptranslation[jsonObj[i].type];
            if (!suggestType)
            {
              suggestType = "";
            }
            var suggestImageUrl = jsonObj[i].imageURL;
            var id = FFSuggest.pLayerName + '_' + i;
            outputText += '<tr id="' + id + '" class="' + FFSuggest.pSuggestRowClass + '" onMouseOver="' + FFSuggest.pInstanceName + '.handleMouseOver(\'' + id + '\');" onMouseOut="' + FFSuggest.pInstanceName + '.handleMouseOut(\'' + id + '\');">' + (FFSuggest.pShowImages ? '<td nowrap="nowrap" class="' + FFSuggest.pSuggestImageClass + '"><img src="' + suggestImageUrl + '" alt=""/></td>' : '') + '<td nowrap="nowrap" class="' + FFSuggest.pSuggestQueryClass + '">' + suggestQuery.replace(new RegExp("(" + query + ")", "ig"), '<span class="' + FFSuggest.pSuggestQueryTypedClass + '">$1</span>') + '</td>' + '<td nowrap="nowrap" class="' + FFSuggest.pSuggestTypeClass + '">' + suggestType + '</td>' + '<td nowrap="nowrap" class="' + FFSuggest.pSuggestAmountClass + '">' + suggestCount + '</td>' + '</tr>';
            FFSuggest.pSuggest[i] = id + suggestQuery;
          }
          outputText += '</table>';

          //show layer
          jq('div#' + FFSuggest.pLayerName).html(outputText);
          FFSuggest.showLayer();          
        }
        else
        {
          //hide layer
          jq('div#' + FFSuggest.pLayerName).hide();
        }
      },
      error: function (e, xhr, settings, exception)
      {
        if (FFSuggest.pDebug)
        {
          console.log('Error:\nHTTP result code: ' + e.status + '\nrequested URL: ' + requestURL);
        }
      }
    });
  }

  this.hideLayer = function(evt)
  {
    var FFSuggest = evt ? evt.data.FFSuggest : this;
    FFSuggest.unmarkAll();
    jq('div#' + FFSuggest.pLayerName).hide();
  }

  this.showLayer = function(evt)
  {
    var FFSuggest = evt ? evt.data.FFSuggest : this;
    jq('div#' + FFSuggest.pLayerName).show();

    // Check browser boundaries
    var windowWidth = jq(window).width();
    var boxWidth = jq('div#' + FFSuggest.pLayerName + ' > table').outerWidth();
    var boxLeft = jq('div#' + FFSuggest.pLayerName).offset().left;
    if( (boxWidth + boxLeft) > windowWidth )
    {
      jq('div#' + FFSuggest.pLayerName).oFFSuggestset({ left: (windowWidth - boxWidth - 10) });
    }
  }

  this.unmarkAll = function()
  {
    var FFSuggest = this;
    jq('tr.' + this.pSuggestHighlightClass).each(function (i)
    {
      jq(this).removeClass(FFSuggest.pSuggestHighlightClass).addClass(FFSuggest.pSuggestRowClass);
    });
  }
}

/*
  A JavaScript object for the select asn.
  Handles <option> changes and xhr-requests
*/
function FFSelectASN()
{
  this.formElement;
  this.countElement;
  this.linkElement;
  this.searchData;
  this.debug;
  this.requestURL;
  this.translation = new Object();
  this.jsonObject = new Object();
  
  // inits 
  this.init = function(formElementId, countElementId, linkElementId, debug, requestURL, translation)
  {
    var FFSelectASN = this;
    this.debug = debug;
    this.requestURL = requestURL;
    this.translation = translation;
    this.formElement = jq("#" + formElementId);
    this.countElement = jq("#" + countElementId);
    this.linkElement = jq("#" + linkElementId);
    this.formElement.find("select").each( function() {
      jq(this).change( {FFSelectASN: FFSelectASN}, FFSelectASN.handleOptionChange );
    });
  }
  
  // handles the changes of <option> elements
  this.handleOptionChange = function(evt)
  {
    var FFSelectASN = evt ? evt.data.FFSelectASN : this;
    FFSelectASN.searchData = new Array();
    
    FFSelectASN.formElement.find("option:selected").each(function () {
      value = jq(this).val();
      if(!value)
      {
        return;
      }
      FFSelectASN.searchData.push(jq(this).val());
    });
    FFSelectASN.handleAjaxOptionChange();
  }
  
  // gets the productcount
  this.handleAjaxOptionChange = function()
  {
    var FFSelectASN = this;
    var JSON;
    FFSelectASN.formElement.find('input[type="submit"]').attr("disabled", "disabled");
    jq.ajax(
    {
      type: "POST",
      url: FFSelectASN.requestURL,
      data: FFSelectASN.formElement.serialize(),
      success: function (jsonObject)
      {
        FFSelectASN.jsonObject = jsonObject;
        FFSelectASN.updateCountElement();
        FFSelectASN.updateFormElement();
        FFSelectASN.updateSelectBoxes();
        FFSelectASN.formElement.find('input[type="submit"]').removeAttr("disabled");
      },
      error: function (e, xhr, settings, exception)
      {
        if (FFSelectASN.debug)
        {
          console.log('Error:\nHTTP result code: ' + e.status + '\nrequested URL: ' + requestURL);
        }
      }
    });
  }
  
  // update countElement
  this.updateCountElement = function()
  {
    var FFSelectASN = this;
    if( FFSelectASN.jsonObject.ObjectCount == 1 )
    {
      var Translation = FFSelectASN.translation.ObjectFound;
    }
    else
    {
      var Translation = FFSelectASN.translation.ObjectsFound;
    }
    FFSelectASN.countElement.html(FFSelectASN.jsonObject.ObjectCount + ' ' + Translation);
  }
  
  // update formElement
  this.updateFormElement = function()
  {
    var FFSelectASN = this;
    FFSelectASN.formElement.attr('action', FFSelectASN.jsonObject.SearchParams);
  }

  // Disables not available groups
  this.updateSelectBoxes = function()
  {
    var FFSelectASN = this;
    FFSelectASN.formElement.find('select').each( function() {
      var jqEl = jq(this);
      if( jq.inArray(this.id, FFSelectASN.jsonObject.Groups) == -1 )
      {
        if( jqEl.find('option:selected').val() == '' )
        {
          this.disabled=true;
          jqEl.parent('.FactFinderASNGroup').addClass('FactFinderDisabledGroup');
          //jqEl.parent('.FactFinderASNGroup').slideUp('slow');
        }
      }
      else
      {
        this.disabled=false;
        jqEl.parent('.FactFinderASNGroup').removeClass('FactFinderDisabledGroup');
        //jqEl.parent('.FactFinderASNGroup').slideDown('slow');
      }
    });
  }
}

/*
  ASO & Recommendation Engine
*/
function FFTracking()
{
  this.track = function(Data)
  {  
    console.log(Data);
    
    jq.ajax({
      type: 'GET',
      url: '?ViewAction=Ajax-Innochange_FactFinder_SCIC',
      data: Data,
      contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
      cache: false
    });
    return;
  }
  
  this.serializeDataForms = function(DataForms)
  {
    var DataArray = new Array();
    jq(DataForms).each( function() {
      DataArray.push(jq(this).serialize());
    });
    var DataString = DataArray.join('&');
    return DataString;
  }
  
  this.generateGUID = function()
  {
    // Some fake GUID. No need for real GUIDs.
    // Thanks to John Millikin from stackoverflow.com
    var S4 = function()
    {
       return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    };
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
  }
  
  this.getSession = function(data)
  {
    jq.ajax({
      type: 'GET',
      url: '?ViewAction=Ajax-Innochange_FactFinder_GetSession',
      data: data,
      success: function(session) {
        jq.cookie('ff_sid', session, {expires: 1, path: '/'});
      },
      contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
      cache: false,
      async: false
    });
  }
}














/* PLUGINS */
/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};


