/*
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
 * Copyright (C) 2007 Vladimir Olexa (vladimir.olexa@gmail.com)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

var files = new Array();
var filesLookup = new Object();
var scripts = new Array();
var currentFile = -1;
var currentRow = null;
var currentStack = null;
var currentCallFrame = null;
var lastStatement = null;
var frameLineNumberStack = new Array();
var previousFiles = new Array();
var nextFiles = new Array();
var isResizingColumn = false;
var draggingBreakpoint = null;
var steppingOut = false;
var steppingOver = false;
var steppingStack = 0;
var pauseOnNextStatement = false;
var pausedWhileLeavingFrame = false;
var consoleWindow = null;
var breakpointEditorHTML = DebuggerDocument.breakpointEditorHTML();
var pendingAction = null;
var isPaused = false;

ScriptCallFrame = function (functionName, index, row)
{
    this.functionName = functionName;
    this.index = index;
    this.row = row;
    this.localVariableNames = null;
}

ScriptCallFrame.prototype.valueForScopeVariable = function (name)
{
    return DebuggerDocument.valueForScopeVariableNamed(name, this.index);
}

ScriptCallFrame.prototype.loadVariables = function ()
{
    if (!this.localVariableNames)
        this.localVariableNames = DebuggerDocument.localScopeVariableNamesForCallFrame(this.index);

    var variablesTable = document.getElementById("variablesTable");
    variablesTable.innerHTML = "";

    if (!this.localVariableNames)
        return;

    for(var i = 0; i < this.localVariableNames.length; i++) {
        var tr = document.createElement("tr");
        var td = document.createElement("td");
        td.innerText = this.localVariableNames[i];
        td.className = "variable";
        tr.appendChild(td);

        td = document.createElement("td");
        td.innerText = this.valueForScopeVariable(this.localVariableNames[i]);
        tr.appendChild(td);
        tr.addEventListener("click", selectVariable, true);

        variablesTable.appendChild(tr);
    }
}

function sleep(numberMillis) 
{
    var now = new Date();
    var exitTime = now.getTime() + numberMillis;
    while (true) {
        now = new Date();
        if (now.getTime() > exitTime)
            return;
    }
}

function headerMouseDown(element) 
{
    if (!isResizingColumn) 
        element.style.background = "url(glossyHeaderPressed.png) repeat-x";
}

function headerMouseUp(element) 
{
    element.style.background = "url(glossyHeader.png) repeat-x";
}

function headerMouseOut(element) 
{
    element.style.background = "url(glossyHeader.png) repeat-x";
}

function filesDividerDragStart(event) 
{
    dividerDragStart(document.getElementById("filesDivider"), filesDividerDrag, filesDividerDragEnd, event, "col-resize");
}

function filesDividerDragEnd(event) 
{
    dividerDragEnd(document.getElementById("filesDivider"), filesDividerDrag, filesDividerDragEnd, event);
}

function filesDividerDrag(event) 
{
    var element = document.getElementById("filesDivider");
    if (document.getElementById("filesDivider").dragging == true) {
        var masterMain = document.getElementById("masterMain");
        var main = document.getElementById("main");
        var fileBrowser = document.getElementById("fileBrowser");
        var x = event.clientX + window.scrollX;
        var delta = element.dragLastX - x;
        var newWidth = constrainedWidthFromElement(fileBrowser.clientWidth - delta, masterMain, 0.1, 0.9);
        if ((fileBrowser.clientWidth - delta) == newWidth) // the width wasn't constrained
            element.dragLastX = x;
        fileBrowser.style.width = newWidth + "px";
        main.style.left = newWidth + "px";
        event.preventDefault();
    }
}

function dividerDragStart(element, dividerDrag, dividerDragEnd, event, cursor) 
{
    element.dragging = true;
    element.dragLastY = event.clientY + window.scrollY;
    element.dragLastX = event.clientX + window.scrollX;
    document.addEventListener("mousemove", dividerDrag, true);
    document.addEventListener("mouseup", dividerDragEnd, true);
    document.body.style.cursor = cursor;
    event.preventDefault();
}

function dividerDragEnd(element, dividerDrag, dividerDragEnd, event) 
{
    element.dragging = false;
    document.removeEventListener("mousemove", dividerDrag, true);
    document.removeEventListener("mouseup", dividerDragEnd, true);
    document.body.style.removeProperty("cursor");
}

function dividerDrag(event) 
{
    var element = document.getElementById("divider");
    if (document.getElementById("divider").dragging == true) {
        var main = document.getElementById("main");
        var top = document.getElementById("info");
        var bottom = document.getElementById("body");
        var y = event.clientY + window.scrollY;
        var delta = element.dragLastY - y;
        var newHeight = constrainedHeightFromElement(top.clientHeight - delta, main);
        if ((top.clientHeight - delta) == newHeight) // the height wasn't constrained
            element.dragLastY = y;
        top.style.height = newHeight + "px";
        bottom.style.top = newHeight + "px";
        event.preventDefault();
    }
}

function sourceDividerDragStart(event) 
{
    dividerDragStart(document.getElementById("divider"), dividerDrag, sourceDividerDragEnd, event, "row-resize");
}

function sourceDividerDragEnd(event) 
{
    dividerDragEnd(document.getElementById("divider"), dividerDrag, sourceDividerDragEnd, event);
}

function infoDividerDragStart(event) 
{
    dividerDragStart(document.getElementById("infoDivider"), infoDividerDrag, infoDividerDragEnd, event, "col-resize");
}

function infoDividerDragEnd(event) 
{
    dividerDragEnd(document.getElementById("infoDivider"), infoDividerDrag, infoDividerDragEnd, event);
}

function infoDividerDrag(event) 
{
    var element = document.getElementById("infoDivider");
    if (document.getElementById("infoDivider").dragging == true) {
        var main = document.getElementById("main");
        var leftPane = document.getElementById("leftPane");
        var rightPane = document.getElementById("rightPane");
        var x = event.clientX + window.scrollX;
        var delta = element.dragLastX - x;
        var newWidth = constrainedWidthFromElement(leftPane.clientWidth - delta, main);
        if ((leftPane.clientWidth - delta) == newWidth) // the width wasn't constrained
            element.dragLastX = x;
        leftPane.style.width = newWidth + "px";
        rightPane.style.left = newWidth + "px";
        event.preventDefault();
    }
}

function columnResizerDragStart(event) 
{
    isResizingColumn = true;
    dividerDragStart(document.getElementById("variableColumnResizer"), columnResizerDrag, columnResizerDragEnd, event, "col-resize");
}

function columnResizerDragEnd(event) 
{
    isResizingColumn = false;
    dividerDragEnd(document.getElementById("variableColumnResizer"), columnResizerDrag, columnResizerDragEnd, event);
}

function columnResizerDrag(event) 
{
    var element = document.getElementById("variableColumnResizer");
    if (element.dragging == true) {
        var main = document.getElementById("rightPane");
        var variableColumn = document.getElementById("variable");
        var rules = document.defaultView.getMatchedCSSRules(variableColumn, "");
        for (var i = 0; i < rules.length; i++) {
            if (rules[i].selectorText == ".variable") {
                var columnRule = rules[i];
                break;
            }
        }

        var x = event.clientX + window.scrollX;
        var delta = element.dragLastX - x;
        var newWidth = constrainedWidthFromElement(variableColumn.clientWidth - delta, main);
        if ((variableColumn.clientWidth - delta) == newWidth) // the width wasn't constrained
            element.dragLastX = x;
        columnRule.style.width = newWidth + "px";
        element.style.left = newWidth + "px";
        event.preventDefault();
    }
}

function constrainedWidthFromElement(width, element, constrainLeft, constrainRight) 
{
    if (constrainLeft === undefined) constrainLeft = 0.25;
    if (constrainRight === undefined) constrainRight = 0.75;
    
    if (width < element.clientWidth * constrainLeft)
        width = element.clientWidth * constrainLeft;
    else if (width > element.clientWidth * constrainRight)
        width = element.clientWidth * constrainRight;
    return width;
}

function constrainedHeightFromElement(height, element) 
{
    if (height < element.clientHeight * 0.25)
        height = element.clientHeight * 0.25;
    else if (height > element.clientHeight * 0.75)
        height = element.clientHeight * 0.75;
    return height;
}

function loaded() 
{
    document.getElementById("divider").addEventListener("mousedown", sourceDividerDragStart, false);
    document.getElementById("infoDivider").addEventListener("mousedown", infoDividerDragStart, false);
    document.getElementById("filesDivider").addEventListener("mousedown", filesDividerDragStart, false);
    document.getElementById("variableColumnResizer").addEventListener("mousedown", columnResizerDragStart, false);
}

function pause() 
{
    DebuggerDocument.pause();
    isPaused = true;
}

function resume()
{
    if (currentRow) {
        currentRow.removeStyleClass("current");
        currentRow = null;
    }

    var stackframeTable = document.getElementById("stackframeTable");
    stackframeTable.innerHTML = ""; // clear the content
    var variablesTable = document.getElementById("variablesTable");
    variablesTable.innerHTML = ""; // clear the content
    currentStack = null;
    currentCallFrame = null;

    pauseOnNextStatement = false;
    pausedWhileLeavingFrame = false;
    steppingOut = false;
    steppingOver = false;
    steppingStack = 0;

    DebuggerDocument.resume();
    isPaused = false;
}

function stepInto()
{
    pauseOnNextStatement = false;
    steppingOut = false;
    steppingOver = false;
    steppingStack = 0;
    DebuggerDocument.stepInto();
}

function stepOver()
{
    pauseOnNextStatement = false;
    steppingOver = true;
    steppingStack = 0;
    DebuggerDocument.resume();
}

function stepOut()
{
    pauseOnNextStatement = pausedWhileLeavingFrame;
    steppingOver = false;
    steppingStack = 0;
    steppingOut = true;
    DebuggerDocument.resume();
}

Element.prototype.removeStyleClass = function(className) 
{
    if (this.hasStyleClass(className))
        this.className = this.className.replace(className, "");
}

Element.prototype.addStyleClass = function(className) 
{
    if (!this.hasStyleClass(className))
        this.className += (this.className.length ? " " + className : className);
}

Element.prototype.hasStyleClass = function(className) 
{
    return this.className.indexOf(className) != -1;
}

Element.prototype.firstParentWithClass = function(className) 
{
    var node = this.parentNode;
    while(!node.hasStyleClass(className)) {
        if (node == document) 
            return null;
        node = node.parentNode;
    }
    return node;
}

Element.prototype.query = function(query) 
{
    return document.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

Element.prototype.removeChildren = function()
{
    while (this.firstChild) 
        this.removeChild(this.firstChild);        
}

function breakpointAction(event)
{
    var file = files[currentFile];
    var lineNum = event.target.title;

    if (!file.breakpoints[lineNum])
        file.breakpoints[lineNum] = new BreakPoint(event.target.parentNode, file, lineNum);
    else
        toggleBreakpointOnLine(lineNum);
}

BreakPoint = function(row, file, line) 
{
    this.row = row;
    this.file = file;
    this.line = line;
    row.addStyleClass("breakpoint");
    row.removeStyleClass("disabled");
    this.value = "break";
    this.enabled = true;
    this.editor = null;
    this.type = 0;
    this.hitcount = 0;
}

function toggleBreakpointEditorOnLine(lineNum)
{
    if (pendingAction) {
        clearTimeout(pendingAction);
        pendingAction = null;
    }
    var file = files[currentFile];
    bp = file.breakpoints[lineNum];
    if (bp) {
        var editor = bp.editor;
        if (!editor) {
            var sourcesDocument = document.getElementById("sources").contentDocument;
            editor = sourcesDocument.createElement("div");
            editor.className = "editor";
            editor.id = lineNum;
            editor.innerHTML = breakpointEditorHTML;
            
            bp.row.childNodes[1].appendChild(editor);

            bp.editor = editor;
            file.breakpoints[lineNum] = bp;

            editor.query('.//input[@class="enable"]').checked = bp.enabled;

            editor.query('.//select[@class="editorDropdown"]').selectedIndex = bp.type;
            updateBreakpointTypeOnLine(lineNum);

            editor.query('.//span[@class="hitCounter"]').innerText = bp.hitcount;
                
            setConditionFieldText(bp);
        } else {
            saveBreakpointOnLine(lineNum);
            bp.row.childNodes[1].removeChild(editor);
            bp.editor = null;
        }
    }
}

function updateBreakpointTypeOnLine(line)
{
    var breakpoint = files[currentFile].breakpoints[line];
    var editor = breakpoint.editor;
    var label = editor.query('.//label[@class="conditionLabel"]');
    var dropdown = editor.query('.//select[@class="editorDropdown"]');
    breakpoint.type = dropdown.selectedIndex;
    switch(breakpoint.type) {
        case 0:
            label.innerText = "Condition:";
            break;
        case 1:
            label.innerText = "Expression:";
            break;
    }
}

function setConditionFieldText(breakpoint)
{
    var conditionField = breakpoint.editor.query('.//div[@class="condition"]');

    var functionBody = breakpoint.value;
    if (!functionBody || functionBody == "break")
        functionBody = "";
    else {
        var startIndex = functionBody.indexOf("return((") + 8;
        var endIndex = null;
        if (startIndex != 7) //-1 + 8, yes, that's lame
            endIndex = functionBody.lastIndexOf("))");
        else {
            startIndex = functionBody.indexOf("{") + 1;
            endIndex = functionBody.lastIndexOf("}"); 
        }
        functionBody = functionBody.substring(startIndex, endIndex);
    }
    conditionField.innerText = functionBody;
    conditionField.addEventListener("keyup", new Function("saveBreakpointOnLine(" + breakpoint.line + ");"), false);
    conditionField.focus();
}

function saveBreakpointOnLine(lineNum)
{
    var file = files[currentFile];
    var breakpoint = file.breakpoints[lineNum];
    row = file.element.firstChild.childNodes.item(lineNum - 1);
    var editor = breakpoint.editor;
    var body = editor.query('.//div[@class="condition"]').innerText;
    var actionIndex = editor.query('.//select[@class="editorDropdown"]').selectedIndex;
    if (body.length == 0)
        breakpoint.value = "break";
    else if (body.indexOf("return") != -1)
        breakpoint.value = "__drosera_breakpoint_conditional_func = function() {" + body + "}; __drosera_breakpoint_conditional_func();";
    else
        breakpoint.value = "__drosera_breakpoint_conditional_func = function() { return((" + body + ")); }; __drosera_breakpoint_conditional_func();";
}

function toggleBreakpointOnLine(lineNum)
{
    var breakpoint = files[currentFile].breakpoints[lineNum];
    pendingAction = null;
    if (breakpoint.enabled)
        breakpoint.row.addStyleClass("disabled");
    else
        breakpoint.row.removeStyleClass("disabled");
    
    var hack = breakpoint.row.offsetTop; // force a relayout if needed.
    
    breakpoint.enabled = !breakpoint.enabled;
    var editor = breakpoint.editor;
    if (editor) {
        editor.query('.//input[@class="enable"]').checked = breakpoint.enabled;
        setConditionFieldText(breakpoint, lineNum);
    }
}

function moveBreakPoint(event)
{
    if (event.target.parentNode.hasStyleClass("breakpoint")) {
        draggingBreakpoint = event.target;
        draggingBreakpoint.started = false;
        draggingBreakpoint.dragLastY = event.clientY + window.scrollY;
        draggingBreakpoint.dragLastX = event.clientX + window.scrollX;
        var sourcesDocument = document.getElementById("sources").contentDocument;
        sourcesDocument.addEventListener("mousemove", breakpointDrag, true);
        sourcesDocument.addEventListener("mouseup", breakpointDragEnd, true);
        sourcesDocument.body.style.cursor = "default";
    }
}

function breakpointDrag(event)
{
    var sourcesDocument = document.getElementById("sources").contentDocument;
    if (!draggingBreakpoint) {
        sourcesDocument.removeEventListener("mousemove", breakpointDrag, true);
        sourcesDocument.removeEventListener("mouseup", breakpointDragEnd, true);
        sourcesDocument.body.style.removeProperty("cursor");
        return;
    }

    var x = event.clientX + window.scrollX;
    var y = event.clientY + window.scrollY;
    var deltaX = draggingBreakpoint.dragLastX - x;
    var deltaY = draggingBreakpoint.dragLastY - y;
    if (draggingBreakpoint.started || deltaX > 4 || deltaY > 4 || deltaX < -4 || deltaY < -4) {
    
        if (!draggingBreakpoint.started) {
            var lineNum = draggingBreakpoint.title;
            var file = files[currentFile];
            var breakpoint = file.breakpoints[lineNum];
            draggingBreakpoint.breakpoint = breakpoint;
            breakpoint.row.removeStyleClass("breakpoint");
            breakpoint.row.removeStyleClass("disabled");

            var editor = breakpoint.editor;
            if (editor)
                toggleBreakpointEditorOnLine(lineNum);
            
            draggingBreakpoint.started = true;
                        
            file.breakpoints[lineNum] = null;

            var dragImage = sourcesDocument.createElement("img");
            if (draggingBreakpoint.breakpoint.enabled)
                dragImage.src = "breakPoint.tif";
            else
                dragImage.src = "breakPointDisabled.tif";

            dragImage.id = "breakpointDrag";
            dragImage.style.top = y - 8 + "px";
            dragImage.style.left = x - 12 + "px";
            sourcesDocument.body.appendChild(dragImage);
        } else {
            var dragImage = sourcesDocument.getElementById("breakpointDrag");
            if (!dragImage) {
                sourcesDocument.removeEventListener("mousemove", breakpointDrag, true);
                sourcesDocument.removeEventListener("mouseup", breakpointDragEnd, true);
                sourcesDocument.body.style.removeProperty("cursor");
                return;
            }

            dragImage.style.top = y - 8 + "px";
            dragImage.style.left = x - 12 + "px";
            if (x > 40)
                dragImage.style.visibility = "hidden";
            else
                dragImage.style.removeProperty("visibility");
        }

        draggingBreakpoint.dragLastX = x;
        draggingBreakpoint.dragLastY = y;
    }
}

function breakpointDragEnd(event)
{
    var sourcesDocument = document.getElementById("sources").contentDocument;
    sourcesDocument.removeEventListener("mousemove", breakpointDrag, true);
    sourcesDocument.removeEventListener("mouseup", breakpointDragEnd, true);
    sourcesDocument.body.style.removeProperty("cursor");

    var dragImage = sourcesDocument.getElementById("breakpointDrag");
    if (!dragImage)
        return;
        
    dragImage.parentNode.removeChild(dragImage);

    var x = event.clientX + window.scrollX;
    if (x > 40 || !draggingBreakpoint)
        return;

    var y = event.clientY + window.scrollY;
    var rowHeight = draggingBreakpoint.parentNode.offsetHeight;
    var row = Math.ceil(y / rowHeight);
    if (row <= 0)
        row = 1;

    var file = files[currentFile];
    var table = file.element.firstChild;
    if (row > table.childNodes.length)
        return;

    var tr = table.childNodes.item(row - 1);
    if (!tr)
        return;
        
    var breakpoint = draggingBreakpoint.breakpoint;
    breakpoint.row = tr;
    
    // leave the editor there if it exists... we'll want to update it to the new values
    breakpoint.editor = file.breakpoints[row].editor;
    
    file.breakpoints[row] = breakpoint;
    
    if (breakpoint.editor) {
        breakpoint.editor.id = row;
        updateBreakpointTypeOnLine(row);
        setConditionFieldText(breakpoint);
    }
    
    if (!breakpoint.enabled)
        tr.addStyleClass("disabled");

    tr.addStyleClass("breakpoint");
    
    draggingBreakpoint = null;
}

function totalOffsetTop(element, stop)
{
    var currentTop = 0;
    while (element.offsetParent) {
        currentTop += element.offsetTop
        element = element.offsetParent;
        if (element == stop)
            break;
    }
    return currentTop;
}

function switchFile(fileIndex)
{
    var filesSelect = document.getElementById("files");
    
    if (fileIndex === undefined) 
        fileIndex = filesSelect.selectedIndex;
    
    fileClicked(filesSelect.options[fileIndex].value, false);
    loadFile(filesSelect.options[fileIndex].value, true);    
}

function syntaxHighlight(code, file)
{
    var keywords = { 'abstract': 1, 'boolean': 1, 'break': 1, 'byte': 1, 'case': 1, 'catch': 1, 'char': 1, 'class': 1, 'const': 1, 'continue': 1, 'debugger': 1, 'default': 1, 'delete': 1, 'do': 1, 'double': 1, 'else': 1, 'enum': 1, 'export': 1, 'extends': 1, 'false': 1, 'final': 1, 'finally': 1, 'float': 1, 'for': 1, 'function': 1, 'goto': 1, 'if': 1, 'implements': 1, 'import': 1, 'in': 1, 'instanceof': 1, 'int': 1, 'interface': 1, 'long': 1, 'native': 1, 'new': 1, 'null': 1, 'package': 1, 'private': 1, 'protected': 1, 'public': 1, 'return': 1, 'short': 1, 'static': 1, 'super': 1, 'switch': 1, 'synchronized': 1, 'this': 1, 'throw': 1, 'throws': 1, 'transient': 1, 'true': 1, 'try': 1, 'typeof': 1, 'var': 1, 'void': 1, 'volatile': 1, 'while': 1, 'with': 1 };

    function echoChar(c) {
        if (c == '<')
            result += '&lt;';
        else if (c == '>')
            result += '&gt;';
        else if (c == '&')
            result += '&amp;';
        else if (c == '\t')
            result += '    ';
        else
            result += c;
    }

    function isDigit(number) {
        var string = "1234567890";
        if (string.indexOf(number) != -1)
            return true;
        return false;
    }

    function isHex(hex) {
        var string = "1234567890abcdefABCDEF";
        if (string.indexOf(hex) != -1)
            return true;
        return false;
    }

    function isLetter(letter) {
        var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if (string.indexOf(letter) != -1)
            return true;
        return false;
    }

    var result = "";
    var cPrev = "";
    var c = "";
    var cNext = "";
    for (var i = 0; i < code.length; i++) {
        cPrev = c;
        c = code.charAt(i);
        cNext = code.charAt(i + 1);

        if (c == "/" && cNext == "*") {
            result += "<span class=\"comment\">";
            echoChar(c);
            echoChar(cNext);
            for (i += 2; i < code.length; i++) {
                c = code.charAt(i);
                if (c == "\n")
                    result += "</span>";
                echoChar(c);
                if (c == "\n")
                    result += "<span class=\"comment\">";
                if (cPrev == "*" && c == "/")
                    break;
                cPrev = c;
            }
            result += "</span>";
            continue;
        } else if (c == "/" && cNext == "/") {
            result += "<span class=\"comment\">";
            echoChar(c);
            echoChar(cNext);
            for (i += 2; i < code.length; i++) {
                c = code.charAt(i);
                if (c == "\n")
                    break;
                echoChar(c);
            }
            result += "</span>";
            echoChar(c);
            continue;
        } else if (c == "\"" || c == "'") {
            var instringtype = c;
            var stringstart = i;
            result += "<span class=\"string\">";
            echoChar(c);
            for (i += 1; i < code.length; i++) {
                c = code.charAt(i);
                if (stringstart < (i - 1) && cPrev == instringtype && code.charAt(i - 2) != "\\")
                    break;
                echoChar(c);
                cPrev = c;
            }
            result += "</span>";
            echoChar(c);
            continue;
        } else if (c == "0" && cNext == "x" && (i == 0 || (!isLetter(cPrev) && !isDigit(cPrev)))) {
            result += "<span class=\"number\">";
            echoChar(c);
            echoChar(cNext);
            for (i += 2; i < code.length; i++) {
                c = code.charAt(i);
                if (!isHex(c))
                    break;
                echoChar(c);
            }
            result += "</span>";
            echoChar(c);
            continue;
        } else if ((isDigit(c) || ((c == "-" || c == ".") && isDigit(cNext))) && (i == 0 || (!isLetter(cPrev) && !isDigit(cPrev)))) {
            result += "<span class=\"number\">";
            echoChar(c);
            for (i += 1; i < code.length; i++) {
                c = code.charAt(i);
                if (!isDigit(c) && c != ".")
                    break;
                echoChar(c);
            }
            result += "</span>";
            echoChar(c);
            continue;
        } else if (isLetter(c) && (i == 0 || !isLetter(cPrev))) {
            var keyword = c;
            var cj = "";
            for (var j = i + 1; j < i + 12 && j < code.length; j++) {
                cj = code.charAt(j);
                if (!isLetter(cj))
                    break;
                keyword += cj;
            }

            if (keywords[keyword]) {
                var functionName = "";
                var functionIsAnonymous = false;
                if (keyword == "function") {
                    var functionKeywordOffset = 8;
                    for (var j = i + functionKeywordOffset; j < code.length; j++) {
                        cj = code.charAt(j);
                        if (cj == " ")
                            continue;
                        if (cj == "(")
                            break;
                        functionName += cj;
                    }

                    if (!functionName.length) {
                        functionIsAnonymous = true;
                        var functionAssignmentFound = false;
                        var functionNameStart = -1;
                        var functionNameEnd = -1;

                        for (var j = i - 1; j >= 0; j--) {
                            cj = code.charAt(j);
                            if (cj == ":" || cj == "=") {
                                functionAssignmentFound = true;
                                continue;
                            }

                            var curCharIsSpace = (cj == " " || cj == "\t" || cj == "\n");
                            if (functionAssignmentFound && functionNameEnd == -1 && !curCharIsSpace) {
                                functionNameEnd = j + 1;
                            } else if (!functionAssignmentFound && !curCharIsSpace) {
                                break;
                            } else if (functionNameEnd != -1 && curCharIsSpace) {
                                functionNameStart = j;
                                break;
                            }
                        }

                        if (functionNameStart != -1 && functionNameEnd != -1)
                            functionName = code.substring(functionNameStart, functionNameEnd);
                    }

                    if (!functionName.length)
                        functionName = "function";

                    file.functionNames.push(functionName);
                }

                var fileIndex = filesLookup[file.url];

                if (keyword == "function" && functionIsAnonymous)
                    result += "<span class=\"keyword\"><a name=\"function-" + fileIndex + "-" + file.functionNames.length + "\" id=\"" + fileIndex + "-" + file.functionNames.length + "\">" + keyword + "</a></span>";
                else
                    result += "<span class=\"keyword\">" + keyword + "</span>";

                if (functionName.length && !functionIsAnonymous) {
                    result += " <a name=\"function-" + fileIndex + "-" + file.functionNames.length + "\" id=\"" + fileIndex + "-" + file.functionNames.length + "\">" + functionName + "</a>";
                    i += keyword.length + functionName.length;
                } else
                    i += keyword.length - 1;

                continue;
            }
        }

        echoChar(c);
    }
        
    return result;
}

function navFilePrevious(element)
{
    if (element.disabled)
        return;
    var lastFile = previousFiles.pop();
    if (currentFile != -1)
        nextFiles.unshift(currentFile);
    loadFile(lastFile, false);
}

function navFileNext(element)
{
    if (element.disabled)
        return;
    var lastFile = nextFiles.shift();
    if (currentFile != -1)
        previousFiles.push(currentFile);
    loadFile(lastFile, false);
}

function updateFunctionStack()
{
    var stackframeTable = document.getElementById("stackframeTable");
    stackframeTable.innerHTML = ""; // clear the content

    currentStack = new Array();
    var stack = DebuggerDocument.currentFunctionStack();
    for(var i = 0; i < stack.length; i++) {
        var tr = document.createElement("tr");
        var td = document.createElement("td");
        td.className = "stackNumber";
        td.innerText = i;
        tr.appendChild(td);

        td = document.createElement("td");
        td.innerText = stack[i];
        tr.appendChild(td);
        tr.addEventListener("click", selectStackFrame, true);

        stackframeTable.appendChild(tr);

        var frame = new ScriptCallFrame(stack[i], i, tr);
        tr.callFrame = frame;
        currentStack.push(frame);

        if (i == 0) {
            tr.addStyleClass("current");
            frame.loadVariables();
            currentCallFrame = frame;
        }
    }
}

function selectStackFrame(event)
{
    var stackframeTable = document.getElementById("stackframeTable");
    var rows = stackframeTable.childNodes;
    for (var i = 0; i < rows.length; i++)
        rows[i].removeStyleClass("current");
    this.addStyleClass("current");
    this.callFrame.loadVariables();
    currentCallFrame = this.callFrame;

    if (frameLineNumberInfo = frameLineNumberStack[this.callFrame.index - 1])
        jumpToLine(frameLineNumberInfo[0], frameLineNumberInfo[1]);
    else if (this.callFrame.index == 0)
        jumpToLine(lastStatement[0], lastStatement[1]);
}

function selectVariable(event)
{
    var variablesTable = document.getElementById("variablesTable");
    var rows = variablesTable.childNodes;
    for (var i = 0; i < rows.length; i++)
        rows[i].removeStyleClass("current");
    this.addStyleClass("current");
}

function switchFunction(index, shouldResetPopup)
{
    if (shouldResetPopup === undefined) shouldResetPopup = false;
    var sourcesFrame = window.frames['sourcesFrame'];
    
    if (shouldResetPopup || index == 0) {
        document.getElementById("functionPopupButtonContent").innerHTML = '<span class="placeholder">&lt;No selected symbol&gt;</span>';
        return;
    }

    var functionSelect = document.getElementById("functions");
    var selectedFunction = functionSelect.childNodes[index];
    var selection = sourcesFrame.getSelection();
    var currentFunction = selectedFunction.value;     
    var currentFunctionElement = sourcesFrame.document.getElementById(currentFunction);
    
    functionSelect.blur();
    sourcesFrame.focus();
    selection.setBaseAndExtent(currentFunctionElement, 0, currentFunctionElement, 1);
    sourcesFrame.location.hash = "#function-" + selectedFunction.value;
    document.getElementById("functionPopupButtonContent").innerText = selectedFunction.innerText;
}

function loadFile(fileIndex, manageNavLists)
{
    var file = files[fileIndex];
    if (!file)
        return;

    if (currentFile != -1 && files[currentFile] && files[currentFile].element)
        files[currentFile].element.style.display = "none";

    if (!file.loaded) {
        var sourcesDocument = document.getElementById("sources").contentDocument;
        var sourcesDiv = sourcesDocument.body;
        var sourceDiv = sourcesDocument.createElement("div");
        sourceDiv.id = "file" + fileIndex;
        sourcesDiv.appendChild(sourceDiv);
        file.element = sourceDiv;

        var table = sourcesDocument.createElement("table");
        sourceDiv.appendChild(table);

        var normalizedSource = file.source.replace(/\r\n|\r/g, "\n"); // normalize line endings
        var lines = syntaxHighlight(normalizedSource, file).split("\n");
        for( var i = 0; i < lines.length; i++ ) {
            var tr = sourcesDocument.createElement("tr");
            var td = sourcesDocument.createElement("td");
            td.className = "gutter";
            td.title = (i + 1);
            td.addEventListener("click", breakpointAction, true);
            td.addEventListener("dblclick", function(event) { toggleBreakpointEditorOnLine(event.target.title); }, true);
            td.addEventListener("mousedown", moveBreakPoint, true);
            tr.appendChild(td);

            td = sourcesDocument.createElement("td");
            td.className = "source";
            td.innerHTML = (lines[i].length ? lines[i] : "&nbsp;");
            tr.appendChild(td);
            table.appendChild(tr);
        }
        
        file.loaded = true;
    }

    file.element.style.removeProperty("display");

    document.getElementById("filesPopupButtonContent").innerText = (file.url ? file.url : "(unknown script)");

    var filesSelect = document.getElementById("files");
    for (var i = 0; i < filesSelect.childNodes.length; i++) {
        if (filesSelect.childNodes[i].value == fileIndex) {
            filesSelect.selectedIndex = i;
            break;
        }
    }

    // Populate the function names pop-up
    if (file.functionNames.length > 0) {
        var functionSelect = document.getElementById("functions");
        var functionOption = document.createElement("option");
        
        document.getElementById("functionNamesPopup").style.display = "inline";
        switchFunction(0, true);
        
        functionSelect.removeChildren();
        functionOption.value = null;
        functionOption.text = "<No selected symbol>";
        functionSelect.appendChild(functionOption);
        
        for (var i = 0; i < file.functionNames.length; i++) {
            functionOption = document.createElement("option");
            functionOption.value = fileIndex + "-" + (i+1);
            functionOption.text = file.functionNames[i] + "()";
            functionSelect.appendChild(functionOption);
        }
    } else
        document.getElementById("functionNamesPopup").style.display = "none";
    
    if (manageNavLists) {
        nextFiles = new Array();
        if (currentFile != -1)
            previousFiles.push(currentFile);
    }

    document.getElementById("navFileLeftButton").disabled = (previousFiles.length == 0);
    document.getElementById("navFileRightButton").disabled = (nextFiles.length == 0);

    //Remember and recall scroll position for current file and file we just loaded
    var frameBody = document.getElementById("sources").contentDocument.body;
    if (currentFile != -1) 
        files[currentFile].scrollPosition = frameBody.scrollTop;
    frameBody.scrollTop = file.scrollPosition;
    frameBody.scrollLeft = 0;
    
    currentFile = fileIndex;
}

function updateFileSource(source, url, force)
{
    var fileIndex = filesLookup[url];
    if (!fileIndex || !source.length)
        return;

    var file = files[fileIndex];
    if (force || file.source.length != source.length || file.source != source) {
        file.source = source;
        file.loaded = false;

        if (file.element) {
            file.element.parentNode.removeChild(file.element);
            file.element = null;
        }

        if (currentFile == fileIndex || force)
            loadFile(fileIndex, false);
    }
}

/**
* ParsedURL - this object chops up full URL into two parts: 
 * 1) The domain: everything from http:// to the end of the domain name
 * 2) The relative path: everything after the domain
 *
 * @param string url URL to be processed
 */
