/*
  YUIDomCollapse by Christian Heilmann
  Version 1.0 / May 2007
  License: http://creativecommons.org/licenses/by/3.0/
  Homepage: http://onlinetools.org/tools/yuidomcollapse/
*/
// YUI Namespace
YAHOO.namespace('otorg');
YAHOO.otorg.DomCollapse = {};

// *** CONFIG *** //
YAHOO.otorg.DomCollapse.config = {
  //the html to show for the trigger when the target is hidden:
  expandTriggerImg: 'arrow-expand.gif',
  
  //the html to show for the trigger when the target is expanded:
  collapseTriggerImg: 'arrow-collapse.gif',
  
  //the "easing" style to use on the target, as chosen from http://developer.yahoo.com/yui/docs/YAHOO.util.Easing.html
  targetEasingStyle: YAHOO.util.Easing.easeBoth,
  
  //the "easing" style to use on the trigger
  triggerEasingStyle: YAHOO.util.Easing.easeBoth,
  
  //the duration of the targets animation (the trigger in/out animations will each be half of this value)
  animDuration: 0.8,
  
  //this number may need to be adjusted depending on the easing style and duration of animation
  //essentially, it means "hide the target when it's at 2pixels or smaller" ie reverts to "height: auto" at 0px for some reason
  prematureIEhidingpixels: 2
  
};
// *** CSS CLASSES CONFIG *** //
YAHOO.otorg.DomCollapse.css = {
  triggerClass:'trigger',
  hideClass:'hide',
  parentClass:'parent',
  openClass:'open'
};

function dbg() {
  return;
  try {
    if( YAHOO.env.ua.ie ) {
      alert(arguments[0].toString());
      return
    }
    if( console && console.log ) console.log( arguments );
    return;
  } catch(e) {}
}


YAHOO.otorg.DomCollapse.config.expandTriggerHTML = function() {
  return '<img border="0" src="/misc/website/images/' + YAHOO.otorg.DomCollapse.config.expandTriggerImg + '" width="9" height="9">';
};
YAHOO.otorg.DomCollapse.config.collapseTriggerHTML = function() {
  return '<img border="0" src="/misc/website/images/' + YAHOO.otorg.DomCollapse.config.collapseTriggerImg + '" width="9" height="9">';
};

