<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Coral USB Accelerator Demo</title>
    <script src="dfu.js"></script>
    <script src="dfuse.js"></script>
    <script src="imagenet_labels.js"></script>
    <script src="tflite.js"></script>
    <script src="interpreter.js"></script>
  </head>
  <body>
    <h1>Coral USB Accelerator Demo</h1>
    <button id="button-firmware">1. Flash Device Firmware</button>&nbsp;<span id="firmware-status"></span><br/><br/>
    <button id="button-init">2. Initialize Device</button><br/><br/>
    <button id="button-image" onclick="document.getElementById('file').click();" disabled>3. Choose Image File</button><br/><br/>
    <input type="file" id="file" style="display:none;"/><br/>
    <canvas id="canvas"></canvas>
    <h2 id="result"></h2>
    <br/><br/>

    <!--button id="test">Inference Test</button><br/><br/-->

    <script>
      async function loadLocalImage(file) {
        return new Promise(resolve => {
          var reader = new FileReader();
          reader.onload = function() {
            var img = new Image();
            img.onload = function() {
              resolve(img);
            };
            img.src = reader.result;
          };
          reader.readAsDataURL(file);
        });
      }

      async function getDFUDescriptorProperties(device) {
        let data = await device.readConfigurationDescriptor(0);
        let configDesc = dfu.parseConfigurationDescriptor(data);
        let funcDesc = null;
        if (configDesc.bConfigurationValue == device.settings.configuration.configurationValue) {
            for (let desc of configDesc.descriptors) {
                if (desc.bDescriptorType == 0x21 && desc.hasOwnProperty("bcdDFUVersion")) {
                    funcDesc = desc;
                    break;
                }
            }
        }

        if (!funcDesc) return {};

        return {
            WillDetach:            ((funcDesc.bmAttributes & 0x08) != 0),
            ManifestationTolerant: ((funcDesc.bmAttributes & 0x04) != 0),
            CanUpload:             ((funcDesc.bmAttributes & 0x02) != 0),
            CanDnload:             ((funcDesc.bmAttributes & 0x01) != 0),
            TransferSize:          funcDesc.wTransferSize,
            DetachTimeOut:         funcDesc.wDetachTimeOut,
            DFUVersion:            funcDesc.bcdDFUVersion
        };
      }

      async function connect(device) {
          await device.open();

          let desc = await getDFUDescriptorProperties(device);
          if (desc && Object.keys(desc).length > 0)
            device.properties = desc;

          device.logDebug = console.log;
          device.logInfo = console.log;
          device.logWarning = console.log;
          device.logError = console.log;
          device.logProgress = console.log;

          return device;
      }

      async function openDevice() {
        try {
          let device = await navigator.usb.requestDevice({ 'filters': [{'vendorId': 0x1a6e, 'productId': 0x089a}] });
          let interfaces = dfu.findDeviceDfuInterfaces(device);
          if (interfaces.length != 1) return null;
          return await connect(new dfu.Device(device, interfaces[0]));
        } catch (error) {
          return null;
        }
      }

      async function loadFile(url) {
        return new Promise(resolve => {
          let req = new XMLHttpRequest();
          req.open('GET', url, true);
          req.responseType = 'arraybuffer';
          req.onload = function (event) { resolve(req.response); };
          req.send(null);
        });
      }

      document.addEventListener('DOMContentLoaded', event => {
        let downloadButton = document.querySelector("#button-firmware");
        downloadButton.addEventListener('click', async function(event) {
          let firmwareFile = await loadFile('/firmware.bin');
          let device = await openDevice();
          if (device) {
            console.log('Device: ', device.properties);
          } else {
            console.log('Cannot open device.');
          }

          if (device && firmwareFile) {
            document.getElementById("firmware-status").textContent = "Flashing...";

            try {
              let status = await device.getStatus();
              if (status.state == dfu.dfuERROR) {
                await device.clearStatus();
              }
            } catch (error) {
              device.logWarning("Failed to clear status");
            }

            try {
              let manifestationTolerant = device.properties.ManifestationTolerant;
              await device.do_download(device.properties.TransferSize, firmwareFile, manifestationTolerant);
              if (!manifestationTolerant)
                await device.waitDisconnected(5000);
              document.getElementById("firmware-status").textContent = "Ready :)";
            } catch (error) {
              document.getElementById("firmware-status").textContent = "Failed :(";
            }
          }
        });
      });

      Module['onRuntimeInitialized'] = () => {
        let inference_test = Module.cwrap("inference_test",  null, [], { async: true });
        let testButton = document.querySelector("#test");
        if (testButton) {
          testButton.addEventListener('click', async () => {
            inference_test();
          });
        }

        let interpreter;

        document.querySelector("#button-init").addEventListener('click', async () => {
          let model = new Uint8Array(await loadFile('/model.tflite'));
          let modelBufferSize = model.length * model.BYTES_PER_ELEMENT;
          let modelBuffer = Module._malloc(modelBufferSize);
          Module.HEAPU8.set(model, modelBuffer);

          interpreter = new tflite.Interpreter();
          if (await interpreter.create(modelBuffer, modelBufferSize)) {
            document.getElementById("button-firmware").disabled = true;
            document.getElementById("button-init").disabled = true;
            document.getElementById("button-image").disabled = false;
          }
        });

        document.querySelector("#file").addEventListener('change', async () => {
          var input = document.getElementById("file");
          var file = input.files[0];
          if (!file) return;

          [_depth, height, width, _channels] = interpreter.inputShape();

          let img = await loadLocalImage(file);
          var c = document.getElementById("canvas");
          c.width = width;
          c.height = height;
          var ctx = c.getContext('2d');
          ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height);

          var imageData = ctx.getImageData(0, 0, width, height);
          interpreter.setRgbaInput(0, imageData.data);
          document.getElementById("result").textContent = "Recognizing...";
          let inference_start = Date.now();
          interpreter.invoke(() => {
            let inference_time = Date.now() - inference_start;
            let maxIndex = interpreter.getClassificationOutput(0);
            document.getElementById("result").textContent = `${imagenet_labels[maxIndex]} (${inference_time} ms)`;
          });
        });
      };
      Module['print'] = txt => console.log(txt);
    </script>
  </body>
</html>