function ParsedURL(url)
{
    // Since we're getting the URL from the browser, we're safe to assume the URL is already well formatted
    // and so there is no need for more sophisticated regular expression here
    var url_parts = ((url.substring(0,4)).toLowerCase() == "file") ? url.match(/(file:[\/]{2,3}(\w|\.|-|_|\/|\%|\:)+)\/(.*)/) : url.match(/(http[s]?:\/\/(www)?\.?(\w|\.|-)+\w(:\d{1,5})?)\/?(.*)/);
    // the domain here is considered the whole http://www.example.org:8000 or file:///Users/user/folder/file.htm string for display purposes
    this.domain = url_parts[1];
    // the relative path is everything following the domain
    this.relativePath = (url_parts[5] === undefined) ? "/" + url_parts[3] : "/" + url_parts[5];
}

/**
* SiteBrowser - modifies the file tree via DOM as new files are being open
 *
 */
function SiteBrowser()
{
    var fileBrowser = document.getElementById("filesBrowserSites");

    this.addURL = function add(url, fileIndex)
    {
        var parsedURL = new ParsedURL(url);
        var divs = fileBrowser.getElementsByTagName("div");

        if (divs.length == 0) { 
            addNewDomain(parsedURL, fileIndex);
        } else {
            var isNew = true;
            for (var i = 0; i < divs.length; i++) {
                if (divs[i].id == parsedURL.domain) {
                    var uls = divs[i].getElementsByTagName("ul");
                    var ul = (uls.length > 0) ? uls[0] : document.createElement("ul");
                    var li = document.createElement("li");
                    
                    li.id = fileIndex;
                    li.addEventListener("click", fileBrowserMouseEvents, false);
                    li.title = li.innerText = parsedURL.relativePath ? parsedURL.relativePath : "/";
                    ul.appendChild(li);
                    isNew = false;
                    break;
                }
            }
            if (isNew) {
                addNewDomain(parsedURL, fileIndex);
            }
        }
    }

    this.selectInitialFile = function sf()
    {
        if (currentFile == -1)
            document.getElementById("1").className = "active";
    }

    function addNewDomain(parsedURL, fileIndex)
    {
        var div = document.createElement("div");
        var ul = document.createElement("ul");
        var li = document.createElement("li");
        
        div.id = div.innerText = div.title = parsedURL.domain;
        div.addEventListener("click", fileBrowserMouseEvents, false);
        // Maybe we can add some roll-overs here...
        //div.addEventListener("mouseover", fileBrowserMouseEvents, false);
        //div.addEventListener("mouseout", fileBrowserMouseEvents, false);
        li.id = fileIndex;
        li.addEventListener("click", fileBrowserMouseEvents, false);
        li.title = li.innerText = parsedURL.relativePath ? parsedURL.relativePath : "/";
        ul.appendChild(li);
        div.appendChild(ul);
        fileBrowser.appendChild(div);        
    }

    function removeFile(fileIndex)
    {
        var theFile = document.getElementById(fileIndex);
        // If we are removing the last file from its site, go ahead and remove the whole site
        if (theFile.parentNode.childNodes.length < 2) { 
            var theSite = theFile.parentNode.parentNode;
            theSite.removeChildren();
            theSite.parentNode.removeChild(theSite);
        }
        else
            theFile.parentNode.removeChild(theFile);
    }
}

