
//This regex patter is used to detect if the box title is for old appx debugger
const OLD_DEBUGGER_PATTERN = new RegExp('^ \\d{7}\\.\\d{3}\\.\\d{7} $'); // Pattern _#######.###.#######_

/*
** This function detects if the box is OLD ILF Debugger screen.
** This logic came from java client
** Note that old debugger is being generated by the engine
*/
function isIlfDebugger(box){
    // Title of the box should have the following pattern
    // Pattern _#######.###.#######_ where #=0-9, _=space
    // Column 36                   57
    var boxTitlePart = "";
    //the title for debugger is most likely under screenTextTitle, so check that first
    if(box && box.widget && box.widget.screenTextTitle && box.widget.screenTextTitle.length >=57){
        //get the area we are interested in
        boxTitlePart = box.widget.screenTextTitle.substring(36,57);
        //see if this area matches the patter we are expecting
        return(OLD_DEBUGGER_PATTERN.test(boxTitlePart));
    }
    if(box && box.widget && box.widget.wLabel && box.widget.wLabel.length >=57){
        //get the area we are interested in
        boxTitlePart = box.widget.wLabel.substring(36,57);
        //see if this area matches the patter we are expecting
        return(OLD_DEBUGGER_PATTERN.test(boxTitlePart));
    }
    return false
}

/*
** This function does merge boxes on old ilf debugger so it looks better
** Box 0 is the main box
** Box 1 is statements Box - this is scrolling
** Box 2 is inspector box - This is scrolling
** Box 3 is footer box
*/
function ilfDebugger_mergeBoxes(){
    var mainBox;
    var statementBox;
    var inspectorBox, inspectorBoxIndex;
    var footerBox, footerBoxIndex;
    /*
    ** we need to fisrt identify our main 4 boxes
    ** The first box is going to be the main one,
    ** the second one is going to be statementBox followed by bunch os scrolling region boxes
    ** after all scrolling regions we get another scroll box which is our inspector box. 
    ** after inspector box we have 2 scrolling regions followed by footer box.
    */
    for (var i = 0; i < appx_session.current_show.boxes.length; i++) {
        var box = appx_session.current_show.boxes[i];
        if(i == 0){
            mainBox = box;
            mainBox.ilfDebuggerMain = true;
            continue;
        }
        if( i == 1){
            statementBox = box;
            statementBox.ilfDebuggerStatements = true;
            continue;
        }
        //skip over scrolling regions
        if (appxIsScrollReg(box)){
            if(!inspectorBox){
                //if we have not reached inspector box yet, we are processing statement lines - mark them as such
                box.ilfDebuggerStatementLine = true;
            }
            continue;
        }
        if(appxIsScroll(box)){
            inspectorBox = box;
            inspectorBoxIndex = i;
            continue;
        }
        else{
            footerBox = box;
            footerBoxIndex = i;
        }
    }//end for

    //Adding an exception for old ilf debugger here. We want to remove the first line. The first line is title and it is already in 
    //screenTextTitle, but since the engine is created the first line, html client doesn't receive the isTitle attribute. So, we remove it
    //since we know that it shouldn't be there.
    for (var j = 0; j < mainBox.rowtext.length; j++) {
        var rowtxt = mainBox.rowtext[j];
        if (rowtxt.pos_row == 1 && rowtxt.string && rowtxt.string.trim().length > 0) {
            rowtxt.string = "";
        }
    }
    //Merge the footerbox with the main box
    //Note: footer bar doesn't exist if the APPX_OLD_DBG env is not set
    if(footerBox && mainBox){
        mainBox.ilfDebuggerHasFooterBox = true;
        mainBox.end_row = footerBox.end_row;
        footerBox.newbox = 0; //index of mainBox
        appxMergeBoxes(footerBox, mainBox);
        //box3.scrollrow = box1.begin_row - (box3.begin_row - 1);
    }
    //no footerbox. Expand the main box to the end of inspector box
    else if(inspectorBox && mainBox){
        mainBox.end_row = inspectorBox.end_row;
    }
    //next we need to somehow convert the inspector's scrolling screen to look line normal screen and display it at the bottom 
    //of statement box.
    if(inspectorBox){
        inspectorBox.bit_mask = inspectorBox.bit_mask ^ SCROLL; //turn off the scroll bit by doing xor
        inspectorBox.newbox = 0; //pretend that it is merged so we don't display it
        //anything between inspectorbox to footerbox is scroll region for inspectorBox - if footerbox exists, otherwise anything after the inspectorbox index is partt of the inspectorbox scroll region
        var ispectorBoxEndRegion = footerBox?footerBoxIndex: appx_session.current_show.boxes.length;
        for( i = inspectorBoxIndex + 1; i < ispectorBoxEndRegion; i++){
            var inspectorBoxRegion = appx_session.current_show.boxes[i];
            inspectorBoxRegion.bit_mask = inspectorBoxRegion.bit_mask ^ SCROLL_REG; //turn off the bit for scroll region
            inspectorBoxRegion.newbox = 0; //index of inspector region
            //Move all the items, widgets, and rotexts to the main box - doesn't seem to need any position adjustment
            while (inspectorBoxRegion.items.length) {
                mainBox.items.push(inspectorBoxRegion.items.shift());
            }
            while (inspectorBoxRegion.rowtext.length) {
                mainBox.rowtext.push(inspectorBoxRegion.rowtext.shift());
            }
            //let the mergebox hendle the widgets since they need position adjustments
            while (inspectorBoxRegion.widgets.length) {
                //need to add 1 to the adjusted positions since they are not part of the scrolling box so they position correctly
                var topAdj = inspectorBoxRegion.begin_row + 1 - mainBox.begin_row;
                var leftAdj = inspectorBoxRegion.begin_column + 1 - mainBox.begin_column;
                var topAdjPx = topAdj * appx_session.rowHeightPx;
                var leftAdjPx = leftAdj * appx_session.colWidthPx;
                var boxwdgt = inspectorBoxRegion.widgets.shift();
                var wx = boxwdgt[0];
                var $tag = boxwdgt[1];
                wx.wPositionY += topAdj;
                wx.wPositionX += leftAdj;
                if ($tag) {
                    $tag.css({
                        "top": (parseInt($tag.css("top")) + topAdjPx) + "px",
                        "left": (parseInt($tag.css("left")) + leftAdjPx) + "px",
                        "font-size": "inherit" //we need this to be able to match the label font size with rowtext font size
                    });
                    //add class so we can change the style later
                    $tag.addClass("appxILFDebugger-inspector-header");
                }
                mainBox.widgets.push(boxwdgt);
            }
        }
    }


    appx_session.topboxid = 0; //index of mainBox
}


