/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 *Module TapEventPlugin
 */

/**
 * onTouchTap事件可选.想用,可以
 * var EventPluginHub = require('qreact/lib/EventPluginHub');
 * var TapEventPlugin = require('qreact/lib/TapEventPlugin')
 * EventPluginHub.injectEventPluginsByName({
 *    TapEventPlugin: TapEventPlugin
 * })
 *
 */


'use strict';

var EventPluginUtils = require('./EventPluginUtils');
var EventPropagators = require('./EventPropagators');
var SyntheticUIEvent = require('./SyntheticUIEvent');
var TouchEventUtils = require('fbjs/lib/TouchEventUtils');
// var ViewportMetrics = require('./ViewportMetrics');


var isStartish = EventPluginUtils.isStartish;
var isEndish = EventPluginUtils.isEndish;

/**
 * Number of pixels that are tolerated in between a `touchStart` and `touchEnd`
 * in order to still be considered a 'tap' event.
 */
var tapMoveThreshold = 10;
var startCoords = { x: null, y: null };

var Axis = {
    x: { page: 'pageX', client: 'clientX', envScroll: 'currentPageScrollLeft' },
    y: { page: 'pageY', client: 'clientY', envScroll: 'currentPageScrollTop' }
};

function getAxisCoordOfEvent(axis, nativeEvent) {
    var singleTouch = TouchEventUtils.extractSingleTouch(nativeEvent);
    if (singleTouch) {
        return singleTouch[axis.page];
    }
    return  nativeEvent[axis.page] 
}

function getDistance(coords, nativeEvent) {
    var pageX = getAxisCoordOfEvent(Axis.x, nativeEvent);
    var pageY = getAxisCoordOfEvent(Axis.y, nativeEvent);
    return Math.pow(Math.pow(pageX - coords.x, 2) + Math.pow(pageY - coords.y, 2), 0.5);
}

var touchEvents = ['topTouchStart', 'topTouchCancel', 'topTouchEnd', 'topTouchMove'];

var dependencies = ['topMouseDown', 'topMouseMove', 'topMouseUp'].concat(touchEvents);

var eventTypes = {
    touchTap: {
        phasedRegistrationNames: {
            bubbled: 'onTouchTap',
            captured: 'onTouchTapCapture'
        },
        dependencies: dependencies
    }
};

var usedTouch = false;
var usedTouchTime = 0;
var TOUCH_DELAY = 1000;

var TapEventPlugin = {

    tapMoveThreshold: tapMoveThreshold,

    eventTypes: eventTypes,

    extractEvents: function(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
        if (!isStartish(topLevelType) && !isEndish(topLevelType)) {
            return null;
        }
        // on ios, there is a delay after touch event and synthetic
        // mouse events, so that user can perform double tap
        // solution: ignore mouse events following touchevent within small timeframe
        if (touchEvents.indexOf(topLevelType) !== -1) {
            usedTouch = true;
            usedTouchTime = Date.now();
        } else {
            if (usedTouch && Date.now() - usedTouchTime < TOUCH_DELAY) {
                return null;
            }
        }
        var event = null;
        var distance = getDistance(startCoords, nativeEvent);
        if (isEndish(topLevelType) && distance < tapMoveThreshold) {
            event = SyntheticUIEvent.getPooled(eventTypes.touchTap, targetInst, nativeEvent, nativeEventTarget);
        }
        if (isStartish(topLevelType)) {
            startCoords.x = getAxisCoordOfEvent(Axis.x, nativeEvent);
            startCoords.y = getAxisCoordOfEvent(Axis.y, nativeEvent);
        } else if (isEndish(topLevelType)) {
            startCoords.x = 0;
            startCoords.y = 0;
        }
        EventPropagators.accumulateTwoPhaseDispatches(event);
        return event;
    }

};

module.exports = require('qreact').TapEventPlugin = TapEventPlugin;

