"use strict";

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

var _preact = require("preact");

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

var _icon = require("./icon");

var _links = require("./links");

var _decimals = require("./utils/decimals");

var _disableScroll = require("./utils/disable-scroll");

const height = 300;
const pathCleanRE = /M[ *M]*/g;

const cleanPath = path => path.trim().replace(pathCleanRE, 'M');

class SignatureInput extends _preact.Component {
  constructor(props) {
    super(props);
    this.clear = this.clear.bind(this);
    this.cancel = this.cancel.bind(this); // pointers

    this.onPointerMove = this.onPointerMove.bind(this);
    this.onPointerUp = this.onPointerUp.bind(this);
    this.calculateCanvasInfo = this.calculateCanvasInfo.bind(this);
    this.renderCanvas = this.renderCanvas.bind(this);
    this.state = {
      hasPath: false
    };
  }

  reset(callback) {
    this.path = '';
    this.break = true;
    this.setState({
      hasPath: false
    }, callback);
  }

  componentDidMount() {
    // eslint-disable-next-line no-console
    console.log('signature comp mounted');
    this.reset(() => {
      this.canvas = this.base.querySelector('canvas');
      this.ctx = this.canvas.getContext('2d');
      (0, _disableScroll.disableScroll)();
      window.addEventListener('resize', this.calculateCanvasInfo, {
        passive: true
      });
      document.addEventListener('pointermove', this.onPointerMove);
      document.addEventListener('pointerup', this.onPointerUp);
      this.calculateCanvasInfo(); // just to make sure layout is complete

      setTimeout(() => this.calculateCanvasInfo(), 500);
      this.renderCanvas();
    });
  }

  onPointerMove(event) {
    event.preventDefault();
    event.stopImmediatePropagation();

    if (event.buttons === 1) {
      const coord = this.adjustCoord(event.clientX, event.clientY, event.pointerType || 'mouse');
      const inside = !!coord;

      if (inside) {
        if (this.lastWasInside) {
          this.appendCoord(coord.x, coord.y);
        } else {
          this.appendCoord(coord.x, coord.y, true);
        }
      }

      this.lastWasInside = inside;
    }
  }

  onPointerUp() {
    this.lastWasInside = false;

    if (!this.state.hasPath && this.path) {
      this.setState({
        hasPath: true
      });
    }
  }

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

  componentWillUnmount() {
    window.removeEventListener('resize', this.calculateCanvasInfo, {
      passive: true
    });
    document.removeEventListener('pointermove', this.onPointerMove);
    document.removeEventListener('pointerup', this.onPointerUp);
    (0, _disableScroll.enableScroll)();
  }
  /**
   * @param {number} clientX
   * @param {number} clientY
   * @param {'mouse' | 'pen' | 'touch'} type
   */


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

    if (type === 'pen') {
      x -= 2;
      y -= 2;
    }

    if (type === 'touch') {
      y -= 10;
      x -= 10;
    }

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

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

    return {
      x,
      y
    };
  }

  appendCoord(x, y, isNew) {
    this.path = cleanPath(this.path);

    if (!this.path.startsWith('M') || isNew) {
      this.path += 'M';
    }

    this.path += " ".concat((0, _decimals.roundToDecimal)(x, 2), ",").concat((0, _decimals.roundToDecimal)(y, 2));
    requestAnimationFrame(this.renderCanvas);
  }

  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.closePath();
    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(_, nextState) {
    // only update if haspath has changed
    return this.state.hasPath !== nextState.hasPath;
  }

  cancel() {
    this.clear();
    this.props.close();
  }

  clear(e) {
    if (e) {
      e.preventDefault();
    }

    this.reset(() => {
      this.renderCanvas();
    });
  }

  render() {
    // eslint-disable-next-line no-console
    console.log('signature comp rendered');
    const {
      updateValue,
      showIncompleteWarning,
      confirmButtonText = 'Sign'
    } = this.props;
    const {
      hasPath
    } = this.state;
    return (0, _preact.h)("div", {
      className: "top-0 left-0 fixed bg-light-gray w-100 h-100 z-9999 flex items-center justify-center"
    }, (0, _preact.h)("div", {
      "data-e2e": "signatureBox",
      className: "relative"
    }, showIncompleteWarning && (0, _preact.h)("div", {
      "data-e2e": "incompleteWarning",
      className: "bg-orange flex items-center w-100 pa2 mb2 br2"
    }, (0, _preact.h)(_icon.Icon, {
      icon: "warning",
      className: "mr2"
    }), "The report is incomplete, but as the primary provider you can still sign and finalize it."), (0, _preact.h)("div", {
      className: "relative"
    }, (0, _preact.h)("div", {
      className: "absolute top-0 right-0  flex items-center"
    }, (0, _preact.h)(_links.Link, {
      href: "#",
      onClick: this.clear,
      "data-e2e": "clearSignatureButton",
      className: 'underline gray ' + (hasPath ? 'o-100' : 'o-0')
    }, "Clear Signature"), (0, _preact.h)("button", {
      onClick: this.cancel,
      className: "pointer button-reset bn bg-transparent db pa3 flex items-center dark-blue"
    }, (0, _preact.h)(_icon.Icon, {
      icon: "close"
    }))), (0, _preact.h)("canvas", {
      "data-e2e": "signaturePad",
      className: "bg-white ba br2 b--gray",
      width: Math.min(window.innerWidth - 10, 660),
      height: height
    })), (0, _preact.h)("div", {
      className: "flex items-center justify-end mt2"
    }, (0, _preact.h)(_button.Button, {
      primary: true,
      large: true,
      disabled: !hasPath,
      className: hasPath ? 'o-100' : 'o-0',
      "data-e2e": "signatureSaveButton",
      onClick: () => {
        updateValue(this.path.trim());
      },
      type: "button"
    }, confirmButtonText))));
  }

}

exports.SignatureInput = SignatureInput;