/*
Script: Element.Dimensions.js
        Contains Element prototypes to deal with Element size and position in space.

Note:
        The functions in this script require n XHTML doctype.

License:
        MIT-style license.
*/

/*
Class: Element
        Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
*/

Element.extend({

        /*
        Property: scrollTo
                Scrolls the element to the specified coordinated (if the element has an overflow)

        Arguments:
                x - the x coordinate
                y - the y coordinate

        Example:
                >$('myElement').scrollTo(0, 100)
        */

        scrollTo: function(x, y){
                this.scrollLeft = x;
                this.scrollTop = y;
        },

        /*
        Property: getSize
                Return an Object representing the size/scroll values of the element.

        Example:
                (start code)
                $('myElement').getSize();
                (end)

        Returns:
                (start code)
                {
                        'scroll': {'x': 100, 'y': 100},
                        'size': {'x': 200, 'y': 400},
                        'scrollSize': {'x': 300, 'y': 500}
                }
                (end)
        */

        getSize: function(){
                return {
                        'scroll': {'x': this.scrollLeft, 'y': this.scrollTop},
                        'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
                        'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight}
                };
        },

        /*
        Property: getPosition
                Returns the real offsets of the element.

        Arguments:
                overflown - optional, an array of nested scrolling containers for scroll offset calculation, use this if your element is inside any element containing scrollbars

        Example:
                >$('element').getPosition();

        Returns:
                >{x: 100, y:500};
        */

        getPosition: function(overflown){
                overflown = overflown || [];
                var el = this, left = 0, top = 0;
                do {
                        left += el.offsetLeft || 0;
                        top += el.offsetTop || 0;
                        el = el.offsetParent;
                } while (el);
                overflown.each(function(element){
                        left -= element.scrollLeft || 0;
                        top -= element.scrollTop || 0;
                });
                return {'x': left, 'y': top};
        },

        /*
        Property: getTop
                Returns the distance from the top of the window to the Element.

        Arguments:
                overflown - optional, an array of nested scrolling containers, see Element::getPosition
        */

        getTop: function(overflown){
                return this.getPosition(overflown).y;
        },

        /*
        Property: getLeft
                Returns the distance from the left of the window to the Element.

        Arguments:
                overflown - optional, an array of nested scrolling containers, see Element::getPosition
        */

        getLeft: function(overflown){
                return this.getPosition(overflown).x;
        },

        /*
        Property: getCoordinates
                Returns an object with width, height, left, right, top, and bottom, representing the values of the Element

        Arguments:
                overflown - optional, an array of nested scrolling containers, see Element::getPosition

        Example:
                (start code)
                var myValues = $('myElement').getCoordinates();
                (end)

        Returns:
                (start code)
                {
                        width: 200,
                        height: 300,
                        left: 100,
                        top: 50,
                        right: 300,
                        bottom: 350
                }
                (end)
        */

        getCoordinates: function(overflown){
                var position = this.getPosition(overflown);
                var obj = {
                        'width': this.offsetWidth,
                        'height': this.offsetHeight,
                        'left': position.x,
                        'top': position.y
                };
                obj.right = obj.left + obj.width;
                obj.bottom = obj.top + obj.height;
                return obj;
        }

});
