var community;
if (!community || typeof community != "object") throw new Error("Не загружен модуль Community");

Community.AutoComplete = Class.create({
  initialize: function(textbox,provider,options)
  {
  options = options || {};
  this.provider = provider;
  this.is_type_ahead = options.type_ahead ? 1 : 0;
  this.is_suggestions = (options.suggestions == 0) ? 0 : 1;

  this.textbox = $(textbox);
  this.textbox.observe("keyup",this.handleKeyUp.bindAsEventListener(this));
  this.textbox.observe("keydown",this.handleKeyDown.bindAsEventListener(this));
  this.textbox.observe("blur",this.hideSuggestions.bind(this));

  this.cur = -1;
  this.suggestions = new Array();
  this.layer = new Element("div",{ "class": "autocomplete_suggestions" });
  this.layer.hide();
  this.layer.observe("mouseup",this.handleMouseUp.bindAsEventListener(this));
  this.layer.observe("mousedown",this.handleMouseDown.bindAsEventListener(this));
  this.layer.observe("mouseover",this.handleMouseOver.bindAsEventListener(this));
  document.body.appendChild(this.layer);
  community.init.add_unload(this.clean.bind(this));
  },

  clean: function()
  {
  this.stop();
  this.textbox = null;
  this.provider = null;
  if (this.layer) { this.layer.remove(); this.layer = null; }
  },

  stop: function()
  {
  if (this.layer)
  {
    this.layer.stopObserving("mouseup");
    this.layer.stopObserving("mousedown");
    this.layer.stopObserving("mouseover");
  }
  if (this.textbox)
  {
    this.textbox.stopObserving("keyup");
    this.textbox.stopObserving("keydown");
    this.textbox.stopObserving("blur");
  }
  },

 autocomplete: function(suggestions,is_type_ahead)
 {
  if (!this.textbox) return;
  if (suggestions.length>0)
  {
    if (is_type_ahead) this.typeAhead(suggestions[0]);
    this.showSuggestions(suggestions);
  }
  else this.hideSuggestions();
 },

 typeAhead: function (suggestion)
 {
  if (!this.is_type_ahead || !this.textbox.createTextRange && !this.textbox.setSelectionRange) return;
  var length = this.textbox.value.length;
        this.textbox.value = suggestion;
        this.selectRange(length,suggestion.length);
 },

 handleKeyDown: function(event)
 {
  switch(event.keyCode)
  {
    case 38: if (this.layer.visible()) { this.previousSuggestion(); event.stop(); }
       break;
    case 40: if (this.layer.visible()) { this.nextSuggestion(); event.stop(); }
       break;
    case 13: if (this.layer.visible()) { this.hideSuggestions(); event.stop(); }
       break;
  }
 },

 handleKeyUp: function(event)
 {
  var keycode = event.keyCode;
  if (keycode == 8 || keycode == 46) this.provider.requestSuggestions(this,false);
  else if (keycode == 27) this.hideSuggestions();
  else if (keycode == 0 ||
     (keycode >= 32 &&
      (keycode < 33 || keycode >= 46) &&
      (keycode < 112 || keycode > 123)
     )
    )
  {
    this.provider.requestSuggestions(this,true);
  }
 },

 handleMouseUp: function(event)
 {
  this.textbox.focus();
  event.stop();
 },

 handleMouseDown: function(event)
 {
  var target = Event.element(event);
  this.textbox.value = target.firstChild.nodeValue;
  this.hideSuggestions();
  event.stop();
 },

 handleMouseOver: function(event)
 {
  this.highlightSuggestion(Event.element(event));
 },

 showSuggestions: function (suggestions)
 {
  if (!this.is_suggestions) return;
  var el = null;
  this.layer.update("");
  if (community.browser.msie && community.browser.version < 7)
  {
    this.layer.appendChild(new Element("iframe",{"class":"iframe_window"}));
  }
  this.cur = -1;
  this.suggestions = new Array();
  var t_this = this;
  $A(suggestions).each(function(value)
    {
      el = new Element("div").update(value);
      t_this.layer.appendChild(el);
      t_this.suggestions.push(el);
    });
  var offset = this.textbox.cumulativeOffset();
  this.layer.setStyle({left:offset[0]+"px",top:(offset[1]+this.textbox.getHeight())+"px",
           width:this.textbox.getWidth()+"px"
         });
  this.layer.show();
 },

 testoffset: function()
 {
	var element = this.textbox;
	alert("here");
	do
	{
		alert("element left: "+element.offsetLeft+", id: "+element.id+", tagname: "+element.tagName);
		if (element.offsetLeft > 700) element.style.background="red";
		element = element.offsetParent;
	} while(element);
 },

 hideSuggestions: function()
 {
  this.layer.hide();
 },

 highlightSuggestion: function(el)
 {
  this.suggestions.each(function(node)
    {
      if (node == el) node.addClassName("autocomplete_current");
      else node.removeClassName("autocomplete_current");
    });
 },

 nextSuggestion: function()
 {
  if (this.suggestions.length > 0 && this.cur < this.suggestions.length-1) {
    var node = this.suggestions[++this.cur];
    this.highlightSuggestion(node);
    this.textbox.value = node.firstChild.nodeValue;
  }
 },

 previousSuggestion: function()
 {
  if (this.suggestions.length > 0 && this.cur > 0)
  {
    var node = this.suggestions[--this.cur];
    this.highlightSuggestion(node);
    this.textbox.value = node.firstChild.nodeValue;
  }
 },

 selectRange: function (start,length)
 {
  if (this.textbox.createTextRange)
  {
    var range = this.textbox.createTextRange();
    range.moveStart("character",start);
    range.moveEnd("character",length - this.textbox.value.length);
    range.select();
  }
  else if (this.textbox.setSelectionRange)
  {
    this.textbox.setSelectionRange(start,length);
  }
  this.textbox.focus();
 }
});