function fileBrowserMouseEvents(event)
{
    switch (event.type)
    {
        case "click":
            // If we clicked on a site, collapse/expand it, if on a file, display it. Since we're only capturing this
            // event from either a DIV or LI element, we don't have to worry about any ambiguity
            (event.target.nodeName.toUpperCase() == "DIV") ? toggleCollapseSite(event) : fileClicked(event.target.id);
            break;
    }
}

function fileClicked(fileId, shouldLoadFile)
{
    if (shouldLoadFile === undefined) 
        shouldLoadFile = true;
    if (currentFile != -1) 
        document.getElementById(currentFile).className = "passive";
    document.getElementById(fileId).className = "active";
    if (shouldLoadFile) 
        loadFile(fileId, false);
}

function toggleCollapseSite(event)
{
    var thisSite = document.getElementById(event.target.id);
    var siteFiles = thisSite.getElementsByTagName("ul");
    
    if (siteFiles[0].style.display == "block" || !siteFiles[0].style.display) {
        siteFiles[0].style.display = "none";
        thisSite.className = "collapsed"; 
    } else {
        siteFiles[0].style.display = "block";
        thisSite.className = "expanded";
    }
}

function didParseScript(source, fileSource, url, sourceId, baseLineNumber)
{
    var fileIndex = filesLookup[url];
    var file = files[fileIndex];
    var firstLoad = false;

    if (!fileIndex || !file) {
        fileIndex = files.length + 1;
        if (url.length)
            filesLookup[url] = fileIndex;

        file = new Object();
        file.scripts = new Array();
        file.breakpoints = new Array();
        file.functionNames = new Array();
        file.source = (fileSource.length ? fileSource : source);
        file.url = (url.length ? url : null);
        file.loaded = false;

        files[fileIndex] = file;

        var filesSelect = document.getElementById("files");
        var option = document.createElement("option");
        files[fileIndex].menuOption = option;
        option.value = fileIndex;
        option.text = (file.url ? file.url : "(unknown script)");
        filesSelect.appendChild(option);

        var siteBrowser = new SiteBrowser();
        siteBrowser.addURL(file.url, fileIndex);
        siteBrowser.selectInitialFile();

        firstLoad = true;
    }

    var sourceObj = new Object();
    sourceObj.file = fileIndex;
    sourceObj.baseLineNumber = baseLineNumber;
    file.scripts.push(sourceId);
    scripts[sourceId] = sourceObj;

    if (!firstLoad)
        updateFileSource((fileSource.length ? fileSource : source), url, false);

    if (currentFile == -1)
        loadFile(fileIndex, false);
}

