<?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
                        // invidividually.
                        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 Drawbord 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>