/* justifyHeight.js v1.4 */
/**
 * Adjusts the height of elements
 */
var JustifyHeight = Class.create({

   /**
    * Constructor
    */
   initialize: function ()
   {
      this.compare = $A();
      this.minHeight = 0;
   },

   /**
    * Adds an element to the list of elements that need adjusting
    *
    * @param Element compareElem The DOM Element that will be used
    *    to compare against the other elements
    * @param Element adjustElem The DOM Element that will be adjusted if the comparison
    *    object turns out to be short. By default, this will be the same as the compareElem
    * @param Integer fudge The number of pixels to subtract from the height delta
    *    when extending the length of the adjustElem
    * @return Object Returns a self reference
    */
   add: function (compareElem, adjustElem, fudge)
   {
      compareElem = $(compareElem);

      if ( !Object.isElement(compareElem) )
         throw "compareElem does not exist: " + compareElem ;

      if ( !adjustElem )
         adjustElem = compareElem;

      adjustElem = $(adjustElem)

      if ( !Object.isElement(adjustElem) )
         throw "adjustElem does not exist: " + adjustElem ;

      this.compare.push($H({
            compare: compareElem,
            adjust: adjustElem,
            fudge: parseInt(fudge ? fudge : 0)
         }));

      return this;
   },

   /**
    * Sets the minimum height that any of the justified elements should be
    *
    * @param Integer minHeight The height in pixels
    * @return Object Returns a self reference
    */
   setMinHeight: function (minHeight)
   {
      this.minHeight = parseInt(minHeight);
      return this;
   },

   /**
    * Executes the actual justification so that the heights are al changed
    *
    * @param Boolean reset Whether the height style of the compare elements should
    *    should be reset before comparing
    * @return Object Returns a self reference
    */
   justify: function ( reset )
   {
      if ( this.compare.size() > 1 ) {

         // will hold a reference to the tallest group
         var tallGroup = null;

         // Will hold the height of the tallest element
         var maxHeight = this.minHeight;

         // find the tallest element
         this.compare.each(function(group) {

            // If they want us to reset the height first...
            if ( reset )
               group.get('compare').setStyle({height: ''});

            var height = group.get('compare').getHeight();
            if ( height > maxHeight ) {
               maxHeight = height;
               tallGroup = group;
            }
         });

         // Adjust each of the elements so that they are as tall as the tallest
         this.compare.without(tallGroup).each(function (group) {

            var height = group.get('compare').getHeight();

            var toAdjust = group.get('adjust');

            toAdjust.setStyle({
               height:
                  toAdjust.getHeight()
                  + (maxHeight - height)
                  - ( parseInt( toAdjust.getStyle('padding-top').gsub(/[^0-9]/, '') ) || 0 )
                  - ( parseInt( toAdjust.getStyle('padding-bottom').gsub(/[^0-9]/, '') ) || 0 )
                  - ( parseInt( toAdjust.getStyle('border-top-width').gsub(/[^0-9]/, '') )  || 0 )
                  - ( parseInt( toAdjust.getStyle('border-bottom-width').gsub(/[^0-9]/, '') ) || 0 )
                  - group.get('fudge')
                  + 'px'
            });

         });

      }

      return this;
   }

});