// Modified: 03.17.08

// Miscellaneous
var sDispEl = "dispel";
var sUIEl = "inpel";
var sInput = "input";
var sInitBox = "initbox";
var sResName = "recommend";
var sNeedName = "primary";
var sFormName = "lllform";
var sShow = "block";
var sHide = "none";
var sHidden1 = "hidden1";
var sHidden2 = "hidden2";
var sErrorBox = "errorbox";
var sErrorMsg = "errmsg";
var sErrorIcon = "erricon";
var sErrorSpace = "space";
var sError = "Error:  ";
var sErrIconExt;
var sErrTextName;
var sErrFocusName;
var sSuffixes = "abcdefgh";
var sNumbers = "0123456789";
var aDIVNames = ["amt",
                 "funds",
                 "ccf",
                 "need",
                 "coll"];
var aNeeds = ["Run",
			  "Ref",
			  "Inv",
			  "Fin",
			  "Buy",
			  "Equ",
			  "Veh",
			  "REP",
			  "Agr"];
                 
var nConfirmID = 1;
var nErrPassThruID = 10;
var nCurrentError = 0;

// Display variables
var nLastNonDynLayer = 1;
var nNumLayers = 4;
var nDisplayLayer= 0;
var nInputLayer= 0;
var aStringTable = ["Do you want to own the equipment at the end of the term?",
                    "Yes",
                    "No",
                    "Do you want to own the vehicle at the end of the term?",
                    "Do you want to use savings or CDs to secure the funds?",
                    ", I want to own the equipment at the end of the term",
                    ", I don't want to own the equipment at the end of the term",
                    ", I want to own the vehicle at the end of the term",
                    ", I don't want to own the vehicle at the end of the term",
                    ", I want to use savings or CDs to secure the funds",
                    ", I don't want to use savings or CDs to secure the funds"];
var aErrorTable =  ["Changing an answer will cause you to lose any subsequent answers. If you are sure you want to make the change, choose OK, otherwise choose Cancel.",
                    "Select a credit card feature.",
                    "Select your primary business need or intent for the funds.",
                    "Answer the questions in the order they appear.",
                    "Enter responses to all questions before requesting a recommendation."];
var aLayerNum =   [1, 1, 2, 1];
var aLayerStart = [1, 2, 3, 5];
var aLayerDID =   [1, 0, 0, 0];
var aLayerIID =   [1, 0, 0, 0];
var aIIDOffset =  [1, 4, 10, 40];
var nNumDIDs = 5;
var aDIDDef =     [1, 4, 10, 18, 40];

// State variables
var sStVersion = "02/29/08a";
var sStRevision = "5";
var aStateTable = ["1@1-0$1!2#.",
                   "*0$1)200].",
                   "*0$1)203].",

                   "2@2-0$1!2#.",
                   "*0$1)308].",
                   "*0$1)300].",
                   "2@2-0$1!2#.",
                   "*0$1)319].",
                   "*0$3)9].",

                   "3@3-0$2!7#.",
                   "*0$7)0].",
                   "*0$3)1].",
                   "*0$3)2].",
                   "*0$3)3].",
                   "*0$3)4].",
                   "*0$3)5].",
                   "*0$3)6].",
                   "3@4-0$2!10#.",
                   "*0$7)0].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$3)10].",
                   "*0$3)12].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "3@4-0$2!10#.",
                   "*0$7)0].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)400].",
                   "*0$1)403].",
                   "*0$1)406].",
                   "*0$1)400].",
                   "*0$1)400].",

                   "4@5-5$1!2#.",
                   "*1002$4)7].",
                   "*1103$4)8].",
                   "4@5-1$1!2#.",
                   "*602$3)10].",
                   "*703$3)11].",
                   "4@5-4$1!2#.",
                   "*802$3)12].",
                   "*903$3)13]."];
var nSizeStateTable = 0;
var nStLayer = 0;
var nStDID = 0;
var nStType = 0;
var nStInputs = 0;
var nStTID = 0;
var nStCmd1 = 0;
var nStParam1 = 0;
var nStCondition = 0;
var nStCmd2 = 0;
var nStParam2 = 0;
var nStAmount = 0;
var nXIDOffset = 48;

