document.observe("dom:loaded", function () {

  $$("fieldset.collapsable").each(function (element) {
    new CollapsableFieldset(element);
  });

  $$("li.tags").each(function (element) {
    new TagsFormControl(element);
  });
  
  $$('textarea.autogrow').each(function (element) {
    new AutoGrow(element);
  });

  var statusMessage = $("status-message");
  if (statusMessage) {
    window.setTimeout(function () {
      Effect.Fade(statusMessage);
    }, 5000);
  }
  
  $$('form').each(function (form) {
    form.preview = function() {
      form.action += "/preview";
      form.submit();
    }
  });
  
});

var TagsFormControl = function(element){
  var text_field = element.down("input[type=text]");  
  var label = element.down("label");
  var form = text_field.form;
  
  var tag_list = new TagList();
  var autocomplete = new AutoComplete();
  
  var blur_timeout = null;
    
  label.observe('click', function(event){
    Event.stop(event);
    text_field.focus();
  });
    
  text_field.observe('keydown', function(event){
    if(event.keyCode == Event.KEY_RETURN)
    {
      Event.stop(event);
      if(autocomplete.current())
      {
        tag_list.add(autocomplete.current().innerText, true);
        autocomplete.remove(autocomplete.current().innerText);
        autocomplete.hide();
      }else{
        text_field.value.split(",").each(function(value){
          tag_list.add(value, true);
        });
        autocomplete.hide();
      }
    }else if ([Event.KEY_DOWN, Event.KEY_UP].include(event.keyCode) && autocomplete.visible()){
      Event.stop(event);
      if(event.keyCode == Event.KEY_DOWN)
        autocomplete.next();
      else
        autocomplete.previous();
    }else if (event.keyCode == Event.KEY_ESC){
      Event.stop(event);
      if(!autocomplete.current())
      {
        text_field.value = "";
        text_field.blur();
      }
      autocomplete.hide();
    }else{
      setTimeout(autocomplete.start, 200); 
    }
  });
  
  text_field.observe('blur', function(event){
    blur_timeout = setTimeout(function(){
      text_field.value = ""
      autocomplete.hide();
    }, 100);
  });
  
  form.observe('submit', function(event){
    text_field.value = '';
  });

  //--- TagList ------------------------------------------------------

  function TagList() {
    var element = text_field.up("ol");
    element.select('input[type=checkbox]').each(function(check_box){
      observe(check_box);
    });
    
    this.observe = observe;
    function observe(check_box) {
      check_box.observe('change', function(){
        if (check_box.checked)
          check_box.up('label').addClassName("selected");
        else
          check_box.up('label').removeClassName("selected");
      });
    }

    this.add = add;
    function add(tag, clear_value) {
      tag = tag.toLowerCase().replace(/(^\s)|(\s$)/g, '').replace(/[,._'"´`¨-]+/g, '').replace(/\s+/g, '-').replace(/(^-+)|(-+$)/g, '');
      var foundMatchingTag = element.select('input[type=checkbox]').any(function(tag_element){
        if(tag_element.value == tag)
        {
          tag_element.up('label').addClassName("selected");
          tag_element.checked = true;
          return true;
        }
      });
      if(!foundMatchingTag && tag != "")
      {
        var li = document.createElement('li');
        var check_box = document.createElement('input');
        check_box.setAttribute("type", "checkbox");
        check_box.setAttribute("value", tag);
        check_box.setAttribute("name", text_field.name);
        check_box.setAttribute("checked", "checked");
        check_box.setAttribute("id", "tag-" + new Date().getMilliseconds());
        var label = document.createElement('label');
        label.setAttribute("for", check_box.id);
        label.addClassName("selected");
        label.innerHTML = check_box.outerHTML + " " + tag;
        li.insert(label);
        text_field.parentElement.insert({ before: li });
        tag_list.observe(li.down('input[type=checkbox]'));
      }
      if(clear_value) {
        text_field.value = "";
      }
    }
    
    this.tag_string = tag_string;
    function tag_string() {
      return element.select('input[type=checkbox]').collect(function(checkbox){
        return checkbox.value;
      }).join(",");
    }  
  }
  
  //--- AutoComplete ---------------------------------------------------
  
  function AutoComplete() {
    var container = $(text_field.id + "autocomplete");
    container.hide();
    var in_progress = false;
    var previous_autocomplete = null;

    container.observe('click', function(event){
      var element = Event.element(event);
      if(element.tagName == "DIV")
      {
        var tag = element.innerText;
        tag_list.add(tag);
        autocomplete.remove(tag);
        text_field.select();
      }
    });
    
    document.observe('scroll', position);
    
    this.start = start;
    function start() {
      if(text_field.value == "")
      {
        hide();
        return false;
      }
      if(in_progress || previous_autocomplete == text_field.value) {
        if(!autocomplete.empty())
        {
          show();
        }
        return false;
      }
      in_progress = true;
      previous_autocomplete = text_field.value;
      new Ajax.Request('/admin/tags/search', 
        { parameters: 
          { query: text_field.value, 
            container: container.id,
            exclude_tags: tag_list.tag_string(),
            id: form.getAttribute("object_id")
          }, 
          method: 'post',
          onComplete: function(response) {
            in_progress = false;
            if (response.status == 200) {
              show();
              first();
            } else {
              hide();
            }
          }
        }
      );
    }
        
    this.visible = visible;
    function visible() {
      return container.visible();
    }
    
    this.show = show;
    function show() {
      position();
      container.show();
    }

    this.hide = hide;
    function hide() {
      container.hide();
    }

    function position() {
      container.setStyle({
        position: 'fixed',
        top: text_field.viewportOffset()['top'] + text_field.measure('border-box-height') + "px",
        left: text_field.measure('left') + 1 + "px"
      });    
    }

    this.remove = remove;
    function remove(tag){
      container.childElements().each(function(div){
        if(div.innerText == tag)
          div.remove();
        if(container.childElements().length == 0)
          hide();
      });
    }

    this.current = current;
    function current() {
      return container.down(".selected");
    }
    
    this.next = next;
    function next() {
      var cur = current();
      if(cur) {
        cur.removeClassName("selected");
        if( cur.nextElementSibling )
          cur.nextElementSibling.addClassName("selected");
        else
          first();
      }else{
        first();
      }
    }
    
    this.first = first;
    function first(){
      container.childElements()[0].addClassName("selected");
    }
    
    this.last = last;
    function last(){
      container.childElements()[container.childElements().length - 1].addClassName("selected");
    }
    
    this.previous = previous;
    function previous() {
      var cur = current();
      if(cur) {
        cur.removeClassName("selected");
        if( cur.previousElementSibling )
          cur.previousElementSibling.addClassName("selected");
      }
    }
    
    this.empty = empty;
    function empty() {
      return container.childElements().length == 0;
    }
  } 
}

var CollapsableFieldset = function(fieldset){
  var legend_element = fieldset.down("legend");
  var ol_element = fieldset.down("ol");
  
  legend_element.observe('click', toggle);
      
  var wrapper = ol_element.wrap('div');
  wrapper.addClassName("wrapper");

  hide();

  function has_error() {
    return ol_element.down("p.error");
  }

  function visible () {
    return wrapper.visible();
  }

  function hide () {
    if (!has_error())
    {
      wrapper.hide();
      handleCollapsed();
    }
  }

  function collapse (event) {
    Effect.SlideUp(wrapper, { duration: 0.4, afterFinish: handleCollapsed });
  }

  function expand () {
    Effect.SlideDown(wrapper, { duration: 0.4, afterFinish: handleExpanded });
  }

  function handleCollapsed () {
    fieldset.addClassName("collapsed");
  }

  function handleExpanded () {
    var input = ol_element.down("input");
    if(input)
      input.focus();
    fieldset.removeClassName("collapsed");
    var viewport_height = document.viewport.getDimensions()['height'];
    var fieldset_offset = viewport_height - (fieldset.viewportOffset()['top'] + fieldset.measure('border-box-height'));
    if(fieldset_offset < 100)
      Effect.ScrollTo(fieldset);
  }

  function toggle (event) {
    event.stop();
    if (!has_error())
      visible() ? collapse() : expand();
  }
}
