/*
 * jQuery.heightOf({height_of, deduct})
 * 
 * Links the height of one element to the window or another element.
 * 
 * The 'height_of' can be:
 * - window (default)
 * - parent
 * - jquery selector
 * 
 * The height will be updated on window resize.
 * 
 * You can also specify a selector for elements whose height should be 
 * deducted. This is useful if you want to make something fit to the window
 * taking into consideration other elements that might occupy vertical space.
 * 
 * This is useful for things like creating a scroll pane that fits to the size
 * of the window, making columns equal height, that sort of thing.
 * 
 * In MSIE there may be problems if the element is in a float, so always wrap
 * floated elements in in a clearfixed container.
 * 
 * Tested in:
 * Firefox 2+
 * Chrome 0.4x
 * Safari 3.x
 * IE7
 * Opera 9.5x
 */


(function($){
    $.fn.heightOf = function(height_of, deduct_selector){
        height_of = height_of || 'window';
        deduct_selector = deduct_selector || false;
        var el = $(this);
        // Fired on window resize
        $(window).resize(
            function(){
                var h, minus_height_fun; 
                // Get start height
                if(height_of === 'window'){
                    // Work around Opera 9.5/jQuery 1.2.6 getting window height wrong
                    var h = $.browser.opera && $.browser.version > "9.5" &&
                             $.fn.jquery <= "1.2.6" ?
                                document.documentElement["clientHeight"] :
                                $(window).height();
                } else if (height_of === 'parent'){
                    h = $(this).parent().height();
                } else {
                    h = $(height_of).height();
                }
                // Minus the height of other elements
                var deduct = 0;
                if(deduct_selector){
                    $(deduct_selector).each(
                        function(){
                            var l_deduct = 0;
                            var l_el = this;
                            l_deduct += $(this).outerHeight();
                            $.each(['marginTop','marginBottom'], function(i,val){
                                var n = $(l_el).css(val).replace(/[^0-9\.]/g,'');
                                if(n){ l_deduct += parseInt(n);}
                            });
                            deduct += l_deduct;
                        });
                }
                // Minus total of deduct and any difference between the els height and outerHeight
                el.height(h-(deduct+(el.outerHeight()-el.height())));
            });
        // Fire window.resize to initialize height
        $(window).resize();
    }
})(jQuery);

