<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You 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.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title>Apache Tomcat WebSocket Examples: Drawboard</title>
    <style type="text/css"><![CDATA[

        body {
            font-family: Arial, sans-serif;
            font-size: 11pt;
            background-color: #eeeeea;
            padding: 10px;
        }

        #console-container {
            float: left;
            background-color: #fff;
            width: 250px;
        }

        #console {
            font-size: 10pt;
            height: 600px;
            overflow-y: scroll;
            padding-left: 5px;
            padding-right: 5px;
        }

        #console p {
            padding: 0;
            margin: 0;
        }

        #drawContainer {
            float: left;
            display: none;
            margin-right: 25px;
        }

        #drawContainer canvas {
            display: block;
            -ms-touch-action: none;
            touch-action: none; /* Disable touch behaviors, like pan and zoom */
            cursor: crosshair;
        }

        #labelContainer {
            margin-bottom: 15px;
        }

        #drawContainer, #console-container {
            box-shadow: 0px 0px 8px 3px #bbb;
            border: 1px solid #CCCCCC;
        }

    ]]></style>
    <script type="application/javascript"><![CDATA[
    "use strict";

    (function() {

        document.addEventListener("DOMContentLoaded", function() {
            // Remove elements with "noscript" class - <noscript> is not
            // allowed in XHTML
            var noscripts = document.getElementsByClassName("noscript");
            for (var i = 0; i < noscripts.length; i++) {
                noscripts[i].parentNode.removeChild(noscripts[i]);
            }

            // Add script for expand content.
            var expandElements = document.getElementsByClassName("expand");
            for (var ixx = 0; ixx < expandElements.length; ixx++) {
                (function(el) {
                    var expandContent = document.getElementById(el.getAttribute("data-content-id"));
                    expandContent.style.display = "none";
                    var arrow = document.createTextNode("◢ ");
                    var arrowSpan = document.createElement("span");
                    arrowSpan.appendChild(arrow);

                    var link = document.createElement("a");
                    link.setAttribute("href", "#!");
                    while (el.firstChild != null) {
                        link.appendChild(el.removeChild(el.firstChild));
                    }
                    el.appendChild(arrowSpan);
                    el.appendChild(link);

                    var textSpan = document.createElement("span");
                    textSpan.setAttribute("style", "font-weight: normal;");
                    textSpan.appendChild(document.createTextNode(" (click to expand)"));
                    el.appendChild(textSpan);


                    var visible = true;

                    var switchExpand = function() {
                        visible = !visible;
                        expandContent.style.display = visible ? "block" : "none";
                        arrowSpan.style.color = visible ? "#000" : "#888";
                        return false;
                    };

                    link.onclick = switchExpand;
                    switchExpand();

                })(expandElements[ixx]);
            }


            var Console = {};

            Console.log = (function() {
                var consoleContainer =
                    document.getElementById("console-container");
                var console = document.createElement("div");
                console.setAttribute("id", "console");
                consoleContainer.appendChild(console);

                return function(message) {
                    var p = document.createElement('p');
                    p.style.wordWrap = "break-word";
                    p.appendChild(document.createTextNode(message));
                    console.appendChild(p);
                    while (console.childNodes.length > 25) {
                        console.removeChild(console.firstChild);
                    }
                    console.scrollTop = console.scrollHeight;
                }
            })();


            function Room(drawContainer) {

                /* A pausable event forwarder that can be used to pause and
                 * resume handling of events (e.g. when we need to wait
                 * for a Image's load event before we can process further
                 * WebSocket messages).
                 * The object's callFunction(func) should be called from an
                 * event handler and give the function to handle the event as
                 * argument.
                 * Call pauseProcessing() to suspend event forwarding and
                 * resumeProcessing() to resume it.
                 */
                function PausableEventForwarder() {

                    var pauseProcessing = false;
                    // Queue for buffering functions to be called.
                    var functionQueue = [];

                    this.callFunction = function(func) {
                        // If message processing is paused, we push it
                        // into the queue - otherwise we process it directly.
                        if (pauseProcessing) {
                            functionQueue.push(func);
                        } else {
                            func();
                        }
                    };

                    this.pauseProcessing = function() {
                        pauseProcessing = true;
                    };

                    this.resumeProcessing = function() {
                        pauseProcessing = false;

                        // Process all queued functions until some handler calls
                        // pauseProcessing() again.
                        while (functionQueue.length > 0 && !pauseProcessing) {
                            var func = functionQueue.pop();
                            func();
                        }
                    };
                }

                // The WebSocket object.
                var socket;
                // ID of the timer which sends ping messages.
                var pingTimerId;

                var isStarted = false;
                var playerCount = 0;

                // An array of PathIdContainer objects that the server
                // did not yet handle.
                // They are ordered by id (ascending).
                var pathsNotHandled = [];

                var nextMsgId = 1;

                var canvasDisplay = document.createElement("canvas");
                var canvasBackground = document.createElement("canvas");
                var canvasServerImage = document.createElement("canvas");
                var canvasArray = [canvasDisplay, canvasBackground,
                    canvasServerImage];
                canvasDisplay.addEventListener("mousedown", function(e) {
                    // Prevent default mouse event to prevent browsers from marking text
                    // (and Chrome from displaying the "text" cursor).
                    e.preventDefault();
                }, false);

                var labelPlayerCount = document.createTextNode("0");
                var optionContainer = document.createElement("div");


                var canvasDisplayCtx = canvasDisplay.getContext("2d");
                var canvasBackgroundCtx = canvasBackground.getContext("2d");
                var canvasServerImageCtx = canvasServerImage.getContext("2d");
                var canvasMouseMoveHandler;
                var canvasMouseDownHandler;

                var isActive = false;
                var mouseInWindow = false;
                var mouseDown = false;
                var currentMouseX = 0, currentMouseY = 0;
                var currentPreviewPath = null;

                var availableColors = [];
                var currentColorIndex;
                var colorContainers;
                var previewTransparency = 0.65;

                var availableThicknesses = [2, 3, 6, 10, 16, 28, 50];
                var currentThicknessIndex;
                var thicknessContainers;

                var availableDrawTypes = [
                           { name: "Brush", id: 1, continuous: true },
                           { name: "Line", id: 2, continuous: false },
                           { name: "Rectangle", id: 3, continuous: false },
                           { name: "Ellipse", id: 4, continuous: false }
                ];
                var currentDrawTypeIndex;
                var drawTypeContainers;


                var labelContainer = document.getElementById("labelContainer");
                var placeholder = document.createElement("div");
                placeholder.appendChild(document.createTextNode("Loading... "));
                var progressElem = document.createElement("progress");
                placeholder.appendChild(progressElem);

                labelContainer.appendChild(placeholder);

                function rgb(color) {
                       return "rgba(" + color[0] + "," + color[1] + ","
                               + color[2] + "," + color[3] + ")";
                   }

                function PathIdContainer(path, id) {
                    this.path = path;
                    this.id = id;
                }

                function Path(type, color, thickness, x1, y1, x2, y2, lastInChain) {
                    this.type = type;
                    this.color = color;
                    this.thickness = thickness;
                    this.x1 = x1;
                    this.y1 = y1;
                    this.x2 = x2;
                    this.y2 = y2;
                    this.lastInChain = lastInChain;

                    function ellipse(ctx, x, y, w, h) {
                        /* Drawing a ellipse cannot be done directly in a
                         * CanvasRenderingContext2D - we need to use drawArc()
                         * in conjunction with scaling the context so that we
                         * get the needed proportion.
                         */
                        ctx.save();

                        // Translate and scale the context so that we can draw
                        // an arc at (0, 0) with a radius of 1.
                        ctx.translate(x + w / 2, y + h / 2);
                        ctx.scale(w / 2, h / 2);

                        ctx.beginPath();
                        ctx.arc(0, 0, 1, 0, Math.PI * 2, false);

                        ctx.restore();
                    }

                    this.draw = function(ctx) {
                        ctx.beginPath();
                        ctx.lineCap = "round";
                        ctx.lineWidth = thickness;
                        var style = rgb(color);
                        ctx.strokeStyle = style;

                        if (x1 == x2 && y1 == y2) {
                            // Always draw as arc to meet the behavior
                            // in Java2D.
                            ctx.fillStyle = style;
                            ctx.arc(x1, y1, thickness / 2.0, 0,
                                    Math.PI * 2.0, false);
                            ctx.fill();
                        } else {
                            if (type == 1 || type == 2) {
                                // Draw a line.
                                ctx.moveTo(x1, y1);
                                ctx.lineTo(x2, y2);
                                ctx.stroke();
                            } else if (type == 3) {
                                // Draw a rectangle.
                                if (x1 == x2 || y1 == y2) {
                                    // Draw as line
                                    ctx.moveTo(x1, y1);
                                    ctx.lineTo(x2, y2);
                                    ctx.stroke();
                                } else {
                                    ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
                                }
                            } else if (type == 4) {
                                // Draw a ellipse.
                                ellipse(ctx, x1, y1, x2 - x1, y2 - y1);
                                ctx.closePath();
                                ctx.stroke();
                            }
                        }
                    };
                }


                function connect() {
                    var host = (window.location.protocol == "https:"
                            ? "wss://" : "ws://") + window.location.host
                            + "/examples/websocket/drawboard";
                    socket = new WebSocket(host);

                    /* Use a pausable event forwarder.
                     * This is needed when we load an Image object with data
                     * from a previous message, because we must wait until the
                     * Image's load event it raised before we can use it (and
                     * in the meantime the socket.message event could be
                     * raised).
                     * Therefore we need this pausable event handler to handle
                     * e.g. socket.onmessage and socket.onclose.
                     */
                    var eventForwarder = new PausableEventForwarder();

                    socket.onopen = function () {
                        // Socket has opened. Now wait for the server to
                        // send us the initial packet.
                        Console.log("WebSocket connection opened.");

                        // Set up a timer for pong messages.
                        pingTimerId = window.setInterval(function() {
                            socket.send("0");
                        }, 30000);
                    };

                    socket.onclose = function () {
                        eventForwarder.callFunction(function() {
                            Console.log("WebSocket connection closed.");
                            disableControls();

                            // Disable pong timer.
                            window.clearInterval(pingTimerId);
                        });
                    };

                    // Handles an incoming Websocket message.
                    var handleOnMessage = function(message) {

                        // Split joined message and process them
                        // individually.
                        var messages = message.data.split(";");
                        for (var msgArrIdx = 0; msgArrIdx < messages.length;
                                msgArrIdx++) {
                            var msg = messages[msgArrIdx];
                            var type = msg.substring(0, 1);

                            if (type == "0") {
                                // Error message.
                                var error = msg.substring(1);
                                // Log it to the console and show an alert.
                                Console.log("Error: " + error);
                                alert(error);

                            } else {
                                if (!isStarted) {
                                    if (type == "2") {
                                        // Initial message. It contains the
                                        // number of players.
                                        // After this message we will receive
                                        // a binary message containing the current
                                        // room image as PNG.
                                        playerCount = parseInt(msg.substring(1));

                                        refreshPlayerCount();

                                        // The next message will be a binary
                                        // message containing the room images
                                        // as PNG. Therefore we temporarily swap
                                        // the message handler.
                                        var originalHandler = handleOnMessage;
                                        handleOnMessage = function(message) {
                                            // First, we restore the original handler.
                                            handleOnMessage = originalHandler;

                                            // Read the image.
                                            var blob = message.data;
                                            // Create new blob with correct MIME type.
                                            blob = new Blob([blob], {type : "image/png"});

                                            var url = URL.createObjectURL(blob);

                                            var img = new Image();

                                            // We must wait until the onload event is
                                            // raised until we can draw the image onto
                                            // the canvas.
                                            // Therefore we need to pause the event
                                            // forwarder until the image is loaded.
                                            eventForwarder.pauseProcessing();

                                            img.onload = function() {

                                                // Release the object URL.
                                                URL.revokeObjectURL(url);

                                                // Set the canvases to the correct size.
                                                for (var i = 0; i < canvasArray.length; i++) {
                                                    canvasArray[i].width = img.width;
                                                    canvasArray[i].height = img.height;
                                                }

                                                // Now draw the image on the last canvas.
                                                canvasServerImageCtx.clearRect(0, 0,
                                                        canvasServerImage.width,
                                                        canvasServerImage.height);
                                                canvasServerImageCtx.drawImage(img, 0, 0);

                                                // Draw it on the background canvas.
                                                canvasBackgroundCtx.drawImage(canvasServerImage,
                                                        0, 0);

                                                isStarted = true;
                                                startControls();

                                                // Refresh the display canvas.
                                                refreshDisplayCanvas();


                                                // Finally, resume the event forwarder.
                                                eventForwarder.resumeProcessing();
                                            };

                                            img.src = url;
                                        };
                                    }
                                } else {
                                    if (type == "3") {
                                        // The number of players in this room changed.
                                        var playerAdded = msg.substring(1) == "+";
                                        playerCount += playerAdded ? 1 : -1;
                                        refreshPlayerCount();

                                        Console.log("Player " + (playerAdded
                                                ? "joined." : "left."));

                                    } else if (type == "1") {
                                        // We received a new DrawMessage.
                                        var maxLastHandledId = -1;
                                        var drawMessages = msg.substring(1).split("|");
                                        for (var i = 0; i < drawMessages.length; i++) {
                                            var elements = drawMessages[i].split(",");
                                            var lastHandledId = parseInt(elements[0]);
                                               maxLastHandledId = Math.max(maxLastHandledId,
                                                       lastHandledId);

                                            var path = new Path(
                                                    parseInt(elements[1]),
                                                    [parseInt(elements[2]),
                                                    parseInt(elements[3]),
                                                    parseInt(elements[4]),
                                                    parseInt(elements[5]) / 255.0],
                                                    parseFloat(elements[6]),
                                                    parseFloat(elements[7]),
                                                    parseFloat(elements[8]),
                                                    parseFloat(elements[9]),
                                                    parseFloat(elements[10]),
                                                    elements[11] != "0");

                                            // Draw the path onto the last canvas.
                                            path.draw(canvasServerImageCtx);
                                        }

                                        // Draw the last canvas onto the background one.
                                        canvasBackgroundCtx.drawImage(canvasServerImage,
                                                0, 0);

                                        // Now go through the pathsNotHandled array and
                                        // remove the paths that were already handled by
                                        // the server.
                                        while (pathsNotHandled.length > 0
                                                && pathsNotHandled[0].id <= maxLastHandledId)
                                            pathsNotHandled.shift();

                                        // Now me must draw the remaining paths onto
                                        // the background canvas.
                                        for (var i = 0; i < pathsNotHandled.length; i++) {
                                            pathsNotHandled[i].path.draw(canvasBackgroundCtx);
                                        }

                                        refreshDisplayCanvas();
                                    }
                                }
                            }
                        }
                    };

                    socket.onmessage = function(message) {
                        eventForwarder.callFunction(function() {
                            handleOnMessage(message);
                        });
                    };

                }


                function refreshPlayerCount() {
                    labelPlayerCount.nodeValue = String(playerCount);
                }

                function refreshDisplayCanvas() {
                    if (!isActive) { // Don't draw a curser when not active.
                        return;
                    }

                    canvasDisplayCtx.drawImage(canvasBackground, 0, 0);
                    if (currentPreviewPath != null) {
                        // Draw the preview path.
                        currentPreviewPath.draw(canvasDisplayCtx);

                    } else if (mouseInWindow && !mouseDown) {
                        canvasDisplayCtx.beginPath();
                        var color = availableColors[currentColorIndex].slice(0);
                        color[3] = previewTransparency;
                        canvasDisplayCtx.fillStyle = rgb(color);

                        canvasDisplayCtx.arc(currentMouseX, currentMouseY,
                                availableThicknesses[currentThicknessIndex] / 2,
                                0, Math.PI * 2.0, true);
                        canvasDisplayCtx.fill();
                    }

                }

                function startControls() {
                    isActive = true;

                    labelContainer.removeChild(placeholder);
                    placeholder = undefined;

                    labelContainer.appendChild(
                            document.createTextNode("Number of Players: "));
                    labelContainer.appendChild(labelPlayerCount);


                    drawContainer.style.display = "block";
                    drawContainer.appendChild(canvasDisplay);

                    drawContainer.appendChild(optionContainer);

                    canvasMouseDownHandler = function(e) {
                        if (e.button == 0) {
                            currentMouseX = e.pageX - canvasDisplay.offsetLeft;
                            currentMouseY = e.pageY - canvasDisplay.offsetTop;

                            mouseDown = true;
                            canvasMouseMoveHandler(e);

                        } else if (mouseDown) {
                            // Cancel drawing.
                            mouseDown = false;
                            currentPreviewPath = null;

                            currentMouseX = e.pageX - canvasDisplay.offsetLeft;
                            currentMouseY = e.pageY - canvasDisplay.offsetTop;

                            refreshDisplayCanvas();
                        }
                    };
                    canvasDisplay.addEventListener("mousedown", canvasMouseDownHandler, false);

                    canvasMouseMoveHandler = function(e) {
                        var mouseX = e.pageX - canvasDisplay.offsetLeft;
                        var mouseY = e.pageY - canvasDisplay.offsetTop;

                        if (mouseDown) {
                            var drawType = availableDrawTypes[currentDrawTypeIndex];

                            if (drawType.continuous) {

                                var path = new Path(drawType.id,
                                        availableColors[currentColorIndex],
                                        availableThicknesses[currentThicknessIndex],
                                        currentMouseX, currentMouseY, mouseX,
                                        mouseY, false);
                                // Draw it on the background canvas.
                                path.draw(canvasBackgroundCtx);

                                // Send it to the sever.
                                pushPath(path);

                                // Refresh old coordinates
                                currentMouseX = mouseX;
                                currentMouseY = mouseY;

                            } else {
                                // Create a new preview path.
                                var color = availableColors[currentColorIndex].slice(0);
                                color[3] = previewTransparency;
                                currentPreviewPath = new Path(drawType.id,
                                        color,
                                        availableThicknesses[currentThicknessIndex],
                                        currentMouseX, currentMouseY, mouseX,
                                        mouseY, false);
                            }

                            refreshDisplayCanvas();
                        } else {
                            currentMouseX = mouseX;
                            currentMouseY = mouseY;

                            if (mouseInWindow) {
                                refreshDisplayCanvas();
                            }
                        }

                    };
                    document.addEventListener("mousemove", canvasMouseMoveHandler, false);

                    document.addEventListener("mouseup", function(e) {
                        if (e.button == 0) {
                            if (mouseDown) {
                                mouseDown = false;
                                currentPreviewPath = null;

                                var mouseX = e.pageX - canvasDisplay.offsetLeft;
                                var mouseY = e.pageY - canvasDisplay.offsetTop;
                                var drawType = availableDrawTypes[currentDrawTypeIndex];

                                var path = new Path(drawType.id, availableColors[currentColorIndex],
                                        availableThicknesses[currentThicknessIndex],
                                        currentMouseX, currentMouseY, mouseX,
                                        mouseY, true);
                                // Draw it on the background canvas.
                                path.draw(canvasBackgroundCtx);

                                // Send it to the sever.
                                pushPath(path);

                                // Refresh old coordinates
                                currentMouseX = mouseX;
                                currentMouseY = mouseY;

                                refreshDisplayCanvas();
                            }
                        }
                    }, false);

                    canvasDisplay.addEventListener("mouseout", function(e) {
                        mouseInWindow = false;
                        refreshDisplayCanvas();
                    }, false);

                    canvasDisplay.addEventListener("mousemove", function(e) {
                        if (!mouseInWindow) {
                            mouseInWindow = true;
                            refreshDisplayCanvas();
                        }
                    }, false);


                    // Create color and thickness controls.
                    var colorContainersBox = document.createElement("div");
                    colorContainersBox.setAttribute("style",
                            "margin: 4px; border: 1px solid #bbb; border-radius: 3px;");
                    optionContainer.appendChild(colorContainersBox);

                    colorContainers = new Array(3 * 3 * 3);
                    for (var i = 0; i < colorContainers.length; i++) {
                        var colorContainer = colorContainers[i] =
                            document.createElement("div");
                        var color = availableColors[i] =
                            [
                                Math.floor((i % 3) * 255 / 2),
                                Math.floor((Math.floor(i / 3) % 3) * 255 / 2),
                                Math.floor((Math.floor(i / (3 * 3)) % 3) * 255 / 2),
                                1.0
                            ];
                        colorContainer.setAttribute("style",
                                "margin: 3px; width: 18px; height: 18px; "
                                + "float: left; background-color: " + rgb(color));
                        colorContainer.style.border = '2px solid #000';
                        colorContainer.addEventListener("mousedown", (function(ix) {
                            return function() {
                                setColor(ix);
                            };
                        })(i), false);

                        colorContainersBox.appendChild(colorContainer);
                    }

                    var divClearLeft = document.createElement("div");
                    divClearLeft.setAttribute("style", "clear: left;");
                    colorContainersBox.appendChild(divClearLeft);


                    var drawTypeContainersBox = document.createElement("div");
                    drawTypeContainersBox.setAttribute("style",
                           "float: right; margin-right: 3px; margin-top: 1px;");
                    optionContainer.appendChild(drawTypeContainersBox);

                    drawTypeContainers = new Array(availableDrawTypes.length);
                    for (var i = 0; i < drawTypeContainers.length; i++) {
                        var drawTypeContainer = drawTypeContainers[i] =
                            document.createElement("div");
                        drawTypeContainer.setAttribute("style",
                                "text-align: center; margin: 3px; padding: 0 3px;"
                                + "height: 18px; float: left;");
                        drawTypeContainer.style.border = "2px solid #000";
                        drawTypeContainer.appendChild(document.createTextNode(
                                String(availableDrawTypes[i].name)));
                        drawTypeContainer.addEventListener("mousedown", (function(ix) {
                            return function() {
                                setDrawType(ix);
                            };
                        })(i), false);

                        drawTypeContainersBox.appendChild(drawTypeContainer);
                    }


                    var thicknessContainersBox = document.createElement("div");
                    thicknessContainersBox.setAttribute("style",
                            "margin: 3px; border: 1px solid #bbb; border-radius: 3px;");
                    optionContainer.appendChild(thicknessContainersBox);

                    thicknessContainers = new Array(availableThicknesses.length);
                    for (var i = 0; i < thicknessContainers.length; i++) {
                        var thicknessContainer = thicknessContainers[i] =
                            document.createElement("div");
                        thicknessContainer.setAttribute("style",
                                "text-align: center; margin: 3px; width: 18px; "
                                + "height: 18px; float: left;");
                        thicknessContainer.style.border = "2px solid #000";
                        thicknessContainer.appendChild(document.createTextNode(
                                String(availableThicknesses[i])));
                        thicknessContainer.addEventListener("mousedown", (function(ix) {
                            return function() {
                                setThickness(ix);
                            };
                        })(i), false);

                        thicknessContainersBox.appendChild(thicknessContainer);
                    }


                    divClearLeft = document.createElement("div");
                    divClearLeft.setAttribute("style", "clear: left;");
                    thicknessContainersBox.appendChild(divClearLeft);


                    setColor(0);
                    setThickness(0);
                    setDrawType(0);

                }

                function disableControls() {
                    document.removeEventListener("mousedown", canvasMouseDownHandler);
                    document.removeEventListener("mousemove", canvasMouseMoveHandler);
                    mouseInWindow = false;
                    refreshDisplayCanvas();

                    isActive = false;
                }

                function pushPath(path) {

                    // Push it into the pathsNotHandled array.
                    var container = new PathIdContainer(path, nextMsgId++);
                    pathsNotHandled.push(container);

                    // Send the path to the server.
                    var message = container.id + "|" + path.type + ","
                            + path.color[0] + "," + path.color[1] + ","
                            + path.color[2] + ","
                            + Math.round(path.color[3] * 255.0) + ","
                            + path.thickness + "," + path.x1 + ","
                            + path.y1 + "," + path.x2 + "," + path.y2 + ","
                            + (path.lastInChain ? "1" : "0");

                    socket.send("1" + message);
                }

                function setThickness(thicknessIndex) {
                    if (typeof currentThicknessIndex !== "undefined")
                        thicknessContainers[currentThicknessIndex]
                            .style.borderColor = "#000";
                    currentThicknessIndex = thicknessIndex;
                    thicknessContainers[currentThicknessIndex]
                        .style.borderColor = "#d08";
                }

                function setColor(colorIndex) {
                    if (typeof currentColorIndex !== "undefined")
                        colorContainers[currentColorIndex]
                            .style.borderColor = "#000";
                    currentColorIndex = colorIndex;
                    colorContainers[currentColorIndex]
                        .style.borderColor = "#d08";
                }

                function setDrawType(drawTypeIndex) {
                    if (typeof currentDrawTypeIndex !== "undefined")
                        drawTypeContainers[currentDrawTypeIndex]
                            .style.borderColor = "#000";
                    currentDrawTypeIndex = drawTypeIndex;
                    drawTypeContainers[currentDrawTypeIndex]
                        .style.borderColor = "#d08";
                }


                connect();

            }


            // Initialize the room
            var room = new Room(document.getElementById("drawContainer"));


        }, false);

    })();
    ]]></script>