// Calculation variables
var nPendingData;
var aInputData = [0, 0, 0, 0];
var nNeedLayer = 3;
var nResult;
var sNeed = "";


// Page initialization
function InitPage() {
    // Initialize display state
    aLayerDID[0] = 1;
    aLayerDID[1] = 2;
    aLayerIID[0] = 1;
    aLayerIID[1] = 4;
    nDisplayLayer = 1;
    nPendingData = 0;
    nResult = 0;

    for (var i = 1; i <= nNumDIDs; i++) {
        ClearInput(i);
    }

    if ((object = GetObject(sInitBox)) != null) {
        object.style.display = sShow;
    }
}


// Primary item state initialization
function InitPrimeItemState() {
    nStLayer = 0;
    nStDID = 0;
    nStType = 0;
    nStInputs = 0;
    InitSecItemState();
}


// Secondary item state initialization
function InitSecItemState() {
    nStTID = 0;
    nStCmd1 = 0;
    nStParam1 = 0;
}


// Shows or Hides display element
function ShowDisplayElement(nDID, bShow) {
    var name = sDispEl + "_" + aDIVNames[nDID - 1];
    var object = GetObject(name);

    if (object != null) {
        object.style.display = (bShow) ? sShow : sHide;
    }
}


function UpdateDisplay(nLayer) {
    var layer = (nLayer > nLastNonDynLayer) ? nLayer : nLastNonDynLayer;

	// Show proper displayable element for specified layer
	UpdateLayer(nLayer);

    if (nCurrentError != 0) {
        ShowErrorBox(0);
        UpdateErrorIcon(sErrIconExt, false);
        UpdateErrorText(sErrTextName, false);
        nCurrentError = 0;
    }

	layer++;

	if (layer <= nNumLayers) {
		// Hide all lower level layers
		for (var i = layer; i <= nNumLayers; i++) {
			HideLayer(i);
		}
	}
}


function GetADAText(nTID) {
    var sText;

    if (nTID < 100) {
        sText = aStringTable[nTID - 1];
    } else {
        var nTextID = nTID % 10000;
        var nPlacement = (nTID - nTextID) / 10000;
        var nShown = nTextID % 100; 
        var nHidden = (nTextID - nShown) / 100;
        var sShown = aStringTable[nShown - 1];
        var sHidden = (nPlacement == 1) ? sHidden1 : sHidden2;
        var sHiddenText = "<span class='" + sHidden + "'>" + aStringTable[nHidden - 1] + "</span>";

        sText = (nPlacement == 1) ? sHiddenText + sShown :  sShown + sHiddenText;
    }

    return sText;    
}


function GetNameSuffix(nIndex) {
    var sRet = "";

    if (nIndex <= sSuffixes.length) {
        sRet = sSuffixes.charAt(nIndex - 1);
    }
    
    return sRet;
}
 

function UpdateUIElementText(nDID, nIndex, nTID) {
    var name = sUIEl + "_" + aDIVNames[nDID - 1] + "_" + GetNameSuffix(nIndex);

    if (nTID != 0) {
        var sText = GetADAText(nTID);
        var object = GetObject(name);

        if (object != null) {
            object.innerHTML = sText;
        }
    }
}


function UpdateLabelText(nDID, nTID) {
    var name = sUIEl + "_" + aDIVNames[nDID - 1];

    if (nTID != 0) {
        var sText = aStringTable[nTID - 1];
        var object = GetObject(name);

        if (object != null) {
            object.innerHTML = sText;
        }
    }
}


function UpdateDropExt(nDID, index, nTID) {
    // Unused in this version of BofA-LLL
}


function SetResultValues(nRID, nData) {
    nResult = nRID;
    if (nData > 0) {
        sNeed = aNeeds[nData - 2];
    }
}


function ClrResultValues() {
    nResult = 0;
    sNeed = "";
}
   

function HandleExpression(nXID) {
    // Unused in this version of BofA-LLL
}

function HandleOption(nID) {
    // Unused in this version of BofA-LLL
}


