/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

async function ConnectDevice(deviceId, serverConnector) {
  console.debug('Connect: ' + deviceId);
  // Prepare messages in case of connection failure
  let connectionAttemptDuration = 0;
  const intervalMs = 15000;
  let connectionInterval = setInterval(() => {
    connectionAttemptDuration += intervalMs;
    if (connectionAttemptDuration > 30000) {
      showError(
          'Connection should have occurred by now. ' +
          'Please attempt to restart the guest device.');
      clearInterval(connectionInterval);
    } else if (connectionAttemptDuration > 15000) {
      showWarning('Connection is taking longer than expected');
    }
  }, intervalMs);

  let module = await import('./cf_webrtc.js');
  let deviceConnection = await module.Connect(deviceId, serverConnector);
  console.info('Connected to ' + deviceId);
  clearInterval(connectionInterval);
  return deviceConnection;
}

function setupMessages() {
  let closeBtn = document.querySelector('#error-message .close-btn');
  closeBtn.addEventListener('click', evt => {
    evt.target.parentElement.className = 'hidden';
  });
}

function showMessage(msg, className) {
  let element = document.getElementById('error-message');
  if (element.childNodes.length < 2) {
    // First time, no text node yet
    element.insertAdjacentText('afterBegin', msg);
  } else {
    element.childNodes[0].data = msg;
  }
  element.className = className;
}

function showWarning(msg) {
  showMessage(msg, 'warning');
}

function showError(msg) {
  showMessage(msg, 'error');
}


class DeviceDetailsUpdater {
  #element;

  constructor() {
    this.#element = document.getElementById('device-details-hardware');
  }

  setHardwareDetailsText(text) {
    this.#element.dataset.hardwareDetailsText = text;
    return this;
  }

  setDeviceStateDetailsText(text) {
    this.#element.dataset.deviceStateDetailsText = text;
    return this;
  }

  update() {
    this.#element.textContent =
        [
          this.#element.dataset.hardwareDetailsText,
          this.#element.dataset.deviceStateDetailsText,
        ].filter(e => e /*remove empty*/)
            .join('\n');
  }
}  // DeviceDetailsUpdater

class DeviceControlApp {
  #deviceConnection = {};
  #currentRotation = 0;
  #displayDescriptions = [];
  #buttons = {};
  #recording = {};
  #phys = {};
  #deviceCount = 0;

  constructor(deviceConnection) {
    this.#deviceConnection = deviceConnection;
  }

