/**
 * @class Ext.Element
 */

Ext.Element.addMethods({
   
/**
     * Sets the element's box. Use getBox() on another element to get a box obj. If animate is true then width, height, x and y will be animated concurrently.
     * @param {Object} box The box to fill {x, y, width, height}
     * @param {Boolean} adjust (optional) Whether to adjust for box-model issues automatically
     * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
     * @return {Ext.Element} this
     */

    setBox
: function(box, adjust, animate){
       
var me = this,
                w
= box.width,
                h
= box.height;
       
if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
           w
-= (me.getBorderWidth("lr") + me.getPadding("lr"));
           h
-= (me.getBorderWidth("tb") + me.getPadding("tb"));
       
}
        me
.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
       
return me;
   
},
   
   
/**
     * Return a box {x, y, width, height} that can be used to set another elements
     * size/location to match this element.
     * @param {Boolean} contentBox (optional) If true a box for the content of the element is returned.
     * @param {Boolean} local (optional) If true the element's left and top are returned instead of page x/y.
     * @return {Object} box An object in the format {x, y, width, height}
     */

        getBox
: function(contentBox, local) {      
           
var me = this,
                xy
,
                left
,
                top
,
                getBorderWidth
= me.getBorderWidth,
                getPadding
= me.getPadding,
                l
,
                r
,
                t
,
                b
;
       
if(!local){
            xy
= me.getXY();
       
}else{
            left
= parseInt(me.getStyle("left"), 10) || 0;
            top
= parseInt(me.getStyle("top"), 10) || 0;
            xy
= [left, top];
       
}
       
var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
       
if(!contentBox){
            bx
= {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
       
}else{
            l
= getBorderWidth.call(me, "l") + getPadding.call(me, "l");
            r
= getBorderWidth.call(me, "r") + getPadding.call(me, "r");
            t
= getBorderWidth.call(me, "t") + getPadding.call(me, "t");
            b
= getBorderWidth.call(me, "b") + getPadding.call(me, "b");
            bx
= {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)};
       
}
        bx
.right = bx.x + bx.width;
        bx
.bottom = bx.y + bx.height;
       
return bx;
       
},
       
   
/**
     * Move this element relative to its current position.
     * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down").
     * @param {Number} distance How far to move the element in pixels
     * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
     * @return {Ext.Element} this
     */

     move
: function(direction, distance, animate){
       
var me = this,          
                xy
= me.getXY(),
                x
= xy[0],
                y
= xy[1],              
                left
= [x - distance, y],
                right
= [x + distance, y],
                top
= [x, y - distance],
                bottom
= [x, y + distance],
                hash
= {
                        l
:     left,
                        left
: left,
                        r
: right,
                        right
: right,
                        t
: top,
                        top
: top,
                        up
: top,
                        b
: bottom,
                        bottom
: bottom,
                        down
: bottom                          
               
};
       
            direction
= direction.toLowerCase();    
            me
.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
   
},
   
   
/**
     * Quick set left and top adding default units
     * @param {String} left The left CSS property value
     * @param {String} top The top CSS property value
     * @return {Ext.Element} this
     */

     setLeftTop
: function(left, top){
           
var me = this,
                style
= me.dom.style;
        style
.left = me.addUnits(left);
        style
.top = me.addUnits(top);
       
return me;
   
},
   
   
/**
     * Returns the region of the given element.
     * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
     * @return {Region} A Ext.lib.Region containing "top, left, bottom, right" member data.
     */

    getRegion
: function(){
       
return Ext.lib.Dom.getRegion(this.dom);
   
},
   
   
/**
     * Sets the element's position and size in one shot. If animation is true then width, height, x and y will be animated concurrently.
     * @param {Number} x X value for new position (coordinates are page-based)
     * @param {Number} y Y value for new position (coordinates are page-based)
     * @param {Mixed} width The new width. This may be one of:

     * @param {Mixed} height The new height. This may be one of:

     * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
     * @return {Ext.Element} this
     */

    setBounds
: function(x, y, width, height, animate){
           
var me = this;
       
if (!animate || !me.anim) {
            me
.setSize(width, height);
            me
.setLocation(x, y);
       
} else {
            me
.anim({points: {to: [x, y]},
                         width
: {to: me.adjustWidth(width)},
                         height
: {to: me.adjustHeight(height)}},
                     me
.preanim(arguments, 4),
                     
'motion');
       
}
       
return me;
   
},

   
/**
     * Sets the element's position and size the specified region. If animation is true then width, height, x and y will be animated concurrently.
     * @param {Ext.lib.Region} region The region to fill
     * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
     * @return {Ext.Element} this
     */

    setRegion
: function(region, animate) {
       
return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
   
}
});