function HandleInit(nInitType, nParam1, nParam2) {
    var bUpdate = false;

    if (nInitType == 0) {
        ClrResultValues();
        nDisplayLayer = nParam1;
        bUpdate = true;
    }

    return bUpdate;
}


function HandleSet(nSetType, nParam1, nParam2) {
    // Unused in this version of BofA-LLL
}


function HandleJump(nID) {
    // Unused in this version of BofA-LLL
}


function ShowErrorBox(nError) {
    var sDisp = (nError > 0) ? sShow : sHide;
    var object;

    if ((object = GetObject(sErrorBox)) != null) {
        object.style.display = sDisp;

        if (nError > 0) {
            if ((object = GetObject(sErrorMsg)) != null) {
                object.innerHTML = sError + aErrorTable[nError - 1];
            }
        }
    }
}


function GetErrorNames(nType, nDID) {
    sErrIconExt = aDIVNames[nDID - 1];
    sErrTextName = sUIEl + "_" + aDIVNames[nDID - 1];
    sErrFocusName = (nType == 1) ? sErrTextName + "_" + GetNameSuffix(1) : sErrTextName;
}


function DisplayError(nLayer, nError) {
    var nDID = aLayerDID[nLayer - 1];
    ShowErrorBox(nError);

    switch (nError) {
        case 2:
        case 3: {
            GetErrorNames(2, nDID);
            break;
        }

        case 4:
        case 5: {
            var iid = aLayerIID[nLayer - 1];

            // Get input type for error names
            InitSecItemState();
            ParseStateItem(iid);
            GetErrorNames(nStType, nDID);
            break;
        }
    }

    UpdateErrorIcon(sErrIconExt, true);
    UpdateErrorText(sErrTextName, true);
    SetFocus(sErrFocusName);
}


function PreGotoExtension(nLayer, nDID) {
    var nError = 0;

    switch (nLayer) {
        case 1: {
            SetResultValues(1, 0);
            break;
        }

        default: {
            // Unsupported parameter values
            break;
        }
    }
      
    return nError;
}


function PostGotoExtension(nLayer, nDID) {
    // Unused in this version of BofA-LLL
}


function ClearInput(nDID) {
    var iid = aDIDDef[nDID - 1];
    var nLayer = GetLayer(nDID);

    if (iid > 0) {
        UpdateInputItem(iid, false);
        aInputData[nLayer - 1] = 0;
    }
}


function UpdateInput(nLayer, bUpdate) {
    var index = nLayer - 1;
    var iid = aLayerIID[index];

    if (iid != 0) {
        UpdateInputItem(iid, bUpdate);

        if (!bUpdate) {
            aInputData[index] = 0;
        }
    }
}


function UpdateInputItem(nIID, bUpdate) {
    InitSecItemState();
    ParseStateItem(nIID);

    switch (nStType) {
        case 1: {  // RB
            for (i = 1; i <= nStInputs; i++) {
                var bCheck = (i == nPendingData) ? bUpdate : false;
                SetRBInput(nStDID, i, bCheck);
            }
            break;
        }

        case 2:  // DROP
        case 3: {
            var value = (bUpdate) ? (nPendingData - 1) : 0;
            SetDropInput(nStDID, value);
            break;
        }
    }
}


function RestoreInputState(nLayer) {
    nPendingData = aInputData[nLayer - 1];
    UpdateInput(nLayer, true);
}


function CheckForError(nLayer) {
    var nError = 0;

    // Check for change of previous choice
    if (nLayer < nInputLayer) {
        nError = nErrPassThruID;
        if (aInputData[nLayer - 1] != nPendingData) {
            if (window.confirm(aErrorTable[nConfirmID - 1])) {
                // OK response
                for (var i = nLayer; i <= nNumLayers; i++) {
                    UpdateInput(i, (i == nLayer));
                }

                ClrResultValues();
                nError = 0;
            } else {
                // Cancel response
                RestoreInputState(nLayer);
            }
        }
    }
      
    return nError;
}


