<!DOCTYPE html>
<html>
  <!--
  Copyright (c) 2012 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
  -->
<head>
  <title>Audio Input Example</title>
  <script type="text/javascript">
    var monitor_device_array = [];
    var enumerate_device_array = [];
    var monitor_notification_count = 0;

    function HandleMessage(message_event) {
      if (message_event.data) {
        var status = document.getElementById('status');
        if (message_event.data == 'EnumerationFailed') {
          status.innerText = 'Device enumeration failed!';
        } else if (message_event.data == 'MonitorDeviceChangeFailed') {
          status.innerText = 'Monitor device change failed!';
        } else if (message_event.data == 'OpenFailed') {
          status.innerText = 'Open device failed!';
        } else if (message_event.data == 'StartFailed') {
          status.innerText = 'Start capturing failed!';
        } else if (message_event.data == 'StopFailed') {
          status.innerText = 'Stop capturing failed!';
        } else {
          AddDevices(message_event.data);
        }
      }
    }

    function AddDevices(command) {
      var serialized_names = '';
      var is_monitor = false;
      if (command.search('Monitor:') == 0) {
        serialized_names = command.substr(8);
        is_monitor = true;
        monitor_notification_count++;
        var counter = document.getElementById('notification_counter');
        counter.innerText = monitor_notification_count;
      } else if (command.search('Enumerate:') == 0) {
        serialized_names = command.substr(10);
      } else {
        status.innerText = 'Unrecognized command!';
        return;
      }

      var storage = serialized_names.length != 0 ?
                    serialized_names.split('#__#') : [];
      if (is_monitor)
        monitor_device_array = storage;
      else
        enumerate_device_array = storage;

      var list = document.getElementById(
          is_monitor ? 'monitor_list' : 'enumerate_list');
      while (list.firstChild)
        list.removeChild(list.firstChild);

      for (var i = 0; i < storage.length; ++i) {
        AppendDevice(
            list, storage[i],
            'javascript:UseDesignatedDevice(' + is_monitor + ',' + i + ');');
      }
    }

    function AppendDevice(list, text, href) {
      var list_item = document.createElement('li');
      var link = document.createElement('a');
      link.href = href;
      link.innerText = text;
      list_item.appendChild(link);
      list.appendChild(list_item);
    }

    function UseDesignatedDevice(is_monitor, index) {
      if (is_monitor)
        UseDevice(monitor_device_array[index], 'Monitor:' + index);
      else
        UseDevice(enumerate_device_array[index], 'Enumerate:' + index);
    }

    function UseDefaultDevice() {
      UseDevice('Default', 'UseDefault');
    }

    function UseDevice(display_text, command) {
      var in_use_device = document.getElementById('in_use_device');
      in_use_device.innerText = display_text;
      var plugin = document.getElementById('plugin');
      plugin.postMessage(command);
    }

    function Stop() {
      var plugin = document.getElementById('plugin');
      plugin.postMessage('Stop');
    }

    function Start() {
      var plugin = document.getElementById('plugin');
      plugin.postMessage('Start');
    }

    function Initialize() {
      var plugin = document.getElementById('plugin');
      plugin.addEventListener('message', HandleMessage, false)
      plugin.postMessage('PageInitialized');
    }

    document.addEventListener('DOMContentLoaded', Initialize, false);
  </script>
</head>

<body>
  <embed id="plugin" type="application/x-ppapi-example-audio-input"
      width="800" height="400"/>
  <div style="margin-bottom:10px">In-use device:
    <span id="in_use_device" style="font-weight:bold">None</span>
  </div>
  <div id="available_devices">
    Available device(s), choose one to open:
    <ul>
      <li><a href="javascript:UseDefaultDevice();">
          Default - use NULL device ref</a></li>
    </ul>
    <div>
      <ul>List retrieved by MonitorDeviceChange(), will change when
          pluging/unpluging devices: (Notifications received:
          <span style="font-weight:bold" id="notification_counter">0</span>
          )</ul>
      <ul id="monitor_list"/>
    </div>
    <div>
      <ul>List retrieved by EnumerateDevices(), never updated after the page is
          initialized:</ul>
      <ul id="enumerate_list"/>
    </div>
  </div>
  <div id="control_panel">
    <a href="javascript:Stop();">Stop</a>
    <a href="javascript:Start();">Start</a> (known issue: crbug.com/161058)
  </div>
  <div id="status"></div>
</body>
</html>
