(function($) {

jQuery.fn.borderWidth = function() { return $(this).outerWidth() - $(this).innerWidth(); }
jQuery.fn.marginWidth = function() { return $(this).outerWidth(true) - $(this).outerWidth(); }
jQuery.fn.paddingWidth = function() { return $(this).innerWidth() - $(this).width(); }

jQuery.fn.stretch = function(options) {
  var o = $.extend({
    usePercents: false,
    equalColumns: false
  }, options);
  $(this).each(function() {
    var $container = $(this);
    var $children = $container.children();
    var totalWidth = 0;
    var containerWidth = $container.width();
    
    // figure out the total width of all the child elements
    $children.each(function() { totalWidth += $(this).outerWidth(true); });
    
    if(o.equalColumns) {
      // resize all the list elements to be equal width and fill the container
      $children.each(function() { 
        var $child = $(this);
        if($children.size() > 0) {
          $child.width(Math.round(1 / $children.size() * containerWidth) - $child.borderWidth() - $child.marginWidth() - $child.paddingWidth());
        }
        else {
          $child.width(0);
        }
      });
    }
    else {
      // resize all the list elements based on their proportional widths to fill the container
      $children.each(function() {
        var $child = $(this);
        if(totalWidth > 0) {
          $child.width(Math.round($child.outerWidth(true) / totalWidth * containerWidth) - $child.borderWidth() - $child.marginWidth() - $child.paddingWidth());
        }
        else {
          $child.width(0);
        }
      });
    }
      
    // calculate the new width of all the child elements
    var newWidthTotal = 0;
    $children.each(function() { newWidthTotal += $(this).outerWidth(true); });
    
    // if the resizing isn't a perfect fit, apply corrections 1px at a time across each element
    // there should really never be more adjustment than 1-2px
    if(newWidthTotal != containerWidth) {
      var correctionRemaining = containerWidth - newWidthTotal;
      for(var i = $children.size()-1; i >= 0 && correctionRemaining > 0; i--) {
        $children.eq(i).width($children.eq(i).width() + 1);
        correctionRemaining--;
        if(i == 0 && correctionRemaining > 0) {
          i = $children.size()-1;
        }
      }
      for(var i = $children.size()-1; i >= 0 && correctionRemaining < 0; i--) {
        $children.eq(i).width($children.eq(i).width() - 1);
        correctionRemaining++;
        if(i == 0 && correctionRemaining > 0) {
          i = $children.size()-1;
        }
      }
    }
      
    // use this if the widths of each child element should be dynamic
    // note that there should be no margins/padding on child elements for this to work properly.
    if(o.usePercents) {
      $children.each(function() {
        var $child = $(this);
        $child.css("width", (parseInt($child.css("width")) / containerWidth * 100) + "%");
      });
    }
  });
}
})(jQuery);