function CheckResultsError() {
    var nError = 0;
    var nLayer = nDisplayLayer;
    var nIID = aLayerIID[nLayer - 1];

    // Get input type to check
    InitSecItemState();
    ParseStateItem(nIID);

    switch (nStType) {
        case 2:    // DROP
        case 3: {  // DROPX
            if (aInputData[nLayer - 1] <= 1) {
                nError = (nStDID == 3) ? 2 : 3;
            }
            break;
        }

        default: {
            if (aInputData[nLayer - 1] == 0) {
                nError = 5;
            }
            break;
        }
    } 
    
    if (nError != 0) {
        HandleError(nLayer, nError);
    }
}


function GetResults() {
    if (nResult > 0) {
		SetInputVal(sResName, nResult);
		SetInputStr(sNeedName, sNeed);

        var object = GetObject(sFormName);
        if (object != null) {
            object.submit();
        }
    } else {
        CheckResultsError();
    }
}


function GetObject(sName) {
	if (document.getElementById) {
		return document.getElementById(sName);
	} else if (document.all) {
		return document.all[sName];
	} else if (document.layers) {
		return document.layers[sName];
	}
}


function SetFocus(sName) {
	var object = GetObject(sName);
    if (object != null) {
		object.focus();
	}
}


function UpdateLayer(nLayer) {
    var index = nLayer - 1;
    var num = aLayerNum[index];
    var nStart = aLayerStart[index];
    var nShow = aLayerDID[index];

    // Show or Hide all displayable elements in layer appropriately
    for (var i = 0; i < num; i++) {
        var bShow = ((nStart + i) == nShow) ? true : false;
	
        ShowDisplayElement(nStart + i, bShow);
    }
}


function HideLayer(nLayer) {
    var index = nLayer - 1;
    var num = aLayerNum[index];
    var nStart = aLayerStart[index];
    var i;

    // Hide all displayable elements in layer
    for (i = 0; i < num; i++) {
        ShowDisplayElement((nStart + i), false);
    }

    // Clear data values for layer
    aLayerDID[index] = 0;
    aLayerIID[index] = 0;
    aInputData[index] = 0;
}


function IsNumber(ch) {
    return ((sNumbers.indexOf(ch) >= 0) ? true : false);
}


function ParseStateItem(nIID) {
    var sStItem = aStateTable[nIID - 1];
    var len = sStItem.length;
    var num = 0;
    var nItemType = 1;

    for (var i = 0; i < len; i++) {
        var ch = sStItem.charAt(i);
        var bError = false;

        if (IsNumber(ch)) {
            num *= 10;
            num += sNumbers.indexOf(ch);
        } else {
            switch (ch) {
                case '@': {
                    if (nItemType != 1) bError = true;
                    nStLayer = num;
                    num = 0;
                    break;
                }

                case '-': {
                    if (nItemType != 1) bError = true;
                    nStDID = num;
                    num = 0;
                    break;
                }

                case '$': {
                    if (nItemType == 3) bError = true;
                    nStTID = num;
                    num = 0;
                    break;
                }

                case '!': {
                    if (nItemType != 1) bError = true;
                    nStType = num;
                    num = 0;
                    break;
                }

                case '#': {
                    if (nItemType != 1) bError = true;
                    nStInputs = num;
                    num = 0;
                    break;
                }

                case '*': {
                    nItemType = 2;
                    break;
                }

                case '+': {
                    nItemType = 3;
                    break;
                }

                case '}': {
                    if (nItemType != 3) bError = true;
                    nStAmount = num;
                    num = 0;
                    break;
                }

                case '<': {
                    if (nItemType != 3) bError = true;
                    num += 1;
                    break;
                }

                case '=': {
                    if (nItemType != 3) bError = true;
                    num += 3;
                    break;
                }

                case '>': {
                    if (nItemType != 3) bError = true;
                    num += 2;
                    break;
                }

                case '?': {
                    if (nItemType != 3) bError = true;
                    nStCondition = num;
                    num = 0;
                    break;
                }

                case ')': {
                    if (nItemType == 1) bError = true;
                    nStCmd1 = num;
                    num = 0;
                    break;
                }

                case ']': {
                    if (nItemType == 1) bError = true;
                    nStParam1 = num;
                    num = 0;
                    break;
                }

                case '(': {
                    if (nItemType != 3) bError = true;
                    nStCmd2 = num;
                    num = 0;
                    break;
                }

                case '[': {
                    if (nItemType != 3) bError = true;
                    nStParam2 = num;
                    num = 0;
                    break;
                }

                case '.': {
                    if (i != (len - 1)) bError = true;
                    break;
                }

                default: {
                    bError = true;
                    break;
                }
            }
        }
    } 
}

 
function MapSIDtoIID(nSID) {
    var offset = nSID % 100;
    var index = ((nSID - offset) / 100) - 1;
    var iid = aIIDOffset[index] + offset;

    return iid;
}


