/*
 * iphone/ipad utilities
 *
 */
var iPhoneUtil = {

    // private variables
    _isIPad: undefined,
    _isIPhone: undefined,
    _isIPod: undefined,
    _isIMobileDevice: undefined,

    /**
     * check if the device is iPad
     *
     */
    isIPad: function() {
        if (this._isIPad === undefined) this._isIPad = (navigator.userAgent.indexOf('iPad') != -1);
        return this._isIPad;
    },


    /**
     * check if the device is iPhone
     *
     */
    isIPhone: function() {
        if (this._isIPhone === undefined) this._isIPhone = (navigator.userAgent.indexOf('iPhone') != -1);
        return this._isIPhone;
    },


    /**
     * check if the device is iPod
     *
     */
    isIPod: function() {
        if (this._isIPod === undefined) this._isIPod = (navigator.userAgent.indexOf('iPod') != -1);
        return this._isIPod;
    },

    /**
     * checks if a device is an apple mobile device
     *
     */
    isIMobileDevice: function() {
        if (this._isIMobileDevice === undefined) this._isIMobileDevice = this.isIPhone() || this.isIPad() || this.isIPod();
        return this._isIMobileDevice;
    },

    /**
     * check if the application is running in a standalone mode
     *
     */
    isStandalone: function() {
        return window.navigator.standalone;
    },


    /**
     * updates an orientation of the device
     *
     */
    updateOrientation: function() {
        document.body.className = (window.orientation == 0 || window.orientation == 180) ? "portrait" : "landscape";
    },


    /**
     * initializes the device orientation tracking
     *
     */
    initOrientationTracking: function() {
        this.updateOrientation();
        var t = this;
        window.onorientationchange = function() {
            t.updateOrientation();
            t.hideURLBar();
        };
    },


    /**
     * hides the URL and Debug bar of the browser window
     *
     */
    hideURLBar: function() {
        setTimeout(function() {
            scrollTo(0, 0);
        }, 0);
    },


    /**
     * slides the top URL and Debug bars away from the screen on start
     *
     */
    hideURLBarOnLoad: function() {
        $(window).load($.proxy(function() {
            this.hideURLBar;
        }, this));
    },


    /**
     * handles the links click in the standalone mode
     *
     */
    fullscreenLinksClickHandler: function(e) {
        /* ignore elements with a target value specified since "target" cannot be handled in full-screen mode those links shall open regularly in Mobile Safari */
        if (!!$(this).attr('target')) return;

        var url = $(this).attr('href');

        /* ignore links other than HTTP(S) and to different origin */
        var match = url.match(/^https?:\/\/(.+?)\/.*$/);
        if (!match || match[1] != window.location.host) return;

        /* finally open the link in full-screen view and prevent default behavior */
        window.location.href = url;
        e.preventDefault();
    },

    /**
     * preliminary initialization of the application before the document load
     *
     */
    appPreLoadInitialization: function() {
        if (!this.isIMobileDevice()) return;
        this.hideURLBarOnLoad();
    },


    /**
     * on document ready initialization of the application
     *
     */
    appPostLoadInitialization: function() {
        if (!this.isIMobileDevice()) return;
        this.initOrientationTracking();
        if (this.isStandalone()) {
            $('#').addClass('fullscreen');
            $('a').click(this.fullscreenLinksClickHandler);
        }
    }
};


/*******************************************************
 * FingerSwipe class
 * implements the finger swipe emulation on touch devices
 * 
 *******************************************************/
function FingerSwipe(client, parameters) {
    this.downX = null;
    this.upX = null;
    this.downY = null;
    this.upY = null;
    this.client = client;
    this.parameters = parameters || {};

    if (iPhoneUtil.isIMobileDevice()) {
        $(client)
            .bind('touchstart', $.proxy(this.onTouchStart, this))
            .bind('touchmove', $.proxy(this.onTouchMove, this))
            .bind('touchend', $.proxy(this.handleSwipe, this))
        ;
    }
    
    // emulate the swipe with mouse moves?
    if ((this.parameters.emulateMouse === undefined) || this.parameters.emulateMouse) {
        $(client)
            .mousedown($.proxy(this.onMouseDown, this))
            .mouseup($.proxy(this.onMouseUp, this))
        ;
    }

    return this;
}

FingerSwipe.prototype = {
    'onMouseDown': function(event) {
        event.preventDefault();
        this.downX = event.pageX;
        this.downY = event.pageY;
    },
    'onMouseUp': function(event) {
        this.upX = event.pageX;
        this.upY = event.pageY;
        this.handleSwipe(event);
    },
    'onTouchStart': function(event) {
        var touch = event.originalEvent.touches[0];
        this.upX = this.downX = touch.pageX;
        this.upY = this.downY = touch.pageY;
        this.parameters.onStart && this.parameters.onStart(this.upX, this.upY); 
    },
    'onTouchMove': function(event) {
        event.preventDefault();
        var touch = event.originalEvent.touches[0];
        this.upX = touch.pageX;
        this.upY = touch.pageY;
        this.parameters.onMove && this.parameters.onMove(this.downX - this.upX, this.downY - this.upY); 
    },
    'handleSwipe': function(event) {
        var xDiff = this.downX - this.upX;
        if (xDiff > 50) {
            event.preventDefault();
            this.parameters.onSwipeLeft && this.parameters.onSwipeLeft(-xDiff); 
        } else if (xDiff < -50) {
            event.preventDefault();
            this.parameters.onSwipeRight && this.parameters.onSwipeRight(xDiff); 
        }
    }
};