function jumpToLine(sourceId, line)
{
    var script = scripts[sourceId];
    if (line <= 0 || !script)
        return;

    var file = files[script.file];
    if (!file)
        return;

    if (currentFile != script.file)
        loadFile(script.file, true);
    if (currentRow)
        currentRow.removeStyleClass("current");
    if (!file.element)
        return;
    if (line > file.element.firstChild.childNodes.length)
        return;

    currentRow = file.element.firstChild.childNodes.item(line - 1);
    if (!currentRow)
        return;

    currentRow.addStyleClass("current");

    var sourcesDiv = document.getElementById("sources");
    var sourcesDocument = document.getElementById("sources").contentDocument;
    var parent = sourcesDocument.body;
    var offset = totalOffsetTop(currentRow, parent);
    if (offset < (parent.scrollTop + 20) || offset > (parent.scrollTop + sourcesDiv.clientHeight - 20))
        parent.scrollTop = totalOffsetTop(currentRow, parent) - (sourcesDiv.clientHeight / 2) + 10;
}

function willExecuteStatement(sourceId, line, fromLeavingFrame)
{
    var script = scripts[sourceId];
    if (line <= 0 || !script)
        return;

    var file = files[script.file];
    if (!file)
        return;

    lastStatement = [sourceId, line];

    var breakpoint = file.breakpoints[line];

    var shouldBreak = false;

    if (breakpoint && breakpoint.enabled) {
        switch(breakpoint.type) {
            case 0:
                shouldBreak = (breakpoint.value == "break" || DebuggerDocument.evaluateScript(breakpoint.value, 0) == 1);
                if (shouldBreak)
                    breakpoint.hitcount++;
                break;
            case 1:
                var message = "Hit breakpoint on line " + line;
                if (breakpoint.value != "break")
                    message = DebuggerDocument.evaluateScript(breakpoint.value, 0);
                if (consoleWindow)
                    consoleWindow.appendMessage("", message);
                breakpoint.hitcount++;
                break;
        }
        var editor = breakpoint.editor;
        var counter = null;
        if (editor)
            counter = breakpoint.editor.query('.//span[@class="hitCounter"]');
        if (counter)
            counter.innerText = breakpoint.hitcount;
    }

    if (pauseOnNextStatement || shouldBreak || (steppingOver && !steppingStack)) {
        pause();
        pauseOnNextStatement = false;
        pausedWhileLeavingFrame = fromLeavingFrame || false;
    }

    if (isPaused) {
        updateFunctionStack();
        jumpToLine(sourceId, line);
    }
}