</head>
<body>
    <div class="noscript"><div style="color: #ff0000; font-size: 16pt;">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable
    Javascript and reload this page!</div></div>
    <div id="labelContainer"/>
    <div id="drawContainer"/>
    <div id="console-container"/>
    <div style="clear: left;"/>

    <h1 class="expand" data-content-id="expandContent" style="font-size: 1.3em;"
        >About Drawboard WebSocket Example</h1>
    <div id="expandContent">
        <p>
            This drawboard is a page where you can draw with your mouse or touch input
            (using different colors) and everybody else which has the page open will
            <em>immediately</em> see what you are drawing.<br/>
            If someone opens the page later, they will get the current room image (so they
            can see what was already drawn by other people).
        </p>
        <p>
            It uses asynchronous sending of messages so that it doesn't need separate threads
            for each client to send messages (this needs NIO or APR connector to be used).<br/>
            Each "Room" (where the drawing happens) uses a ReentrantLock to synchronize access
            (currently, only a single Room is implemented).
        </p>
        <p>
            When you open the page, first you will receive a binary websocket message containing
            the current room image as PNG image. After that, you will receive string messages
            that contain the drawing actions (line from x1,y1 to x2,y2).<br/>
            <small>Note that it currently only uses simple string messages instead of JSON because
            I did not want to introduce a dependency on a JSON lib.</small>
        </p>
        <p>
            It uses synchronization mechanisms to ensure that the final image will look the same
            for every user, regardless of what their network latency/speed is – e.g. if two user
            draw at the same time on the same place, the server will decide which line was the
            first one, and that will be reflected on every client.
        </p>
    </div>
</body>
</html>