    /*!
     * Ext JS Library 3.0.3
     * Copyright(c) 2006-2009 Ext JS, LLC
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    /**
     * @class Ext.Element
     */

    // special markup used throughout Ext when box wrapping elements
    Ext.Element.boxMarkup = '';

    Ext.Element.addMethods(function(){
    	var INTERNAL = "_internal";
    	return {
    	    /**
    	     * More flexible version of {@link #setStyle} for setting style properties.
    	     * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
    	     * a function which returns such a specification.
    	     * @return {Ext.Element} this
    	     */
    	    applyStyles : function(style){
    	        Ext.DomHelper.applyStyles(this.dom, style);
    	        return this;
    	    },

    		/**
    	     * Returns an object with properties matching the styles requested.
    	     * For example, el.getStyles('color', 'font-size', 'width') might return
    	     * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.
    	     * @param {String} style1 A style name
    	     * @param {String} style2 A style name
    	     * @param {String} etc.
    	     * @return {Object} The style object
    	     */
    	    getStyles : function(){
    		    var ret = {};
    		    Ext.each(arguments, function(v) {
    			   ret[v] = this.getStyle(v);
    		    },
    		    this);
    		    return ret;
    	    },

    		getStyleSize : function(){
    	        var me = this,
    	        	w,
    	        	h,
    	        	d = this.dom,
    	        	s = d.style;
    	        if(s.width && s.width != 'auto'){
    	            w = parseInt(s.width, 10);
    	            if(me.isBorderBox()){
    	               w -= me.getFrameWidth('lr');
    	            }
    	        }
    	        if(s.height && s.height != 'auto'){
    	            h = parseInt(s.height, 10);
    	            if(me.isBorderBox()){
    	               h -= me.getFrameWidth('tb');
    	            }
    	        }
    	        return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
    	    },

    	    // private  ==> used by ext full
    		setOverflow : function(v){
    			var dom = this.dom;
    	    	if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug
    	    		dom.style.overflow = 'hidden';
    	        	(function(){dom.style.overflow = 'auto';}).defer(1);
    	    	}else{
    	    		dom.style.overflow = v;
    	    	}
    		},

    	   /**
    		* Wraps the specified element with a special 9 element markup/CSS block that renders by default as
    		* a gray container with a gradient background, rounded corners and a 4-way shadow.
    		* This special markup is used throughout Ext when box wrapping elements ({@link Ext.Button},
    		* {@link Ext.Panel} when {@link Ext.Panel#frame frame=true}, {@link Ext.Window}).  The markup
    		* is of this form:
    		*
    Ext.Element.boxMarkup =
        '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div>
         <div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div>
         <div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
    		*
    		* Example usage:
    		*
    // Basic box wrap
    Ext.get("foo").boxWrap();

    // You can also add a custom class and use CSS inheritance rules to customize the box look.
    // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example
    // for how to create a custom box wrap style.
    Ext.get("foo").boxWrap().addClass("x-box-blue");
    		*
    		* @param {String} class (optional) A base CSS class to apply to the containing wrapper element
    		* (defaults to 'x-box'). Note that there are a number of CSS rules that are dependent on
    		* this name to make the overall effect work, so if you supply an alternate base class, make sure you
    		* also supply all of the necessary rules.
    		* @return {Ext.Element} this
    		*/
    	    boxWrap : function(cls){
    	        cls = cls || 'x-box';
    	        var el = Ext.get(this.insertHtml("beforeBegin", "" + String.format(Ext.Element.boxMarkup, cls) + ""));        //String.format(''+Ext.Element.boxMarkup+'', cls)));
    	        Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
    	        return el;
    	    },

            /**
             * Set the size of this Element. If animation is true, both width and height will be animated concurrently.
             * @param {Mixed} width The new width. This may be one of:
             * A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).
             * A String used to set the CSS width style. Animation may not be used.
             * A size object in the format {width: widthValue, height: heightValue}.
             *
             * @param {Mixed} height The new height. This may be one of:
             * A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).
             * A String used to set the CSS height style. Animation may not be used.
             *
             * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
             * @return {Ext.Element} this
             */
    	    setSize : function(width, height, animate){
    			var me = this;
    			if(Ext.isObject(width)){ // in case of object from getSize()
    			    height = width.height;
    			    width = width.width;
    			}
    			width = me.adjustWidth(width);
    			height = me.adjustHeight(height);
    			if(!animate || !me.anim){
    			    me.dom.style.width = me.addUnits(width);
    			    me.dom.style.height = me.addUnits(height);
    			}else{
    			    me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
    			}
    			return me;
    	    },

    	    /**
    	     * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders
    	     * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements
    	     * if a height has not been set using CSS.
    	     * @return {Number}
    	     */
    	    getComputedHeight : function(){
    		    var me = this,
    	        	h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
    	        if(!h){
    	            h = parseInt(me.getStyle('height'), 10) || 0;
    	            if(!me.isBorderBox()){
    	                h += me.getFrameWidth('tb');
    	            }
    	        }
    	        return h;
    	    },

    	    /**
    	     * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders
    	     * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements
    	     * if a width has not been set using CSS.
    	     * @return {Number}
    	     */
    	    getComputedWidth : function(){
    	        var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
    	        if(!w){
    	            w = parseInt(this.getStyle('width'), 10) || 0;
    	            if(!this.isBorderBox()){
    	                w += this.getFrameWidth('lr');
    	            }
    	        }
    	        return w;
    	    },

    	    /**
    	     * Returns the sum width of the padding and borders for the passed "sides". See getBorderWidth()
    	     for more information about the sides.
    	     * @param {String} sides
    	     * @return {Number}
    	     */
    	    getFrameWidth : function(sides, onlyContentBox){
    	        return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
    	    },

    	    /**
    	     * Sets up event handlers to add and remove a css class when the mouse is over this element
    	     * @param {String} className
    	     * @return {Ext.Element} this
    	     */
    	    addClassOnOver : function(className){
    	        this.hover(
    	            function(){
    	                Ext.fly(this, INTERNAL).addClass(className);
    	            },
    	            function(){
    	                Ext.fly(this, INTERNAL).removeClass(className);
    	            }
    	        );
    	        return this;
    	    },

    	    /**
    	     * Sets up event handlers to add and remove a css class when this element has the focus
    	     * @param {String} className
    	     * @return {Ext.Element} this
    	     */
    	    addClassOnFocus : function(className){
    		    this.on("focus", function(){
    		        Ext.fly(this, INTERNAL).addClass(className);
    		    }, this.dom);
    		    this.on("blur", function(){
    		        Ext.fly(this, INTERNAL).removeClass(className);
    		    }, this.dom);
    		    return this;
    	    },

    	    /**
    	     * Sets up event handlers to add and remove a css class when the mouse is down and then up on this element (a click effect)
    	     * @param {String} className
    	     * @return {Ext.Element} this
    	     */
    	    addClassOnClick : function(className){
    	        var dom = this.dom;
    	        this.on("mousedown", function(){
    	            Ext.fly(dom, INTERNAL).addClass(className);
    	            var d = Ext.getDoc(),
    	            	fn = function(){
    		                Ext.fly(dom, INTERNAL).removeClass(className);
    		                d.removeListener("mouseup", fn);
    		            };
    	            d.on("mouseup", fn);
    	        });
    	        return this;
    	    },

    	    /**
    	     * Returns the width and height of the viewport.
            *
            var vpSize = Ext.getBody().getViewSize();

            // all Windows created afterwards will have a default value of 90% height and 95% width
            Ext.Window.override({
                width: vpSize.width * 0.9,
                height: vpSize.height * 0.95
            });
            // To handle window resizing you would have to hook onto onWindowResize.

    	     * @return {Object} An object containing the viewport's size {width: (viewport width), height: (viewport height)}
    	     */
    	    getViewSize : function(){
    	        var doc = document,
    	        	d = this.dom,
    	        	extdom = Ext.lib.Dom,
    	        	isDoc = (d == doc || d == doc.body);
    	        return { width : (isDoc ? extdom.getViewWidth() : d.clientWidth),
    	        		 height : (isDoc ? extdom.getViewHeight() : d.clientHeight) };
    	    },

    	    /**
    	     * Returns the size of the element.
    	     * @param {Boolean} contentSize (optional) true to get the width/size minus borders and padding
    	     * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
    	     */
    	    getSize : function(contentSize){
    	        return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
    	    },

    	    /**
    	     * Forces the browser to repaint this element
    	     * @return {Ext.Element} this
    	     */
    	    repaint : function(){
    	        var dom = this.dom;
    	        this.addClass("x-repaint");
    	        setTimeout(function(){
    	            Ext.fly(dom).removeClass("x-repaint");
    	        }, 1);
    	        return this;
    	    },

    	    /**
    	     * Disables text selection for this element (normalized across browsers)
    	     * @return {Ext.Element} this
    	     */
    	    unselectable : function(){
    	        this.dom.unselectable = "on";
    	        return this.swallowEvent("selectstart", true).
    	        		    applyStyles("-moz-user-select:none;-khtml-user-select:none;").
    	        		    addClass("x-unselectable");
    	    },

    	    /**
    	     * Returns an object with properties top, left, right and bottom representing the margins of this element unless sides is passed,
    	     * then it returns the calculated width of the sides (see getPadding)
    	     * @param {String} sides (optional) Any combination of l, r, t, b to get the sum of those sides
    	     * @return {Object/Number}
    	     */
    	    getMargins : function(side){
    		    var me = this,
    		    	key,
    		    	hash = {t:"top", l:"left", r:"right", b: "bottom"},
    		    	o = {};

    		    if (!side) {
    		        for (key in me.margins){
    		        	o[hash[key]] = parseInt(me.getStyle(me.margins[key]), 10) || 0;
                    }
    		        return o;
    	        } else {
    	            return me.addStyles.call(me, side, me.margins);
    	        }
    	    }
        };
    }());