/* touch.js
 * A play area for OL on iphone
 */

/*
derived from: http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/

A generic handler intercepts and remaps touchevents as mouseevents
*/

function touchHandler(event)
{

    var touches = event.changedTouches,
        first = touches[0],
        type = "";

    if (event.changedTouches.length > 1){
        return null;
    };

    switch(event.type){
        case "touchstart":
            type = "mousedown";
            //event.preventDefault();
            break;

        case "touchmove":
            type="mousemove";
            event.preventDefault();
            break;

        case "touchend":
            type="mouseup";
            break;

        default:
            return;
        }

    var simulatedEvent = document.createEvent("MouseEvent");

    //initMouseEvent(type, canBubble, cancelable, view, clickCount, screenX, screenY, clientX, clientY,
    //               ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);

    simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
                                  false, false, false, false, 0/*left*/, null);

    first.target.dispatchEvent(simulatedEvent);
}

function hook_touch_to_mouse(node, decorate)
{
    if(decorate != null){
        touchHandler = decorate(touchHandler);
    };

    node.addEventListener("touchstart", touchHandler, false);
    node.addEventListener("touchmove", touchHandler, false);
    node.addEventListener("touchend", touchHandler, false);
    node.addEventListener("touchcancel", touchHandler, false);
};

var hook_touch = hook_touch_to_mouse;

function hook_touch_for(nodes, decorate){
    if (decorate == null){
        var decorate = function (func){return func};
    }

    for(i=0;i<nodes.length;i=i+1){
        hook_touch(nodes[i], decorate);
    }
}

/*
 * a class based approach to basic OL touch event, based on
 * whatamap.com's event examples
 */

TouchHandler = OpenLayers.Class({
    touchStartX: null,
    touchStartY: null,
    scale: 1,

    initialize: function(map, skiphook) {
        this.map = map;
        // monkey-p map to include limitZoomOut
        map.constructor.prototype['limitZoomOut'] = function()
        {
            if ( this.getZoom() <= 2 ) {
                return true;
            }
            return false;
        };
        if(skiphook == null){
            this.hook_touch(map);
        }
    },

    touchstart: function(){
        var inDoubleTap = false;
        var doubleTapTimer = false;
        var zoom = null;

        var obj = this;
        return function (event) {
            event.preventDefault();
            if(event.touches.length == 1) {
                if(!doubleTapTimer){
                    doubleTapTimer = setTimeout(function(){ inDoubleTap = false;
                                                            doubleTapTimer = false; },
                                                500);
                }

                if(!inDoubleTap) {
                    inDoubleTap = true;
                }else{
                    inDoubleTap = false;
                    var out = "out";
                    if (zoom == null || zoom == out){
                        obj.map.zoomIn();
                        zoom = "in";
                    } else {
                        obj.map.zoomOut();
                        zoom = out;
                    }
                }

                var touch = event.touches[0];
                obj.touchStartX = touch.clientX;
                obj.touchStartY = touch.clientY;

                if (touch.target.width === 128) {
                    return false;
                } else {
                    return true;
                }
            };
            return null;
        };
    },

    pan_touch: function (){
        var obj = this;
        return function (e) {
            e.preventDefault();
            if(e.touches.length == 1) {
	        var touch = e.touches[0];
	        obj.map.pan(obj.touchStartX - touch.clientX, obj.touchStartY - touch.clientY);
            }
        };
    },

    zoom_guesture: function(){
        var obj = this;
        return function (e) {
            e.preventDefault();

            if (e.scale > 1 && e.scale != obj.scale) {
	        //	if (this.map.limitZoomIn() == false) {
	        obj.map.zoomIn();
	        //	}
            } else {
	        if (e.scale < 1 && e.scale != obj.scale) {
	            if (obj.map.limitZoomOut() == false) {
		        obj.map.zoomOut();
	            }
	        }
            }
            obj.scale = e.scale;
        };
    },

    hook_touch: function (){
        var map = this.map;
        map.div.addEventListener("touchstart", this.touchstart(), false);
        map.div.addEventListener("touchmove", this.pan_touch(map), false);

        // guestures are currently like unicorns to me... never seen on in the wild
        // but touchevents have scale and rotation
        map.div.addEventListener("touchend", this.zoom_guesture(map), false);
        map.div.addEventListener("guestureend", this.zoom_guesture(map), false);
    }
});

// debugging

function repmsg (id, msg){
        node = document.getElementById(id);
        node.innerHTML = msg;
};

function dec_debug(func){
    return function(event){
        repmsg('debug', event.type + ' ' + xystr(event));
        return func(event);
    };
}

function xystr(event){
    var coords = " ";
    for(i=0;i<event.touches.length;i=i+1){
        coords = coords + " x:" + event.touches[i].pageX + " y:" + event.touches[i].pageY;
    };
    coords = coords + " s:" + event.scale + " r:" + event.rotation;
    return coords;
};





