;;
/* *********************************** */
/*  jQuer-Plugin
/*  autosuggest v.1.0.0
/*  (c) Seitenbau GmbH, Konstanz
/*  packed by: http://dean.edwards.name/packer/
/* *********************************** */
jQuery.fn.autosuggest = function(user_remote, user_conf) {
  // set vars
  var as_input = jQuery(this[0]);
  var as_input_offset = as_input.offset({scroll:false,border:true,margin:true,padding:true});  
  var as_user_input = null;
  var as_form = jQuery(as_input.parents('form')[0]);
  var as_result = null;
  var as_hidden = null;
  var as_last_result = false;
  var as_show_result = false;
  var as_result_pos = -1;
  var as_count_request = 0;
  var as_timer = 0;
  var as_key = {
    up:38,
    down:40,
    enter:13,
    esc:27
  };
  var as_deadkeys = new Array(9,16,17,18,19,20,23,33,34,35,36,37,39,44,45,46,91,112,113,114,115,116,117,118,119,120,121,122,123,145,188);

  // check given object
  if(as_input[0].tagName.toLowerCase() != 'input') {
    delete_vars();
    return true;
  }

  // ajax settings
  var remote = {
    url: null,
    data: null,
    method: 'get'
  };
  switch(typeof user_remote)
  {
    case 'object':
      jQuery.extend(remote, user_remote);
      delete user_remote;
      break;
    case 'string':
      remote.url = user_remote;
      delete user_remote;
      break;
    default:
      alert('Cannot handle remote-parameter!');
      delete_vars();
      return true;
      break;
  }

  // plugin-configuration
  var conf = {
    requestMin: 2,
    /*requestTimeout: 400,*/
    requestTimeout: 250,
    inputClass: 'autosuggest',
    inputValue: false,
    inputLoadingClass: 'autosuggest-loading',
    resultClass: 'autosuggest-result',
    resultID: false,
    resultEffect: 'fade',
    resultAppear: 'fast',
    resultCallback: false,
    resultElement: 'li',
    resultSelectedClass: 'selected',
    hiddenName: 'autosuggest-key',
    hiddenKey: 'key',
    submitCallback: false,
    moveLeft: 0,
    moveTop: 0,
    addWidth: 0,
    parentElement: 'body'
  };
  if(user_conf) {
    jQuery.extend(conf, user_conf);
    if(conf.requestMin <= 0) {
      conf.requestMin = 1;
    }
    delete user_conf;
  }

  // create result-object
  as_result = jQuery(document.createElement('div'))
    .addClass(conf.resultClass)
    .css({
      'position':'absolute',
      'left':(as_input_offset.left+conf.moveLeft),
      'top':((as_input_offset.top + as_input.height())+conf.moveTop),
      'width':(as_input.width()+conf.addWidth)
    })
    .appendTo(conf.parentElement)
    .hide();
  if(conf.resultID != false) {
    as_result.attr({'id':conf.resultID});
  }

  // create hidden input
  as_hidden = jQuery(document.createElement('input'))
    .attr({
      'type':'hidden',
      'value':'',
      'name':conf.hiddenName
    })
    .insertAfter(as_input);

  // configure input-object
  as_input.attr({'autocomplete':'off'}).addClass(conf.inputClass);
  if(conf.inputValue != false) {
    as_input.val(conf.inputValue);
  }
  as_input.focus(function(){
    as_show_result = true;
    if(as_input.val() == conf.inputValue) {
      as_input.val('');
    }
    if(as_last_result === true) {
      show_autosuggest();
    }
  });
  as_input.blur(function(){
    setTimeout(function(){
      as_show_result = false;
      if(as_input.val() == '' && conf.inputValue != false) {
        as_input.val(conf.inputValue);
      }
      blur_autosuggest();
    }, 250 );
  });

  // check user-input
  as_input.keydown(function(e){
    e.stopPropagation();
    clearTimeout(as_timer);

    var keycode = e.keyCode || window.event.keyCode;

    // no action on deadkeys
    if(jQuery.inArray(keycode, as_deadkeys) >= 0) {
      return true;
    }

    // switch autosuggest behavior on keycode
    switch(keycode)
    {
      // cancel on esc key
      case as_key.esc:
        as_input.val(as_user_input);
        as_hidden.val('');
        blur_autosuggest(function(){
          cancel_autosuggest();
        });
        break;

      // submit on enter key
      case as_key.enter:
        exec_result();
        return false;
        break;

      // walk through as_result
      case as_key.up:
      case as_key.down:
        //e.preventDefault();
        walk_result(keycode);
        break;

      // valid key pressed
      default:
        // count request
        if(as_count_request > 10000) {
          as_count_request = 0;
        }
        else {
          as_count_request++;
        }

        // deselect result
        deselect_result();
        as_hidden.val('');

        // set timeout for ajax-request
        as_timer = setTimeout(function(){
          if(as_input.val().length >= conf.requestMin) {
          
            /* 07.08.2009 Ralph Hohenstein
             * Anpassung fuer chiron:
             * 1. Verzeichnis mitgeben: ermittlung des Bereichs           
             */
            var chiron_area = location.pathname;
            chiron_area = chiron_area.substr(1);
            chiron_area = chiron_area.substring(0,chiron_area.indexOf('/'));

            
            var as_this_request = as_count_request;

            // add loading-class
            as_input.addClass(conf.inputLoadingClass);

            // reset result-position
            as_result_pos = -1;

            // start request
            jQuery.ajax({
              global: false,
              type: remote.method,
              data: jQuery.extend(remote.data, {'autosuggest':as_input.val(),'area':chiron_area}),
              url: remote.url,
              error: function(){
                if(as_this_request == as_count_request) {
                  as_input.removeClass(conf.inputLoadingClass);
                }
                return true;
              },
              success: function(data){
                if(as_this_request == as_count_request) {
                  // run content-callback
                  if(typeof conf.resultCallback == 'function') {
                    data = conf.resultCallback(data);
                  }

                  // append result
                  if(data) {
                    as_user_input = as_input.val();
                    as_result.empty().append(data);
                    as_last_result = true;
                    show_autosuggest();
                    mouse_result();

                    return 'test';
                  }
                  // close div data result is empty
                  else {
                    blur_autosuggest(function(){
                      cancel_autosuggest();
                    });
                  }

                }
              },
              complete: function(){
                if(as_this_request == as_count_request) {
                  as_input.removeClass(conf.inputLoadingClass);
                }
              }
            });
          }
          else {
            cancel_autosuggest();
          }
        },conf.requestTimeout);
        break;
    };
  });

  // cancel autosuggest
  function cancel_autosuggest()
  {
    as_form.children('select').show();
    clearTimeout(as_timer);
    as_result.empty().hide();
    as_last_result = false;
    as_count_request++;
    as_input.removeClass(conf.inputLoadingClass);
  };

  // blur autosuggest
  function blur_autosuggest(fnc)
  {
    switch(conf.resultEffect.toLowerCase())
    {
      default:
      case 'fade':
        as_result.fadeOut(conf.resultAppear,function(){
          if(typeof fnc == 'function') {
            fnc(this);
          }
        });
        break;

      case 'slide':
        as_result.slideUp(conf.resultAppear,function(){
          if(typeof fnc == 'function') {
            fnc(this);
          }
        });
        break;

      case 'show':
        as_result.hide(conf.resultAppear,function(){
          if(typeof fnc == 'function') {
            fnc(this);
          }
        });
        break;
    }
    
    as_form.children('select').show();
    
  };

  // show autosuggest
  function show_autosuggest(fnc)
  {
    if(as_show_result === true) {
    
    as_form.children('select').hide();
        
      switch(conf.resultEffect.toLowerCase())
      {
        default:
        case 'fade':
          as_result.fadeIn(conf.resultAppear,function(){
          if(typeof fnc == 'function') {
            fnc(this);
          }
        });
          break;

        case 'slide':
          as_result.slideDown(conf.resultAppear,function(){
          if(typeof fnc == 'function') {
            fnc(this);
          }
        });
          break;

        case 'show':
          as_result.show(conf.resultAppear,function(){
          if(typeof fnc == 'function') {
            fnc(this);
          }
        });
          break;
      }
    }
  };

  // walk through result
  function walk_result(key)
  {
    var max_result = jQuery(conf.resultElement, as_result).length -1;
    switch(key)
    {
      case as_key.up:
        if((as_result_pos-1) >= 0) {
          as_result_pos = as_result_pos -1;
        }
        else {
          as_result_pos = max_result;
        }
        select_result(as_result_pos,true);
        break;

      case as_key.down:
        if((as_result_pos+1) <= max_result) {
          as_result_pos = as_result_pos+1;
        }
        else {
          as_result_pos = 0;
        }
        select_result(as_result_pos,true);
        break;
    }
  };

  // add class to selected Element and change input-value
  function select_result(i,copyText)
  {
    deselect_result();
    var as_selected = jQuery(conf.resultElement +':eq('+(i)+')', as_result).addClass(conf.resultSelectedClass);
    var as_selected_text = as_selected.text();

    as_hidden.val(as_selected.attr(conf.hiddenKey));
    if(as_selected_text != '' && copyText) {
      as_input.val(as_selected_text);
    }
  };

  // deselect result
  function deselect_result()
  {
    jQuery(conf.resultElement, as_result).removeClass(conf.resultSelectedClass);
  };

  // execute result
  function exec_result()
  {
    if(typeof conf.submitCallback == 'function') {
      conf.submitCallback(as_hidden.val(),as_input.val());
    }
    else {
      as_form.submit();
    }
    cancel_autosuggest();
    return true;
  };

  // select via mouse
  function mouse_result()
  {
    jQuery(conf.resultElement, as_result).hover(
      function(){
        select_result(jQuery(this).prevAll().length, false);
      },
      function(){
        deselect_result();
        as_result_pos = -1;
      }
    ).click(function(){
      select_result(jQuery(this).prevAll().length, true);
      exec_result();
    });
  };

  // delete vars
  function delete_vars()
  {
    delete as_input;
    delete as_input_offset;
    delete as_user_input;
    delete as_form;
    delete as_result;
    delete as_hidden;
    delete as_last_result;
    delete as_show_result;
    delete as_result_pos;
    delete as_count_request;
    delete as_timer;
    delete as_key;
    delete as_deadkeys;
  };
};
