(function() {
  var useState = React.useState;
  var useEffect = React.useEffect;
  var useRef = React.useRef;
  var useCallback = React.useCallback;

  var Spring = window.CityPhysics && window.CityPhysics.Spring;

  function useSpringPress(opts) {
    opts = opts || {};
    var hoverScale = opts.hoverScale != null ? opts.hoverScale : 1.01;
    var pressScale = opts.pressScale != null ? opts.pressScale : 0.98;

    var _hover = useState(false);
    var hovered = _hover[0], setHovered = _hover[1];
    var _pressed = useState(false);
    var pressed = _pressed[0], setPressed = _pressed[1];
    var ref = useRef(null);
    var scaleSpring = useRef(null);

    useEffect(function() {
      if (!Spring) return;
      scaleSpring.current = new Spring({ stiffness: 220, damping: 20, mass: 0.8, initial: 1 });
      var unsub = scaleSpring.current.onChange(function(v) {
        if (ref.current) ref.current.style.transform = 'translateZ(0) scale(' + v + ')';
      });
      return unsub;
    }, []);

    useEffect(function() {
      if (!scaleSpring.current) return;
      if (pressed) scaleSpring.current.setTarget(pressScale);
      else if (hovered) scaleSpring.current.setTarget(hoverScale);
      else scaleSpring.current.setTarget(1);
    }, [hovered, pressed, hoverScale, pressScale]);

    var onMouseEnter = useCallback(function(e) {
      setHovered(true);
      if (opts.onMouseEnter) opts.onMouseEnter(e);
    }, [opts.onMouseEnter]);

    var onMouseLeave = useCallback(function(e) {
      setHovered(false);
      setPressed(false);
      if (opts.onMouseLeave) opts.onMouseLeave(e);
    }, [opts.onMouseLeave]);

    var onMouseDown = useCallback(function(e) {
      setPressed(true);
      if (opts.onMouseDown) opts.onMouseDown(e);
    }, [opts.onMouseDown]);

    var onMouseUp = useCallback(function(e) {
      setPressed(false);
      if (opts.onMouseUp) opts.onMouseUp(e);
    }, [opts.onMouseUp]);

    var bind = {
      ref: ref,
      onMouseEnter: onMouseEnter,
      onMouseLeave: onMouseLeave,
      onMouseDown: onMouseDown,
      onMouseUp: onMouseUp,
      onTouchStart: onMouseDown,
      onTouchEnd: onMouseUp,
      className: (opts.className || '') + (pressed ? ' glass-pressed' : hovered ? ' glass-hovered' : '')
    };

    return { ref: ref, bind: bind, hovered: hovered, pressed: pressed };
  }

  window.useSpringPress = useSpringPress;
})();