function HandleGoto(nSID) {
    var iid = MapSIDtoIID(nSID);
    var bParsing = true;
    var bUpdate = false;
    
    // Reset state variables
    InitPrimeItemState();
    
    while (bParsing) {
        var index;
        var i;

        // Set state variables for displayable element
        ParseStateItem(iid);
        UpdateLabelText(nStDID, nStTID);
        nDisplayLayer = nStLayer;
        index = nDisplayLayer - 1;
        
        bParsing = false;

        // Process by type
        switch (nStType) {
            case 1: {  // RB
                aLayerDID[index] = nStDID;
                aLayerIID[index] = iid;

                for (i = 1; i <= nStInputs; i++) {
                    InitSecItemState();
                    ParseStateItem(iid + i);
                    UpdateUIElementText(nStDID, i, nStTID);
                    bUpdate = true;
                }
                break;
            }

            case 2: {  // DROP
                aLayerDID[index] = nStDID;
                aLayerIID[index] = iid;
                bUpdate = true;
                break;
            }
            
            case 3: {  // DROPX
                aLayerDID[index] = nStDID;
                aLayerIID[index] = iid;

                for (i = 1; i <= nStInputs; i++) {
                    InitSecItemState();
                    ParseStateItem(iid + i);
                    UpdateDropExt(nStDID, i, nStTID);
                    bUpdate = true;
                }
                break;
            }

            case 4: {  // ED
                bParsing = true;
                iid += nStInputs;
                break;
            }

            case 5: {  // SUB
                // SUB is currently invalid case");
                break;
            }
        }
    }

    return bUpdate;
}


function HandleCalc(nRID) {
    nDisplayLayer = nInputLayer;
    SetResultValues(nRID, 0);
}


function HandleCalcExt(nRID, nLayer) {
    nDisplayLayer = nInputLayer;
    SetResultValues(nRID, aInputData[nNeedLayer - 1]);
}


function UpdateErrorIcon(ext, bError) {
    var sIcon = sErrorIcon + ext;
    var sSpace = sErrorSpace + ext;
    var sIconDisp = (bError) ? sShow : sHide;
    var sSpaceDisp = (bError) ? sHide : sShow;
    var object;

    if ((object = GetObject(sIcon)) != null) {
        object.style.display = sIconDisp;
    }

    if ((object = GetObject(sSpace)) != null) {
        object.style.display = sSpaceDisp;
    }
}


function UpdateErrorText(sName, bError) {
    var sColor = (bError) ? sErrClr : sNormClr;
    var object = GetObject(sName);

    if (object != null) {
        object.style.color = sColor;
    }
}


function HandleError(nLayer, nError) {
    if (nError != nErrPassThruID) {
        DisplayError(nLayer, nError);
        nCurrentError = nError;
        ClrResultValues();
    }
}


function GetLayer(nDID) {
    var nLayer = 0;

    for (var i =0; i < nNumLayers; i++) {
        if ((aLayerStart[i] + aLayerNum[i] - 1) >= nDID) {
            nLayer = i + 1;
            break;
        }
    }    
    
    return nLayer;
}


function GetDID(sName) {
    var nDID = 0;

    for (var i =0; i < nNumDIDs; i++) {
        if (aDIVNames[i] == sName) {
            nDID = i + 1;
            break;
        }
    }    
    
    return nDID;
}