  start() {
    console.debug('Device description: ', this.#deviceConnection.description);
    this.#deviceConnection.onControlMessage(msg => this.#onControlMessage(msg));
    createToggleControl(
        document.getElementById('keyboard-capture-control'), 'keyboard',
        enabled => this.#onKeyboardCaptureToggle(enabled));
    createToggleControl(
        document.getElementById('mic-capture-control'), 'mic',
        enabled => this.#onMicCaptureToggle(enabled));
    createToggleControl(
        document.getElementById('camera-control'), 'videocam',
        enabled => this.#onCameraCaptureToggle(enabled));
    createToggleControl(
        document.getElementById('record-video-control'), 'movie_creation',
        enabled => this.#onVideoCaptureToggle(enabled));
    const audioElm = document.getElementById('device-audio');

    let audioPlaybackCtrl = createToggleControl(
        document.getElementById('audio-playback-control'), 'speaker',
        enabled => this.#onAudioPlaybackToggle(enabled), !audioElm.paused);
    // The audio element may start or stop playing at any time, this ensures the
    // audio control always show the right state.
    audioElm.onplay = () => audioPlaybackCtrl.Set(true);
    audioElm.onpause = () => audioPlaybackCtrl.Set(false);

    this.#showDeviceUI();
  }

  #showDeviceUI() {
    window.onresize = evt => this.#resizeDeviceDisplays();
    // Set up control panel buttons
    this.#buttons = {};
    this.#buttons['power'] = createControlPanelButton(
        'power', 'Power', 'power_settings_new',
        evt => this.#onControlPanelButton(evt));
    this.#buttons['home'] = createControlPanelButton(
        'home', 'Home', 'home', evt => this.#onControlPanelButton(evt));
    this.#buttons['menu'] = createControlPanelButton(
        'menu', 'Menu', 'menu', evt => this.#onControlPanelButton(evt));
    this.#buttons['rotate'] = createControlPanelButton(
        'rotate', 'Rotate', 'screen_rotation',
        evt => this.#onRotateButton(evt));
    this.#buttons['rotate'].adb = true;
    this.#buttons['volumedown'] = createControlPanelButton(
        'volumedown', 'Volume Down', 'volume_down',
        evt => this.#onControlPanelButton(evt));
    this.#buttons['volumeup'] = createControlPanelButton(
        'volumeup', 'Volume Up', 'volume_up',
        evt => this.#onControlPanelButton(evt));

    createModalButton(
        'device-details-button', 'device-details-modal',
        'device-details-close');
    createModalButton(
        'bluetooth-modal-button', 'bluetooth-prompt',
        'bluetooth-prompt-close');
    createModalButton(
        'bluetooth-prompt-wizard', 'bluetooth-wizard',
        'bluetooth-wizard-close', 'bluetooth-prompt');
    createModalButton(
        'bluetooth-wizard-device', 'bluetooth-wizard-confirm',
        'bluetooth-wizard-confirm-close', 'bluetooth-wizard');
    createModalButton(
        'bluetooth-wizard-another', 'bluetooth-wizard',
        'bluetooth-wizard-close', 'bluetooth-wizard-confirm');
    createModalButton(
        'bluetooth-prompt-list', 'bluetooth-list',
        'bluetooth-list-close', 'bluetooth-prompt');
    createModalButton(
        'bluetooth-prompt-console', 'bluetooth-console',
        'bluetooth-console-close', 'bluetooth-prompt');
    createModalButton(
        'bluetooth-wizard-cancel', 'bluetooth-prompt',
        'bluetooth-wizard-close', 'bluetooth-wizard');

    positionModal('device-details-button', 'bluetooth-modal');
    positionModal('device-details-button', 'bluetooth-prompt');
    positionModal('device-details-button', 'bluetooth-wizard');
    positionModal('device-details-button', 'bluetooth-wizard-confirm');
    positionModal('device-details-button', 'bluetooth-list');
    positionModal('device-details-button', 'bluetooth-console');

    createButtonListener('bluetooth-prompt-list', null, this.#deviceConnection,
      evt => this.#onRootCanalCommand(this.#deviceConnection, "list", evt));
    createButtonListener('bluetooth-wizard-device', null, this.#deviceConnection,
      evt => this.#onRootCanalCommand(this.#deviceConnection, "add", evt));
    createButtonListener('bluetooth-list-trash', null, this.#deviceConnection,
      evt => this.#onRootCanalCommand(this.#deviceConnection, "del", evt));
    createButtonListener('bluetooth-prompt-wizard', null, this.#deviceConnection,
      evt => this.#onRootCanalCommand(this.#deviceConnection, "list", evt));
    createButtonListener('bluetooth-wizard-another', null, this.#deviceConnection,
      evt => this.#onRootCanalCommand(this.#deviceConnection, "list", evt));

    if (this.#deviceConnection.description.custom_control_panel_buttons.length >
        0) {
      document.getElementById('control-panel-custom-buttons').style.display =
          'flex';
      for (const button of this.#deviceConnection.description
               .custom_control_panel_buttons) {
        if (button.shell_command) {
          // This button's command is handled by sending an ADB shell command.
          this.#buttons[button.command] = createControlPanelButton(
              button.command, button.title, button.icon_name,
              e => this.#onCustomShellButton(button.shell_command, e),
              'control-panel-custom-buttons');
          this.#buttons[button.command].adb = true;
        } else if (button.device_states) {
          // This button corresponds to variable hardware device state(s).
          this.#buttons[button.command] = createControlPanelButton(
              button.command, button.title, button.icon_name,
              this.#getCustomDeviceStateButtonCb(button.device_states),
              'control-panel-custom-buttons');
          for (const device_state of button.device_states) {
            // hinge_angle is currently injected via an adb shell command that
            // triggers a guest binary.
            if ('hinge_angle_value' in device_state) {
              this.#buttons[button.command].adb = true;
            }
          }
        } else {
          // This button's command is handled by custom action server.
          this.#buttons[button.command] = createControlPanelButton(
              button.command, button.title, button.icon_name,
              evt => this.#onControlPanelButton(evt),
              'control-panel-custom-buttons');
        }
      }
    }

    // Set up displays
    this.#createDeviceDisplays();

    // Set up audio
    const deviceAudio = document.getElementById('device-audio');
    for (const audio_desc of this.#deviceConnection.description.audio_streams) {
      let stream_id = audio_desc.stream_id;
      this.#deviceConnection.getStream(stream_id)
          .then(stream => {
            deviceAudio.srcObject = stream;
            let playPromise = deviceAudio.play();
            if (playPromise !== undefined) {
              playPromise.catch(error => {
                showWarning(
                    'Audio playback is disabled, click on the speaker control to activate it');
              });
            }
          })
          .catch(e => console.error('Unable to get audio stream: ', e));
    }

    // Set up touch input
    this.#startMouseTracking();

    this.#updateDeviceHardwareDetails(
        this.#deviceConnection.description.hardware);

    // Show the error message and disable buttons when the WebRTC connection
    // fails.
    this.#deviceConnection.onConnectionStateChange(state => {
      if (state == 'disconnected' || state == 'failed') {
        this.#showWebrtcError();
      }
    });

    let bluetoothConsole =
        cmdConsole('bluetooth-console-view', 'bluetooth-console-input');
    bluetoothConsole.addCommandListener(cmd => {
      let inputArr = cmd.split(' ');
      let command = inputArr[0];
      inputArr.shift();
      let args = inputArr;
      this.#deviceConnection.sendBluetoothMessage(
          createRootcanalMessage(command, args));
    });
    this.#deviceConnection.onBluetoothMessage(msg => {
      let decoded = decodeRootcanalMessage(msg);
      let deviceCount = btUpdateDeviceList(decoded);
      if (deviceCount > 0) {
        this.#deviceCount = deviceCount;
        createButtonListener('bluetooth-list-trash', null, this.#deviceConnection,
           evt => this.#onRootCanalCommand(this.#deviceConnection, "del", evt));
      }
      btUpdateAdded(decoded);
      let phyList = btParsePhys(decoded);
      if (phyList) {
        this.#phys = phyList;
      }
      bluetoothConsole.addLine(decoded);
    });
  }

  #onRootCanalCommand(deviceConnection, cmd, evt) {
    if (cmd == "list") {
      deviceConnection.sendBluetoothMessage(createRootcanalMessage("list", []));
    }
    if (cmd == "del") {
      let id = evt.srcElement.getAttribute("data-device-id");
      deviceConnection.sendBluetoothMessage(createRootcanalMessage("del", [id]));
      deviceConnection.sendBluetoothMessage(createRootcanalMessage("list", []));
    }
    if (cmd == "add") {
      let name = document.getElementById('bluetooth-wizard-name').value;
      let type = document.getElementById('bluetooth-wizard-type').value;
      if (type == "remote_loopback") {
        deviceConnection.sendBluetoothMessage(createRootcanalMessage("add", [type]));
      } else {
        let mac = document.getElementById('bluetooth-wizard-mac').value;
        deviceConnection.sendBluetoothMessage(createRootcanalMessage("add", [type, mac]));
      }
      let phyId = this.#phys["LOW_ENERGY"].toString();
      if (type == "remote_loopback") {
        phyId = this.#phys["BR_EDR"].toString();
      }
      let devId = this.#deviceCount.toString();
      this.#deviceCount++;
      deviceConnection.sendBluetoothMessage(createRootcanalMessage("add_device_to_phy", [devId, phyId]));
    }
  }

  #showWebrtcError() {
    document.getElementById('status-message').className = 'error';
    document.getElementById('status-message').textContent =
        'No connection to the guest device. ' +
        'Please ensure the WebRTC process on the host machine is active.';
    document.getElementById('status-message').style.visibility = 'visible';
    const deviceDisplays = document.getElementById('device-displays');
    deviceDisplays.style.display = 'none';
    for (const [_, button] of Object.entries(this.#buttons)) {
      button.disabled = true;
    }
  }

  #takePhoto() {
    const imageCapture = this.#deviceConnection.imageCapture;
    if (imageCapture) {
      const photoSettings = {
        imageWidth: this.#deviceConnection.cameraWidth,
        imageHeight: this.#deviceConnection.cameraHeight
      };
      imageCapture.takePhoto(photoSettings)
          .then(blob => blob.arrayBuffer())
          .then(buffer => this.#deviceConnection.sendOrQueueCameraData(buffer))
          .catch(error => console.error(error));
    }
  }

  #getCustomDeviceStateButtonCb(device_states) {
    let states = device_states;
    let index = 0;
    return e => {
      if (e.type == 'mousedown') {
        // Reset any overridden device state.
        adbShell('cmd device_state state reset');
        // Send a device_state message for the current state.
        let message = {
          command: 'device_state',
          ...states[index],
        };
        this.#deviceConnection.sendControlMessage(JSON.stringify(message));
        console.debug('Control message sent: ', JSON.stringify(message));
        let lidSwitchOpen = null;
        if ('lid_switch_open' in states[index]) {
          lidSwitchOpen = states[index].lid_switch_open;
        }
        let hingeAngle = null;
        if ('hinge_angle_value' in states[index]) {
          hingeAngle = states[index].hinge_angle_value;
          // TODO(b/181157794): Use a custom Sensor HAL for hinge_angle
          // injection instead of this guest binary.
          adbShell(
              '/vendor/bin/cuttlefish_sensor_injection hinge_angle ' +
              states[index].hinge_angle_value);
        }
        // Update the Device Details view.
        this.#updateDeviceStateDetails(lidSwitchOpen, hingeAngle);
        // Cycle to the next state.
        index = (index + 1) % states.length;
      }
    }
  }

  #resizeDeviceDisplays() {
    // Padding between displays.
    const deviceDisplayWidthPadding = 10;
    // Padding for the display info above each display video.
    const deviceDisplayHeightPadding = 38;

    let deviceDisplayList = document.getElementsByClassName('device-display');
    let deviceDisplayVideoList =
        document.getElementsByClassName('device-display-video');
    let deviceDisplayInfoList =
        document.getElementsByClassName('device-display-info');

    const deviceDisplays = document.getElementById('device-displays');
    const rotationDegrees = this.#getTransformRotation(deviceDisplays);
    const rotationRadians = rotationDegrees * Math.PI / 180;

    // Auto-scale the screen based on window size.
    let availableWidth = deviceDisplays.clientWidth;
    let availableHeight = deviceDisplays.clientHeight - deviceDisplayHeightPadding;

    // Reserve space for padding between the displays.
    availableWidth = availableWidth -
        (this.#displayDescriptions.length * deviceDisplayWidthPadding);

    // Loop once over all of the displays to compute the total space needed.
    let neededWidth = 0;
    let neededHeight = 0;
    for (let i = 0; i < deviceDisplayList.length; i++) {
      let deviceDisplayDescription = this.#displayDescriptions[i];
      let deviceDisplayVideo = deviceDisplayVideoList[i];

      const originalDisplayWidth = deviceDisplayDescription.x_res;
      const originalDisplayHeight = deviceDisplayDescription.y_res;

      const neededBoundingBoxWidth =
          Math.abs(Math.cos(rotationRadians) * originalDisplayWidth) +
          Math.abs(Math.sin(rotationRadians) * originalDisplayHeight);
      const neededBoundingBoxHeight =
          Math.abs(Math.sin(rotationRadians) * originalDisplayWidth) +
          Math.abs(Math.cos(rotationRadians) * originalDisplayHeight);

      neededWidth = neededWidth + neededBoundingBoxWidth;
      neededHeight = Math.max(neededHeight, neededBoundingBoxHeight);
    }

    const scaling =
        Math.min(availableWidth / neededWidth, availableHeight / neededHeight);

    // Loop again over all of the displays to set the sizes and positions.
    let deviceDisplayLeftOffset = 0;
    for (let i = 0; i < deviceDisplayList.length; i++) {
      let deviceDisplay = deviceDisplayList[i];
      let deviceDisplayVideo = deviceDisplayVideoList[i];
      let deviceDisplayInfo = deviceDisplayInfoList[i];
      let deviceDisplayDescription = this.#displayDescriptions[i];

      let rotated = this.#currentRotation == 1 ? ' (Rotated)' : '';
      deviceDisplayInfo.textContent = `Display ${i} - ` +
          `${deviceDisplayDescription.x_res}x` +
          `${deviceDisplayDescription.y_res} ` +
          `(${deviceDisplayDescription.dpi} DPI)${rotated}`;

      const originalDisplayWidth = deviceDisplayDescription.x_res;
      const originalDisplayHeight = deviceDisplayDescription.y_res;

      const scaledDisplayWidth = originalDisplayWidth * scaling;
      const scaledDisplayHeight = originalDisplayHeight * scaling;

      const neededBoundingBoxWidth =
          Math.abs(Math.cos(rotationRadians) * originalDisplayWidth) +
          Math.abs(Math.sin(rotationRadians) * originalDisplayHeight);
      const neededBoundingBoxHeight =
          Math.abs(Math.sin(rotationRadians) * originalDisplayWidth) +
          Math.abs(Math.cos(rotationRadians) * originalDisplayHeight);

      const scaledBoundingBoxWidth = neededBoundingBoxWidth * scaling;
      const scaledBoundingBoxHeight = neededBoundingBoxHeight * scaling;

      const offsetX = (scaledBoundingBoxWidth - scaledDisplayWidth) / 2;
      const offsetY = (scaledBoundingBoxHeight - scaledDisplayHeight) / 2;

      deviceDisplayVideo.style.width = scaledDisplayWidth;
      deviceDisplayVideo.style.height = scaledDisplayHeight;
      deviceDisplayVideo.style.transform = `translateX(${offsetX}px) ` +
          `translateY(${offsetY}px) ` +
          `rotateZ(${rotationDegrees}deg) `;

      deviceDisplay.style.left = `${deviceDisplayLeftOffset}px`;
      deviceDisplay.style.width = scaledBoundingBoxWidth;
      deviceDisplay.style.height = scaledBoundingBoxHeight;

      deviceDisplayLeftOffset = deviceDisplayLeftOffset + deviceDisplayWidthPadding +
          scaledBoundingBoxWidth;
    }
  }

  #getTransformRotation(element) {
    if (!element.style.textIndent) {
      return 0;
    }
    // Remove 'px' and convert to float.
    return parseFloat(element.style.textIndent.slice(0, -2));
  }

