import { addEventListener, removeEventListener, normalizeEvent } from '../core/event';
import * as zrUtil from '../core/util';
import Eventful from '../mixin/Eventful';
import env from '../core/env';
var TOUCH_CLICK_DELAY = 300;
var mouseHandlerNames = ['click', 'dblclick', 'mousewheel', 'mouseout', 'mouseup', 'mousedown', 'mousemove', 'contextmenu'];
var touchHandlerNames = ['touchstart', 'touchend', 'touchmove'];
var pointerEventNames = {
  pointerdown: 1,
  pointerup: 1,
  pointermove: 1,
  pointerout: 1
};
var pointerHandlerNames = zrUtil.map(mouseHandlerNames, function (name) {
  var nm = name.replace('mouse', 'pointer');
  return pointerEventNames[nm] ? nm : name;
});

function eventNameFix(name) {
  return name === 'mousewheel' && env.browser.firefox ? 'DOMMouseScroll' : name;
} // function onMSGestureChange(proxy, event) {
//     if (event.translationX || event.translationY) {
//         // mousemove is carried by MSGesture to reduce the sensitivity.
//         proxy.handler.dispatchToElement(event.target, 'mousemove', event);
//     }
//     if (event.scale !== 1) {
//         event.pinchX = event.offsetX;
//         event.pinchY = event.offsetY;
//         event.pinchScale = event.scale;
//         proxy.handler.dispatchToElement(event.target, 'pinch', event);
//     }
// }

/**
 * Prevent mouse event from being dispatched after Touch Events action
 * @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
 * 1. Mobile browsers dispatch mouse events 300ms after touchend.
 * 2. Chrome for Android dispatch mousedown for long-touch about 650ms
 * Result: Blocking Mouse Events for 700ms.
 */


function setTouchTimer(instance) {
  instance._touching = true;
  clearTimeout(instance._touchTimer);
  instance._touchTimer = setTimeout(function () {
    instance._touching = false;
  }, 700);
}

var domHandlers = {
  /**
   * Mouse move handler
   * @inner
   * @param {Event} event
   */
  mousemove: function (event) {
    event = normalizeEvent(this.dom, event);
    this.trigger('mousemove', event);
  },

  /**
   * Mouse out handler
   * @inner
   * @param {Event} event
   */
  mouseout: function (event) {
    event = normalizeEvent(this.dom, event);
    var element = event.toElement || event.relatedTarget;

    if (element !== this.dom) {
      while (element && element.nodeType !== 9) {
        // 忽略包含在root中的dom引起的mouseOut
        if (element === this.dom) {
          return;
        }

        element = element.parentNode;
      }
    }

    this.trigger('mouseout', event);
  },

  /**
   * Touch开始响应函数
   * @inner
   * @param {Event} event
   */
  touchstart: function (event) {
    // Default mouse behaviour should not be disabled here.
    // For example, page may needs to be slided.
    event = normalizeEvent(this.dom, event); // Mark touch, which is useful in distinguish touch and
    // mouse event in upper applicatoin.

    event.zrByTouch = true;
    this._lastTouchMoment = new Date();
    this.handler.processGesture(event, 'start'); // In touch device, trigger `mousemove`(`mouseover`) should
    // be triggered, and must before `mousedown` triggered.

    domHandlers.mousemove.call(this, event);
    domHandlers.mousedown.call(this, event);
    setTouchTimer(this);
  },

  /**
   * Touch移动响应函数
   * @inner
   * @param {Event} event
   */
  touchmove: function (event) {
    event = normalizeEvent(this.dom, event); // Mark touch, which is useful in distinguish touch and
    // mouse event in upper applicatoin.

    event.zrByTouch = true;
    this.handler.processGesture(event, 'change'); // Mouse move should always be triggered no matter whether
    // there is gestrue event, because mouse move and pinch may
    // be used at the same time.

    domHandlers.mousemove.call(this, event);
    setTouchTimer(this);
  },

  /**
   * Touch结束响应函数
   * @inner
   * @param {Event} event
   */
  touchend: function (event) {
    event = normalizeEvent(this.dom, event); // Mark touch, which is useful in distinguish touch and
    // mouse event in upper applicatoin.

    event.zrByTouch = true;
    this.handler.processGesture(event, 'end');
    domHandlers.mouseup.call(this, event); // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
    // triggered in `touchstart`. This seems to be illogical, but by this mechanism,
    // we can conveniently implement "hover style" in both PC and touch device just
    // by listening to `mouseover` to add "hover style" and listening to `mouseout`
    // to remove "hover style" on an element, without any additional code for
    // compatibility. (`mouseout` will not be triggered in `touchend`, so "hover
    // style" will remain for user view)
    // click event should always be triggered no matter whether
    // there is gestrue event. System click can not be prevented.

    if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
      domHandlers.click.call(this, event);
    }

    setTouchTimer(this);
  },
  pointerdown: function (event) {
    domHandlers.mousedown.call(this, event); // if (useMSGuesture(this, event)) {
    //     this._msGesture.addPointer(event.pointerId);
    // }
  },
  pointermove: function (event) {
    // FIXME
    // pointermove is so sensitive that it always triggered when
    // tap(click) on touch screen, which affect some judgement in
    // upper application. So, we dont support mousemove on MS touch
    // device yet.
    if (!isPointerFromTouch(event)) {
      domHandlers.mousemove.call(this, event);
    }
  },
  pointerup: function (event) {
    domHandlers.mouseup.call(this, event);
  },
  pointerout: function (event) {
    // pointerout will be triggered when tap on touch screen
    // (IE11+/Edge on MS Surface) after click event triggered,
    // which is inconsistent with the mousout behavior we defined
    // in touchend. So we unify them.
    // (check domHandlers.touchend for detailed explanation)
    if (!isPointerFromTouch(event)) {
      domHandlers.mouseout.call(this, event);
    }
  }
};

