<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

<!--
Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.

Use of this source code is governed by a BSD-style license
that can be found in the LICENSE file in the root of the source
tree. An additional intellectual property rights grant can be found
in the file PATENTS. All contributing project authors may
be found in the AUTHORS file in the root of the source tree.
-->

<html>

<head>
<title>WebRTC Test</title>

<style type="text/css">
body, input, button, select, table {
  font-family:"Lucida Grande", "Lucida Sans", Verdana, Arial, sans-serif;
  font-size: 13 px;
}
body, input:enable, button:enable, select:enable, table {
  color: rgb(51, 51, 51);
}
h1 {font-size: 40 px;}
</style>

<script type="text/javascript">

// TODO: Catch more exceptions

var server;
var myId = -1;
var myName;
var remoteId = -1;
var remoteName;
var request = null;
var hangingGet = null;
var pc = null;
var localStream = null;
var disconnecting = false;
var callState = 0; // 0 - Not started, 1 - Call ongoing


// General

function toggleExtraButtons() {
  document.getElementById("createPcBtn").hidden =
    !document.getElementById("createPcBtn").hidden;
  document.getElementById("test1Btn").hidden =
    !document.getElementById("test1Btn").hidden;
}

function trace(txt) {
  var elem = document.getElementById("debug");
  elem.innerHTML += txt + "<br>";
}

function trace_warning(txt) {
  var wtxt = "<b>" + txt + "</b>";
  trace(wtxt);
}

function trace_exception(e, txt) {
  var etxt = "<b>" + txt + "</b> (" + e.name + " / " + e.message + ")";
  trace(etxt);
}

function setCallState(state) {
  trace("Changing call state: " + callState + " -> " + state);
  callState = state;
}

function checkPeerConnection() {
  if (!pc) {
    trace_warning("No PeerConnection object exists");
    return 0;
  }
  return 1;
}


// Local stream generation

function gotStream(s) {
  var url = webkitURL.createObjectURL(s);
  document.getElementById("localView").src = url;
  trace("User has granted access to local media. url = " + url);
  localStream = s;
}

function gotStreamFailed(error) {
  alert("Failed to get access to local media. Error code was " + error.code +
    ".");
  trace_warning("Failed to get access to local media. Error code was " +
    error.code);
}

function getUserMedia() {
  try {
    navigator.webkitGetUserMedia("video,audio", gotStream, gotStreamFailed);
    trace("Requested access to local media");
  } catch (e) {
    trace_exception(e, "getUserMedia error");
  }
}


// Peer list and remote peer handling

function peerExists(id) {
  try {
    var peerList = document.getElementById("peers");
    for (var i = 0; i < peerList.length; i++) {
      if (parseInt(peerList.options[i].value) == id)
        return true;
    }
  } catch (e) {
    trace_exception(e, "Error searching for peer");
  }
  return false;
}

function addPeer(id, pname) {
  var peerList = document.getElementById("peers");
  var option = document.createElement("option");
  option.text = pname;
  option.value = id;
  try {
    // For IE earlier than version 8
    peerList.add(option, x.options[null]);
  } catch (e) {
    peerList.add(option, null);
  }
}

function removePeer(id) {
  try {
    var peerList = document.getElementById("peers");
    for (var i = 0; i < peerList.length; i++) {
      if (parseInt(peerList.options[i].value) == id) {
        peerList.remove(i);
        break;
      }
    }
  } catch (e) {
    trace_exception(e, "Error removing peer");
  }
}

function clearPeerList() {
  var peerList = document.getElementById("peers");
  while (peerList.length > 0)
    peerList.remove(0);
}

function setSelectedPeer(id) {
  try {
    var peerList = document.getElementById("peers");
    for (var i = 0; i < peerList.length; i++) {
      if (parseInt(peerList.options[i].value) == id) {
        peerList.options[i].selected = true;
        return true;
      }
    }
  } catch (e) {
    trace_exception(e, "Error setting selected peer");
  }
  return false;
}

