var Browser = function() {
    var o = {
        isIE:0, isOpera:0, isGecko:0, isWebkit:0, isMobile: null 
    };
    
    var ua = navigator.userAgent, m;

    // Modern KHTML browsers should qualify as Safari X-Grade
    if ((/KHTML/).test(ua)) {
        o.isWebkit=1;
    }
    // Modern WebKit browsers are at least X-Grade
    m=ua.match(/AppleWebKit\/([^\s]*)/);
    if (m&&m[1]) {
        o.isWebkit=parseFloat(m[1]);

        // Mobile browser check
        if (/ Mobile\//.test(ua)) {
            o.isMobile = "Apple"; // iPhone or iPod Touch
        } else {
            m=ua.match(/NokiaN[^\/]*/);
            if (m) {
                o.isMobile = m[0]; // Nokia N-series, ex: NokiaN95
            }
        }
    }

    if (!o.isWebkit) { // not webkit
        // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
        m=ua.match(/Opera[\s\/]([^\s]*)/);
        if (m&&m[1]) {
            o.isOpera=parseFloat(m[1]);
            m=ua.match(/Opera Mini[^;]*/);
            if (m) {
                o.isMobile = m[0]; // ex: Opera Mini/2.0.4509/1316
            }
        } else { // not opera or webkit
            m=ua.match(/MSIE\s([^;]*)/);
            if (m&&m[1]) {
                o.isIE=parseFloat(m[1]);
            } else { // not opera, webkit, or ie
                m=ua.match(/Gecko\/([^\s]*)/);
                if (m) {
                    o.isGecko=1; // Gecko detected, look for revision
                    m=ua.match(/rv:([^\s\)]*)/);
                    if (m&&m[1]) {
                        o.isGecko=parseFloat(m[1]);
                    }
                }
            }
        }
    }
    
    return o;
}();


/**
 * Returns the height of the document.
 * @return {Int} The height of the actual document (which includes the body and its margin).
 */
function get_DocumentHeight() {
    var scrollHeight = (document.compatMode != 'CSS1Compat') ? document.body.scrollHeight : document.documentElement.scrollHeight;
    return Math.max(scrollHeight, get_ViewportHeight());
}

/**
 * Returns the width of the document.
 * @return {Int} The width of the actual document (which includes the body and its margin).
 */
function get_DocumentWidth() {
    var scrollWidth = (document.compatMode != 'CSS1Compat') ? document.body.scrollWidth : document.documentElement.scrollWidth;
    return Math.max(scrollWidth, get_ViewportWidth());
}

/**
 * Returns the current height of the viewport.
 * @return {Int} The height of the viewable area of the page (excludes scrollbars).
 */
function get_ViewportHeight() {
    var height = self.innerHeight; // Safari, Opera
    var mode = document.compatMode;

    if ( (mode || Browser.isIE) && !Browser.isOpera ) { // IE, Gecko
        height = (mode == 'CSS1Compat') ?
                document.documentElement.clientHeight : // Standards
                document.body.clientHeight; // Quirks
    }

    return height;
}

/**
 * Returns the current width of the viewport.
 * @return {Int} The width of the viewable area of the page (excludes scrollbars).
 */
function get_ViewportWidth() {
    var width = self.innerWidth;  // Safari
    var mode = document.compatMode;
    
    if (mode || Browser.isIE) { // IE, Gecko, Opera
        width = (mode == 'CSS1Compat') ?
                document.documentElement.clientWidth : // Standards
                document.body.clientWidth; // Quirks
    }
    return width;
}


/**
 * Returns the current width of the system scrollbars.
 * @return {Int} The width of the system scrollbars.
 */
function get_ScrollbarWidth() {
    with( document.body )  {
	    
	    var initial_overflow = style.overflow;
	    
	    style.overflow = 'hidden';
	
	    var width = clientWidth;
	    
	    style.overflow = 'scroll';
	    width -= clientWidth;
	
	    if( ! width ) 
	       width = ( offsetWidth - clientWidth );
	
	    style.overflow = initial_overflow;
	    
	    return width;
    }
}



/**
 * Displays Browser information.
 */
function test_Browser()  {
    var BrowserInfo = '';

    for( var i in Browser )
        BrowserInfo += ( i + ' :: ' + Browser[ i ] + '<br />' );

    alert( BrowserInfo );
}
