

function CreateChatWindow( td )
{
    var chatTab = AddNode( td, "DIV" );
    chatTab.style.backgroundColor = "#DDDDDD";
    chatTab.style.width = "250px";
    chatTab.style.height = "400px";
    chatTab.style.fontFamily = "Courier New";
    chatTab.style.overflowX = "scroll";
    chatTab.style.overflowY = "scroll";
    return chatTab;
}


function InChatMode()
{
    return document.body.onkeydown == null;
}


    function getCursorTag( editorDiv )
    {
        var cursorTag = cursorTagsByEditorID[ editorDiv.id ];
        if (!cursorTag)
        {
            gainedFocus( editorDiv, true );
            cursorTag = cursorTagsByEditorID[ editorDiv.id ];
        }
        return cursorTag;
    }
    var cursorTagsByEditorID = new Object();


function gainedFocus( editorDiv, isReadOnly )
{
    if ( !isReadOnly )
        setTimeout( function()
            {
                editorDiv.onkeydown = handleSpecialCharacters;
                editorDiv.onkeypress = echoKeyCode;
                editorDiv.onblur = function()
                {
                    Action.Add( "typeBlur" );
                };
                document.body.onkeydown = null;
                editorDiv.focus();
            }, 50);

    // Append Cursor
    editorDiv.innerHTML += "<span class='textCursorLeading'>&nbsp;</span>";

    var cursorTag = editorDiv.lastChild;
    while ( cursorTag.nodeType == 3 )
        cursorTag = cursorTag.previousSibling;

    cursorTagsByEditorID[ editorDiv.id ] = cursorTag;

    editorDiv.style.borderWidth = "1px";
    editorDiv.style.borderColor = "black";
    editorDiv.style.borderStyle = "dotted";
}



function lostFocus( editorDiv )
{
    if ( editorDiv.onkeydown )
    {
        editorDiv.onblur = null;
        editorDiv.onkeydown = null;
        editorDiv.onkeypress = null;
        document.body.onkeydown = KeyIsDown;
    }
    editorDiv.blur();

    var cursorTag = getCursorTag(editorDiv);

    if (cursorTag.className == "textCursorLeading" )
        editorDiv.removeChild( cursorTag );
    else
    {
        cursorTag.insertAdjacentHTML("beforeBegin", cursorTag.innerHTML);
        editorDiv.removeChild( cursorTag );
    }

    editorDiv.style.borderColor = "white";
    editorDiv.style.borderStyle = "solid";
}



function echoKeyCode( )
{
    var c = String.fromCharCode( event.keyCode );
    if (event.keyCode == _KEYCODE_RETURN )
        c = "RETURN";
    if (event.keyCode == _KEYCODE_SPACE )
        c = "SPACE";
    Action.Add( "type", c );
}


function handleSpecialCharacters( )
{
    switch ( event.keyCode )
    {
        case _KEYCODE_BACKSPACE:
        {
            Action.Add( "backspace" );

            event.cancelBubble = true;
            event.returnValue = false;
            return false;
        }
        case _KEYCODE_ARROW_LEFT:
        {
            Action.Add( "moveBack" );
            break;
        }
        case _KEYCODE_ARROW_RIGHT:
        {
            Action.Add( "moveForward" );
            break;
        }
        case _KEYCODE_ESC:
        {
            Action.Add( "typeBlur" );
            break;
        }
    }
}



function typeCharacter( editorDiv, c )
{
    var cursorTag = getCursorTag(editorDiv);

    var before = cursorTag.parentNode.innerHTML;

    if ( c == "RETURN" )
	    cursorTag.insertAdjacentHTML( "beforeBegin", "<br>" );
    else if (c == "SPACE")
	    cursorTag.insertAdjacentHTML( "beforeBegin", "&nbsp;" );
    else if (c == "<")
	    cursorTag.insertAdjacentHTML( "beforeBegin", "&lt;" );
    else if (c == ">")
	    cursorTag.insertAdjacentHTML( "beforeBegin", "&gt;" );
    else if (c == "&")
	    cursorTag.insertAdjacentHTML( "beforeBegin", "&amp;" );
    else
	    cursorTag.insertAdjacentHTML( "beforeBegin", c );

    if (c == "RETURN")
        cursorTag.scrollIntoView();
    else
    {
        var childList = cursorTag.parentNode.childNodes;
        var startInx = list_index( childList, cursorTag );
        for (var inx = startInx; inx >= 0; inx--)
        {
            var e = childList[inx];
            if (e.nodeName == "BR")
                break;
        }

        var charCount = (startInx-inx);
        if ( charCount >= 23 )
            cursorTag.scrollIntoView();
    }
}

function pressBackspace( editorDiv )
{
    var cursorTag = getCursorTag(editorDiv);
    _GetChar( cursorTag, true );
}
function moveBack( editorDiv )
{
    var cursorTag = getCursorTag(editorDiv);
    var prevChar = _GetChar( cursorTag, true );
    if (!prevChar)
        return;

    if (cursorTag.className == "textCursorLeading")
    {
        cursorTag.innerHTML = prevChar;
        cursorTag.className = "textCursor";
    }
    else
    {
        cursorTag.insertAdjacentHTML("afterEnd", cursorTag.innerHTML);
        cursorTag.innerHTML = prevChar;
    }
}
function moveForward( editorDiv )
{
    var cursorTag = getCursorTag(editorDiv);
    var nextChar = _GetChar( cursorTag, false );
    if (!nextChar)
        return;

    cursorTag.insertAdjacentHTML("beforeBegin", cursorTag.innerHTML);
    cursorTag.innerHTML = nextChar;
}


    function _GetChar( cursorTag, previous )
    {
        var adjacentNode = (previous ? cursorTag.previousSibling : cursorTag.nextSibling);
        if (adjacentNode == null)
            return null;

        while (adjacentNode.nodeType == XMLDOM_NODE_TEXT && adjacentNode.data.length == 0)
        {
            var emptyNode = adjacentNode;
            adjacentNode = (previous ? emptyNode.previousSibling : emptyNode.nextSibling);
            if (adjacentNode == null)
                return null;
        }


        if (adjacentNode.nodeType == XMLDOM_NODE_TEXT)
        {
            var textNode = adjacentNode;
            var txt = textNode.data;
            var ch = txt.charAt( previous?txt.length-1:0 );
            textNode.data = (previous) ? txt.substr(0,txt.length-1) : txt.substr(1);
            return ch;
        }
        else
        {
            var e = adjacentNode;
            e.parentNode.removeChild( e );
            return e.outerHTML;
        }
    }