function isPointerFromTouch(event) {
  var pointerType = event.pointerType;
  return pointerType === 'pen' || pointerType === 'touch';
} // function useMSGuesture(handlerProxy, event) {
//     return isPointerFromTouch(event) && !!handlerProxy._msGesture;
// }
// Common handlers


zrUtil.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
  domHandlers[name] = function (event) {
    event = normalizeEvent(this.dom, event);
    this.trigger(name, event);
  };
});
/**
 * 为控制类实例初始化dom 事件处理函数
 *
 * @inner
 * @param {module:zrender/Handler} instance 控制类实例
 */

function initDomHandler(instance) {
  zrUtil.each(touchHandlerNames, function (name) {
    instance._handlers[name] = zrUtil.bind(domHandlers[name], instance);
  });
  zrUtil.each(pointerHandlerNames, function (name) {
    instance._handlers[name] = zrUtil.bind(domHandlers[name], instance);
  });
  zrUtil.each(mouseHandlerNames, function (name) {
    instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);
  });

  function makeMouseHandler(fn, instance) {
    return function () {
      if (instance._touching) {
        return;
      }

      return fn.apply(instance, arguments);
    };
  }
}

function HandlerDomProxy(dom) {
  Eventful.call(this);
  this.dom = dom;
  /**
   * @private
   * @type {boolean}
   */

  this._touching = false;
  /**
   * @private
   * @type {number}
   */

  this._touchTimer;
  this._handlers = {};
  initDomHandler(this);

  if (env.pointerEventsSupported) {
    // Only IE11+/Edge
    // 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240),
    // IE11+/Edge do not trigger touch event, but trigger pointer event and mouse event
    // at the same time.
    // 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on
    // screen, which do not occurs in pointer event.
    // So we use pointer event to both detect touch gesture and mouse behavior.
    mountHandlers(pointerHandlerNames, this); // FIXME
    // Note: MS Gesture require CSS touch-action set. But touch-action is not reliable,
    // which does not prevent defuault behavior occasionally (which may cause view port
    // zoomed in but use can not zoom it back). And event.preventDefault() does not work.
    // So we have to not to use MSGesture and not to support touchmove and pinch on MS
    // touch screen. And we only support click behavior on MS touch screen now.
    // MS Gesture Event is only supported on IE11+/Edge and on Windows 8+.
    // We dont support touch on IE on win7.
    // See <https://msdn.microsoft.com/en-us/library/dn433243(v=vs.85).aspx>
    // if (typeof MSGesture === 'function') {
    //     (this._msGesture = new MSGesture()).target = dom; // jshint ignore:line
    //     dom.addEventListener('MSGestureChange', onMSGestureChange);
    // }
  } else {
    if (env.touchEventsSupported) {
      mountHandlers(touchHandlerNames, this); // Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
      // addEventListener(root, 'mouseout', this._mouseoutHandler);
    } // 1. Considering some devices that both enable touch and mouse event (like on MS Surface
    // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
    // mouse event can not be handle in those devices.
    // 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent
    // mouseevent after touch event triggered, see `setTouchTimer`.


    mountHandlers(mouseHandlerNames, this);
  }

  function mountHandlers(handlerNames, instance) {
    zrUtil.each(handlerNames, function (name) {
      addEventListener(dom, eventNameFix(name), instance._handlers[name]);
    }, instance);
  }
}

var handlerDomProxyProto = HandlerDomProxy.prototype;

handlerDomProxyProto.dispose = function () {
  var handlerNames = mouseHandlerNames.concat(touchHandlerNames);

  for (var i = 0; i < handlerNames.length; i++) {
    var name = handlerNames[i];
    removeEventListener(this.dom, eventNameFix(name), this._handlers[name]);
  }
};

handlerDomProxyProto.setCursor = function (cursorStyle) {
  this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
};

zrUtil.mixin(HandlerDomProxy, Eventful);
export default HandlerDomProxy;