<!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>