function SetInputVal(sName, nValue) {
    var object = GetObject(sName);

    if (object != null) {
        object.value = nValue;
    }
}

function SetInputStr(sName, sText) {
    var object = GetObject(sName);

    if (object != null) {
        object.value = sText;
    }
}


function SetRBInput(nDID, nID, bCheck) {
    var form = GetObject(sFormName);

    if (form != null) {
        var len = form.length;
        var name = sInput + "_" + aDIVNames[nDID - 1];
        var object;
        
        for (var i = 0; i < len; i++) {
            if (form.elements[i].name == name) {
                object = form.elements[i + nID - 1];
                break;
            }
        }

        if (object != null) {
            object.checked = bCheck;
        }
    }
}


function SetDropInput(nDID, nIndex) {
    var name = sInput + "_" + aDIVNames[nDID - 1];
    var object = GetObject(name);

    if (object != null) {
        object.selectedIndex = nIndex;
    }
}


function HandleInputIndex(nDID, nIndex) {
    var nLayer = GetLayer(nDID);
    var nError = CheckForError(nLayer);

    if (nError > 0) {
        HandleError(nLayer, nError);
    } else {
        var iid = aLayerIID[nLayer - 1];
        var bUpdate = false;

        if (iid == 0) {
            nStCmd1 = 0;
        } else {
            iid += nIndex;
            aInputData[nLayer - 1] = nPendingData;
            nInputLayer = nLayer;
    
            // Reset and set state variables
            InitSecItemState();
            ParseStateItem(iid);
        }

        // Process command
        switch (nStCmd1) {
            case 1: {  // GOTO
                ClrResultValues();
                bUpdate = HandleGoto(nStParam1);
                break;
            }

            case 2: {  // GOTOX (GOTO with Extensions)
                nError = PreGotoExtension(nLayer, nDID);

                if (nError == 0) {
                    bUpdate = HandleGoto(nStParam1);
                    PostGotoExtension(nLayer, nDID);
                } else {
                    HandleError(nLayer, nError);
                }
                break;
            }

            case 3: {  // CALC
                HandleCalc(nStParam1);
                bUpdate = true;
                break;
            }

            case 4: {  // CALCX
                HandleCalcExt(nStParam1, nLayer);
                bUpdate = true;
                break;
            }

            case 5: {  // EXP
                HandleExpression(nStParam1);
                break;
            }

            case 6: {  // OPT
                HandleOption(nStParam1);
                break;
            }

            case 7: {  // INIT
                bUpdate = HandleInit(nStParam1, nLayer, nIndex);
                break;
            }

            case 8: {  // SET
                HandleSet(nStParam1, nLayer, nIndex);
                break;
            }

            case 9: {  // JUMP
                ClrResultValues();
                bUpdate = HandleJump(nStParam1);
                break;
            }

            case 10: {  // ERR
                nCurrentError = nStParam1;
                nDisplayLayer = nInputLayer;
                bUpdate = true;
                break;
            }

            case 11: {  // NOP
                nDisplayLayer = nInputLayer;
                bUpdate = true;
                break;
            }

            default: {
                // Invalid command");
                break;
            }
        }

        if (bUpdate) {
            UpdateDisplay(nDisplayLayer);
        }
    }	
}


function RadioEvent(sName, nIndex) {
    nPendingData = nIndex;
    var nDID = GetDID(sName);
    HandleInputIndex(nDID, nIndex);
}


function SelectEvent(sName) {
    var nDID = GetDID(sName);
    var name = sInput + "_" + aDIVNames[nDID - 1];
    var object = GetObject(name);

    if (object != null) {
    	if (object.selectedIndex > 4 && sName == 'need') {
        	nPendingData = object.selectedIndex + 2;
        }else{
        	nPendingData = object.selectedIndex + 1;
        }
        if (sName == 'need') {
        	HandleInputIndex(nDID, nPendingData);
        	if (object.selectedIndex == 7){
        		RadioEvent('coll',2);
        		HideLayer(4);
        		        	
        	}
        }else{
        	HandleInputIndex(nDID, nPendingData);
        }
    }
}


