var __assign = this && this.__assign || function () {
  __assign = Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];

      for (var p in s) {
        if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
      }
    }

    return t;
  };

  return __assign.apply(this, arguments);
};

var __rest = this && this.__rest || function (s, e) {
  var t = {};

  for (var p in s) {
    if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  }

  if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
    if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  }
  return t;
};

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import classnames from 'classnames';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import "./style/canvas-color-picker.css";
import debounce from 'lodash/debounce';
import ReactDOM from 'react-dom';
export var CanvasColorPickerPosition;

(function (CanvasColorPickerPosition) {
  CanvasColorPickerPosition["topRight"] = "top-right";
  CanvasColorPickerPosition["topLeft"] = "top-left";
  CanvasColorPickerPosition["leftBottom"] = "left-bottom";
  CanvasColorPickerPosition["rightBottom"] = "right-bottom";
})(CanvasColorPickerPosition || (CanvasColorPickerPosition = {}));

var defaultProps = {
  visible: false,
  magnifierSquareLength: 200,
  magnifierScaleRatio: 100,
  magnifierLineColor: '#4A5472',
  magnifierSquareLineColor: '#fff',
  exitKeyCode: 'Escape',
  displayColorInfo: true,
  magnifierFollowMouse: false,
  debounceTime: 200,
  closeAfterPickColor: true,
  fixedPosition: CanvasColorPickerPosition.topRight,
  clickAwayTargetToClose: true
};
var prefixCls = 'dmc-canvas-color-picker';
var cursorCls = prefixCls + "-cursor";
var otherProps = {};

