﻿/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* $LastChangedDate: 2007-10-06 20:11:15 +0200 (Sa, 06 Okt 2007) $
* $Rev: 3581 $
*
* Version: @VERSION
*
* Requires: jQuery 1.2+
*/

(function($) {

    $.dimensions = {
        version: '@VERSION'
    };

    // Create innerHeight, innerWidth, outerHeight and outerWidth methods
    $.each(['Height', 'Width'], function(i, name) {

        // innerHeight and innerWidth
        $.fn['inner' + name] = function() {
            if (!this[0]) return;

            var torl = name == 'Height' ? 'Top' : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right

            return num(this, name.toLowerCase()) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
        };

        // outerHeight and outerWidth
        $.fn['outer' + name] = function(options) {
            if (!this[0]) return;

            var torl = name == 'Height' ? 'Top' : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right

            options = $.extend({ margin: false }, options || {});

            return num(this, name.toLowerCase())
				+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
				+ num(this, 'padding' + torl) + num(this, 'padding' + borr)
				+ (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
        };
    });

    // Create scrollLeft and scrollTop methods
    $.each(['Left', 'Top'], function(i, name) {
        $.fn['scroll' + name] = function(val) {
            if (!this[0]) return;

            return val != undefined ?

            // Set the scroll offset
			this.each(function() {
			    this == window || this == document ?
					window.scrollTo(
						name == 'Left' ? val : $(window)['scrollLeft'](),
						name == 'Top' ? val : $(window)['scrollTop']()
					) :
					this['scroll' + name] = val;
			}) :

            // Return the scroll offset
			this[0] == window || this[0] == document ?
				self[(name == 'Left' ? 'pageXOffset' : 'pageYOffset')] ||
					$.boxModel && document.documentElement['scroll' + name] ||
					document.body['scroll' + name] :
				this[0]['scroll' + name];
        };
    });

    $.fn.extend({
        position: function() {
            var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;

            if (elem) {
                // Get *real* offsetParent
                offsetParent = this.offsetParent();

                // Get correct offsets
                offset = this.offset();
                parentOffset = offsetParent.offset();

                // Subtract element margins
                offset.top -= num(elem, 'marginTop');
                offset.left -= num(elem, 'marginLeft');

                // Add offsetParent borders
                parentOffset.top += num(offsetParent, 'borderTopWidth');
                parentOffset.left += num(offsetParent, 'borderLeftWidth');

                // Subtract the two offsets
                results = {
                    top: offset.top - parentOffset.top,
                    left: offset.left - parentOffset.left
                };
            }

            return results;
        },

        offsetParent: function() {
            var offsetParent = this[0].offsetParent;
            while (offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static'))
                offsetParent = offsetParent.offsetParent;
            return $(offsetParent);
        }
    });

    function num(el, prop) {
        return parseInt($.css(el.jquery ? el[0] : el, prop)) || 0;
    };

})(jQuery);