function getPeerName(id) {
  try {
    var peerList = document.getElementById("peers");
    for (var i = 0; i < peerList.length; i++) {
      if (parseInt(peerList.options[i].value) == id) {
        return peerList.options[i].text;
      }
    }
  } catch (e) {
    trace_exception(e, "Error finding peer name");
    return;
  }
  return;
}

function storeRemoteInfo() {
  try {
    var peerList = document.getElementById("peers");
    if (peerList.selectedIndex < 0) {
      alert("Please select a peer.");
      return false;
    } else
      remoteId = parseInt(peerList.options[peerList.selectedIndex].value);
      remoteName = peerList.options[peerList.selectedIndex].text;
  } catch (e) {
    trace_exception(e, "Error storing remote peer info");
    return false;
  }
  return true;
}


// Call control

function createPeerConnection() {
  if (pc) {
    trace_warning("PeerConnection object already exists");
  }
  trace("Creating PeerConnection object");
  try {
    pc = new webkitPeerConnection("STUN stun.l.google.com:19302",
      onSignalingMessage);
  pc.onaddstream = onAddStream;
  pc.onremovestream = onRemoveStream;
  } catch (e) {
    trace_exception(e, "Create PeerConnection error");
  }
}

function doCall() {
  if (!storeRemoteInfo())
    return;
  document.getElementById("call").disabled = true;
  document.getElementById("peers").disabled = true;
  createPeerConnection();
  trace("Adding stream");
  pc.addStream(localStream);
  document.getElementById("hangup").disabled = false;
  setCallState(1);
}

function hangUp() {
  document.getElementById("hangup").disabled = true;
  trace("Sending BYE to " + remoteName + " (ID " + remoteId + ")");
  sendToPeer(remoteId, "BYE");
  closeCall();
}

function closeCall() {
  trace("Stopping showing remote stream");
  document.getElementById("remoteView").src = "dummy";
  if (pc) {
    trace("Stopping call [pc.close()]");
    pc.close();
    pc = null;
  } else
    trace("No pc object to close");
  remoteId = -1;
  document.getElementById("call").disabled = false;
  document.getElementById("peers").disabled = false;
  setCallState(0);
}


// PeerConnection callbacks

function onAddStream(e) {
  var stream = e.stream;
  var url = webkitURL.createObjectURL(stream);
  document.getElementById("remoteView").src = url;
  trace("Started showing remote stream. url = " + url);
}

function onRemoveStream(e) {
  // Currently if we get this callback, call has ended.
  document.getElementById("remoteView").src = "";
  trace("Stopped showing remote stream");
}

function onSignalingMessage(msg) {
  trace("Sending message to " + remoteName + " (ID " + remoteId + "):\n" + msg);
  sendToPeer(remoteId, msg);
}

// TODO: Add callbacks onconnecting, onopen and onstatechange.


// Server interaction

function handleServerNotification(data) {
  trace("Server notification: " + data);
  var parsed = data.split(",");
  if (parseInt(parsed[2]) == 1) { // New peer
    var peerId = parseInt(parsed[1]);
    if (!peerExists(peerId)) {
      var peerList = document.getElementById("peers");
      if (peerList.length == 1 && peerList.options[0].value == -1)
        clearPeerList();
      addPeer(peerId, parsed[0]);
      document.getElementById("peers").disabled = false;
      document.getElementById("call").disabled = false;
    }
  } else if (parseInt(parsed[2]) == 0) { // Removed peer
    removePeer(parseInt(parsed[1]));
    if (document.getElementById("peers").length == 0) {
      document.getElementById("peers").disabled = true;
      addPeer(-1, "No other peer connected");
    }
  }
}