  #onControlMessage(message) {
    let message_data = JSON.parse(message.data);
    console.debug('Control message received: ', message_data)
    let metadata = message_data.metadata;
    if (message_data.event == 'VIRTUAL_DEVICE_BOOT_STARTED') {
      // Start the adb connection after receiving the BOOT_STARTED message.
      // (This is after the adbd start message. Attempting to connect
      // immediately after adbd starts causes issues.)
      this.#initializeAdb();
    }
    if (message_data.event == 'VIRTUAL_DEVICE_SCREEN_CHANGED') {
      if (metadata.rotation != this.#currentRotation) {
        // Animate the screen rotation.
        const targetRotation = metadata.rotation == 0 ? 0 : -90;

        $('#device-displays')
            .animate(
                {
                  textIndent: targetRotation,
                },
                {
                  duration: 1000,
                  step: (now, tween) => {
                    this.#resizeDeviceDisplays();
                  },
                });
      }

      this.#currentRotation = metadata.rotation;
    }
    if (message_data.event == 'VIRTUAL_DEVICE_CAPTURE_IMAGE') {
      if (this.#deviceConnection.cameraEnabled) {
        this.#takePhoto();
      }
    }
    if (message_data.event == 'VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED') {
      this.#updateDisplayVisibility(metadata.display, metadata.mode);
    }
  }

  #updateDeviceStateDetails(lidSwitchOpen, hingeAngle) {
    let deviceStateDetailsTextLines = [];
    if (lidSwitchOpen != null) {
      let state = lidSwitchOpen ? 'Opened' : 'Closed';
      deviceStateDetailsTextLines.push(`Lid Switch - ${state}`);
    }
    if (hingeAngle != null) {
      deviceStateDetailsTextLines.push(`Hinge Angle - ${hingeAngle}`);
    }
    let deviceStateDetailsText = deviceStateDetailsTextLines.join('\n');
    new DeviceDetailsUpdater()
        .setDeviceStateDetailsText(deviceStateDetailsText)
        .update();
  }

  #updateDeviceHardwareDetails(hardware) {
    let hardwareDetailsTextLines = [];
    Object.keys(hardware).forEach((key) => {
      let value = hardware[key];
      hardwareDetailsTextLines.push(`${key} - ${value}`);
    });

    let hardwareDetailsText = hardwareDetailsTextLines.join('\n');
    new DeviceDetailsUpdater()
        .setHardwareDetailsText(hardwareDetailsText)
        .update();
  }

  // Creates a <video> element and a <div> container element for each display.
  // The extra <div> container elements are used to maintain the width and
  // height of the device as the CSS 'transform' property used on the <video>
  // element for rotating the device only affects the visuals of the element
  // and not its layout.
  #createDeviceDisplays() {
    console.debug(
        'Display descriptions: ', this.#deviceConnection.description.displays);
    this.#displayDescriptions = this.#deviceConnection.description.displays;
    let anyDisplayLoaded = false;
    const deviceDisplays = document.getElementById('device-displays');
    for (const deviceDisplayDescription of this.#displayDescriptions) {
      let deviceDisplay = document.createElement('div');
      deviceDisplay.classList.add('device-display');
      // Start the screen as hidden. Only show when data is ready.
      deviceDisplay.style.visibility = 'hidden';

      let deviceDisplayInfo = document.createElement("div");
      deviceDisplayInfo.classList.add("device-display-info");
      deviceDisplayInfo.id = deviceDisplayDescription.stream_id + '_info';
      deviceDisplay.appendChild(deviceDisplayInfo);

      let deviceDisplayVideo = document.createElement('video');
      deviceDisplayVideo.autoplay = true;
      deviceDisplayVideo.muted = true;
      deviceDisplayVideo.id = deviceDisplayDescription.stream_id;
      deviceDisplayVideo.classList.add('device-display-video');
      deviceDisplayVideo.addEventListener('loadeddata', (evt) => {
        if (!anyDisplayLoaded) {
          anyDisplayLoaded = true;
          this.#onDeviceDisplayLoaded();
        }
      });
      deviceDisplay.appendChild(deviceDisplayVideo);

      deviceDisplays.appendChild(deviceDisplay);

      let stream_id = deviceDisplayDescription.stream_id;
      this.#deviceConnection.getStream(stream_id)
          .then(stream => {
            deviceDisplayVideo.srcObject = stream;
          })
          .catch(e => console.error('Unable to get display stream: ', e));
    }
  }

  #initializeAdb() {
    init_adb(
        this.#deviceConnection, () => this.#showAdbConnected(),
        () => this.#showAdbError());
  }

  #showAdbConnected() {
    // Screen changed messages are not reported until after boot has completed.
    // Certain default adb buttons change screen state, so wait for boot
    // completion before enabling these buttons.
    document.getElementById('status-message').className = 'connected';
    document.getElementById('status-message').textContent =
        'adb connection established successfully.';
    setTimeout(() => {
      document.getElementById('status-message').style.visibility = 'hidden';
    }, 5000);
    for (const [_, button] of Object.entries(this.#buttons)) {
      if (button.adb) {
        button.disabled = false;
      }
    }
  }

  #showAdbError() {
    document.getElementById('status-message').className = 'error';
    document.getElementById('status-message').textContent =
        'adb connection failed.';
    document.getElementById('status-message').style.visibility = 'visible';
    for (const [_, button] of Object.entries(this.#buttons)) {
      if (button.adb) {
        button.disabled = true;
      }
    }
  }

  #onDeviceDisplayLoaded() {
    document.getElementById('status-message').textContent =
        'Awaiting bootup and adb connection. Please wait...';
    this.#resizeDeviceDisplays();

    let deviceDisplayList = document.getElementsByClassName('device-display');
    for (const deviceDisplay of deviceDisplayList) {
      deviceDisplay.style.visibility = 'visible';
    }

    // Enable the buttons after the screen is visible.
    for (const [key, button] of Object.entries(this.#buttons)) {
      if (!button.adb) {
        button.disabled = false;
      }
    }
    // Start the adb connection if it is not already started.
    this.#initializeAdb();
  }

  #onRotateButton(e) {
    // Attempt to init adb again, in case the initial connection failed.
    // This succeeds immediately if already connected.
    this.#initializeAdb();
    if (e.type == 'mousedown') {
      adbShell(
          '/vendor/bin/cuttlefish_sensor_injection rotate ' +
          (this.#currentRotation == 0 ? 'landscape' : 'portrait'))
    }
  }

  #onControlPanelButton(e) {
    if (e.type == 'mouseout' && e.which == 0) {
      // Ignore mouseout events if no mouse button is pressed.
      return;
    }
    this.#deviceConnection.sendControlMessage(JSON.stringify({
      command: e.target.dataset.command,
      button_state: e.type == 'mousedown' ? 'down' : 'up',
    }));
  }

  #onKeyboardCaptureToggle(enabled) {
    if (enabled) {
      document.addEventListener('keydown', evt => this.#onKeyEvent(evt));
      document.addEventListener('keyup', evt => this.#onKeyEvent(evt));
    } else {
      document.removeEventListener('keydown', evt => this.#onKeyEvent(evt));
      document.removeEventListener('keyup', evt => this.#onKeyEvent(evt));
    }
  }

  #onKeyEvent(e) {
    e.preventDefault();
    this.#deviceConnection.sendKeyEvent(e.code, e.type);
  }

  #startMouseTracking() {
    let $this = this;
    let mouseIsDown = false;
    let mouseCtx = {
      down: false,
      touchIdSlotMap: new Map(),
      touchSlots: [],
    };
    function onStartDrag(e) {
      e.preventDefault();

      // console.debug("mousedown at " + e.pageX + " / " + e.pageY);
      mouseCtx.down = true;

      $this.#sendEventUpdate(mouseCtx, e);
    }

    function onEndDrag(e) {
      e.preventDefault();

      // console.debug("mouseup at " + e.pageX + " / " + e.pageY);
      mouseCtx.down = false;

      $this.#sendEventUpdate(mouseCtx, e);
    }

    function onContinueDrag(e) {
      e.preventDefault();

      // console.debug("mousemove at " + e.pageX + " / " + e.pageY + ", down=" +
      // mouseIsDown);
      if (mouseCtx.down) {
        $this.#sendEventUpdate(mouseCtx, e);
      }
    }

    let deviceDisplayList = document.getElementsByClassName('device-display');
    if (window.PointerEvent) {
      for (const deviceDisplay of deviceDisplayList) {
        deviceDisplay.addEventListener('pointerdown', onStartDrag);
        deviceDisplay.addEventListener('pointermove', onContinueDrag);
        deviceDisplay.addEventListener('pointerup', onEndDrag);
      }
    } else if (window.TouchEvent) {
      for (const deviceDisplay of deviceDisplayList) {
        deviceDisplay.addEventListener('touchstart', onStartDrag);
        deviceDisplay.addEventListener('touchmove', onContinueDrag);
        deviceDisplay.addEventListener('touchend', onEndDrag);
      }
    } else if (window.MouseEvent) {
      for (const deviceDisplay of deviceDisplayList) {
        deviceDisplay.addEventListener('mousedown', onStartDrag);
        deviceDisplay.addEventListener('mousemove', onContinueDrag);
        deviceDisplay.addEventListener('mouseup', onEndDrag);
      }
    }
  }

  #sendEventUpdate(ctx, e) {
    let eventType = e.type.substring(0, 5);

    // The <video> element:
    const deviceDisplay = e.target;

    // Before the first video frame arrives there is no way to know width and
    // height of the device's screen, so turn every click into a click at 0x0.
    // A click at that position is not more dangerous than anywhere else since
    // the user is clicking blind anyways.
    const videoWidth = deviceDisplay.videoWidth ? deviceDisplay.videoWidth : 1;
    const videoHeight =
        deviceDisplay.videoHeight ? deviceDisplay.videoHeight : 1;
    const elementWidth =
        deviceDisplay.offsetWidth ? deviceDisplay.offsetWidth : 1;
    const elementHeight =
        deviceDisplay.offsetHeight ? deviceDisplay.offsetHeight : 1;

    // vh*ew > eh*vw? then scale h instead of w
    const scaleHeight = videoHeight * elementWidth > videoWidth * elementHeight;
    let elementScaling = 0, videoScaling = 0;
    if (scaleHeight) {
      elementScaling = elementHeight;
      videoScaling = videoHeight;
    } else {
      elementScaling = elementWidth;
      videoScaling = videoWidth;
    }

    // The screen uses the 'object-fit: cover' property in order to completely
    // fill the element while maintaining the screen content's aspect ratio.
    // Therefore:
    // - If vh*ew > eh*vw, w is scaled so that content width == element width
    // - Otherwise,        h is scaled so that content height == element height
    const scaleWidth = videoHeight * elementWidth > videoWidth * elementHeight;

    // Convert to coordinates relative to the video by scaling.
    // (This matches the scaling used by 'object-fit: cover'.)
    //
    // This scaling is needed to translate from the in-browser x/y to the
    // on-device x/y.
    //   - When the device screen has not been resized, this is simple: scale
    //     the coordinates based on the ratio between the input video size and
    //     the in-browser size.
    //   - When the device screen has been resized, this scaling is still needed
    //     even though the in-browser size and device size are identical. This
    //     is due to the way WindowManager handles a resized screen, resized via
    //     `adb shell wm size`:
    //       - The ABS_X and ABS_Y max values of the screen retain their
    //         original values equal to the value set when launching the device
    //         (which equals the video size here).
    //       - The sent ABS_X and ABS_Y values need to be scaled based on the
    //         ratio between the max size (video size) and in-browser size.
    const scaling =
        scaleWidth ? videoWidth / elementWidth : videoHeight / elementHeight;

    let xArr = [];
    let yArr = [];
    let idArr = [];
    let slotArr = [];

    if (eventType == 'mouse' || eventType == 'point') {
      xArr.push(e.offsetX);
      yArr.push(e.offsetY);

      let thisId = -1;
      if (eventType == 'point') {
        thisId = e.pointerId;
      }

      slotArr.push(0);
      idArr.push(thisId);
    } else if (eventType == 'touch') {
      // touchstart: list of touch points that became active
      // touchmove: list of touch points that changed
      // touchend: list of touch points that were removed
      let changes = e.changedTouches;
      let rect = e.target.getBoundingClientRect();
      for (let i = 0; i < changes.length; i++) {
        xArr.push(changes[i].pageX - rect.left);
        yArr.push(changes[i].pageY - rect.top);
        if (ctx.touchIdSlotMap.has(changes[i].identifier)) {
          let slot = ctx.touchIdSlotMap.get(changes[i].identifier);

          slotArr.push(slot);
          if (e.type == 'touchstart') {
            // error
            console.error('touchstart when already have slot');
            return;
          } else if (e.type == 'touchmove') {
            idArr.push(changes[i].identifier);
          } else if (e.type == 'touchend') {
            ctx.touchSlots[slot] = false;
            ctx.touchIdSlotMap.delete(changes[i].identifier);
            idArr.push(-1);
          }
        } else {
          if (e.type == 'touchstart') {
            let slot = -1;
            for (let j = 0; j < ctx.touchSlots.length; j++) {
              if (!ctx.touchSlots[j]) {
                slot = j;
                break;
              }
            }
            if (slot == -1) {
              slot = ctx.touchSlots.length;
              ctx.touchSlots.push(true);
            }
            slotArr.push(slot);
            ctx.touchSlots[slot] = true;
            ctx.touchIdSlotMap.set(changes[i].identifier, slot);
            idArr.push(changes[i].identifier);
          } else if (e.type == 'touchmove') {
            // error
            console.error('touchmove when no slot');
            return;
          } else if (e.type == 'touchend') {
            // error
            console.error('touchend when no slot');
            return;
          }
        }
      }
    }

    for (let i = 0; i < xArr.length; i++) {
      xArr[i] = xArr[i] * scaling;
      yArr[i] = yArr[i] * scaling;

      // Substract the offset produced by the difference in aspect ratio, if
      // any.
      if (scaleWidth) {
        // Width was scaled, leaving excess content height, so subtract from y.
        yArr[i] -= (elementHeight * scaling - videoHeight) / 2;
      } else {
        // Height was scaled, leaving excess content width, so subtract from x.
        xArr[i] -= (elementWidth * scaling - videoWidth) / 2;
      }

      xArr[i] = Math.trunc(xArr[i]);
      yArr[i] = Math.trunc(yArr[i]);
    }

    // NOTE: Rotation is handled automatically because the CSS rotation through
    // transforms also rotates the coordinates of events on the object.

    const display_label = deviceDisplay.id;

    this.#deviceConnection.sendMultiTouch(
        {idArr, xArr, yArr, down: ctx.down, slotArr, display_label});
  }

  #updateDisplayVisibility(displayId, powerMode) {
    const display = document.getElementById('display_' + displayId).parentElement;
    if (display == null) {
      console.error('Unknown display id: ' + displayId);
      return;
    }
    powerMode = powerMode.toLowerCase();
    switch (powerMode) {
      case 'on':
        display.style.visibility = 'visible';
        break;
      case 'off':
        display.style.visibility = 'hidden';
        break;
      default:
        console.error('Display ' + displayId + ' has unknown display power mode: ' + powerMode);
    }
  }

  #onMicCaptureToggle(enabled) {
    return this.#deviceConnection.useMic(enabled);
  }

  #onCameraCaptureToggle(enabled) {
    return this.#deviceConnection.useCamera(enabled);
  }

  #getZeroPaddedString(value, desiredLength) {
    const s = String(value);
    return '0'.repeat(desiredLength - s.length) + s;
  }

  #getTimestampString() {
    const now = new Date();
    return [
      now.getFullYear(),
      this.#getZeroPaddedString(now.getMonth(), 2),
      this.#getZeroPaddedString(now.getDay(), 2),
      this.#getZeroPaddedString(now.getHours(), 2),
      this.#getZeroPaddedString(now.getMinutes(), 2),
      this.#getZeroPaddedString(now.getSeconds(), 2),
    ].join('_');
  }

  #onVideoCaptureToggle(enabled) {
    const recordToggle = document.getElementById('record-video-control');
    if (enabled) {
      let recorders = [];

      const timestamp = this.#getTimestampString();

      let deviceDisplayVideoList =
        document.getElementsByClassName('device-display-video');
      for (let i = 0; i < deviceDisplayVideoList.length; i++) {
        const deviceDisplayVideo = deviceDisplayVideoList[i];

        const recorder = new MediaRecorder(deviceDisplayVideo.captureStream());
        const recordedData = [];

        recorder.ondataavailable = event => recordedData.push(event.data);
        recorder.onstop = event => {
          const recording = new Blob(recordedData, { type: "video/webm" });

          const downloadLink = document.createElement('a');
          downloadLink.setAttribute('download', timestamp + '_display_' + i + '.webm');
          downloadLink.setAttribute('href', URL.createObjectURL(recording));
          downloadLink.click();
        };

        recorder.start();
        recorders.push(recorder);
      }
      this.#recording['recorders'] = recorders;

      recordToggle.style.backgroundColor = 'red';
    } else {
      for (const recorder of this.#recording['recorders']) {
        recorder.stop();
      }
      recordToggle.style.backgroundColor = '';
    }
    return Promise.resolve(enabled);
  }

  #onAudioPlaybackToggle(enabled) {
    const audioElem = document.getElementById('device-audio');
    if (enabled) {
      audioElem.play();
    } else {
      audioElem.pause();
    }
  }

  #onCustomShellButton(shell_command, e) {
    // Attempt to init adb again, in case the initial connection failed.
    // This succeeds immediately if already connected.
    this.#initializeAdb();
    if (e.type == 'mousedown') {
      adbShell(shell_command);
    }
  }
}  // DeviceControlApp

window.addEventListener("load", async evt => {
  try {
    setupMessages();
    let connectorModule = await import('./server_connector.js');
    let deviceConnection = await ConnectDevice(
        connectorModule.deviceId(), await connectorModule.createConnector());
    let deviceControlApp = new DeviceControlApp(deviceConnection);
    deviceControlApp.start();
    document.getElementById('device-connection').style.display = 'block';
  } catch(err) {
    console.error('Unable to connect: ', err);
    showError(
      'No connection to the guest device. ' +
      'Please ensure the WebRTC process on the host machine is active.');
  }
  document.getElementById('loader').style.display = 'none';
});
