<!DOCTYPE html>
<html>

<!--
Copyright 2022 The IREE Authors

Licensed under the Apache License v2.0 with LLVM Exceptions.
See https://llvm.org/LICENSE.txt for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

<head>
  <meta charset="utf-8" />
  <title>IREE Static Web Sample</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="/ghost.svg" type="image/svg+xml">

  <script src="./easeljs.min.js"></script>
  <script src="./iree_api.js"></script>
</head>

<body style="background-color: #2b2c30; color: #ABB2BF">
  <h1>IREE Static Web Sample</h1>

  <canvas id="drawingCanvas" width="256" height="256"
          style="border:2px solid #000000; background-color: #FFFFFF;"
          oncontextmenu="return false;">
  </canvas>
  <canvas id="rescaledCanvas" width="28" height="28"
          style="border:2px solid #000000; background-color: #FFFFFF;">
  </canvas>

  <br>
  <div style="border:2px solid #000000; background-color: #CCCCCC; padding: 8px; color: #111111; width:440px">
    <button id="predictButton" disabled onclick="predictDigit()">Predict handwritten digit</button>
    <button id="clearCanvasButton" onclick="clearCanvas()">Clear canvas</button>
    <br>
    Prediction result: <div id="predictionResult" style="display:inline"></div>
  </div>

  <script>
    // <canvas> drawing using easeljs forked from:
    //   https://createjs.com/demos/easeljs/curveto
    //   https://github.com/CreateJS/EaselJS/blob/master/examples/CurveTo.html

    const predictButtonElement = document.getElementById('predictButton');
    const predictionResultElement = document.getElementById('predictionResult');
    const drawingCanvasElement = document.getElementById("drawingCanvas");
    const rescaledCanvasElement = document.getElementById("rescaledCanvas");
    const rescaledCanvasContext = rescaledCanvasElement.getContext("2d");
    let stage;
    let drawingCanvasShape;
    let oldPt, oldMidPt;
    let titleText;
    let ireeInitialized = false;
    const primaryColor = "#000000";
    const eraseColor = "#FFFFFF";
    const stroke = 32;

    function predictDigit() {
      // TODO(scotttodd): debounce / rate limit this?
      ireePredictDigit(getRescaledCanvasData()).then((result) => {
        predictionResultElement.innerHTML = result;
      }).catch((error) => {
        console.error('error predicting digit:', error);
        predictionResultElement.innerHTML = "<b>" + error + "</b>";
      });
    }

    function clearCanvas() {
      stage.clear();
      stage.removeAllChildren();

      drawingCanvasShape = new createjs.Shape();
      stage.addChild(drawingCanvasShape);
      stage.update();

      updateRescaledCanvas();
    }

    function initDrawing() {
      rescaledCanvasContext.imageSmoothingEnabled = false;
      rescaledCanvasContext.mozImageSmoothingEnabled = false;
      rescaledCanvasContext.webkitImageSmoothingEnabled = false;
      rescaledCanvasContext.msImageSmoothingEnabled = false;

      stage = new createjs.Stage(drawingCanvasElement);
      stage.autoClear = false;
      stage.enableDOMEvents(true);

      createjs.Touch.enable(stage);
      createjs.Ticker.framerate = 24;

      stage.addEventListener("stagemousedown", handleMouseDown);
      stage.addEventListener("stagemouseup", handleMouseUp);

      drawingCanvasShape = new createjs.Shape();
      stage.addChild(drawingCanvasShape);

      // Add instruction text.
      titleText = new createjs.Text("Click and Drag to draw", "18px Arial", "#000000");
      titleText.x = 30;
      titleText.y = 100;
      stage.addChild(titleText);

      stage.update();
    }

    function handleMouseDown(event) {
      if (!event.primary && !event.secondary) { return; }

      if (stage.contains(titleText)) {
        stage.clear();
        stage.removeChild(titleText);
      }

      oldPt = new createjs.Point(stage.mouseX, stage.mouseY);
      oldMidPt = oldPt.clone();
      stage.addEventListener("stagemousemove", handleMouseMove);
    }

    function handleMouseMove(event) {
      if (!event.primary && !event.secondary) { return; }

      const midPt = new createjs.Point(
        oldPt.x + stage.mouseX >> 1, oldPt.y + stage.mouseY >> 1);

      const color = event.nativeEvent.which == 1 ? primaryColor : eraseColor;
      drawingCanvasShape.graphics.clear()
          .setStrokeStyle(stroke, 'round', 'round')
          .beginStroke(color).moveTo(midPt.x, midPt.y)
          .curveTo(oldPt.x, oldPt.y, oldMidPt.x, oldMidPt.y);

      oldPt.x = stage.mouseX;
      oldPt.y = stage.mouseY;
      oldMidPt.x = midPt.x;
      oldMidPt.y = midPt.y;

      stage.update();
      updateRescaledCanvas();

      if (ireeInitialized) {
        predictDigit();
      }
    }

    function handleMouseUp(event) {
      if (!event.primary && !event.default) { return; }
      stage.removeEventListener("stagemousemove", handleMouseMove);
    }

    function updateRescaledCanvas() {
      rescaledCanvasContext.clearRect(
        0, 0, rescaledCanvasElement.width, rescaledCanvasElement.height);
      rescaledCanvasContext.drawImage(
          drawingCanvasElement,
          /*sx=*/0, /*sy=*/0,
          /*sWidth=*/256, /*sHeight=*/256,
          /*dx=*/0, /*dy=*/0,
          /*dWidth=*/28, /*dHeight=*/28);
    }

    function getRescaledCanvasData() {
      return rescaledCanvasContext.getImageData(0, 0, 28, 28);
    }

    initDrawing();

    ireeInitializeWorker().then((result) => {
      predictButtonElement.disabled = false;
      ireeInitialized = true;
    }).catch((error) => {
      console.error("Failed to initialize IREE, error: '" + error + "'");
    });
  </script>
</body>

</html>
