"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _preact = require("preact");

var _button = require("./button");

const height = 300;

class SignatureInput extends _preact.Component {
  constructor(props) {
    super(props);
    this.mouseMove = this.mouseMove.bind(this);
    this.mouseEnd = this.mouseEnd.bind(this);
    this.mouseDown = this.mouseDown.bind(this);
    this.mouseUp = this.mouseUp.bind(this);
    this.mouseLeave = this.mouseLeave.bind(this);
    this.touchStart = this.touchStart.bind(this);
    this.touchMove = this.touchMove.bind(this);
    this.touchEnd = this.touchEnd.bind(this);
    this.calculateCanvasInfo = this.calculateCanvasInfo.bind(this);
    this.renderCanvas = this.renderCanvas.bind(this);
  }

  reset() {
    this.path = '';
    this.break = true;
  }

  componentDidMount() {
    this.reset();
    this.canvas = this.base.querySelector('canvas');
    this.ctx = this.canvas.getContext('2d');
    window.addEventListener('resize', this.calculateCanvasInfo, {
      passive: true
    });
    window.addEventListener('scroll', this.calculateCanvasInfo, {
      passive: true
    });
    document.addEventListener('mouseup', this.mouseUp);
    document.addEventListener('touchmove', this.touchMove);
    document.addEventListener('touchend', this.touchEnd);
    document.addEventListener('touchcancel', this.touchEnd);
    this.canvas.addEventListener('touchstart', this.touchStart);
    this.calculateCanvasInfo();
    this.renderCanvas();
  }

  calculateCanvasInfo() {
    const {
      top,
      left,
      width,
      height
    } = this.canvas.getBoundingClientRect();
    this.canvasInfo = {
      left,
      top,
      height,
      width
    };
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.calculateCanvasInfo, {
      passive: true
    });
    window.removeEventListener('scroll', this.calculateCanvasInfo, {
      passive: true
    });
    document.removeEventListener('mouseup', this.mouseUp);
    document.removeEventListener('touchmove', this.touchMove);
    document.removeEventListener('touchend', this.touchEnd);
    document.removeEventListener('touchcancel', this.touchEnd);
    this.canvas && this.canvas.removeEventListener('touchstart', this.touchStart);
  }

  adjustCoord(clientX, clientY) {
    const {
      left,
      top,
      height,
      width
    } = this.canvasInfo;
    const x = clientX - left;
    const y = clientY - top;

    if (x < 0 || x > width) {
      return null;
    }

    if (y < 0 || y > height) {
      return null;
    }

    return {
      x,
      y
    };
  }

  appendCoord(x, y) {
    this.path += " ".concat(x, ",").concat(y);
    requestAnimationFrame(this.renderCanvas);
  }

  mouseDown(e) {
    e.preventDefault();
    e.stopImmediatePropagation();
  }

  mouseLeave(e) {
    if (e.buttons === 1) {
      this.appendCoord(e.layerX, e.layerY);
      this.break = true;
    }
  }

  mouseUp() {
    this.break = true;
  }

  mouseEnd(e) {
    e.preventDefault();
    e.stopImmediatePropagation();
    this.break = true;
  }

  mouseMove(e) {
    e.preventDefault();
    e.stopImmediatePropagation();

    if (e.buttons === 1) {
      if (this.break) {
        this.break = false;
        this.path += ' M';
      }

      const adjusted = this.adjustCoord(e.clientX, e.clientY);

      if (adjusted) {
        this.appendCoord(adjusted.x, adjusted.y);
      } else {
        this.break = true;
      }
    }
  }

  touchStart(e) {
    this.drawing = true;
    this.path += ' M'; // this prevents to "M"s next to each other if
    // there's a touch start without a touch move

    this.touchMove(e);
    e.preventDefault();
  }

  touchMove(e) {
    if (this.drawing) {
      const touch = e.touches[0];
      const isStylus = touch.touchType === 'stylus';
      const adjusted = this.adjustCoord(touch.clientX + (isStylus ? 0 : -20), touch.clientY + (isStylus ? 0 : -10));

      if (adjusted) {
        this.appendCoord(adjusted.x, adjusted.y);
      } else {
        this.break = true;
      }
    }
  }

  touchEnd() {
    this.break = true;
  }

  renderCanvas() {
    const {
      ctx
    } = this;
    const {
      width,
      height
    } = this.canvas;
    ctx.clearRect(0, 0, width, height);
    const marginFromEdge = width * 0.1;
    const marginFromBottom = 80; // signature line

    ctx.beginPath();
    ctx.moveTo(marginFromEdge, height - marginFromBottom);
    ctx.lineTo(width - marginFromEdge, height - marginFromBottom);
    ctx.strokeStyle = '#ddd';
    ctx.lineWidth = 2;
    ctx.stroke();
    ctx.strokeStyle = '#000';
    ctx.lineWidth = 1;
    ctx.fillStyle = '#000';

    if (this.path) {
      ctx.stroke(new Path2D(this.path));
    }

    if (this.props.name) {
      ctx.font = '18px sans-serif';
      ctx.fillText(this.props.name, marginFromEdge, height - (marginFromBottom - 25));
    }
  }

  shouldComponentUpdate() {
    return false;
  }

  render({
    updateValue,
    close
  }) {
    return (0, _preact.h)("div", {
      className: "top-0 left-0 fixed bg-gray w-100 h-100 z-9999 flex items-center justify-center"
    }, (0, _preact.h)("div", {
      "data-e2e": "signatureBox"
    }, (0, _preact.h)("canvas", {
      "data-e2e": "signaturePad",
      className: "bg-white ba",
      width: Math.min(window.innerWidth - 10, 660),
      height: height,
      onMouseMove: this.mouseMove,
      onMouseDown: this.mouseDown,
      onMouseCancel: this.mouseCancel,
      onMouseLeave: this.mouseLeave
    }), (0, _preact.h)("div", {
      className: "flex items-center justify-between mt2"
    }, (0, _preact.h)(_button.Button, {
      primary: true,
      large: true,
      "data-e2e": "signatureSaveButton",
      onClick: () => {
        updateValue(this.path.trim());
      },
      type: "button"
    }, "Save"), (0, _preact.h)("div", null, (0, _preact.h)(_button.Button, {
      large: true,
      onClick: () => {
        this.reset();
        this.renderCanvas();
      },
      className: "mr2",
      type: "button"
    }, "Clear"), (0, _preact.h)(_button.Button, {
      large: true,
      onClick: () => {
        this.reset();
        this.renderCanvas();
        close();
      },
      "data-e2e": "cancelSignatureButton",
      type: "button"
    }, "Cancel")))));
  }

}

var _default = SignatureInput;
exports.default = _default;