/*-------------------------------- Folder ------------------------------------*/

var Folder = Class.create({

  initialize: function(toggle, options) {

    this.toggle = $(toggle);
    this.element = $(this.toggle.rel);
    this.options = options || {};

    this.active = this.options.active || Element.hasClassName(this.toggle, "active");
    this.element[this.active ? 'show' : 'hide']();

    if (this.options.loaded == true)
      this.loaded = true;
    else
      this.loaded = this.active;

    this.loading = false;
    
    if (this.options.effect)
      this.options.effectOptions = this.options.effectOptions || {};

    this.eventOnClick = this.onClick.bindAsEventListener(this);
    Event.observe(this.toggle, "click", this.eventOnClick);
  },

  destroy: function() {
    Event.stopObserving(this.toggle, "click", this.eventOnClick);
  },

  activate: function() {
    if (this.loaded || !this.load()) this._toggle(true);
  },

  deactivate: function() {
    this._toggle(false);
  },

  load: function(onComplete) {
    if (this.toggle.href && this.toggle.href != '#') {
      this.loading = true;
      this.loaded = false;
      if (this.options.onLoading) this.options.onLoading(this);
      this._toggle(true);
      return new Ajax.Updater(this.element, this.toggle.href, {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(request) {
          this.loaded = true;
          this.loading = false;
          if (this.options.onComplete) this.options.onComplete(this);
        }.bind(this)
      });
    }
  },

  _toggle: function(active) {
    if (this.active == active) return;
    this.active = active;

    (this.active ? Element.addClassName : Element.removeClassName)(this.toggle, "active");

    if (this.options.effect)
      Effect.toggle(this.element, this.options.effect, this.options.effectOptions);
    else
      (this.active ? Element.show : Element.hide)(this.element);
    if (this.options.onChange) this.options.onChange(this);
  },

  onClick: function(event) {
      Event.stop(event);
      this.toggle.blur();
      if (!this.loading) {
        if (Event.metaKey(event)) {
          if (this.active) {
            this.load();
            return false;
          } else {
            this.loaded = false;
          }
        }
        if (this.options.onClick && this.options.onClick(this, event) == false)
          return false;
        this.active ? this.deactivate() : this.activate();
      }
    return false;
  }
});

InstanceManager.create(Folder);

/*-------------------------------- TABS ------------------------------------*/

var Tabs = Class.create({

  initialize: function(container, options) {

    container = $(container);
    this.options = options || {};

    this.onClick  = this.options.onClick;
    this.onChange = this.options.onChange;

    Object.extend( this.options, {
      onClick: this.tabClicked.bind(this),
      onChange: this.tabChanged.bind(this)
    });
    this.tabs = []
    var toggles = container.getElementsByTagName(this.options.toggleTag || 'a');
    for (var i=0; i < toggles.length; i++) {
      if (toggles[i].rel) {
        var tab = new Folder(toggles[i], this.options);
        this.tabs.push(tab);
        if (tab.active) this.activeTab = tab;
      }
    }

    if (this.options.active)
      this.activate(this.options.active, true);
  },

  destroy: function() {
    this.tabs.each(function(tab) { tab.destroy() });
  },

  tabClicked: function(tab) {
    if (this.onClick) this.onClick(this, tab);
    return (this.activeTab != tab);
  },

  tabChanged: function(tab) {
    var activeTabChanged = this._activate(tab);
    if (this.onChange)
      activeTabChanged = activeTabChanged && this.onChange(this);
    return activeTabChanged;
  },

  activate: function(tab, skipCallback) {
    tab = $(tab);
    if (!tab) return false;

    tab = this.tabs.find(function(t){ return t.element == tab });
    if (!tab) return false;

    if (skipCallback)
      return this._activate(tab);
    else {
      if (this.tabChanged(tab)) {
        this.activeTab.activate();
        return true;
      }
      return false;
    }
  },

  _activate: function(tab) {
    if (this.activeTab != tab) {
      if (this.activeTab) this.activeTab.deactivate();
      this.activeTab = tab;
      return true;
    } else
      return false;
  },

  deactivate: function() {
    if (this.activeTab) this.activeTab.deactivate();
    this.activeTab = null;
  }
});

InstanceManager.create(Tabs);