//---------------------------------------------------------------------------------------

Community.AutoComplete.Users = Class.create({
 initialize: function()
 {
  this.request = null;
 },

 requestSuggestions: function(autocompleter,is_type_ahead)
 {
  if (this.request) this.request.transport.abort();
  this.request = new Ajax.Request(community.url.info_ajax,{
        parameters: { cmd:"search_user",title:autocompleter.textbox.value,autocomplete:1 },
        onSuccess: function(transport)
          {
            var response = transport.responseText.split(",");
            if (response[0] != "OK") return;
            autocompleter.autocomplete($A(response.slice(1)),is_type_ahead);
          }
      });
 }
});


//---------------------------------------------------------------------------------------

Community.AutoComplete.Groups = Class.create({
 initialize: function()
 {
  this.request = null;
 },

 requestSuggestions: function(autocompleter,is_type_ahead)
 {
  if (this.request) this.request.transport.abort();
  this.request = new Ajax.Request(community.url.info_ajax,{
        parameters: { cmd:"search_group",title:autocompleter.textbox.value,autocomplete:1 },
        onSuccess: function(transport)
          {
            var response = transport.responseText.split(",");
            if (response[0] != "OK") return;
            autocompleter.autocomplete($A(response.slice(1)),is_type_ahead);
          }
      });
 }
});

//----------------------------------------------------------------------------------------

Community.AutoComplete.Tags = Class.create({
 initialize: function()
 {
  this.request = null;
 },

 requestSuggestions: function(autocompleter,is_type_ahead)
 {
  if (this.request) this.request.transport.abort();
  this.request = new Ajax.Request(community.url.tags_ajax,{
        parameters: { cmd:"tag.search",tag:autocompleter.textbox.value,autocomplete:1 },
        onSuccess: function(transport)
          {
            var response = transport.responseText.split(",");
            if (response[0] != "OK") return;
            autocompleter.autocomplete($A(response.slice(1)),is_type_ahead);
          }
      });
 }
});