YAHOO.otorg.DomCollapse._heights = {};
YAHOO.otorg.DomCollapse.init = function(e, id){
  dbg('INIT!')
  // shortcut for CSS properties
  if( !id ) {
    var old_heights = YAHOO.otorg.DomCollapse._heights;
    YAHOO.otorg.DomCollapse._heights = {};
    for( h in old_heights ) {
      if( !h.match('^yui-gen') )
        YAHOO.otorg.DomCollapse._heights[ h ] = old_heights[ h ] ;
    }
  }
  var css = YAHOO.otorg.DomCollapse.css;
  if(typeof(css) !== 'undefined'){
    // get all elements with the correct class
    var elms = id && id.toString() != "" ? [ YAHOO.util.Dom.get( id ) ] : YAHOO.util.Dom.getElementsByClassName(css.triggerClass);
    // loop over all the elements
    for(var i=0,j=elms.length;i<j;i++){
      // if the trigger is not a link
      dbg('init: ', elms[i]);
      if(elms[i].nodeName.toLowerCase()!=='a'){
        // get the next element  
        elms[i].innerHTML = elms[i].innerHTML.replace('\(more\)', YAHOO.otorg.DomCollapse.config.expandTriggerHTML());
        var t = YAHOO.otorg.DomCollapse.getNext(elms[i]);
        if(t){
          // get the element's ID or create a new one
          var newID = t.id || YAHOO.util.Dom.generateId();
          t.setAttribute('id',newID);
          YAHOO.otorg.DomCollapse.setElHeight( newID, t.offsetHeight );
          // create a new target and replace the element's
          // content with this new element
          var a = document.createElement('a');
          a.setAttribute('href','#'+newID);
          var c = elms[i].innerHTML;
          a.innerHTML = elms[i].innerHTML;
          elms[i].innerHTML = '';
          elms[i].appendChild(a);
          YAHOO.util.Dom.addClass(elms[i],css.parentClass);
          YAHOO.util.Dom.addClass(t,css.hideClass);
          // add a click handler to the link pointing to toggle()
          if( !id || id.toString() == '' ) YAHOO.util.Event.on(a, 'click', YAHOO.otorg.DomCollapse.toggle);
        };
      // if the trigger is a link
      } else {
        // get the ID from the href attribute
        var newID = elms[i].href.replace(/.*#/,'');
        // grab the connected element, or the next sibling in case
        // it doesn't exist
        var t = document.getElementById(newID) || YAHOO.otorg.DomCollapse.getNext(elms[i]);
        if(t !== null){
          // re-set the href attribute to this element
          if(t.id !== newID){
            newID = t.id;
            elms[i].setAttribute('href','#'+newID);
          };
          YAHOO.otorg.DomCollapse.setElHeight( newID, t.offsetHeight );
          YAHOO.util.Dom.addClass(elms[i],css.parentClass);
          YAHOO.util.Dom.addClass(t,css.hideClass);
        
          // add a click handler to the link pointing to toggle
          if( !id || id.toString() == '' ) YAHOO.util.Event.on(elms[i], 'click', YAHOO.otorg.DomCollapse.toggle);
        };
      };
    }
  }
  dbg('/INIT')
};

YAHOO.otorg.DomCollapse.setElHeight = function( id, px ) {
  //~ console.log('set height: ' + id + '=' + px );
  YAHOO.otorg.DomCollapse._heights[ id ] = px;
};
YAHOO.otorg.DomCollapse.getElHeight = function( id ) {
  return YAHOO.otorg.DomCollapse._heights[ id ] || YAHOO.util.Dom.get(id).offsetHeight;
};
// tool method to get the next sibling that is not a text node
YAHOO.otorg.DomCollapse.getNext = function(o){
  var t = o.nextSibling;
  if(t){
    while(t.nodeType !== 1 && t.nextSibling){
      t = t.nextSibling;
    }
  }
  return t;  
};
YAHOO.otorg.DomCollapse.isToggling = function(e) {
  return YAHOO.otorg.DomCollapse.toggling ? 1 : 0;
};
YAHOO.otorg.DomCollapse.toggleComplete = function(e) {
dbg('toggle off');
  YAHOO.otorg.DomCollapse.toggling = 0;
};
YAHOO.otorg.DomCollapse.toggleStarted = function(e) {
dbg('toggle on');
  YAHOO.otorg.DomCollapse.toggling = 1;
};

// method to toggle the showing and hiding of the next element
YAHOO.otorg.DomCollapse.toggle = function(e, args ){

  var tid = args ? args['tid'] : '';
  var pid = args ? args['pid'] : '';
  var expanding = args ? args['expanding'] : 0;
  var noToggleProtection = args ? args['noToggleProtection'] : 0;
  var dontAnimateParent = args ? args['dontAnimateParent'] : 0;
  
  if( !noToggleProtection ) {
   dbg( YAHOO.otorg.DomCollapse.isToggling() ? 'toggle protector!' : 'allow toggle');
    if( YAHOO.otorg.DomCollapse.isToggling() ) {      
      if(e) YAHOO.util.Event.preventDefault(e);
      return;
    }    
  }

  /*
YUIDomCollapse fancy add-on by Christian Heilmann
Version 1.0 / May 2007
License: http://creativecommons.org/licenses/by/3.0/
Homepage: http://onlinetools.org/tools/yuidomcollapse/
*/  

  if( !noToggleProtection ) YAHOO.otorg.DomCollapse.toggleStarted();
  // shortcut to CSS object
  var css = YAHOO.otorg.DomCollapse.css;
  // get the trigger element, which is the one clicked on if it has
  // the trigger class
  var id = tid ? tid : this.href.replace(/.*#/,'');
  var t = document.getElementById(id);

  var parent = pid ? YAHOO.util.Dom.get(pid)
    : tid ? YAHOO.util.Dom.get(tid)
    : ( YAHOO.util.Dom.hasClass(this,css.triggerClass) ? this : this.parentNode );
      
  // retrieve the ID from the href attribute and make sure the element 
  // exists    
  dbg('toggle: ' + id);
  if(t != undefined){
    // get overflow style - elements need to have overflow hidden 
    // to animate smoothly
    // set overflow to hidden
    YAHOO.util.Dom.setStyle(t,'overflow','hidden');
    // get the height and compare it to the offsetHeight, thus 
    // getting the real height + padding
    //~ var height = YAHOO.util.Dom.getStyle(t,'height');
    //~ if(height==='auto'){
      //~ curHeight = t.clientHeight;
    //~ } else {          
      //~ curHeight = Math.max(parseInt(height),t.offsetHeight);
      //~ if( curHeight == 0 ) {
        //~ YAHOO.util.Dom.setStyle(t,'height', 'auto');
        //~ curHeight = t.clientHeight;
        //~ YAHOO.util.Dom.setStyle(t,'height', '0px');
      //~ }
    //~ }
    var x = YAHOO.otorg.DomCollapse.getElHeight( t.id );
    // if the element is currently hidden
  
    if( expanding > 0 || ( !(expanding < 0) && YAHOO.util.Dom.hasClass(t,css.hideClass) )){
      // set its height and opacity to 0 and add the height class
      dbg('expand ' + t.id );
      YAHOO.util.Dom.setStyle(t,'display','none');
      YAHOO.util.Dom.setStyle(t,'height','0px');
      YAHOO.util.Dom.setStyle(t,'opacity',0);
      YAHOO.util.Dom.removeClass(t,css.hideClass);
      
      // prepare the animation animate the element
      var a = new YAHOO.util.Anim(t, { opacity: {from:0,to: 1} ,height:{from:0,to:x} },
        YAHOO.otorg.DomCollapse.config.animDuration,
        YAHOO.otorg.DomCollapse.config.targetEasingStyle 
      );
      //~ var parentout = new YAHOO.util.Anim(parent, { opacity: {from:1,to: 0} },
        //~ YAHOO.otorg.DomCollapse.config.animDuration/2,
        //~ YAHOO.otorg.DomCollapse.config.triggerEasingStyle
      //~ );
      //~ var parentin = new YAHOO.util.Anim(parent, { opacity: {from:0,to: 1} },
        //~ YAHOO.otorg.DomCollapse.config.animDuration/2,
        //~ YAHOO.otorg.DomCollapse.config.triggerEasingStyle
      //~ );
      a.onStart.subscribe( function() { 
        if( parent && parent.firstChild) {
          parent.firstChild.innerHTML = ( parent.firstChild.innerHTML || parent.firstChild.toString() ).replace( YAHOO.otorg.DomCollapse.config.expandTriggerImg, YAHOO.otorg.DomCollapse.config.collapseTriggerImg); 
        }
      });
      a.onTween.subscribe( function() { //this is here so IE doesn't prematurely show the element before it's supposed to have height
        if( !YAHOO.util.Dom.getStyle(t,'height').match( /^0/ ) )
          YAHOO.util.Dom.setStyle(t,'display','');
      });
      // re-set the overflow and set the appropriate class to the 
      // trigger element when the animation has finished
      a.onComplete.subscribe(
        function(){        
          YAHOO.util.Dom.setStyle(t,'overflow','visible');
          //~ YAHOO.util.Dom.replaceClass(parent,css.parentClass,css.openClass);
          YAHOO.otorg.DomCollapse.toggleComplete();
        }
      );
      //~ alert('!');
      //~ YAHOO.util.Dom.removeClass(t,css.heightClass);
      //~ alert('!');
      //~ parentout.onComplete.subscribe( function() { 
        //~ if( parent && parent.firstChild) {
          //~ parent.firstChild.innerHTML = ( parent.firstChild.innerHTML || parent.firstChild.toString() ).replace( YAHOO.otorg.DomCollapse.config.expandTriggerImg, YAHOO.otorg.DomCollapse.config.collapseTriggerImg); 
        //~ }
        //~ parentin.animate() 
      //~ } );        
      //~ parentin.onComplete.subscribe( YAHOO.otorg.DomCollapse.toggleComplete );
      a.animate();
      //~ if( !dontAnimateParent ) parentout.animate();
    // if the element is currently visible
    } else {
      dbg('collapse ' + t.id );
      // prepare and start the animation
      var a = new YAHOO.util.Anim(t, { opacity: {from:1,to: 0} ,height:{from:x,to:0} },
        YAHOO.otorg.DomCollapse.config.animDuration,
        YAHOO.otorg.DomCollapse.config.targetEasingStyle 
      );
      //~ var parentout = new YAHOO.util.Anim(parent, { opacity: {from:1,to: 0} },
        //~ YAHOO.otorg.DomCollapse.config.animDuration/2,
        //~ YAHOO.otorg.DomCollapse.config.triggerEasingStyle
      //~ );
      //~ var parentin = new YAHOO.util.Anim(parent, { opacity: {from:0,to: 1} },
        //~ YAHOO.otorg.DomCollapse.config.animDuration/2,
        //~ YAHOO.otorg.DomCollapse.config.triggerEasingStyle
      //~ );

      a.onTween.subscribe( function() { //this is here so IE doesn't prematurely show the element before it's supposed to have height
        if( parseInt(YAHOO.util.Dom.getStyle(t,'height').replace( /px$/, '' )) <= YAHOO.otorg.DomCollapse.config.prematureIEhidingpixels ) 
          YAHOO.util.Dom.setStyle(t,'display','none');
          
        if( (a.currentFrame / a.totalFrames)*100 > 75 ) {
          if( parent ) {
            parent.firstChild.innerHTML =parent.firstChild.innerHTML.replace( YAHOO.otorg.DomCollapse.config.collapseTriggerImg, YAHOO.otorg.DomCollapse.config.expandTriggerImg);
          }
        }
      });

      // when the animation is done, hide it with the right class, 
      // re-set its styles and replace the open with a parent class
      a.onComplete.subscribe(
        function(){                    
          YAHOO.util.Dom.addClass(t,css.hideClass);
          YAHOO.util.Dom.setStyle(t,'height',x+'px');
          YAHOO.util.Dom.setStyle(t,'opacity',1);
          YAHOO.util.Dom.setStyle(t,'overflow','visible');
          YAHOO.otorg.DomCollapse.toggleComplete();
          //~ YAHOO.util.Dom.replaceClass(parent,css.openClass,css.parentClass);            
          if( parent ) {
            parent.firstChild.innerHTML =parent.firstChild.innerHTML.replace( YAHOO.otorg.DomCollapse.config.collapseTriggerImg, YAHOO.otorg.DomCollapse.config.expandTriggerImg);
          }
          YAHOO.otorg.DomCollapse.toggleComplete();
        }
      );
      //~ parentout.onComplete.subscribe( function() { 
        //~ if( parent ) {
          //~ parent.firstChild.innerHTML =parent.firstChild.innerHTML.replace( YAHOO.otorg.DomCollapse.config.collapseTriggerImg, YAHOO.otorg.DomCollapse.config.expandTriggerImg);
        //~ }
        //~ parentin.animate(); 
      //~ } );        
      //~ parentin.onComplete.subscribe( YAHOO.otorg.DomCollapse.toggleComplete );
      a.animate();
       //~ if( !dontAnimateParent ) parentout.animate();
   };
  }
  else { dbg('undefined?') }
  YAHOO.util.Event.preventDefault(e);
};

// If the DOM is ready, go for it.
YAHOO.util.Event.onDOMReady(YAHOO.otorg.DomCollapse.init);