//create old ilf editor's footer buttons
/*engine creates these buttons and set them on the screen via screen text. There are 2 issues here:
**  1. engine doesn't send screen texts to html client
**  2. buttons are formatted as a textin a way so they get converted to button widget via auto gui - which html client doesn't do
**     even java cloient has dificullty converting all of them to buttons.
** So, it is best for the clinet to create these buttons locally and send the appropriate option to the engine
*/
function ilfDebugger_create_footer_buttons(){
    //we use the screenBuf to find debugger because where we use this function, the screen is not switched yet
    var $debuggerBox = $("#screenBuf .appxILFDebugger");
    if($debuggerBox.length <= 0 ){
        return; //not in debugger?
    }
    //last 3 lines are going to be the footer location. Try to find the size of the debugger then reduce it by 3
    var footerLine1 = ($debuggerBox.outerHeight() / appx_session.rowHeightPx) - 3;
    var footerLine2 = footerLine1 + 1;

    //add line 1 buttons
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine1, "col":17 }, OPT_ENTER   , "Step", "Step - Single Step (Return)"                                    ); //RETURN
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine1, "col":33 }, 2           , "Step/Return"    , "Step/Return - Continue until a Return (Opt-2)"       ); //USER_2
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine1, "col":49 }, OPT_SLCT_KEY, "Toggle Trap"       , "Toggle Trap (F3)"                                 ); //F3

    //add line 2 buttons
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine2, "col":1  }, 0           , "Go"             , "Go - Continue Execution (Opt-0)"                     ); //USER_0
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine2, "col":17 }, 1           , "Step/Into"      , "Step/Into - Step into child process or gosub (Opt-1)"); //USER_1
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine2, "col":33 }, 3           , "Step/End"       , "Step/End - Continue until current code ends (Opt-3)" ); //USER_3
    ilfDebugger_add_footer_button($debuggerBox, {"row":footerLine2, "col":49 }, OPT_CHG_MODE, "Edit Values"    , "Edit Values (F12)"                                   ); //F12
}

/*
** This function creates and adds a new button to ild debugger footer bar
** arguments:
** $box:  jQuery object of the main debugger box
** position: Position of the button in row and column {row, col}
** cmd: appx option number that is being sent to engine on click
** label: button's label
** tooltip: button's tooltip
*/
function ilfDebugger_add_footer_button($box, position, cmd, label, tooltip){
    var $button = $('<button type="button" class="appxILFDebugger-button button appx-border appx-border-bevel-raised appxwidget"></button>');
    if(tooltip){
        $button.attr("title", tooltip);
    }
    if(label){
        $button.html(label);
    }
    //add the button o the screen
    $box.append($button);
    $button.css({
        "top": (parseInt(position.row) * appx_session.rowHeightPx) + "px",
        "left":(parseInt(position.col) * appx_session.colWidthPx ) + "px"
    });
    if(cmd){
        $button.on("click", function(){
            appxwidgetcallback(cmd); 
        }); 
    }
}

/*
**This function can add extra processing to the statements that come from the engine
*/
function ilfDebugger_style_statements($statementRow){ 
    var $stmtTags = $statementRow.children(".label");
    $stmtTags.each(function(){
        //Make all comments green
        if(ilfDebugger_isComment($(this).text())){
            $(this).addClass("appxILFDebugger-comment");
        }
    });
}

/*
** Returs true if the statement is a commented statement
*/
function ilfDebugger_isComment(statement){
    if(statement.startsWith("*") || 
       statement.startsWith("C") || 
       statement.startsWith("*", 5) || //multi line comments
       statement.startsWith("*", 6)){  //comment statements
        return true;
    }
    else{
        return false;
    }
}