var CanvasColorPicker = function CanvasColorPicker(props) {
  var _a;

  var _b, _c;

  var _d = props,
      visible = _d.visible,
      toMeasureCanvas = _d.toMeasureCanvas,
      toGetColorCanvas = _d.toGetColorCanvas,
      magnifierSquareLength = _d.magnifierSquareLength,
      magnifierScaleRatio = _d.magnifierScaleRatio,
      handlePickColor = _d.handlePickColor,
      magnifierLineColor = _d.magnifierLineColor,
      magnifierSquareLineColor = _d.magnifierSquareLineColor,
      exitKeyCode = _d.exitKeyCode,
      displayColorInfo = _d.displayColorInfo,
      magnifierFollowMouse = _d.magnifierFollowMouse,
      debounceTime = _d.debounceTime,
      closeAfterPickColor = _d.closeAfterPickColor,
      handleVisibleChange = _d.handleVisibleChange,
      _onlyVisibleAfterMouseEnter = _d.onlyVisibleAfterMouseEnter,
      fixedPosition = _d.fixedPosition,
      useShadowElementToPickColor = _d.useShadowElementToPickColor,
      shadowElementContainer = _d.shadowElementContainer,
      clickAwayTargetToClose = _d.clickAwayTargetToClose,
      restProps = __rest(_d, ["visible", "toMeasureCanvas", "toGetColorCanvas", "magnifierSquareLength", "magnifierScaleRatio", "handlePickColor", "magnifierLineColor", "magnifierSquareLineColor", "exitKeyCode", "displayColorInfo", "magnifierFollowMouse", "debounceTime", "closeAfterPickColor", "handleVisibleChange", "onlyVisibleAfterMouseEnter", "fixedPosition", "useShadowElementToPickColor", "shadowElementContainer", "clickAwayTargetToClose"]); // 实际绑定鼠标事件元素


  var _e = useState(toMeasureCanvas),
      toMeasureEl = _e[0],
      setToMeasureEl = _e[1];

  var onlyVisibleAfterMouseEnter = magnifierFollowMouse ? true : _onlyVisibleAfterMouseEnter;

  var _f = useState(visible),
      _visible = _f[0],
      setVisible = _f[1];

  var magnifierRef = useRef(null);

  var _g = useState(0),
      clientX = _g[0],
      setClientX = _g[1];

  var _h = useState(0),
      clientY = _h[0],
      setClientY = _h[1]; // 计算后的光标距离 canvas 元素左边界和上边界的像素值


  var offsetLeftRef = useRef(0);
  var offsetTopRef = useRef(0);

  var _j = useState(''),
      curColor = _j[0],
      setCurColor = _j[1];

  var mouseAxisDataRef = useRef('');
  var mouseEnterCanvasRef = useRef(false);
  var prevVisibleRef = useRef(_visible);
  var otherWrapProps = useMemo(function () {
    if (magnifierFollowMouse) {
      return {
        style: {
          transform: "translate(" + clientX + "px, " + clientY + "px)"
        }
      };
    } else {
      return otherProps;
    }
  }, [clientX, clientY, magnifierFollowMouse]);
  var drawLine = useCallback(function (ctx, step, width, height) {
    if (width === void 0) {
      width = magnifierSquareLength;
    }

    if (height === void 0) {
      height = magnifierSquareLength;
    }

    if (ctx) {
      // draw magnifier line
      ctx.beginPath();
      ctx.strokeStyle = magnifierLineColor;
      ctx.lineWidth = 1;
      var initRatio = magnifierScaleRatio % 2 === 0 ? 0.5 : 1;

      for (var x = initRatio * step; x <= magnifierSquareLength; x += step) {
        ctx.moveTo(x, 0);
        ctx.lineTo(x, height);
      }

      for (var y = initRatio * step; y <= magnifierSquareLength; y += step) {
        ctx.moveTo(0, y);
        ctx.lineTo(width, y);
      }

      ctx.stroke(); // draw center highlight square

      ctx.beginPath();
      ctx.strokeStyle = magnifierSquareLineColor;
      var unitSquareCnt = magnifierSquareLength / step;
      var centerSquareStartX = (unitSquareCnt - 1) / 2 * step;
      var centerSquareStartY = (unitSquareCnt - 1) / 2 * step;
      ctx.moveTo(centerSquareStartX, centerSquareStartY);
      ctx.lineTo(centerSquareStartX + step, centerSquareStartY);
      ctx.lineTo(centerSquareStartX + step, centerSquareStartY + step);
      ctx.lineTo(centerSquareStartX, centerSquareStartY + step);
      ctx.lineTo(centerSquareStartX, centerSquareStartY);
      ctx.stroke();
      ctx.closePath();
    }
  }, [magnifierSquareLength, magnifierLineColor, magnifierScaleRatio, magnifierSquareLineColor]);
  var styleWidth = (_b = toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.style) === null || _b === void 0 ? void 0 : _b.width;
  var styleHeight = (_c = toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.style) === null || _c === void 0 ? void 0 : _c.height;
  var getColor = useCallback(function () {
    var _a;

    var canvasCtx = (_a = toGetColorCanvas || toMeasureCanvas) === null || _a === void 0 ? void 0 : _a.getContext('2d');

    if (canvasCtx) {
      var colors = Array.from(canvasCtx.getImageData(offsetLeftRef.current, offsetTopRef.current, 1, 1).data);
      setCurColor("rgba(" + colors[0] + "," + colors[1] + "," + colors[2] + "," + colors[3] / 255 + ")");
    }
  }, [toGetColorCanvas, toMeasureCanvas]);
  var debRef = useRef();
  var debounceFunc = useMemo(function () {
    debRef.current && debRef.current.cancel();
    var func = debounce(getColor, debounceTime);
    debRef.current = func;
    return func;
  }, [debounceTime, getColor]);
  var debouncedGetColor = useCallback(debounceFunc, [debounceFunc]); // canvas 元素距离根元素左边界和上边界的像素值

  var toMeasureCanvasOffsetData = useMemo(function () {
    if (toMeasureCanvas) {
      // maptalks canvas 存在行内样式 width height 且 可能与 canvas 宽高不一致
      var widthRatio = 1;
      var heightRatio = 1;
      var width = toMeasureCanvas.width,
          height = toMeasureCanvas.height;

      if (width && styleWidth) {
        widthRatio = width / Number.parseInt(styleWidth.replace('px', ''), 10);
      }

      if (height && styleHeight) {
        heightRatio = height / Number.parseInt(styleHeight.replace('px', ''), 10);
      }

      var offsetLeft = toMeasureCanvas.offsetLeft;
      var offsetTop = toMeasureCanvas.offsetTop;
      var offsetHeight = toMeasureCanvas.offsetHeight;
      var offsetWidth = toMeasureCanvas.offsetWidth;
      var parentEl = toMeasureCanvas.offsetParent;

      while (parentEl) {
        offsetLeft += parentEl.offsetLeft;
        offsetTop += parentEl.offsetTop;
        parentEl = parentEl.offsetParent;
      }

      return [offsetLeft, offsetTop, widthRatio, heightRatio, offsetWidth, offsetHeight];
    }

    return [0, 0, 1, 1]; // map canvas 宽高变更 需要重新计算以上值
  }, [toMeasureCanvas, styleWidth, styleHeight]);
  var handleMouseMove = useCallback(function (e) {
    if (visible) {
      // 初始化时光标已经在元素内部
      if (!(toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.classList.contains(cursorCls))) {
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.classList.add(cursorCls);
      }

      var getColorCanvas = toGetColorCanvas || toMeasureCanvas;
      var offsetLeft = toMeasureCanvasOffsetData[0],
          offsetTop = toMeasureCanvasOffsetData[1],
          widthRatio = toMeasureCanvasOffsetData[2],
          heightRatio = toMeasureCanvasOffsetData[3];
      var _a = [e.pageX - offsetLeft, e.pageY - offsetTop],
          _offsetLeft = _a[0],
          _offsetTop = _a[1];
      offsetLeftRef.current = _offsetLeft * widthRatio;
      offsetTopRef.current = _offsetTop * heightRatio;

      if (magnifierFollowMouse) {
        setClientX(e.clientX);
        setClientY(e.clientY);
      }

      if (magnifierRef.current && getColorCanvas) {
        var magnifierCtx = magnifierRef.current.getContext('2d');
        var canvasCtx = toMeasureCanvas === null || toMeasureCanvas === void 0 ? void 0 : toMeasureCanvas.getContext('2d');

        if (canvasCtx && toMeasureCanvas && magnifierCtx) {
          magnifierCtx.imageSmoothingEnabled = false;
          magnifierCtx.drawImage(getColorCanvas, (_offsetLeft - magnifierSquareLength / 2 / Math.sqrt(magnifierScaleRatio)) * widthRatio, (_offsetTop - magnifierSquareLength / 2 / Math.sqrt(magnifierScaleRatio)) * heightRatio, magnifierSquareLength / Math.sqrt(magnifierScaleRatio) * widthRatio, magnifierSquareLength / Math.sqrt(magnifierScaleRatio) * heightRatio, 0, 0, magnifierSquareLength, magnifierSquareLength);
          drawLine(magnifierCtx, Math.sqrt(magnifierScaleRatio)); // console.log(
          //   (_offsetLeft - magnifierSquareLength / 2 / Math.sqrt(magnifierScaleRatio)) *
          //     widthRatio,
          //   (_offsetTop - magnifierSquareLength / 2 / Math.sqrt(magnifierScaleRatio)) *
          //     heightRatio,
          // );

          if (displayColorInfo) {
            if (magnifierFollowMouse) {
              debouncedGetColor();
            } else {
              getColor();
            }
          }
        }
      }
    }
  }, [visible, toMeasureEl, toGetColorCanvas, toMeasureCanvas, toMeasureCanvasOffsetData, magnifierFollowMouse, magnifierSquareLength, magnifierScaleRatio, drawLine, displayColorInfo, debouncedGetColor, getColor]);
  var handleMouseEnter = useCallback(function (e) {
    e.preventDefault();
    e.stopImmediatePropagation();
    mouseEnterCanvasRef.current = true;

    if (visible && toMeasureEl) {
      if (onlyVisibleAfterMouseEnter) {
        setVisible(true);
      }

      toMeasureEl.classList.add(cursorCls);
    }
  }, [visible, toMeasureEl, onlyVisibleAfterMouseEnter]);
  var handleMouseLeave = useCallback(function (e) {
    e.preventDefault();
    e.stopImmediatePropagation();
    mouseEnterCanvasRef.current = false;

    if (toMeasureEl) {
      if (onlyVisibleAfterMouseEnter) {
        setVisible(false);
      }

      toMeasureEl.classList.remove(cursorCls);
    }
  }, [onlyVisibleAfterMouseEnter, toMeasureEl]);
  var handleKeyUp = useCallback(function (e) {
    e.preventDefault();
    e.stopImmediatePropagation();

    if (exitKeyCode && e.key === exitKeyCode) {
      setVisible(false);
    }
  }, [exitKeyCode]);
  var handleMouseDown = useCallback(function (e) {
    // 缓存点击坐标 防止拖拽地图时取色
    mouseAxisDataRef.current = e.pageX + "," + e.pageY;
  }, []);
  var handleMouseUp = useCallback(function (e) {
    e.preventDefault();
    e.stopImmediatePropagation();
    var curMouseAxisData = e.pageX + "," + e.pageY;

    if (toMeasureCanvas && mouseAxisDataRef.current === curMouseAxisData) {
      var ctx = (toGetColorCanvas || toMeasureCanvas).getContext('2d');

      if (ctx) {
        var color = Array.from(ctx.getImageData(offsetLeftRef.current, offsetTopRef.current, 1, 1).data);
        color[3] = color[3] / 255;
        handlePickColor === null || handlePickColor === void 0 ? void 0 : handlePickColor(color); // const [r, g, b, a] = color;
        // console.log('rgba:', r, g, b, a);

        if (closeAfterPickColor) {
          setVisible(false);
        }
      }
    }
  }, [closeAfterPickColor, handlePickColor, toGetColorCanvas, toMeasureCanvas]);
  var handleClick = useCallback(function (e) {
    e.preventDefault();
    e.stopImmediatePropagation();
    var target = e.target;

    if (toMeasureEl && !toMeasureEl.contains(target) && visible) {
      setVisible(false);
      handleVisibleChange === null || handleVisibleChange === void 0 ? void 0 : handleVisibleChange(false);
    }
  }, [handleVisibleChange, toMeasureEl, visible]);
  useEffect(function () {
    if (toMeasureEl) {
      toMeasureEl.addEventListener('mouseenter', handleMouseEnter);
      toMeasureEl.addEventListener('mouseleave', handleMouseLeave);
      toMeasureEl.addEventListener('mousemove', handleMouseMove);
      toMeasureEl.addEventListener('mousedown', handleMouseDown);
      toMeasureEl.addEventListener('mouseup', handleMouseUp);
    }

    return function () {
      if (toMeasureEl) {
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.removeEventListener('mouseenter', handleMouseEnter);
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.removeEventListener('mouseleave', handleMouseLeave);
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.removeEventListener('mousemove', handleMouseMove);
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.removeEventListener('mousedown', handleMouseDown);
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.removeEventListener('mouseup', handleMouseUp);
        toMeasureEl.classList.remove(cursorCls);
      }
    };
  }, [handleMouseDown, handleMouseEnter, handleMouseLeave, handleMouseMove, handleMouseUp, onlyVisibleAfterMouseEnter, toMeasureEl]);
  useEffect(function () {
    var _a; // 开启光标进入取色器可见后，外部状态不实时变更内部，而是在具体事件调用后赋值


    if (!onlyVisibleAfterMouseEnter) {
      setVisible(visible);
      var magnifierCtx = ((_a = magnifierRef.current) === null || _a === void 0 ? void 0 : _a.getContext('2d')) || null;
      drawLine(magnifierCtx, Math.sqrt(magnifierScaleRatio));
    }
  }, [drawLine, magnifierScaleRatio, onlyVisibleAfterMouseEnter, visible]);
  useEffect(function () {
    if (prevVisibleRef.current !== _visible) {
      prevVisibleRef.current = _visible; // 开启光标进入取色器可见后，光标移出状态不反馈到外部

      if (!(!mouseEnterCanvasRef.current && onlyVisibleAfterMouseEnter && !_visible)) {
        handleVisibleChange === null || handleVisibleChange === void 0 ? void 0 : handleVisibleChange(_visible);
      }

      if (!_visible) {
        toMeasureEl === null || toMeasureEl === void 0 ? void 0 : toMeasureEl.classList.remove(cursorCls);
      }
    }
  }, [handleVisibleChange, _visible, toMeasureEl, onlyVisibleAfterMouseEnter]);
  useEffect(function () {
    if (exitKeyCode) {
      document.addEventListener('keyup', handleKeyUp);
    }

    return function () {
      document.removeEventListener('keyup', handleKeyUp);
    };
  }, [exitKeyCode, handleKeyUp]);
  useEffect(function () {
    if (toMeasureCanvas && !useShadowElementToPickColor) {
      setToMeasureEl(toMeasureCanvas);
    }
  }, [toMeasureCanvas, useShadowElementToPickColor]); // click outside

  useEffect(function () {
    if (clickAwayTargetToClose) {
      document.addEventListener('click', handleClick);
    }

    return function () {
      document.removeEventListener('click', handleClick);
    };
  }, [clickAwayTargetToClose, handleClick]);
  return _jsx("div", __assign({}, restProps, {
    className: classnames(prefixCls, (_a = {}, _a[prefixCls + "-visible"] = _visible && toMeasureEl, _a[prefixCls + "-" + fixedPosition] = fixedPosition && !magnifierFollowMouse, _a))
  }, otherWrapProps, {
    children: _jsxs("div", __assign({
      className: prefixCls + "-wrapper"
    }, {
      children: [_jsx("canvas", __assign({
        ref: magnifierRef,
        width: magnifierSquareLength,
        height: magnifierSquareLength,
        className: prefixCls + "-magnifier"
      }, {
        children: "Your browser do not support canvas"
      }), void 0), displayColorInfo && curColor && _jsx("div", __assign({
        className: prefixCls + "-color-hint"
      }, {
        children: curColor.toUpperCase()
      }), void 0), useShadowElementToPickColor && /*#__PURE__*/ReactDOM.createPortal(_jsx("div", {
        ref: function ref(node) {
          if (node) {
            setToMeasureEl(node);
          }
        },
        style: {
          zIndex: 9999,
          display: visible ? 'block' : 'none',
          position: 'absolute',
          left: toMeasureCanvasOffsetData[0] + "px",
          top: toMeasureCanvasOffsetData[1] + "px",
          width: toMeasureCanvasOffsetData[4] + "px",
          height: toMeasureCanvasOffsetData[5] + "px"
        }
      }, void 0), shadowElementContainer || document.body)]
    }), void 0)
  }), void 0);
};

CanvasColorPicker.displayName = 'CanvasColorPicker';
CanvasColorPicker.defaultProps = defaultProps;
export default CanvasColorPicker;

