/** */
Ext.define('Ext.rtl.dom.Element_scroll', {
    override: 'Ext.dom.Element',

    /**
     * @private
     * Returns a number indicating how the browser reports scrollLeft on overflowing rtl
     * elements.  This method cannot be used reliably on the documentElement or
     * document.body because the behavior of these elements can be different from other
     * elements in some browsers.
     * 
     * 0: offset from right (negative number) - firefox
     * 1: offset from left (positive number) - IE6, IE7, IE6 - IE9 quirks, and Webkit
     * 2: offset from right (positive number) - IE8 - IE10 & IE10 quirks
     * 
     * @return {Number}
     */
    getRtlScrollFlag: function() {
        var el = Ext.getBody().createChild({
            tag: 'div',
            style: 'position:absolute;overflow:auto;height:100px;width:100px;',
            children: [{
                tag: 'div',
                style: 'height:30px;width:150px;'
            }]
        }),
        dom = el.dom,
        flag = 2;

        if (dom.scrollLeft === 50) {
            flag = 1;
        } else {
            dom.scrollLeft = -1;
            if (dom.scrollLeft) {
                flag = 0;
            }
        }

        el.remove();

        return flag;
    },

    rtlGetScroll: function() {
        var me = this,
            dom = me.dom,
            doc = document,
            body = doc.body,
            scroll = me.getScroll(),
            // The left value returned from getScroll() may be a negative number.  In rtl
            // mode left should always be reported as a positive number of pixels from the
            // right, so use the absolute value of left.
            left = Math.abs(scroll.left),
            isDocOrBody = (dom === doc || dom === body);

        if ((isDocOrBody ? (3 & me._rtlDocScrollFlag) :
            (me._rtlScrollFlag || me.getRtlScrollFlag())) === 1) {
            // If the browser reports scrollLeft as the number of pixels from left
            // (same as ltr) we need to convert it to a rtl position by subtracting it
            // from scrollWidth
            if (isDocOrBody) {
                dom = body;
            }
            
            left = dom.scrollWidth - left -
                (isDocOrBody ? Ext.Element.getViewportWidth() : dom.clientWidth);
        }
        scroll.left = left;

        return scroll;
    }
}, function() {
    var Element = this;
    Ext.on({
        ready: function() {
            // scrollLeft on the document/body is reported differently from ordinary
            // overflowing elements in many browsers (see #getRtlScrollFlag). This
            // function attaches to onReady with a priority of 1000 so that we can detect
            // how the browser reports scrollLeft by manipulating the document/body before
            // any components have been rendered to the page.  There are 2 separate things
            // we have to detect:
            // 1. The element that overflows - when the document overflows some browsers
            // set scrollLeft on the document body (webkit and IE quirks), while other
            // browsers set scrollLeft on the documentElement (all other supported browsers
            // at the time of this writing).
            // 2. The scrollLeft of the overflowing document/body can be one of the
            // following:
            //    a. number of pixels offset from right expressed as a negative number
            //       (Webkit, Firefox)
            //    b. number of pixels offset from right expressed as a positive number
            //       (IE8 - IE10 strict mode, and IE10 quirks mode.
            //    c. number of pixels offset from left expressed as a positive number
            //       (IE6 - IE9 quirks mode, and IE6/IE7 strict mode.
            //
            // The following logic feture detects the handling of scrollLeft and sets the 
            // _rtlDocScrollFlag property on this class' prototype as a bit flag which has 
            // the following values:
            // 
            // 0 - docEl, negative right
            // 1 - docEl, positive left
            // 2 - docEl, positive right
            // 4 - body, negative right
            // 5 - body, positive left
            var doc = document,
                docEl = doc.documentElement,
                body = doc.body,
                // flag defaults to body, negative right (webkit) so no detection needed
                // is needed for this scenario
                flag = 4,
                bodyStyle = body.style,
                // save the direction property so we can set it back when we are done.
                direction = bodyStyle.direction,
                el = Ext.getBody().createChild(
                    '<div style="height:20000px;width:20000px;"></div>'
                ), 
                dom = el.dom,
                ltrRight, rtlRight

            bodyStyle.direction = 'ltr';
            ltrRight = dom.getBoundingClientRect().right;

            bodyStyle.direction = 'rtl';
            rtlRight = dom.getBoundingClientRect().right;

            // when the body has vertical overflow some browser continue to show the
            // vertical scrollbar on the right side of the page even in rtl mode.
            Element.prototype._rtlBodyScrollbarOnRight = (ltrRight === rtlRight);

            // First, check if scrollLeft is a non-zero value on the documentElement or
            // body. This means scrollLeft is a positive number offset from the left.
            if (docEl.scrollLeft > 0) {
                // IE6/7 strict
                flag = 1;
            } else if (body.scrollLeft > 0) {
                // IE6 - IE9 quirks
                flag = 5;
            } else {
                // The next step is to attempt to set scrollLeft values, This allows us to
                // test for non-zero values to see if the value was valid (scrollLeft
                // resets to 0 when a non-valid value is set).
                // attempt to set the documentElement's scrollLeft to a negative number
                docEl.scrollLeft = -1;
                if (docEl.scrollLeft) {
                    // it worked! we were able to set a negative scroll left on the
                    // documentElement (firefox)
                    flag = 0;
                } else {
                    // attempt to set the documentElement's scrollLeft to a positive number
                    docEl.scrollLeft = 1;
                    if (docEl.scrollLeft) {
                        // success setting scroll left to a positive number on
                        // documentElement (IE8 strict, IE9 strict, and IE10 quirks)
                        flag = 2;
                    }
                }
            }

            el.remove();
            if (!direction) {
                // if direction is an empty string, we set it back to "ltr", because once
                // the direction style on the body element is changed to "rtl" in webkit,
                // it becomes permanent, even after it is set back to "", unless it is first
                // explicitly set back to "ltr"
                bodyStyle.direction = 'ltr';
                // read the scroll width before setting the direction back to "".
                // This forces webkit to update its computed direction style to ltr
                body.scrollWidth;
            }
            // set direction back to its original value
            bodyStyle.direction = direction;
            Element.prototype._rtlDocScrollFlag = flag;
        },
        single: true,
        priority: 1001
    });
});