function handlePeerMessage(peer_id, msg) {
  var peerName = getPeerName(peer_id);
  if (peerName == undefined) {
    trace_warning("Received message from unknown peer (ID " + peer_id +
      "), ignoring message:");
    trace(msg);
    return;
  }
  trace("Received message from " + peerName + " (ID " + peer_id + "):\n" + msg);
  // Assuming we receive the message from the peer we want to communicate with.
  // TODO: Only accept messages from peer we communicate with with if call is
  // ongoing.
  if (msg.search("BYE") == 0) {
    // Other side has hung up.
    document.getElementById("hangup").disabled = true;
    closeCall()
  } else {
    if (!pc) {
      // Other side is calling us, startup
      if (!setSelectedPeer(peer_id)) {
        trace_warning("Recevied message from unknown peer, ignoring");
        return;
      }
      if (!storeRemoteInfo())
        return;
      document.getElementById("call").disabled = true;
      document.getElementById("peers").disabled = true;
      createPeerConnection();
      try {
        pc.processSignalingMessage(msg);
      } catch (e) {
        trace_exception(e, "Process signaling message error");
      }
      trace("Adding stream");
      pc.addStream(localStream);
      document.getElementById("hangup").disabled = false;
    } else {
      try {
        pc.processSignalingMessage(msg);
      } catch (e) {
        trace_exception(e, "Process signaling message error");
      }
    }
  }
}

function getIntHeader(r, name) {
  var val = r.getResponseHeader(name);
  trace("header value: " + val);
  return val != null && val.length ? parseInt(val) : -1;
}

function hangingGetCallback() {
  try {
    if (hangingGet.readyState != 4 || disconnecting)
      return;
    if (hangingGet.status != 200) {
      trace_warning("server error, status: " + hangingGet.status + ", text: " +
        hangingGet.statusText);
      disconnect();
    } else {
      var peer_id = getIntHeader(hangingGet, "Pragma");
      if (peer_id == myId) {
        handleServerNotification(hangingGet.responseText);
      } else {
        handlePeerMessage(peer_id, hangingGet.responseText);
      }
    }

    if (hangingGet) {
      hangingGet.abort();
      hangingGet = null;
    }

    if (myId != -1)
      window.setTimeout(startHangingGet, 0);
  } catch (e) {
    trace_exception(e, "Hanging get error");
  }
}

function onHangingGetTimeout() {
  trace("hanging get timeout. issuing again");
  hangingGet.abort();
  hangingGet = null;
  if (myId != -1)
    window.setTimeout(startHangingGet, 0);
}

function startHangingGet() {
  try {
    hangingGet = new XMLHttpRequest();
    hangingGet.onreadystatechange = hangingGetCallback;
    hangingGet.ontimeout = onHangingGetTimeout;
    hangingGet.open("GET", server + "/wait?peer_id=" + myId, true);
    hangingGet.send();  
  } catch (e) {
    trace_exception(e, "Start hanging get error");
  }
}

function sendToPeer(peer_id, data) {
  if (myId == -1) {
    alert("Not connected.");
    return;
  }
  if (peer_id == myId) {
    alert("Can't send a message to oneself.");
    return;
  }
  var r = new XMLHttpRequest();
  r.open("POST", server + "/message?peer_id=" + myId + "&to=" + peer_id, false);
  r.setRequestHeader("Content-Type", "text/plain");
  r.send(data);
  r = null;
}

function signInCallback() {
  try {
    if (request.readyState == 4) {
      if (request.status == 200) {
        var peers = request.responseText.split("\n");
        myId = parseInt(peers[0].split(",")[1]);
        trace("My id: " + myId);
        clearPeerList();
        var added = 0;
        for (var i = 1; i < peers.length; ++i) {
          if (peers[i].length > 0) {
            trace("Peer " + i + ": " + peers[i]);
            var parsed = peers[i].split(",");
            addPeer(parseInt(parsed[1]), parsed[0]);
            ++added;
          }
        }
        if (added == 0)
          addPeer(-1, "No other peer connected");
        else {
          document.getElementById("peers").disabled = false;
          document.getElementById("call").disabled = false;
        }
        startHangingGet();
        request = null;
        document.getElementById("connect").disabled = true;
        document.getElementById("disconnect").disabled = false;
      }
    }
  } catch (e) {
    trace_exception(e, "Sign in error");
    document.getElementById("connect").disabled = false;
  }
}

