/*
 * Viewporter v2.0
 * http://github.com/zynga/viewporter
 *
 * Copyright 2011, Zynga Inc.
 * Licensed under the MIT License.
 * https://raw.github.com/zynga/viewporter/master/MIT-LICENSE.txt
 */
var viewporter;
(function() {

    var _viewporter;

    // initialize viewporter object
    viewporter = {

        // options
        forceDetection: false,
        
        // set to true to prevent page scroll.
        preventPageScroll: false,

        // constants
        ACTIVE: (function() {

            // iPad's don't allow you to scroll away the UI of the browser
            if((/ipad/i).test(navigator.userAgent)) {
                return false;
            }

            // WebOS has no touch events, but definitely the need for viewport normalization
            if((/webos/i).test(navigator.userAgent)) {
                return true;
            }

            // touch enabled devices
            if('ontouchstart' in window) {
                return true;
            }

            return false;

        })(),

        READY: false,

        // methods
        isLandscape: function() {
            if (/Firefox/.test(navigator.userAgent) && /Mobile/.test(navigator.userAgent)) {
                return (window.screen.width > window.screen.height);
            }
            return window.orientation === 90 || window.orientation === -90;
        },

        ready: function(callback) {
            window.addEventListener('viewportready', callback, false);
        },
        
        change: function(callback) {
            window.addEventListener('viewportchange', callback, false);
        },

        refresh: function(){
            if (_viewporter){
                _viewporter.prepareVisualViewport();
            }
        }
    };

    // if we are on Desktop, no need to go further
    if (!viewporter.ACTIVE) {
        return;
    }

    // create private constructor with prototype..just looks cooler
    var _Viewporter = function() {

        var that = this;

        // Scroll away the header, but not in Chrome
        this.IS_ANDROID = /Android/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);

        var _onReady = function() {

            // scroll the shit away and fix the viewport!
            that.prepareVisualViewport();

            // listen for orientation change
            var cachedOrientation = window.orientation;
            window.addEventListener('orientationchange', function() {
                if(window.orientation !== cachedOrientation) {
                    that.prepareVisualViewport();
                    cachedOrientation = window.orientation;
                }
            }, false);

            
            // prevent page scroll if `preventPageScroll` option was set to `true`
            document.body.addEventListener('touchmove', function(event) {
                if (viewporter.preventPageScroll){
                    event.preventDefault();
                }
            }, false);
            
            // reset page scroll if `preventPageScroll` option was set to `true`
            // this is used after showing the address bar on iOS
            document.body.addEventListener("touchstart", function() {
                if (viewporter.preventPageScroll) {
                    that.prepareVisualViewport();
                }
            }, false);
            
        };


        // listen for document ready if not already loaded
        // then try to prepare the visual viewport and start firing custom events
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function() {
                _onReady();
            }, false);
        } else {
            _onReady();
        }


    };

    _Viewporter.prototype = {

        getProfile: function() {

            if(viewporter.forceDetection) {
                return null;
            }

            for(var searchTerm in viewporter.profiles) {
                if(new RegExp(searchTerm).test(navigator.userAgent)) {
                    return viewporter.profiles[searchTerm];
                }
            }
            return null;
        },

        postProcess: function() {

            // let everyone know we're finally ready
            viewporter.READY = true;

            this.triggerWindowEvent(!this._firstUpdateExecuted ? 'viewportready' : 'viewportchange');
            this._firstUpdateExecuted = true;

        },

        prepareVisualViewport: function() {

            var that = this;

            // if we're running in webapp mode (iOS), there's nothing to scroll away
            if(navigator.standalone) {
                return this.postProcess();
            }

            // maximize the document element's height to be able to scroll away the url bar
            document.documentElement.style.minHeight = '5000px';

            var startHeight = window.innerHeight;
            var deviceProfile = this.getProfile();
            var orientation = viewporter.isLandscape() ? 'landscape' : 'portrait';

            // try scrolling immediately
            window.scrollTo(0, that.IS_ANDROID ? 1 : 0); // Android needs to scroll by at least 1px

            // start the checker loop
            var iterations = 40;
            var check = window.setInterval(function() {

                // retry scrolling
                window.scrollTo(0, that.IS_ANDROID ? 1 : 0); // Android needs to scroll by at least 1px

                function androidProfileCheck() {
                    return deviceProfile ? window.innerHeight === deviceProfile[orientation] : false;
                }
                function iosInnerHeightCheck() {
                    return window.innerHeight > startHeight;
                }

                iterations--;

                // check iterations first to make sure we never get stuck
                if ( (that.IS_ANDROID ? androidProfileCheck() : iosInnerHeightCheck()) || iterations < 0) {

                    
                    document.getElementById('viewporter').style.position = 'relative';

                    // Special case for mobile firefox browser
                    if (/Firefox/.test(navigator.userAgent)) {
                        document.getElementById('viewporter').style.width = window.innerWidth + 'px';
                        document.getElementById('viewporter').style.height = (window.screen.height - 110) + 'px';

                    } else {
                        // set minimum height of content to new window height
                        document.documentElement.style.minHeight = window.innerHeight + 'px';

                        // set the right height for the body wrapper to allow bottom positioned elements
                        document.getElementById('viewporter').style.height = window.innerHeight + 'px';
                    }

                    clearInterval(check);

                    // fire events, get ready
                    that.postProcess();

                }

            }, 10);

        },

        triggerWindowEvent: function(name) {
            var event = document.createEvent("Event");
            event.initEvent(name, false, false);
            window.dispatchEvent(event);
        }

    };

    // initialize
    _viewporter = new _Viewporter();

})();

viewporter.profiles = {

    // Motorola Xoom
    'MZ601': {
        portrait: 696,
        landscape: 1176
    },

    // Samsung Galaxy S, S2 and Nexus S
    'GT-I9000|GT-I9100|Nexus S': {
        portrait: 508,
        landscape: 295
    },

    // Samsung Galaxy S, S2 and Nexus S
    'GT-I9000|GT-I9100|Nexus S': {
        portrait: 508,
        landscape: 295
    },

    // Samsung Galaxy Pad
    'GT-P1000': {
        portrait: 657,
        landscape: 400
    },

    // HTC Desire & HTC Desire HD
    'Desire_A8181|DesireHD_A9191': {
        portrait: 533,
        landscape: 320
    }

};