﻿var http_request = false;
// ----------------------------------------------------------------------------
function ajaxRequestGET(url, responseCallback, responseArgs) {
  http_request = false;
  if (window.XMLHttpRequest) { // Mozilla, Safari,...
    http_request = new XMLHttpRequest();
    if (http_request.overrideMimeType) {
      http_request.overrideMimeType('text/html');
    }
  } else if (window.ActiveXObject) { // IE
    try {
      http_request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) { }
    }
  }
  if (!http_request) {
    alert('Could not load XMLHTTP');
    return false;
  }
  http_request.onreadystatechange = function () { responseCallback(responseArgs) };
  http_request.open('GET', url, true);
  http_request.send(null);
}
// ----------------------------------------------------------------------------
String.prototype.trim = function () {
  var s = this;
  while (s.substring(0, 1) == ' ') {
    s = s.substring(1, s.length);
  }
  while (s.substring(s.length - 1, s.length) == ' ') {
    s = s.substring(0, s.length - 1);
  }
  return s;
}
/**********************************************************/
function AutoSuggest(args) {
  var _this = this; //The 'me' variable allow you to access the AutoSuggest object from the elem's event handlers defined below.
  this.KEY = { TAB: 9, ESC: 27, ENTER: 13, UP: 38, DOWN: 40 }; // Keycode constants

  this.eligible = new Array(); //Arrow to store a subset of eligible suggestions that match the user's input
  this.inputText = null; //The text input by the user.
  this.pick = -1; //A pointer to the index of the highlighted eligible item. -1 means nothing highlighted.

  this.elem = null;
  this.lang = 1;
  this.seeMore = 'See more "<strong>{0}</strong>"...';
  this.suggestions = []; //A reference to the element we're binding the list to.
  this.url = '';
  if (getCookie) {
    var aalang = parseInt(getCookie('aalang'));
    if (aalang) this.lang = aalang;
  }

  if (args) {
    var o;
    o = args['elem']; if (o) this.elem = o;
    o = args['lang']; if (o) this.lang = o;
    o = args['seeMore']; if (o) this.seeMore = o;
    o = args['suggestions']; if (o) this.suggestions = o;
    o = args['url']; if (o) this.url = o;
  }

  this.div = document.getElementById("autosuggest"); //A div to use to create the dropdown.
  this.isMouseOver = false;

  this.elem.setAttribute("autocomplete", "off"); // Turn off browser's autocomplete
  if (!this.elem.id) alert('Error: Input field must have ID');

  // --------------------------------------------------------------------------
  // Handle control key strokes
  // --------------------------------------------------------------------------
  this.elem.onkeydown = function (ev) {
    var key = _this._getKeyCode(ev);

    switch (key) {
      //use the highlighted suggestion, if there is one. 
      case _this.KEY.TAB: _this._usePick(); break;

      //get rid of the autosuggest dropdown  
      case _this.KEY.ESC: _this._hideMenu(); break;
      case _this.KEY.ENTER: _this._usePick(); break;

      //Move selected menu item up and down in the suggestions. 
      case _this.KEY.UP: if (_this.pick > 0) { _this.pick--; } _this._changePick(); break;
      case _this.KEY.DOWN: if (_this.pick < (_this.eligible.length - 1)) { _this.pick++; } _this._changePick(); break;
    }
  };

  // --------------------------------------------------------------------------
  // Handle text input key strokes
  // --------------------------------------------------------------------------
  this.elem.onkeyup = function (ev) {
    var key = _this._getKeyCode(ev);
    switch (key) {
      case _this.KEY.TAB:
      case _this.KEY.ESC:
      case _this.KEY.UP:
      case _this.KEY.DOWN:
      case _this.KEY.ENTER:
        return;
      default:
        _this.ShowSuggestions(this.value);
    }
  };
  // --------------------------------------------------------------------------
  // Hide suggestions when clicking outside textbox and suggestion menu
  // --------------------------------------------------------------------------
  this.elem.onblur = function () {
    if (!_this.isMouseOver) _this._hideMenu();
  }
  // --------------------------------------------------------------------------
  this.AutoSuggestResponse = function (localThis) {
    if (http_request) {
      if (http_request.readyState == 4) {
        var res = false;
        if (http_request.status == 200) {
          var suggest;
          eval(http_request.responseText);
          localThis.eligible = localThis.getEligible(suggest);
          localThis.RenderSuggestions();
        }
      }
    }
  }
  // --------------------------------------------------------------------------
  this.AutoSuggestRequest = function (query) {
    var url = (this.url ? this.url : '/controls/autosuggest.aspx') + '?s=' + query + '&l=' + this.lang;
    ajaxRequestGET(url, this.AutoSuggestResponse, this);
    return false;
  }
  // --------------------------------------------------------------------------
  this.RenderSuggestions = function () {
    if (this.eligible && this.eligible.length > 0) {
      this._renderMenu();
      this._positionMenu();
      this._showMenu();
    } else {
      this._hideMenu();
    }
  }
  // --------------------------------------------------------------------------
  this.ShowSuggestions = function (query) {
    query = query.trim();
    if (query && query != this.inputText) {
      this.AutoSuggestRequest(query);
    }
    this.inputText = query;
    if (!this.inputText) this._hideMenu();
  }

  /********************************************************
  Insert the highlighted suggestion into the input box, and 
  remove the suggestion dropdown.
  ********************************************************/
  this._usePick = function () {
    if (this.pick > -1) {
      var value = this.eligible[this.pick];
      var token = '<!-- '
      var index = value.lastIndexOf(token);
      value = value.substr(index + token.length);
      token = ' -->';
      value = value.substr(0, value.length - token.length);
      this.elem.value = value;

      this._hideMenu();
      //It's impossible to cancel the Tab key's default behavior. 
      //So this undoes it by moving the focus back to our field right after
      //the event completes.
      setTimeout("document.getElementById('" + this.elem.id + "').focus()", 0);

      var e;
      e = document.getElementById('hfAutoSuggestStore'); if (e) e.value = '1';
      e = document.getElementById('hfAutoSuggestInner'); if (e) e.value = '1';

      if (this.elem.submit) {
        this.elem.submit();
      } else if (this.elem.form && this.elem.form.submit) {
        this.elem.form.submit();
      }
    }
  };

  /********************************************************
  Display the dropdown. Pretty straightforward.
  ********************************************************/
  this._showMenu = function () {
    if (this.eligible.length > 0)
      this.div.style.display = 'block';
  };

  /********************************************************
  Hide the dropdown and clear any highlight.
  ********************************************************/
  this._hideMenu = function () {
    this.div.style.display = 'none';
    this.pick = -1;
  };

  /********************************************************
  Modify the HTML in the dropdown to move the highlight.
  ********************************************************/
  this._changePick = function () {
    var lis = this.div.getElementsByTagName('LI');
    for (var i = 0; i < lis.length; i++) {
      var li = lis[i];

      if (this.pick == i) {
        li.className = "selected";
      }
      else {
        if (li && li.className) {
          li.className = "";
        }
      }
    }
  };

  /********************************************************
  Position the dropdown div below the input text field.
  ********************************************************/
  this._positionMenu = function () {
    var el = this.elem;
    var x = 0;
    var y = el.offsetHeight;

    //Walk up the DOM and add up all of the offset positions.
    while (el.offsetParent && el.tagName.toUpperCase() != 'BODY') {
      x += el.offsetLeft;
      y += el.offsetTop;
      el = el.offsetParent;
    }

    x += el.offsetLeft;
    y += el.offsetTop;

    y -= 1;

    this.div.style.left = x + 'px';
    this.div.style.top = y + 'px';
  };

  /********************************************************
  Build the HTML for the dropdown div
  ********************************************************/
  this._renderMenu = function () {
    var ul = document.createElement('ul');
    var a, li;
    var list = this.eligible;

    for (var i = 0; i < list.length; i++) {
      li = document.createElement('li');
      a = document.createElement('a');
      a.href = "javascript:false";
      a.innerHTML = list[i];
      li.appendChild(a);

      if (this.pick == i) {
        li.className = "selected";
      }
      ul.appendChild(li);
    }

    this.div.replaceChild(ul, this.div.childNodes[0]);


    /********************************************************
    mouseover handler for the dropdown ul
    move the highlighted suggestion with the mouse
    ********************************************************/
    ul.onmouseout = function (ev) {
      _this.isMouseOver = false;
    }
    ul.onmouseover = function (ev) {
      _this.isMouseOver = true;

      //Walk up from target until you find the LI.
      var target = _this._getSource(ev);
      while (target.parentNode && target.tagName.toUpperCase() != 'LI') {
        target = target.parentNode;
      }

      var lis = _this.div.getElementsByTagName('LI');


      for (var i = 0; i < lis.length; i++) {
        var li = lis[i];
        if (li == target) {
          _this.pick = i;
          break;
        }
      }
      _this._changePick();
    };

    /********************************************************
    click handler for the dropdown ul
    insert the clicked suggestion into the input
    ********************************************************/
    ul.onclick = function (ev) {
      _this.elem.focus();
      _this._usePick();
      _this._hideMenu();
      _this._cancel(ev);
      return false;
    };

    this.div.className = "suggestion_list " + this.elem.id;
    this.div.style.position = 'absolute';

  };

  /********************************************************
  determine which of the suggestions matches the input
  ********************************************************/

  this._appendEligible = function (s, ft, i0, i1, max, prefix, suffix) {
    if (!prefix) prefix = '';
    if (!suffix) suffix = '';
    if (i0 + i1 > max) {
      ft += prefix + s.substr(i0, max) + suffix + '...';
    }
    else {
      ft += prefix + s.substr(i0, i1) + suffix;
    }
    return ft;
  }

  this.getEligible = function (suggestions, input, max) {

    if (!suggestions) suggestions = this.suggestions;
    if (!input) input = this.inputText;
    if (!max) max = 10;

    var eligible = new Array();

    input = input.toLowerCase();
    var s, ft;
    var index;
    var count = 0;
    var i0, i1, maxLength = 35;
    var checkAnywhere = true; // (input.length > 2 && !(parseInt(input.charAt(0)) > -1));
    var checkE = (input.indexOf('e') > -1 ? true : false);


    if (suggestions.length > 0) {
      var GC_FLAG = "##";
      var realSuggestion;
      for (var i = 0; i < suggestions.length; i++) {
        s = suggestions[i];

        if (s.indexOf(GC_FLAG) == 0) {
          index = s.indexOf(GC_FLAG, GC_FLAG.length);
          realSuggestion = s.substr(GC_FLAG.length, (index > GC_FLAG.length ? index - GC_FLAG.length : s.length - GC_FLAG.length));

          s = s.replace(GC_FLAG, '').replace(GC_FLAG, '');
        } else {
          realSuggestion = s;
        }

        index = s.toLowerCase().indexOf(input);

        if (index < 0 && checkE) {
          index = s.replace('é', 'e').toLowerCase().indexOf(input);
        }

        if (index > -1 && (checkAnywhere || index == 0)) {

          ft = '';
          i0 = 0;
          i1 = index;
          ft = this._appendEligible(s, ft, i0, i1, maxLength);

          if (i0 + i1 < maxLength) {
            i0 += i1;
            i1 = input.length;
            ft = this._appendEligible(s, ft, i0, i1, maxLength, '<strong>', '</strong>');

            if (i0 + i1 < maxLength) {
              i0 += i1;
              i1 = s.length - i0;
              ft = this._appendEligible(s, ft, i0, i1, maxLength);
            }
          }
          eligible[eligible.length] = '<div>' + ft + '</div><!-- ' + realSuggestion + ' -->'; //.replace(/-/g, ' ')
          if (eligible.length == max) break;
        }
      }
    }
    if (eligible && eligible.length > 0) {
      eligible[eligible.length] = '<div>' + this.seeMore.replace("{0}", input) + '</div><!-- ' + input + ' -->';
    }
    return eligible;
  }
  // --------------------------------------------------------------------------
  // Determine the keycode pressed
  // --------------------------------------------------------------------------
  this._getKeyCode = function (ev) {
    return (ev ? ev.keyCode : (window.event ? window.event.keyCode : false));
  }
  // --------------------------------------------------------------------------
  // Determine the event source element
  // --------------------------------------------------------------------------
  this._getSource = function (ev) {
    return (ev ? ev.target : (window.event ? window.event.srcElement : false));
  }
  // --------------------------------------------------------------------------
  //Cancel an event
  // --------------------------------------------------------------------------
  this._cancel = function (ev) {
    if (ev) {
      //Moz
      ev.preventDefault();
      ev.stopPropagation();
    }
    if (window.event) {
      //IE
      window.event.returnValue = false;
    }
  }
  // --------------------------------------------------------------------------
}
