/* vim: set foldmethod=marker filetype=javascript: */

/* @Purpose: Turn a link object into a
 * @Require: Prototype >= 1.6.0
 * @Version 0.0.6
 * See viewmore.txt in this dir for detailed documentation and changelog
 */

var ViewMore = {
  Version: '0.0.5',
  REQUIRED_PROTOTYPE: '1.6.0',
  NeverCalled: 1,

  // Version string testing taken from Scriptaculous
  // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)

  // {{{ load()
  load : function(){
    function convertVersionString(versionString){
      var r = versionString.split('.');
      return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
    }

    if(typeof(Prototype) === 'undefined' ||
       !Prototype.Version ||
       (convertVersionString(Prototype.Version) < 
        convertVersionString(ViewMore.REQUIRED_PROTOTYPE))) {
       ViewMore.unusable = 1;
       throw("ViewMore requires the Prototype JavaScript framework >= " +
             ViewMore.REQUIRED_PROTOTYPE);
    }

    this.list = new Hash();
  }, // }}}

  // {{{ viewmore(hider, hidee, starthidden, [togglefn])
  viewmore: function(hider, hidee, starthidden, togglefn) {
    if(ViewMore.unusable) return 0;
    ViewMore.NeverCalled = 0;

    // If given nothing, try to use all elements with class name 'viewmore'
    if(!hider) hider = $$('.viewmore');

    // If array, call self recursively:
    if(Object.isArray(hider)) {
      var okflag = 0;
      hider.each(function(el){
        if(ViewMore.viewmore(el, hidee, starthidden, togglefn))
          okflag++;
      });

      return okflag;
    }

    if(Object.isString(hider))
      hider = $(hider);
    if(!hider) return 0;

    if(!hidee) {
      $w(hider.className).each(function(cName){
        if(cName.substring(0, 9) === 'viewmore_') {
          cName = cName.substring(9, cName.length);

          if(cName) {
            hidee = $(cName);
            if(!hidee) {
              hidee = $$('.' + cName);
            }
            throw $break;
          }
        }
      });
    } else if(Object.isString(hidee)) {
      hidee = $(hidee);
    }

    if(!hidee)
      return 0;

    if(Object.isArray(hidee)) {
      if(!hidee.length) return 0;
    } else {
      hidee = new Array(hidee);
    }

    var evt;
    if(hider.nodeName === 'INPUT' && hider.type === 'checkbox'
       && typeof(Prototype) !== 'undefined' && Prototype.Browser.IE) {
      evt = 'click';
    } else if(hider.nodeName === 'A') {
      evt = 'click';
    } else {
      evt = 'change';
    }

    hider.observe(evt, function(ev) {
      var el = ev.element ? Event.element(ev) : ev;

      if(el.nodeName === 'A')
        ev.stop();

      if(togglefn) {
        togglefn(hidee, Event.element(ev));
      } else {
        hidee.each(function(el){ el.toggle(); });
        hider.fire('viewmore:' + (hidee[0].visible() ? 'show' : 'hide'));
      }
    }, true);

    if(starthidden) {
      hidee.each(function(hidee_el) {
        if(!hidee_el.hasClassName('viewmore_nostarthidden'))
          hidee_el.hide();
      });
    }

    return 1;
  }, // }}}

  // {{{ Add(hider, hidee, start, [togglefn])
  Add : function(hider, hidee, start, togglefn) {
    if(!this.pending) this.pending = new Array();
    this.pending.push(new Array(hider, hidee, start, togglefn));
    ViewMore.NeverCalled = 0;
  }, // }}}

  // {{{ ProcessPending()
  ProcessPending : function() {
    if(ViewMore.NeverCalled) {
      ViewMore.Add(false, false, 1);
      ViewMore.NeverCalled = 0;
    }

    if(!this.pending) return;

    for(var i = 0; i<this.pending.length; i++) {
      var pend = this.pending[i];
      this.viewmore(pend[0], pend[1], pend[2], pend[3]);
    }
    this.pending = false;
  } // }}}

};

ViewMore.load();

Event.observe(window, 'load', function() {
  ViewMore.ProcessPending();
});
