/**
 * Extending jQuery with autocomplete
 * Version: 1.4.2
 * Author: Yanik Gleyzer (clonyara)
 */
(function($) {

// some key codes
 var RETURN = 13;
 var TAB = 9;
 var ESC = 27;
 var ARRLEFT = 37;
 var ARRUP = 38;
 var ARRRIGHT = 39;
 var ARRDOWN = 40;
 var BACKSPACE = 8;
 var DELETE = 46;
 
function debug(s){
  $('#info').append(htmlspecialchars(s)+'<br>');
}
// getting caret position obj: {start,end}
function getCaretPosition(obj){
  var start = -1;
  var end = -1;
 if(typeof obj.selectionStart != "undefined"){
    start = obj.selectionStart;
    end = obj.selectionEnd;
  }
  else if(document.selection&&document.selection.createRange){
    var M=document.selection.createRange();
    var Lp;
    try{
      Lp = M.duplicate();
      Lp.moveToElementText(obj);
    }catch(e){
      Lp=obj.createTextRange();
    }
    Lp.setEndPoint("EndToStart",M);
    start=Lp.text.length;
  //  if(start>obj.value.length)
  //    start = -1;
    
    Lp.setEndPoint("EndToStart",M);
    end=Lp.text.length;
//    if(end>obj.value.length)
//      end = -1;
  }
  return {'start':start,'end':end};
}
// set caret to
function setCaret(obj,l){
  obj.focus();
  if (obj.setSelectionRange){
    obj.setSelectionRange(l,l);
  }
  else if(obj.createTextRange){
    m = obj.createTextRange();      
    m.moveStart('character',l+1);
    m.collapse();
    m.select();
  }
}
// prepare array with velued objects
// required properties are id and value
// rest of properties remaines
function prepareArray(jsondata){
  var new_arr = [];
  for(var i=0;i<jsondata.length;i++){
    if(jsondata[i].id != undefined && jsondata[i].value != undefined){
      jsondata[i].id = jsondata[i].id+"";
      jsondata[i].value = jsondata[i].value+"";
      //if(jsondata[i].info != undefined)
      //  jsondata[i].info = jsondata[i].info+"";
      new_arr.push(jsondata[i]);
    }
  }
  return new_arr;
}
// php analogs
function escapearg(s){
  if(s == undefined || !s) return '';
  return s.replace('\\','\\\\').
           replace('*','\\*').
           replace('.','\\.').
           replace('/','\\/');
}
function htmlspecialchars(s){
  if(s == undefined || !s) return '';
  return s.replace('&','&amp;').
           replace('<','&lt;').
           replace('>','&gt;');
}
function ltrim(s){
  if(s == undefined || !s) return '';
  return s.replace(/^\s+/g,'');
}

// extending jQuery
$.fn.autocomplete = function(options){ return this.each(function(){
  // take me
  var me = $(this);
  var me_this = $(this).get(0);

  // test for supported text elements
  if(!me.is('input:text,input:password,textarea'))
  return;

  // get or ajax_get required!
  if(!options && (!$.isFunction(options.get) || !options.ajax_get)){
  return;
  }  
  // check plugin enabled
  if(me.attr('jqac') == 'on') return;

  // plugin on!
  me.attr('jqac','on');

  // no browser's autocomplete!
  me.attr('autocomplete','off');

  // default options
  options = $.extend({ 
                      delay     : 600 ,
                      timeout   : 7000 ,
                      minchars  : 1 ,
                      multi     : true ,
                      cache     : true , 
                      height    : 150 ,
                      autowidth : true ,
                      noresults : 'No job found match found'
                      },
                      options);
  
 // me.blur( function (ev) { 
//     clearSuggestions();
  //      } );
  
  // bind key events
  // handle special keys here
  me.keydown(function(ev){
    switch(ev.which){
      // return choose highlighted item or default propogate
      case RETURN:
        if(!suggestions_menu){
         return true; }
         //return true;
        else{ 
        setHighlightedValue(); }
        return false;
      // escape clears menu
      case ESC:
        clearSuggestions();
        return false;
        // up changes highlight
        case ARRUP:
        var browser=navigator.appName;
        if ((browser=="Microsoft Internet Explorer"))
        {
        changeHighlight(ev.keyCode);
        setHighlightedValue();
        return false;
        }
        else{
        return false;
        }
      // down changes highlight or open new menu
      case ARRDOWN:
        var browser=navigator.appName;
        if ((browser=="Microsoft Internet Explorer"))
        {
        if(!suggestions_menu) getSuggestions(getUserInput());
        else changeHighlight(ev.keyCode);
        return false;
        }
        else{
        return false;
        }
    }
    return true;
  });
  me.keypress(function(ev){
    // ev.which doesn't work here - it always returns 0
    switch(ev.keyCode){
    //  case RETURN:
 //     {  submittfrm('frmSreachBykeyWord','keyword');
 //        return false;}
      case ESC:
        return false;
      // up changes highlight
      case ARRUP:
        changeHighlight(ev.keyCode);
        setHighlightedValue();
        return false;
      // down changes highlight or open new menu
      case ARRDOWN:
        if(!suggestions_menu) getSuggestions(getUserInput());
        else {changeHighlight(ev.keyCode);setHighlightedValue();}
        return false;
     }
     return true;
  });
  // handle normal characters here
  me.keyup(function(ev) {
      switch(ev.which) {
        case RETURN:
            {
            clearSuggestions();
            //submittfrm('frmSreachBykeyWord','keyword');
            return true;
            }
        case ESC: case ARRLEFT: case ARRRIGHT: case ARRUP: case ARRDOWN:
           return false; 
        default:
          getSuggestions(getUserInput());
           return false;
      }
      return true;
  });

  // init variables
  var user_input = "";
  var input_chars_size  = 0;
  var suggestions = [];
  var current_highlight = 0;
  var suggestions_menu = false;
  var suggestions_list = false;
  var iframe_menu = false;
  var loading_indicator = false;
  var clearSuggestionsTimer = false;
  var getSuggestionsTimer = false;
  var showLoadingTimer = false;
  var zIndex = me.css('z-index');

  // get user input
  function getUserInput(){
    var val = me.val();
    if(options.multi){
      var pos = getCaretPosition(me_this);
      var start = pos.start;
      for(;start>0 && val.charAt(start-1) != ',';start--){}
      var end = pos.start;
      for(;end<val.length && val.charAt(end) != ',';end++){}
      var val = val.substr(start,end-start);
    }
    return ltrim(val);
  }
  // set suggestion
  function setSuggestion(val){
    user_input = val;
    if(options.multi){
      var orig = me.val();
      var pos = getCaretPosition(me_this);
      var start = pos.start;
      for(;start>0 && orig.charAt(start-1) != ',';start--){}
      var end = pos.end;
      for(;end<orig.length && orig.charAt(end) != ',';end++){}
      var new_val = orig.substr(0,start) + (start>0?' ':'') + val + orig.substr(end);
      me.val(new_val);
      setCaret(me_this,start + val.length + (start>0?1:0));
    }
    else{
      me_this.focus();
      me.val(val);
    }
  }
  // get suggestions
  function getSuggestions(val){
    // input length is less than the min required to trigger a request
    // reset input string
    // do nothing
    if (val.length < options.minchars){
      clearSuggestions();
      return false;
    }
    // if caching enabled, and user is typing (ie. length of input is increasing)
    // filter results out of suggestions from last request
    if (options.cache && val.length > input_chars_size && suggestions.length){
      var arr = [];
      for (var i=0;i<suggestions.length;i++){
        var re = new RegExp("("+escapearg(val)+")",'ig');
        if(re.exec(suggestions[i].value))
          arr.push( suggestions[i] );
      }
      user_input = val;
      input_chars_size = val.length;
      suggestions = arr;
      createList(suggestions);
      showImage();
      return false;
    }
    else{// do new request
      clearTimeout(getSuggestionsTimer);
      user_input = val;
      input_chars_size = val.length;
      getSuggestionsTimer = setTimeout( 
        function(){ 
          suggestions = [];
          // call pre callback, if exists
          if($.isFunction(options.pre_callback))
            options.pre_callback();
          // call get
          if($.isFunction(options.get)){
            suggestions = prepareArray(options.get(val));
            createList(suggestions);
            showImage();
          }
          // call AJAX get
          else if($.isFunction(options.ajax_get)){
            clearSuggestions();
            //clearImage();
            //showLoadingTimer = setTimeout(show_loading,options.delay);
            //clearImage();     
            options.ajax_get(val,ajax_continuation);
          }
        },
        options.delay );
    }
    return false;
  };
  
  
  // AJAX continuation
  function ajax_continuation(jsondata){
    hide_loading();
    suggestions = prepareArray(jsondata);
    createList(suggestions);
    showImage();
  }
  // shows loading indicator
  function show_loading(){
    if(!loading_indicator){
      clearImage();
      loading_indicator = $('<div class="jqac-menu" ><div class="jqac-loading">Loading...</div></div>').get(0);
      //var img = $('<div id="oldImage" style="margin:0px; padding:0px;"><img src="/images/line.gif" align="top" alt="" /></div>').get(0);
      $(loading_indicator).css('position','absolute');
      var pos = me.offset();
      $(loading_indicator).css('left', pos.left + "px");
      $(loading_indicator).css('top', ( pos.top + me.height() + 2 ) + "px");
      if(!options.autowidth)
      $(loading_indicator).width(me.width());
      //$(loading_indicator).append(img);
      $('body').append(loading_indicator);
      showImage();
    }
    $(loading_indicator).show();
    setTimeout(hide_loading,5000);
  }
  // hides loading indicator 
  function hide_loading(){
    if(loading_indicator)
      $(loading_indicator).hide();
    clearTimeout(showLoadingTimer);
  }
  // create suggestions list
  function createList(arr){
    if(suggestions_menu)
      $(suggestions_menu).remove();
    hide_loading();
    killTimeout();

    // create holding div
    suggestions_menu = $('<div class="jqac-menu"  id="jqac-menu-close"></div>').get(0);
    var b = 0;
    if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){ //test for MSIE x.x;
    var ieversion=new Number(RegExp.$1) // capture x.x portion and store as a number
    if (ieversion==6)
        { 
        b = 208; }
    else if (ieversion==7)
        {  b = 210; }
    }
    else
        {  b = 210; }
    $(suggestions_menu).css({'position':'absolute',
                             'z-index':zIndex,
                             'max-height':options.height+'px',
                             'margin-top':'3px',
                             'overflow-y':'auto',
                             'width':b+'px'});

    // create and populate ul
    suggestions_list = $('<ul></ul>').get(0);
    // set some CSS's
    $(suggestions_list).
      css('list-style','none').
      css('margin','0px 0px 0px 0px').
      css('padding','0px 0px 0px 0px').
      css('overflow','hidden');
    // regexp for replace 
    var re = new RegExp("("+escapearg(htmlspecialchars(user_input))+")",'ig');
    // loop throught arr of suggestions creating an LI element for each suggestion
    
    //var img = $('<div id="oldImage" style="margin:0px; padding:0px;"><img src="/images/line.gif" align="top" alt="" /></div>').get(0);
    
    for (var i=0;i<arr.length;i++){
      var val = new String(arr[i].value);
      // using RE
      var output = htmlspecialchars(val).replace(re,'<b class="bluecolor">$1</b>');
      // using substr
      //var st = val.toLowerCase().indexOf( user_input.toLowerCase() );
      //var len = user_input.length;
      //var output = val.substring(0,st)+"<em>"+val.substring(st,st+len)+"</em>"+val.substring(st+len);

      var span = $('<div class="jqac-link">'+output+'</div>').get(0);
      var span2 = '';
            
      if (arr[i].info != undefined && arr[i].info != ""){
        span2 = ($('<div class="jqac-info">'+arr[i].info+' <span class="resultstyle">results</span></div>'));
      }
      $(span).attr('name',i+1);
      $(span).click(function () { setHighlightedValue();clearSuggestions(); });
      $(span).mouseover(function () { setHighlight($(this).attr('name'),true);setHighlightedValue(); });

      var li = $('<li></li>').get(0);
      $(li).append(span);
      $(li).append(span2);
          
      $(suggestions_list).append(li);
     
    }

    // no results
    if (arr.length == 0){
      $(suggestions_list).append('<li class="jqac-warning">'+options.noresults+'</li>');
    }
    
    $(suggestions_menu).append(suggestions_list);
    //$(suggestions_menu).append(img);
    // get position of target textfield
    // position holding div below it
    // set width of holding div to width of field
    var pos = me.offset();

    $(suggestions_menu).css('left', pos.left + "px");
    $(suggestions_menu).css('top', ( pos.top + me.height() + 2 ) + "px");
    if(!options.autowidth)
      $(suggestions_menu).width(me.width());

    // set mouseover functions for div
    // when mouse pointer leaves div, set a timeout to remove the list after an interval
    // when mouse enters div, kill the timeout so the list won't be removed
    $(suggestions_menu).mouseover(function(){ killTimeout() });
    $(suggestions_menu).mouseout(function(){ resetTimeout() });

    // add DIV to document
    $('body').append(suggestions_menu);

    // bgIFRAME support
    if($.fn.bgiframe)
      $(suggestions_menu).bgiframe({height: suggestions_menu.scrollHeight});


    // adjust height: add +20 for scrollbar
    if(suggestions_menu.scrollHeight > options.height){
      //alert(suggestions_menu.scrollHeight);
      //alert(options.height);
      $(suggestions_menu).height(options.height);
      $(suggestions_menu).width($(suggestions_menu).width());
    }
	
    // currently no item is highlighted
    current_highlight = 0;

    // remove list after an interval
    clearSuggestionsTimer = setTimeout(function () { clearSuggestions() }, options.timeout);
  };
  // set highlighted value
  function setHighlightedValue(){
    if(current_highlight && suggestions[current_highlight-1]){
      var sugg = suggestions[ current_highlight-1 ];
      if(sugg.affected_value != undefined && sugg.affected_value != '')
        setSuggestion(sugg.affected_value);
      else
        setSuggestion(sugg.value);
      // pass selected object to callback function, if exists
      if ($.isFunction(options.callback))
        options.callback( suggestions[current_highlight-1] );

      //clearSuggestions();
    }
  };
  // change highlight according to key
  function changeHighlight(key){	
    if(!suggestions_list || suggestions.length == 0) return false;
    var n;
    if (key == ARRDOWN)
      n = current_highlight + 1;
    else if (key == ARRUP)
      n = current_highlight - 1;

    if (n > $(suggestions_list).children().size())
      n = 1;
    if (n < 1)
      n = $(suggestions_list).children().size();
    setHighlight(n);
  };
  // change highlight
  function setHighlight(n,mouse_mode){
    if (!suggestions_list) return false;
    if (current_highlight > 0) clearHighlight();
    current_highlight = Number(n);
    var li = $(suggestions_list).children().get(current_highlight-1);
    li.className = 'jqac-highlight';
    // for mouse mode don't adjust scroll! prevent scrolling jumps
    if(!mouse_mode) adjustScroll(li);
    killTimeout();
  };
  // clear highlight
  function clearHighlight(){
    if (!suggestions_list)return false;
    if (current_highlight > 0){
      $(suggestions_list).children().get(current_highlight-1).className = '';
      current_highlight = 0;
    }
  };
  // clear suggestions list
  function clearSuggestions(){
    killTimeout();
    if(suggestions_menu){
      $(suggestions_menu).remove();
      suggestions_menu = false;
      suggestions_list = false;
      current_highlight = 0;
    }
  };
  // set scroll
  function adjustScroll(el){
    if(!suggestions_menu) return false;
    var viewportHeight = suggestions_menu.clientHeight;        
    var wholeHeight = suggestions_menu.scrollHeight;
    var scrolled = suggestions_menu.scrollTop;
    var elTop = el.offsetTop;
    var elBottom = elTop + el.offsetHeight;
    if(elBottom > scrolled + viewportHeight){
      suggestions_menu.scrollTop = elBottom - viewportHeight;
    }
    else if(elTop < scrolled){
      suggestions_menu.scrollTop = elTop;
    }
    return true; 
  } 
  // timeout funcs
  function killTimeout(){
    clearTimeout(clearSuggestionsTimer);
  };
  function resetTimeout(){
    clearTimeout(clearSuggestionsTimer);
    clearSuggestionsTimer = setTimeout(function () { clearSuggestions() }, 7000);
  };

  function clearImage() {
  document.getElementById('bottomImage').style.display = "none";
  }
  
  function showImage(){
  document.getElementById('bottomImage').style.display = "block";
  }
  

})};

})($);