function didEnterCallFrame(sourceId, line)
{
    if (steppingOver || steppingOut)
        steppingStack++;

    if (lastStatement)
        frameLineNumberStack.unshift(lastStatement);
    willExecuteStatement(sourceId, line);
}

function willLeaveCallFrame(sourceId, line)
{
    if (line <= 0)
        resume();
    willExecuteStatement(sourceId, line, true);
    frameLineNumberStack.shift();
    if (!steppingStack)
        steppingOver = false;
    if (steppingOut && !steppingStack) {
        steppingOut = false;
        pauseOnNextStatement = true;
    }
    if ((steppingOver || steppingOut) && steppingStack >= 1)
        steppingStack--;
}

function exceptionWasRaised(sourceId, line)
{
    pause();
    updateFunctionStack();
    jumpToLine(sourceId, line);
}

function showConsoleWindow()
{
    if (!consoleWindow)
        consoleWindow = window.open("console.html", "console", "top=200, left=200, width=500, height=300, toolbar=yes, resizable=yes");
    else
        consoleWindow.focus();
}

function closeFile(fileIndex)
{
    if (fileIndex != -1) {
        currentFile = -1;
        var file = files[fileIndex];
        var sourcesDocument = document.getElementById("sources").contentDocument;
        // Clean up our file's content 
        sourcesDocument.getElementById("file" + fileIndex).removeChildren();
        // Remove the file from the open files pool
        delete sourcesDocument.getElementById("file" + fileIndex);

        var filesSelect = document.getElementById("files");
        // Select the next loaded file. If we're at the end of the list, loop back to beginning. 
        var nextSelectedFile = (filesSelect.selectedIndex + 1 >= filesSelect.options.length) ? 0 : filesSelect.selectedIndex;
        // Remove the file from file lists
        filesSelect.options[filesSelect.selectedIndex] = null;        
        SiteBrowser.removeFile(fileIndex);
        delete files[fileIndex];
        
        // Clean up the function list
        document.getElementById("functions").removeChildren();

        // Display appropriate place-holders, if we closed all files
        if (filesSelect.options.length < 1) {
            document.getElementById("filesPopupButtonContent").innerHTML = "<span class='placeholder'>&lt;No files loaded&gt;</span>";
            document.getElementById("functionNamesPopup").style.display = "none";
        }
        else 
            switchFile(nextSelectedFile);
    }    
}

function closeCurrentFile()
{
    closeFile(currentFile);
}