function signIn() {
  try {
    request = new XMLHttpRequest();
    request.onreadystatechange = signInCallback;
    request.open("GET", server + "/sign_in?" + myName, true);
    request.send();
  } catch (e) {
    trace_exception(e, "Start sign in error");
    document.getElementById("connect").disabled = false;
  }
}

function connect() {
  myName = document.getElementById("local").value.toLowerCase();
  server = document.getElementById("server").value.toLowerCase();
  if (myName.length == 0) {
    alert("I need a name please.");
    document.getElementById("local").focus();
  } else {
    // TODO: Disable connect button here, but we need a timeout and check if we
    // have connected, if so enable it again.
    signIn();
  }
}

function disconnect() {
  if (callState == 1)
    hangUp();

  disconnecting = true;
  
  if (request) {
    request.abort();
    request = null;
  }

  if (hangingGet) {
    hangingGet.abort();
    hangingGet = null;
  }

  if (myId != -1) {
    request = new XMLHttpRequest();
    request.open("GET", server + "/sign_out?peer_id=" + myId, false);
    request.send();
    request = null;
    myId = -1;
  }

  clearPeerList();
  addPeer(-1, "Not connected");
  document.getElementById("connect").disabled = false;
  document.getElementById("disconnect").disabled = true;
  document.getElementById("peers").disabled = true;
  document.getElementById("call").disabled = true;

  disconnecting = false;
}


// Window event handling

window.onload = getUserMedia;
window.onbeforeunload = disconnect;


</script>
</head>

<body>
<h1>WebRTC</h1>
You must have a WebRTC capable browser in order to make calls using this test
page.<br>&nbsp;

<table border="0">
<tr>
 <td>Local Preview</td>
 <td>Remote Video</td>
</tr>
<tr>
 <td>
  <video width="320" height="240" id="localView" autoplay="autoplay"></video>
 </td>
 <td>
  <video width="640" height="480" id="remoteView" autoplay="autoplay"></video>
 </td>
</tr>
</table>

<table border="0">
<tr>
 <td valign="top">
  <table border="0" cellpaddning="0" cellspacing="0">
  <tr>
   <td>Server:</td>
   <td>
    <input type="text" id="server" size="30" value="http://localhost:8888"/>
   </td>
  </tr>
  <tr>
   <td>Name:</td><td><input type="text" id="local" size="30" value="name"/></td>
  </tr>
  </table>
 </td>
 <td valign="top">
  <button id="connect" onclick="connect();">Connect</button><br>
  <button id="disconnect" onclick="disconnect();" disabled="true">Disconnect
  </button>
 </td>
 <td>&nbsp;&nbsp;&nbsp;</td>
 <td valign="top">
  Connected peers:<br>
  <select id="peers" size="5" disabled="true">
   <option value="-1">Not connected</option>
  </select>
  </td>
 <td valign="top">
  <!--input type="text" id="peer_id" size="3" value="1"/><br-->
  <button id="call" onclick="doCall();" disabled="true">Call</button><br>
  <button id="hangup" onclick="hangUp();" disabled="true">Hang up</button><br>
 </td>
 <td>&nbsp;&nbsp;&nbsp;</td>
 <td valign="top">
  <button onclick="toggleExtraButtons();">Toggle extra buttons (debug)</button>
  <br>
  <button id="createPcBtn" onclick="createPeerConnection();" hidden="true">
  Create peer connection</button>
 </td>
</tr>
</table>

<button onclick="document.getElementById('debug').innerHTML='';">Clear log
</button>
<pre id="debug"></pre>

</body>

</html>

