﻿//
// When the DOM is completely loaded and ready for consumption
// initialize our application
//
/*jsl:option explicit*/
/// <reference path="../tools/jquery-1.3.2-vsdoc2.js" />

var gftApp=null;

$(function() {    
    //setup jQuery
    $.ajaxSetup({
        cache: false,
        contentType: "application/json; charset=utf-8",
        type: "POST",
        dataType: "json",
        processData: false
    });
    
    //load up some data
    beforeAppLoad();           
      
    //init the application
    gftApp = new gftaeApplication();
    gftApp.init();
    
    toggleStyleSheets();    

    attachHandlers();
});


function attachHandlers(){
    var pwField = $('#createAccountPassword');
    if( pwField != null && pwField.length > 0 ){
        pwField.passwordStrength({
            targetDiv: '#passwordStrengthMeter',
            classes : Array('is10','is20','is30'),
            labels : Array( translate('WEAK_PASSWORD'), translate( 'MEDIUM_PASSWORD' ), translate( 'STRONG_PASSWORD' ))
        });
    }
}

//
// Define our GFT Application Class Object
//
function gftaeApplication()
{
    //application properties
    this._logerrors = true;
    
    this._appProps = null;
    this._applicationId = null;
    this._applicationTypeId = null;
    this._applicationType = null;
    this._dateFormat = "mm/dd/yyyy";
    this._language = null;
        
    this._referralId = 0;
    this._advertiserId = 0;
    this._salesId = 0;
    this._techVendorId = 0;
    this._specTypeId = 0;
    this._originUrl = "";
    this._appemail = "";
    this._isComplete = false;
    this._isVerified = false;
    this._autoResume = false;
    
    //misc.
    this._retriesBeforeFail = 5;
    this._retryAttempt = 0;
    this._applicationSteps = null;    
    this._currentStep = 0;
    this._redirectOnSubmit;
    this._formname = "gftae_form";
    this._inframe = false;    
    
    this._eventsInitialized = false;
    this._actionsInitialized = false;
    this._newapp = false;
    
    this._dealbookAccountUserName = "";
    this._dealbookAccountID = 0;
    this._fundingemail = "";
    this.groupregion = "";
    this.skipCurrentStep = false;
    this.accountType = "";
    
    var _thisapp = null; //reference to to this app. Always use this to reference this object
                         //to avoid confusion and conflicts with jQuery                        

    //we need to queue up any actions that can't occur yet. If an action affects
    //an element that isn't on the screen yet or an action that must occur
    //on elements of another step
    this._actionQueue = new Array();

    this.init = function() {
        ajaxWorking();

        this._appProps = null;
        this._applicationId = null;
        this._applicationTypeId = null;
        this._applicationType = null;
        this._dateFormat = "mm/dd/yyyy";
        this._language = null;

        this._referralId = 0;
        this._advertiserId = 0;
        this._salesId = 0;
        this._techVendorId = 0;
        this._specTypeId = 0;

        this._originUrl = "";
        this._appemail = "";
        this._isComplete = false;
        this._isVerified = false;
        this._autoResume = false;

        //misc.
        this._retryAttempt = 0;
        this._applicationSteps = null;
        this._currentStep = 0;
        this._redirectOnSubmit;
        this._nextStep = null;
        this._eventsInitialized = false;
        this._actionsInitialized = false;

        this._dealbookAccountUserName = "";
        this._dealbookAccountID = 0;
        this._fundingemail = "";
        this.groupregion = "";
        this.skipCurrentStep = false;
        this.accountType = "";

        _thisapp = this;

        //*************************************************************************
        //** examine the query string for important information that is required 
        //** before we can make a new application
        //*************************************************************************
        var query = $.query(document.location.href);

        if (hasValue(query.language)) {
            _thisapp._language = query.language;
        }

        if (hasValue(query.applicationid)) {
            _thisapp._applicationId = query.applicationid;
            _thisapp._autoResume = true;
        }

        if (!hasValue(query.applicationtype)) {
            ajaxError("getApplicationID", translate("APP_TYPE_NOT_SPECIFIED"), "applicationtype");
            _thisapp.doExit();
        }
        else {
            _thisapp._applicationType = query.applicationtype;
            _thisapp._applicationTypeId = _thisapp.getApplicationTypeID(_thisapp._applicationType);
            _thisapp.getLocalization();

            _thisapp.initializeApplication();
            _thisapp.initializeValidation();
        }

        gftApp = _thisapp;
    };
    
    //
    // init
    //
    this.initializeApplication = function()
    {        
        //Build in some failover logic in case we can't make a new ApplicationID. 
        //If this happens then we're having some system issuesand we need to stop
        //an infinite loop from happening
        if ( _thisapp._retryAttempt <= _thisapp._retriesBeforeFail )
        {
            _thisapp.getApplicationID();
            _thisapp._retryAttempt++;
        }
        else
        {
            ajaxError("initializeApplication", translate("ERROR_CREATING_NEW_APP"), "");
            appStopError();
        }
    };

    this.initializeValidation = function()
    {        
        //setup validation;
        $("#"+_thisapp._formname).validate({
            ignore: ":hidden",
            errorElement: "div",
            onkeyup: false,     
            errorClass: "gft-error",            
            focusCleanup: true,            
            showErrors: function(errorMap, errorList) {                          
                jQuery.each(errorList, function(index, item) {                               
                    $(item.element).addClass("gft-error");                    
                    return true;
                });
                this.defaultShowErrors();
            },
            invalidHandler: function(e, validator) {                                 
                //show a validation failure modal
                var infoHeader = translate("VALIDATION_FAIL_POPUP_HEADER");
                var infoText = translate("VALIDATION_FAIL_POPUP_TEXT");            
                ajaxAlert(infoHeader, infoText);
                $("#jQueryAjaxAlert").dialog("open");                
            },
            unhighlight: function(element) {                            
                $(element).removeClass('gft-error');
                $(element).parents("div .gft-container-left-form-question").find(".gft-error-icon").remove();
            },
            errorPlacement: function(error, element) {                                
                if ($(element).parents("div .gft-container-left-form-question").find(".gft-error-icon").length == 0)
                {
                    $(element).parents("div .gft-container-left-form-question").find(".clear").before("<div class=\"gft-error-icon\">&nbsp;</div>");
                }                             
            },            
            submitHandler: function(){                
                ajaxWorking("SAVING_DATA");
                $("#jQueryAjaxWorking").dialog("open");
                var fnCallback = "_thisapp.stepApplication(0)";
                _thisapp.saveApplicationStep(fnCallback);
            }
        });
    };

    //
    // init application steps
    //
    this.getStepsByApplicationType = function(keepStepPosition)
    {
        //get steps       
        $.ajax({             
            data: "{applicationTypeId:\"" + _thisapp._applicationTypeId +
                  "\",language:\"" + _thisapp._language + 
                  "\",isComplete:\"" + _thisapp._isComplete + 
                  "\",applicationId:\"" + _thisapp._applicationId + 
                  "\"}",
            url: "Application.asmx/GetStepsByApplicationTypeID",
            success: function(response) {            
                var data = eval('(' + response.d + ')');
                             
                if (hasValue(data))
                {
                    _thisapp._applicationSteps = data;
                                    
                    //parse the querystring and see if we are requesting a
                    //specific step
                    var query = $.query(document.location.href);
                    
                    if (!keepStepPosition)
                    {
                        _thisapp._currentStep = (hasValue(query.step) && query.step <= _thisapp.getLastStep()) ? query.step : 0;
                    }                                      
                                       
                    if (hasValue(query.inframe))
                    {
                        _thisapp._inframe = true;
                    }

                    //if we're all initialized then we only need to draw the steps
                    //if we are complete we need to redraw everything to make sure we
                    //make it to the thank you step
                    if (_thisapp._eventsInitialized)
                    {
                        _thisapp.drawStepList();
                        $("#jQueryAjaxWorking").dialog("destroy");
                    }
                    else
                    {
                        _thisapp.drawApplication();
                    }
                }
                else
                {
                    //this usually means there are no steps defined for the translation
                    //try resetting to the default translation
                    ajaxError("getStepsByApplicationType", translate("NO_STEPS_FOUND"), _thisapp._language);
                    
                    if (_thisapp._retryAttempt <= _thisapp._retriesBeforeFail)
                    {
                        //reset the applications language to the default, then intialize again
                        // I.E. try to auto recover because we'll assume this is a bad translation language
                        _thisapp._retryAttempt++;
                        _thisapp.setApplicationViewLanguage(_thisapp._applicationId, _thisapp.getApplicationTypeLanguage(_thisapp._applicationTypeId));                        
                        _thisapp.initializeApplication();
                    }
                    else
                    {
                        appStopError();
                    }                                        
                }                
            },
            error: function(msg) {                
                ajaxError(this.url, msg, this.data);
            }
        });
        
    };

    //wire up the buttons to move us through the steps
    this.attachEvents = function()
    {              
        //step forward
        $("#btnStepForward").click(function() {                                                                        
            if ($("#"+_thisapp._formname).valid())
            {
                $("#btnStepForward").attr("disabled", "true");
                ajaxWorking("SAVING_DATA");
                $("#jQueryAjaxWorking").dialog("open");
                
                var fnCallback = "_thisapp.stepApplication(1)";                
                _thisapp.saveApplicationStep(fnCallback);
            }
        });
        
        //step backward
        $("#btnStepBack").click(function() {
			$("#btnStepBack").attr("disabled", "true");
			ajaxWorking("SAVING_DATA");
			$("#jQueryAjaxWorking").dialog("open");

			 var fnCallback = "_thisapp.stepApplication(-1)";
			 _thisapp.saveApplicationStep(fnCallback);
        });
        
        $("#btnSubmitApp").click(function() {
            if ($("#"+_thisapp._formname).valid())
            {
                $("#jQueryAjaxWorking").dialog("destroy");
                _thisapp.submitApplication();
            }
        });
        

        $("#btnSubmitDeposit").click(function() {
        
            if ($("#"+_thisapp._formname).valid())
            {
                $("#jQueryAjaxWorking").dialog("destroy");

                fundingStepTwo(_thisapp);
                
//                //may not need this line
//                _thisapp.saveApplicationStep(null);
                _thisapp.submitDepositApplication();
                                             
                //_thisapp.submitApplication();                
            }
        });        

        //the save button should save the current state without checking for
        //validation
        $("#btnSave").click(function() {           
            ajaxWorking("SAVING_APPLICATION");
            $("#jQueryAjaxWorking").dialog("open");
            
            var fnCallback = "_thisapp.stepApplication(0)";            
            _thisapp.saveApplicationStep(null);
        });
    };

    // paint the buttons to the screen
    this.drawStepButtons = function()
    {    
        $("#gft-container-left-buttons").empty();
        
        if(_thisapp._applicationType.toLowerCase() != "funding")
        {
            $("#gft-container-left-buttons").append("<li class=\"gft-container-left-buttons-button save\" style=\"display:none;\" id=\"btnSave\">" + translate("NAVIGATION_SAVE") + "</li>");
        }
        
        $("#gft-container-left-buttons").append("<li class=\"gft-container-left-buttons-button inactive\" style=\"display:none;\" id=\"btnStepBack\">" + translate("NAVIGATION_BACK") + "</li>");
        
        if(_thisapp._applicationSteps[_thisapp._currentStep].StepCode != "funding_credit_card")
        {
            $("#gft-container-left-buttons").append("<li class=\"gft-container-left-buttons-button submit\" style=\"display:none;\" id=\"btnSubmitApp\">" + translate("NAVIGATION_SUBMIT_APPLICATION") + "</li>");
        }
        else
        {
            $("#gft-container-left-buttons").append("<li class=\"gft-container-left-buttons-button submit\" style=\"display:none;\" id=\"btnSubmitDeposit\">" + translate("NAVIGATION_SUBMIT_DEPOSIT") + "</li>");
        }
        
        $("#gft-container-left-buttons").append("<li class=\"gft-container-left-buttons-button active\" style=\"display:none;\" id=\"btnStepForward\">" + translate("NAVIGATION_SAVE_CONTINUE") + "</li>");        
        $("#gft-container-left-buttons").wrapInner("<ul></ul>");
        $("#gft-container-left-buttons").append("<div class=\"clear\"></div>");

        //99 means we are on the thank you step
        if (_thisapp._applicationSteps[_thisapp._currentStep].StepCode != "thankyou")
        {
                
                
            if (_thisapp._applicationSteps[_thisapp._currentStep].Sequence == _thisapp.getFirstStep())
            {
                $("#btnStepBack").css("display", "none");
            }
            else
            {
                $("#btnStepBack").css("display", "");
            }
            
            if (_thisapp._applicationSteps[_thisapp._currentStep].IsSubmit)
            {
                $("#btnStepForward").css("display", "none");
                
                if(_thisapp._applicationSteps[_thisapp._currentStep].StepCode != "funding_credit_card")
                {                   
                    $("#btnSubmitApp").css("display", "");
                }
                else
                {
                    $("#btnSubmitDeposit").css("display", "");
                }
            }
            else if (_thisapp._applicationSteps[_thisapp._currentStep].Sequence == _thisapp.getLastStep())
            {
                $("#btnSubmitApp").css("display", "none");
                $("#btnStepForward").css("display", "none");
            }
            else
            {
                $("#btnSubmitApp").css("display", "none");
                $("#btnStepForward").css("display", "");
            }
            
            if (_thisapp._applicationSteps[_thisapp._currentStep].CanSave)
            {
                $("#btnSave").css("display", "");
            }
            else
            {
                $("#btnSave").css("display", "none");
            }
                        
            _thisapp.attachEvents();  
        }
        else
        {        
            if (_thisapp._applicationType == "JP")
            {
                var aff_image = getAffiliateImage(_thisapp._applicationId, _thisapp._advertiserId);
                
                if (hasValue(aff_image))
                {
                    $("body").append(aff_image);
                }
            }
            
            
            if(_thisapp._applicationType.toLowerCase() == "funding")   
            {     
                try
                {                                                                                 
                    MaskNumber(_thisapp._applicationId, '1df4cc65-af52-4447-8097-6b8a61d9be51');                 
                }
                catch(err)
                {} 
            }
            
        }
                                      
        _thisapp._eventsInitialized = true;       
    };
    
    this.getLastStep = function()
    {
        var finalStep = 0;
        jQuery.each(_thisapp._applicationSteps, function(index, item) {
            if (item.IsActive && item.IsNumbered) 
            {
                finalStep = Math.max(finalStep, item.Sequence);
            }
        });
        
        return finalStep;
    };

    this.getFirstStep = function()
    {    
        var firstStep = 99;
        jQuery.each(_thisapp._applicationSteps, function(index, item) {            
            if (item.IsActive) 
            {
                firstStep = Math.min(firstStep, item.Sequence);
            }
        });
        
        return firstStep;
    };
    
    //
    // Once we have a valid applicationId that exists in the
    // database we can move on and draw the application to 
    // the screen
    //
    this.drawApplication = function(stepsOnly)
    {      
        $("#gft-container-left").empty();
        $("#gft-container-right").empty();
        _thisapp.getQuestionsByStep(_thisapp._applicationSteps[_thisapp._currentStep].StepID, _thisapp._applicationTypeId, _thisapp._applicationId, _thisapp._language, _thisapp._referralId);      
    };
    
    this.drawStepList = function()
    {
        //clear the step container
        $("#gft-container-right-steps").empty();

        //add step graphical indicator if this is a numbered step.
        if ( _thisapp._applicationSteps[_thisapp._currentStep].IsNumbered )
        {                       
            var elemId;
            var elemNum = 0;
            
            //some steps share a sequence because there are multiple paths to go
            //down, like corporate versus deposit accounts. Don't count steps with
            //the same sequence number as other steps
            var aNumbered = new Array();
            jQuery.each(_thisapp._applicationSteps, function(index, item) {
                    
                if (item.IsActive && item.IsNumbered && jQuery.inArray( item.Sequence, aNumbered ) == -1 )
                {                            
                    //denote that this sequence number is already counted.
                    aNumbered.push(item.Sequence);
                    
                    elemId = "stepIndicator" + elemNum;
                    
                    $("#gft-container-right-steps").append("<li id=\""+ elemId +"\" class=\"gft-container-right-steps-step\"><a href=\"#\">" + item.StepName + "</a></li>");

                    if (index < _thisapp._currentStep)
                    {                                
                        $("#"+elemId).addClass("completed");  
                    }
                    else if (index == _thisapp._currentStep)
                    {                                    
                        $("#"+elemId).addClass("active");                              
                    }
                    else
                    {
                        $("#"+elemId).addClass("incomplete");   
                    }
                    
                    elemNum = elemNum+1;
                }
                
                return true; 
            });
        }               

        $("#gft-container-right-steps").wrapInner("<ul></ul>");
    }

    //
    // Find an in process application that this user already started
    // this will be an id stored in a cookie. Use this to retrieve
    // any saved answers.
    //
    this.getApplicationID = function()
    {        
        if (!hasValue(_thisapp._applicationId)) //if we don't have an application id already try getting it from a cookie
        {
            // Don't check for the cookie value if this is the funding application
            if(_thisapp._applicationType.toLowerCase() != "funding")
            {
                _thisapp._applicationId = getCookieValue();
            }
        } 
        
        //if we still don't have a value then see if we want to retrieve
        //an application OR make a new one
        if (!hasValue(_thisapp._applicationId))
        {            
            _thisapp._applicationId = cEmptyGuid
        }
        
        _thisapp.findExistingApplication(_thisapp._applicationId);        
    };

    this.doExit = function()
    {        
        //document.href = "errorPage.html"
    };
    
    this.getLocalization = function(applicationTypeId)
    {
        var appTypeName = _thisapp.getApplicationTypeName(_thisapp._applicationTypeId);
        _thisapp._applicationType = appTypeName;
      
        switch(appTypeName)
        {
            case "UK":
            case "AU":
                _thisapp._dateFormat = "dd/mm/yyyy";
                $("#gftae_header").addClass("gftae-header-" + appTypeName.toLowerCase());
                break;
                
            case "JP":
                _thisapp._dateFormat = "yyyy/mm/dd";
                $("#gftae_header").addClass("gft-header-" + appTypeName.toLowerCase());
                break;
                
            default:
                _thisapp._dateFormat = "mm/dd/yyyy";
                break;
        }
        
        if ($.browser.msie)
        {
            $("#gftae_header").removeClass("gftae-header");
            $("#gftae_header").addClass("gftae-header-msie");
            
            $("#gftae_content").removeClass("gtae-content");
            $("#gftae_content").addClass("gtae-content-msie");
        }
    };

    this.getApplicationTypeID = function(applicationType)
    {
        var applicationId = 0;
        
        $.ajax({                 
                data: "{applicationType:\"" + applicationType + "\"}",
                url: "Application.asmx/GetApplicationTypeID",                
                async: false,
                success: function(response) {                    
                    var data = eval('(' + response.d + ')');
                    
                    if (isNaN(data[0].ApplicationTypeID))
                    {
                        ajaxAlert(null, translate("COULD_NOT_LOCATE_APPTYPE") + " \"" + applicationType + "\".<br /> " + translate("APP_CREATION_FAILED"));
                        _thisapp.doExit();
                    }
                    else
                    {
                        applicationId = data[0].ApplicationTypeID;                        
                    }                                        
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);
                    _thisapp.doExit();
                }            
            });
            
        return applicationId;        
    };
    
    //set the language to view this application in
    this.setApplicationViewLanguage = function(applicationId, language)
    {        
        $.ajax({                
                data: "{applicationId:'" + applicationId + 
                      "',language:\"" + language + 
                      "\"}",
                url: "Application.asmx/SetApplicationViewLanguage",
                async: false,
                success: function(response) {                    
                    var data = eval('(' + response.d + ')');                    
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);
                    _thisapp.doExit();
                }            
            });
    };     
    
    this.getApplicationTypeName = function(applicationTypeId)
    {
        var appTypeName = "";
        
        $.ajax({                 
                data: "{applicationTypeId:'" + applicationTypeId + "'}",
                url: "Application.asmx/GetApplicationTypeName",                
                async: false,
                success: function(response) {                    
                    var data = eval('(' + response.d + ')');                    
                    appTypeName = data[0].ApplicationTypeName;
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);                  
                }
            });
            
         return appTypeName;
    };
    
    this.getApplicationTypeLanguage = function(applicationTypeId)
    {
        
        var appTypeLanguage = "";
        
        $.ajax({                 
                data: "{applicationTypeId:'" + applicationTypeId + "'}",
                url: "Application.asmx/GetApplicationTypeLanguage",
                async: false,
                success: function(response) {                    
                    var data = eval('(' + response.d + ')');           
                    appTypeLanguage = data[0].LanguageCode;
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);                  
                }
            });
            
         return appTypeLanguage;
    };
    
    //
    // Create a new application
    // -stores the GUID for the database id in a cookie named "gftae_application"
    //
    this.generateNewApplication = function() {

        //*************************************************************************
        //** examine the query string for important information that is required 
        //** before we can make a new application
        //*************************************************************************
        var query = $.query(document.location.href);

        //get referral information
        if (hasValue(document.referrer)) {
            _thisapp._originUrl = document.referrer;
        }
        if (hasValue(query.rpid)) {
            _thisapp._referralId = query.rpid;
        }
        if (hasValue(query.aid)) {
            _thisapp._advertiserId = query.aid;
        }
        if (hasValue(query.advid)) // Added for Japanese affiliate who cannot use "aid"
        {
            _thisapp._advertiserId = query.advid;
        }
        if (hasValue(query.sid)) {
            _thisapp._salesId = query.sid;
        }
        if (hasValue(query.tid)) {
            _thisapp._techVendorId = query.tid;
        }

        if (hasValue(query.language)) {
            _thisapp._language = query.language;
        }

        if (hasValue(query.spectypeid)) {
            _thisapp._specTypeId = query.spectypeid;
        }

        $.ajax({
            data: "{applicationTypeId:'" + _thisapp._applicationTypeId +
                  "', rpid:\"" + _thisapp._referralId +
                  "\", aid:\"" + _thisapp._advertiserId +
                  "\", sid:\"" + _thisapp._salesId +
                  "\", tid:\"" + _thisapp._techVendorId +
                  "\", specTypeId:\"" + _thisapp._specTypeId +
                  "\", originUrl:\"" + _thisapp._originUrl +
                  "\", email:\"" + _thisapp._appemail +
                  "\", languageCode:\"" + _thisapp._language +
                  "\"}",
            url: "Application.asmx/GenerateNewApplication",
            async: false,
            success: function(response) {
                var data = eval('(' + response.d + ')');
                _thisapp._newapp = false;
                _thisapp._applicationId = data[0].ApplicationID;

                return true;
            },
            error: function(msg) {
                ajaxError(this.url, msg, this.data);
            }
        });

        //set the language on this app if one was specified
        //        if (hasValue(query.language))
        //        {        
        //            _thisapp.setApplicationViewLanguage(_thisapp._applicationId, query.language);
        //        }
    };
    
    this.isComputerPublic = function()
    {        
        var fnPublicComputer = function()
        {
            expireCookie();            
            _thisapp.initializeApplication();
        };
        
        var fnPrivateComputer = function()
        {
             //store the application id in a cookie for future reference
            // TODO: Test to see if cookies/javascript are on or fail the app?
            bakeCookie();
            _thisapp.initializeApplication();
        };
        
        title = "QUESTION_PUBLIC_TITLE";
        msg = "QUESTION_PUBLIC";
        btno = "LABEL_NO"; 
        btnyes = "LABEL_YES";   
        
        ajaxConfirm(title,
                    msg,
                    btno, fnPrivateComputer, null, 
                    btnyes, fnPublicComputer, null,
                    null);
    };

    //
    // Get all the questions on this step and display them
    // remember that some questions are linked to other questions
    // which may affect how/if they show up on the screen
    //
    var aQuestionAction = new Array();
    var answerCache = new Array();

    this.getQuestionsByStep = function(stepId, applicationTypeId, applicationId, language, referralId) {
        $.ajax({
            url: "Application.asmx/GetQuestionsByStep",
            data: "{stepId:'" + stepId +
                  "', applicationTypeId:'" + applicationTypeId +
                  "', applicationId:'" + applicationId +
                  "', language:'" + language +
                  "', rpid:\"" + referralId +
                  "\"}",
            success: function(response) {
                //var data = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;                
                var data = eval('(' + response.d + ')')[0];
                var parentID = "step_" + data.StepID;
                _thisapp._actionsInitialized = false;

                //add contact information
                $("#gftae_customheader").html(data.CustomHeaderText);

                //step header
                $("#gft-container-left").append("<div id=\"gft-container-left-introduction\"></div>");
                $("#gft-container-left-introduction").append("<div id=\"gft-container-left-legend\" class=\"gft-container-left-legend\">" + ((data.StepCode != "thankyou") ? translate("BOLD_FIELDS_REQ") : "") + "</div>");
                $("#gft-container-left-introduction").append("<div id=\"gft-container-left-step-header\" class=\"gft-container-left-introduction\"><h1>" + data.StepName + "</h1><p class=\"note\">" + (hasValue(data.StepDescription) ? data.StepDescription : "") + "</p></div>");

                //question container
                $("#gft-container-left").append("<div id=\"gft-question-container\" class=\"gft-question-container\"></div>");

                //create the right container header               
                $("#gft-container-right").html("<div id=\"gft-container-right-step-header\" class=\"gft-container-right-step-header\"><h1>" + translate("APP_STEPS") + "</h1></div>");

                //add the step container
                $("#gft-container-right").append("<div id=\"gft-container-right-steps\" class=\"gft-container-right-steps\"></div>");

                //reset the question actions
                aQuestionAction = new Array();

                // Clear the answer cache before we start displaying the current page
                answerCache = new Array();
                //2010-05-12 vshin: Initialize the answer cache with the data just read from the database
                //  (including nulls for questions not having answers yet):
                for (var i = 0; i < data.QuestionGroups.length; i++) {
                    var questionList = data.QuestionGroups[i].QuestionList;
                    for (var j = 0; j < questionList.length; j++) {
                        var answers = questionList[j].Answer;
                        answerCache[questionList[j].QuestionId] = (answers.length > 0) ? answers[0].AnswerValueText : Array(null, null);
                    }
                }

                if (data.QuestionGroups.length == 0) {
                    _thisapp.stepApplication(1);
                }
                else {
                     //draw question groups/questions/answers      
                    _thisapp.showQuestionGroups(data.QuestionGroups, parentID);

                    //run all the actions for this step                
                    addActions(aQuestionAction);

                    //-- BEGIN Welcome Step
                    // if this is the welcome step of an existing app set some values

                    if (_thisapp._applicationSteps[_thisapp._currentStep].StepCode == "welcome" && _thisapp._applicationId != cEmptyGuid) {
                        var welcomePageInputs = $("#gft-question-container input");
                        jQuery.each(welcomePageInputs, function(index, item) {

                            //is this a new app?
                            switch (index) {
                                case 0: //new app                                
                                    $(item).attr("checked", false);
                                    break;

                                case 1: //existing app
                                    //we KNOW that this needs to end up being checked no matter
                                    //what because after we save the app it's always an existing app
                                    $(item).attr("checked", true);
                                    break;

                                case 2: //application id
                                    $(item).val(_thisapp._applicationId);
                                    break;

                                case 3:  //email                  
                                    $(item).val(_thisapp._appemail);
                                    break;

                                case 4: //private computer
                                    if (hasValue(getCookieValue())) {
                                        $(item).attr("checked", true);
                                    }
                                    break;

                                case 5: //public computer
                                    if (!hasValue(getCookieValue())) {
                                        $(item).attr("checked", true);
                                    }
                                    break;
                            }

                        });
                    }
                    //-- END Welcome Step

                    //initialize the steplist
                    _thisapp.drawStepList();

                    //after we draw our questions then we update the buttons that drive us to
                    //to differnt steps and wire up the events behind them
                    $("#gft-container-left").append("<div id=\"gft-container-left-buttons\" class=\"gft-container-left-buttons\"></div>");
                    _thisapp.drawStepButtons();

                    //draw the footer
                    _thisapp.showApplicationInformation();

                    //bring the screen back to the top
                    window.scroll(0, 0);

                    //process the action queue
                    _thisapp.runActionQueue();
                    _thisapp._actionsInitialized = true;               
                }

                $("#jQueryAjaxWorking").dialog("close");

                // if this is a funding app, attach the account number
                var windowLoc = window.location.toString().toLowerCase();
                if( windowLoc.indexOf( 'applicationtype=funding' ) >= 0 ){
                    if( windowLoc.indexOf( 'acct' ) >= 0 ){
                        // Parse out the account number
                        // http://apps..../funding.aspx?applicationtype=funding&acct=123&param=val
                        var acct = windowLoc.split( 'acct' )[1].split( '&' )[0].substring( 1 );
                        $( '#e823798a-0bd9-4c41-b4d8-7b90e451150d input' ).val( acct );
                    }
                }
            },
            error: function(msg) {
                ajaxError(this.url, msg, this.data);
            }
            
        });
    };
    
    this.addActionToQueue=function(action)
    {       
        //we shouldn't need to queue question specific items since they come fresh with every step
        //make sure the action does not already exist in the queue, too
        if (!inQueue(action.QuestionLinkID) && action.LinkedQuestionID == null)
        {        
            _thisapp._actionQueue.push(action);        
        }
    };       
    
    //we need to make sure that actions happen in a specific order because
    // Groups can affect questions which can affect answers
    // This means we need to Weight the QuestionLinkActions and run the lowest
    // weighted numbers first. Use the DB to adjust which items take priorty
    // tblQuestionLinkAction.QuestionActionWeight
    this.runActionQueue=function()
    {       
        var requeue = new Array();
        var currentAction;
        var elemType;
        var answerElemId;
        var linkedGroupElemId;
        var elemN;
 
        //since we're popping we want to sort highest to lowest
        //because we want to run the highest weighted stuff last
        _thisapp._actionQueue.sort(function(a,b){
            return b.QuestionActionWeight - a.QuestionActionWeight;
        });

        jQuery.each(_thisapp._actionQueue, function(index, currentAction)        
        {    
            linkedGroupElemId = "group_"+ currentAction.LinkedQuestionGroupID;
            
            if ( $("#"+linkedGroupElemId).length > 0 )            
            {            
                elemN = currentAction.QuestionID+"_"+currentAction.QuestionGroupID;
                
                //if this is a MultiText/MultiNumber, we need to know which position
                // in the answer to get
                if (currentAction.AnswerTypeName.match(/Multi/g) || currentAction.AnswerTypeName.match(/Phone/g))
                {
                    elemN += "_"+ currentAction.AnswerTypeName.toLowerCase()+"_";
                    
                    var mav = currentAction.ActionTextValue.split("|");
                    var pos = 0;
                    
                    if ( mav.length > 1 )
                        pos = mav[1];
                    else
                        pos = mav[0];
                        
                    elemN+=pos;               
                }
                elemType = $("input[name=answer_"+elemN+"]").attr("type");
                
                //if this is a dropdown list then we have to use different syntax. Total H4ckX0r.
                if ( !hasValue(elemType) )
                {
                    elemType = $("#answer_"+elemN+"").attr("type");    
                }
                
                answerElemId = "answer_"+elemN;
                         
              
                var match = findMatch(currentAction, elemType, answerElemId);
                if (match[0])
                {
                    _thisapp.fireAction(currentAction, match[1]);
                }                                            
            }
            
            //some actions are linked only to a group and won't have
            //a linkequestionid. If this is the case always requeue it
            if (!hasValue(currentAction.LinkedQuestionID))
            {
                requeue.push( currentAction ); 
            }
        });
                                        
        _thisapp._actionQueue = requeue.slice();
        requeue = null;                
    };

    //
    // Every question must belong to a group. This gives us some additional
    // formatting options. Draw each group and the questions contained in it
    //
    this.showQuestionGroups = function(questionGroups, parentID)
    {              
        var groupElemID;
        var tagName;
        var sHeader;
        
        jQuery.each(questionGroups, function(index, item) {
            groupElemID = "group_"+item.QuestionGroupID;
               
            var validationTag = "";
            $("#gft-question-container").append("<div class=\"gft-container-left-form gft-container-left-form-active\" id=\"" + groupElemID + "\" name=\"" + groupElemID + "\"></div>");
                      
            //add question group headers
            $("#" + groupElemID).append("<div class=\"gft-container-left-introduction\"></div>")            
            var sHeader = (!item.IsHeaderHidden) ? "<h1>" + item.QuestionGroupHeader + "</h1>" : "";
            var sHeaderDesc = (hasValue(item.QuestionGroupDescription)) ? "<p class=\"questiongroupdesc\">" + item.QuestionGroupDescription + "</p>" : "";
            $("#" + groupElemID+ " .gft-container-left-introduction").append(sHeader + sHeaderDesc)        
                        
            //show questions if there are any
            if (hasValue(item.QuestionList))
            {
                _thisapp.showQuestions(item.QuestionList, (hasValue(item.QuestionAlignment))?item.QuestionAlignment:"", groupElemID, item.QuestionGroupID);
            }
           
            return true;
        });        
    };

    this.showApplicationInformation = function()
    {
        $("#gft-container-right").append("<div id=\"gft-application-information\" class=\"gft-application-information\"></div>");
                
        var sPrivacyTitle;        
        var sPrivacyLink = "";

        // Do not get the cookie value if the application type is funding
        if (_thisapp._applicationType.toLowerCase() != "funding")
        {
            if (hasValue(getCookieValue()))
            {           
                sPrivacyTitle = translate("COMPUTER_LABEL_PRIVATE");
                sPrivacyLink += "<a href='javascript:makePublic()'>" + sPrivacyTitle + "</a>";
            }
            else
            {
                sPrivacyTitle = translate("COMPUTER_LABEL_PUBLIC"); 
                sPrivacyLink += "<a href='javascript:makePrivate()'>" + sPrivacyTitle + "</a>";
            }
        }
        
        //verisign image
        $("#gft-application-information").html("<div class=\"gft-security\"></div>");
        
        //privacy
        $("#gft-application-information").append("<div id=\"gft-computer-type\" class=\"gft-computer-type\"></div>");        
        $("#gft-computer-type").html("<ul><li>Public or Shared Computer</li><li class=\"active-type\">" + sPrivacyLink + "</li></ul>");
        
        //application number
        $("#gft-application-information").append("<div id=\"gft-application-number\" class=\"gft-application-number\"></div>");
        $("#gft-application-number").html("<ul><li></li><li>" + _thisapp._applicationId + "</li><li>" + appEngineVersion + "</li></ul>");             
        
        //add a feedback link          
        if(blnDebugModeOn == true)
        {
            $("#gft-application-information").append("<div id=\"gft-application-feedback\" class=\"gft-application-feedback\"></div>");
            //$("#gft-application-feedback").append("<ul><li class=\"active-type\"><a class=\"active-type\" onClick=\"javascript:window.open('unittests/ErrorForm.aspx?applicationid=" + _thisapp._applicationId + "','', 'width=415,height=300,resizable=false,status=false,toolbar=false');\">Send your Feedback</a></li></ul>");
        }
            
        
    };        
    
    
    //
    // Draw individual questions
    //
    this.showQuestions = function(questionList, questionAlignment, groupElemID, questionGroupId) {
        jQuery.each(questionList, function(index, item) {
            var sClass = "";
            var questionContainerID = "" + item.QuestionID;
            var sQuestionText;
            var sQuestionDescription;
            var sQuestionHelp;

            //clear the floats
            $("#" + questionContainerID).append("<div class=\"clear\"/>");

            //add a new question container
            $("#" + groupElemID).append("<div class=\"gft-container-left-form-question\" id=\"" + questionContainerID + "\"></div>");

            //Is the question text hidden?
            if (!item.IsQuestionTextHidden) {
                sQuestionText = item.QuestionText;
            }
            else {
                sQuestionText = "";
            }

            //Is the question text hidden?            
            if (hasValue(item.QuestionDescription) && item.AnswerTypeName != "AgreementText") {
                sQuestionDescription = item.QuestionDescription;
            }
            else if (hasAttribute(item.AnswerTypeExtra, "w8preview")) {
                sQuestionDescription = "<a href=\"javascript:viewW8('" + _thisapp._applicationId + "')\">" + translate("PREVIEW_W8") + "</a>";
            }
            else {
                sQuestionDescription = "";
            }

            if (item.RequiredName != "None") {
                sClass = "required";
            }

            sQuestionText = "<label class=\"" + sClass + "\">" + sQuestionText + "<br/><span>" + sQuestionDescription + "</span></label>";
            $("#" + questionContainerID).append(sQuestionText);

            //show available answers for this question
            _thisapp.showAnswers(item, groupElemID, questionGroupId, questionContainerID);

            //this is a very special case and we need to assign some functions that always fire
            //when we see the answer to this question
            if (item.AnswerTypeName == "AccountType") {
                //then bind a click even to make sure any changes fire it too.
                $("input[name=answer_" + item.QuestionID + "_" + item.QuestionGroupID + "]").bind("click", function(args) {
                    var fnCallback = "gftApp.getStepsByApplicationType(true)";
                    _thisapp.accountTypeID = $("#" + item.QuestionID + "_" + item.QuestionGroupID).val();                
                    gftApp.saveApplicationStep(fnCallback);
                });

                //call this after we setup the question to make sure that if we are on a return app we have the right steps
                gftApp.getStepsByApplicationType(true);
            }



            //add an informational popup with qtip with more information if we have a description            
            sQuestionHelp = item.QuestionHelp;

            if (hasValue(sQuestionHelp)) {
                var qHelpPopup = "<div class=\"gft-container-left-form-question-information\" id=\"" + item.QuestionID + "_info\"></div>";

                $("#" + questionContainerID).append(qHelpPopup);
                $("#" + item.QuestionID + "_info").bind("click", function(e) {
                    ajaxAlert(sQuestionText, sQuestionHelp);
                    $("#jQueryAjaxAlert").dialog("open");
                });
            }

            // Agreement text
            if (hasAttribute(item.AnswerTypeExtra, "agreement")) {
                // Set info icon display to none
                $("#" + item.QuestionID + "_info").css({ 'display': 'none' });

                // Show agreement text "link"
                var htmlAgreementLink = "<div class=\"gft-agreement-link\" id=\"" + item.QuestionID + "_agreement\">" + translate("CLICK_FOR_AGREEMENT") + "</div>";
                $("#" + questionContainerID).append(htmlAgreementLink);

                // Open dialog
                $("#" + item.QuestionID + "_agreement").click(function() {
                    ajaxAgreement(sQuestionHelp);
                    $("#jQueryAjaxAlert").dialog("open");
                });
            }
            //---/ End agreement text                       

            if (hasValue(sQuestionText)) {
                $("#" + questionContainerID).append("<div class=\"clear\"/>");
            }

            //save up the actions until the step has finished drawing
            //then we'll run the queue
            jQuery.each(item.ActionList, function(index, item) {
                aQuestionAction.push(item);
                return true;
            });

            jQuery.each(item.AffectedList, function(index, item) {
                aQuestionAction.push(item);
                return true;
            });

        });
    };

    //
    // Display all possible answers controls for a question
    //
    //   answerList : array of possible answers    
    //   questionId : guid
    //   question.AnswerTypeName from tblAnswerType
    //
    this.showAnswers = function(question, groupElemID, questionGroupId, questionContainerID) {

        var answerList = question.AnswerList;
        var questionId = question.QuestionID;
        var answer = question.Answer;

        var sClass;
        var sAnswerClass;
        var sDisabled;

        var output;
        var applicationAnswer = "";
        var answerElemID;
        var answerElemName;

        var sAddTextInput = "";
        var isDisabled = "";
        var bDisabled;
        var isOtherFieldNumber = false;

        var taText = "";


        if (hasValue(answer)) {
            applicationAnswer = answer;

            if (answer.length == 1) // a single answer exists
            {
                applicationAnswer = hasValue(answer[0].AnswerValueText) ? answer[0].AnswerValueText : "";
            }
            else {
                //we have multiple answers in tblApplicationAnswer
                // (i.e. checkbox, multiselect, etc)
                // turn this into a delimited string
                jQuery.each(answer, function(index, item) {
                    applicationAnswer += item.AnswerValueText;
                    if (index < answer.length - 1) applicationAnswer += gftae_delimiter;

                    return true;
                });
            }
        }

        //if there are several answers then draw the answer types (checkboxes, dropdownlists, radio, etc)
        if (answerList.length > 0 || question.AnswerTypeName == "DropDown") {
            switch (question.AnswerTypeName) {
                //dropdown lists are special                              
                case "DropDown":
                    var answerElemID = "answer_" + questionId + "_" + questionGroupId;
                    var output = "";

                    //AnswerTypeExtra will contain the lookup table we want to go get our answers from                    
                    switch (question.AnswerTypeExtra) {
                        case "Country":
                            var outputDefault = "<option value=\"0\">" + translate("SELECT_COUNTRY") + "</option>";

                            jQuery.each(countryList, function(index, item) {
                                if ((gftApp._applicationType == "US" && item.country == "United States") || (gftApp._applicationType == "AU" && item.country == "Australia") || (gftApp._applicationType == "UK" && item.country == "United Kingdom") || (gftApp._applicationType == "JP" && item.country == "Japan") || (gftApp._applicationType == "SG" && item.country == "Singapore")) {
                                    if (gftApp._applicationType == "JP" && item.country == "Japan") {
                                        var usOnTop = "<option value=\"" + item.country_id + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName, "country_id") + " >日本</option>";
                                        output = usOnTop + output;
                                    }
                                    else {
                                        var usOnTop = "<option value=\"" + item.country_id + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName, "country_id") + " >" + item.country + "</option>";
                                        output = usOnTop + output;
                                    }
                                }
                                else {
                                    output += "<option value=\"" + item.country_id + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName, "country_id") + " >" + item.country + "</option>";
                                }
                            });
                            break;

                        case "State":
                            output += "<option value=\"0\">" + translate("SELECT_STATE") + "</option>";
                            jQuery.each(stateList, function(index, item) {
                            output += "<option value=\"" + item.StateID + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName, "StateID") + " >" + item.State1 + "</option>";
                            });
                            break;

                        //by default, assume the answers are in the answer table                              
                        default:
                            output += "<option value=\"0\">" + translate("SELECT_VALUE") + "</option>";
                            jQuery.each(answerList, function(index, item) {
                                output += "<option value=\"" + item.AnswerValueID + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName) + " >" + item.AnswerValueName + "</option>";
                            });
                    }


                    output = "<select id=\"" + answerElemID + "\" class=\"dropdown\" name=\"" + answerElemID + "\">" + outputDefault + output + "</select>";

                    sAnswerClass = "text";
                    $("#" + questionContainerID).append(output);

                    if (question.RequiredName != "None") {
                        addValidation(answerElemID, question, null);
                    }
                    break;

                default:
                    jQuery.each(answerList, function(index, item) {
                        output = "";
                        answerElemID = "answer_" + questionId + "_" + questionGroupId + "_" + item.AnswerValueID;
                        answerElemName = "answer_" + questionId + "_" + questionGroupId;

                        isDisabled = "";
                        if (hasAttribute(question.AnswerAlignment, "readonly")) {
                            isDisabled = "DISABLED";
                        }

                        sAnswerClass = "text";
                        isOtherFieldNumber = false;

                        switch (question.AnswerTypeName) {
                            case "SocialSecurity":
                                // special socialsecurity box
                                output = "<label for=\"" + answerElemID + "\" id=\"" + answerElemID + "\" class=\"answer_label\"><label for=\"" + answerElemID + "\">" + item.AnswerValueName + "</label>";
                                break;
                            case "Checkbox":
                                //if the checkboxes share a common NAME attribute they will be validated as a group
                                //otherwise they will be validated individually. This is based on whether or not
                                //the entire question is set to be required (RequiredID > 1). By default, we
                                //assume that each checkbox must be validated individually.                                
                                if (question.Required != "None") {
                                    answerElemID = "answer_" + questionId + "_" + questionGroupId;
                                }
                                output += "<li class=\"box\"><input id=\"" + answerElemID + "\" name=\"" + answerElemName + "\"" + IsChecked(item, applicationAnswer, question.AnswerTypeName) + " type=\"checkbox\" value=\"" + item.AnswerValueID + "\">" + item.AnswerValueName + "</li>";

                                break;

                            //we always validate radio items as a group                              
                            case "Radio":
                                //see if we want to add another input item on the end of this radio box                                
                                if (/\[\[[a-zA-Z]*\]\]$/.test(item.AnswerValueName)) {

                                    //if the radio box has an associated text box
                                    //determine if we need to disable/clear it or not
                                    if (hasValue(IsChecked(item, applicationAnswer, question.AnswerTypeName))) {
                                        sDisabled = "";
                                        sClass += "";
                                    }
                                    else {
                                        sDisabled = "DISABLED";
                                        sClass = "ui-state-disabled";
                                    }

                                    sOtherText = hasValue(applicationAnswer.split(gftae_delimiter)[1]) ? applicationAnswer.split(gftae_delimiter)[1] : "";
                                    sAddTextInput = ": <input id=\"" + answerElemID + "_text\" name=\"" + answerElemID + "_text\" type=\"text\" class=\"" + sClass + "\" " + sDisabled + " value=\"" + sOtherText + "\"></input>";

                                    //if the extra field is a number then add a validator to it
                                    if (/\[\[Number\]\]$/.test(item.AnswerValueName)) {
                                        isOtherFieldNumber = true;
                                    }
                                }
                                else {
                                    sAddTextInput = "";
                                }

                                /****************************************************************************
                                ** If the AnswerValue contains the value [[Text]] then add a text box to
                                ** this Radio input option. This will mean that this question will fill both
                                ** the AnswerValueInt and AnswerValueText fields
                                ****************************************************************************/
                                //fix the label on answers with extra info Other[[Text]] Other[[Number]]                                
                                item.AnswerValueName = (item.AnswerValueName).replace(/\[\[[a-zA-Z]*\]\]$/, "");

                                output = "<li class=\"radio\"><input id=\"" + answerElemID + "\" name=\"" + answerElemName + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName) + " type=\"radio\" " + isDisabled + " value=\"" + item.AnswerValueID + "\" onclick=\"setupRadioTextBoxes('" + answerElemName + "')\">" + item.AnswerValueName;
                                output += sAddTextInput + "</li>";
                                break;

                            //AccountType questions are special radio boxes                              
                            case "AccountType":
                                output = "<li class=\"radio\"><input id=\"" + answerElemID + "\" name=\"" + answerElemName + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName) + " type=\"radio\" " + isDisabled + " value=\"" + item.AnswerValueID + "\" onclick=\"setupRadioTextBoxes('" + answerElemName + "')\">" + item.AnswerValueName + "</li>";
                                break;

                            //AccountPackage questions are special radio boxes                              
                            case "AccountPackage":
                                var answerValueExtra = item.AnswerValueExtra.split("|");
                                //the actual radio button 
                                output = "<ul class=\"radioButtonAccounts\">";
                                output += "     <li class=\"radio\"><input id=\"" + answerElemID + "\" name=\"" + answerElemName + "\" " + IsChecked(item, applicationAnswer, question.AnswerTypeName) + " type=\"radio\" " + isDisabled + " value=\"" + item.AnswerValueID + "\" onclick=\"setupRadioTextBoxes('" + answerElemName + "')\"></ul>";
                                output += "</ul>"


                                // Begin apply default state
                                var sPackageState = "";

                                if (IsChecked(item, applicationAnswer, question.AnswerTypeName) == "checked=\"true\"")
                                    sPackageState = "active";
                                //---/ End apply default state


                                var sPackage = "Platinum-" + _thisapp._applicationType;

                                switch (index) {
                                    case 0:
                                        sPackage = "Platinum-" + _thisapp._applicationType;
                                        break;

                                    case 1:
                                        sPackage = "Gold-" + _thisapp._applicationType;
                                        break;

                                    case 2:
                                        sPackage = "Silver-" + _thisapp._applicationType;
                                        break;

                                    case 3:
                                        sPackage = "Bronze-" + _thisapp._applicationType;
                                        break;

                                    case 4:
                                        sPackage = "Green-" + _thisapp._applicationType;
                                        break;
                                }

                                //account package details
                                output += "<div class=\"accountPackage " + sPackageState + "\" id=\"" + answerElemID + "_accountPackage\">";
                                output += "    <ul class=\"accountPackageList\">";
                                output += "        <li class=\"accountDescription " + sPackage + "\">";
                                output += "            <h1>" + item.AnswerValueName + "</h1>";
                                output += "        </li>";
                                output += "        <li><span class=\"icon" + (answerValueExtra[1] != "0" ? answerValueExtra[1] : "X") + "\"></span></li>";
                                output += "        <li><span class=\"icon" + (answerValueExtra[2] != "0" ? "Check" : "X") + "\"></span></li>";
                                output += "        <li><span class=\"icon" + (answerValueExtra[3] != "0" ? answerValueExtra[3] : "X") + "\"></span></li>";
                                output += "        <li><span class=\"icon" + (answerValueExtra[4] != "0" ? answerValueExtra[4] : "X") + "\"></span></li>";
                                output += "        <li class=\"lastItem\"><span class=\"icon" + (answerValueExtra[5] != "0" ? answerValueExtra[5] : "X") + "\"></span></li>";
                                output += "        <div class=\"clear\"></div>";
                                output += "     </ul>";

                                //end accountPackage
                                output += " </div>";

                                break;

                            default:
                                output = "<label for=\"" + answerElemID + "\" id=\"" + answerElemID + "\" class=\"answer_label\"><label for=\"" + answerElemID + "\">" + item.AnswerValueName + "</label>";
                                break;
                        }


                        $("#" + questionContainerID).append(output);




                        // Begin highlight selected account package
                        $("input[id='" + answerElemID + "']").click(function(item) {
                            // Remove all active classes
                            $(".accountPackage").removeClass("active");

                            // Add the active class
                            $("#" + this.id + "_accountPackage").addClass("active");
                        });
                        //---/ End highlight selected account package




                        //if this item is Other[[Number]] make sure we add a validator to make it a number
                        if (isOtherFieldNumber) {
                            $("input[id='" + answerElemName + "']").bind("click", function(e) {
                                if ($(e.target).val() == item.AnswerValueID) {
                                    $("#" + answerElemID + "_text").rules("add", "gftae_numeric")
                                }
                                else {
                                    $("#" + answerElemID + "_text").rules("remove", "gftae_numeric")
                                }
                            });
                        }

                        addValidation(answerElemID, question, item);
                    });

                    switch (question.AnswerTypeName) {
                        case "Radio":
                            var sRadioClass = "radioButton";
                            if (hasAttribute(question.AnswerAlignment, "horizontal")) {
                                sRadioClass += "Inline";
                            }
                            $("#" + questionContainerID + " li").wrapAll("<ul class=\"" + sRadioClass + "\"></ul>");
                            break;

                        case "AccountType":
                            $("#" + questionContainerID + " li").wrapAll("<ul class=\"radioButton\"></ul>");
                            break;

                        case "AccountPackage":
                            //remove the first lable element or it messes up or formatting
                            $("#" + questionContainerID + " label").remove();

                            //make sure the header is added to the account package page
                            if ($(".accountPackageHeading").length == 0) {
                                var acctPackageHeader = "";
                                acctPackageHeader = "<div class=\"accountPackageHeading\">";
                                acctPackageHeader += "    <ul>";
                                acctPackageHeader += "        <li class=\"" + translate("DEPOSIT_PACKAGE_HEADER_CLASS") + "\">&nbsp;</li>";
                                acctPackageHeader += "        <li><span class=\"heading\">" + translate("FIRST_PACKAGE_HEADER") + "</span></li>";
                                acctPackageHeader += "        <li><span class=\"heading\">" + translate("SECOND_PACKAGE_HEADER") + "</span></li>";
                                acctPackageHeader += "        <li><span class=\"heading\">" + translate("THIRD_PACKAGE_HEADER") + "</span></li>";
                                acctPackageHeader += "        <li><span class=\"heading\">" + translate("FOURTH_PACKAGE_HEADER") + "</span></li>";
                                acctPackageHeader += "        <li><span class=\"heading\">" + translate("FIFTH_PACKAGE_HEADER") + "</span></li>";
                                acctPackageHeader += "       <div class=\"clear\"></div>";
                                acctPackageHeader += "   </ul>";
                                acctPackageHeader += "</div>";

                                $("#" + questionContainerID).prepend(acctPackageHeader);
                            }
                            break;

                        case "Checkbox":
                            $("#" + questionContainerID + " li").wrapAll("<ul class=\"checkbox\"></ul>");

                            // Inject a check for task 5.7 of Apps 2.5
                            // Allow checkboxes to affect eachother in a group
                            // Foreign Correspondant question of US, AU, JP apps.
                            if ($.inArray(questionContainerID,
                                ['36f80b2e-960b-4933-9b5c-1a22345b68b0', 'e6d81f17-b023-4a16-b36f-677366366ae4', '1a025e54-bbbc-418b-bfb4-c7d569ba36bf']
                            ) > -1) {
                                $('#' + questionContainerID + ' input[type=checkbox]').bind('click', { questionContainerID: questionContainerID }, function(myEvent) {
                                    /*
                                    * if I'm not NONE, and I'm now checked, uncheck none
                                    * If I'm not NONE, and I'm now unchecked, do nothing
                                    * If I'm NONE, do nothing
                                    */
                                    if (this.value != 133) {
                                        if (this.checked == true) {
                                            $('#' + myEvent.data.questionContainerID + ' input[value=133][checked=true]').attr("checked", false);
                                        }
                                    }
                                    else {
                                        if (this.checked == true) {
                                            $('#' + myEvent.data.questionContainerID + ' input[value!=133]').attr("checked", false);
                                        }
                                    }

                                });
                            }
                            break;
                    }

                    break;
            }
        }
        //else we only have one answer or just some text to draw, or a header or
        // some descriptive text     
        else {
            if (hasAttribute(question.AnswerAlignment, "readonly")) {
                sDisabled = "DISABLED";
                bDisabled = true;
                sClass = "ui-state-disabled";
            }
            else {
                sClass = "";
                bDisabled = false;
                sDisabled = "";
            }

            // check for class based attributes
            if (hasAttribute(question.AnswerAlignment, "small")) {
                sClass = "small";
            }

            if (hasAttribute(question.AnswerAlignment, "big")) {
                sClass = "big";
            }

            answerElemID = "answer_" + questionId + "_" + questionGroupId;

            var numFields;
            var multiFieldDelimiter;
            var extendedDesc;
            var fldNameExtra;
            var answerItems;
            var fc;

            switch (question.AnswerTypeName) {
                //text box                              
                case "Text":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    break;
                case "TextWide":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " textwide", applicationAnswer));
                    break;
                case "SocialSecurity":

                    // Reload properties for the app.
                    if (!hasValue(_thisapp._accountType)) {
                        _thisapp.getApplicationProperties();
                    }

                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    addValidation(answerElemID, question, _thisapp._accountType);
                    break;
                case "TextOnly":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    addValidation(answerElemID, question, null);
                    break;
                case "MultiText":
                    numFields = 1;
                    if (hasValue(question.AnswerTypeExtra))
                        numFields = parseInt(question.AnswerTypeExtra);
                    //get the labels for each field                    
                    if (hasValue(question.ExtendedDescription))
                        extendedDesc = question.ExtendedDescription.split("|");

                    multiFieldDelimiter = "";

                    answerItems = applicationAnswer.split(gftae_delimiter);
                    for (fc = 0; fc < numFields; fc++) {
                        fldNameExtra = "_multitext_" + fc.toString();
                        manswer = (fc < answerItems.length) ? answerItems[fc] : "";
                        mlabel = hasValue(extendedDesc) ? extendedDesc[fc] : "";

                        writeInput(questionContainerID, makeMultiInput(groupElemID, question.QuestionHelp, answerElemID + fldNameExtra, answerElemID + fldNameExtra, "text", bDisabled, sClass + " text", manswer, mlabel, multiFieldDelimiter, fc, numFields));
                        addValidation(answerElemID + fldNameExtra, question, null);
                    }
                    break;

                //number                              
                case "ZipCode":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    break;

                //number                              
                case "Number":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    break;

                case "Phone":
                    numFields = 1;

                    if (hasValue(question.AnswerTypeExtra))
                        numFields = parseInt(question.AnswerTypeExtra);
                    //get the labels for each field
                    if (hasValue(question.ExtendedDescription)) {
                        extendedDesc = question.ExtendedDescription.split("|");
                    }
                    else {
                        extendedDesc = "";
                    }

                    multiFieldDelimiter = "-";

                    var sFieldLengthClass = "small";
                    answerItems = applicationAnswer.split(gftae_delimiter);

                    for (fc = 0; fc < numFields; fc++) {
                        if (fc == numFields - 1) {
                            sFieldLengthClass = "phone";


                            if (fc < extendedDesc.length - 1) {
                                mlabel = hasValue(extendedDesc) ? extendedDesc[fc] + " - " + extendedDesc[fc + 1] : "";
                            }
                            else {
                                mlabel = hasValue(extendedDesc) ? extendedDesc[fc] : "";
                            }

                        }
                        else {
                            mlabel = hasValue(extendedDesc) ? extendedDesc[fc] : "";
                        }

                        fldNameExtra = "_phone_" + fc.toString();
                        manswer = (fc < answerItems.length) ? answerItems[fc] : "";

                        writeInput(questionContainerID, makeMultiInput(groupElemID, question.QuestionHelp, answerElemID + fldNameExtra, answerElemID + fldNameExtra, "text", bDisabled, sClass + " text " + sFieldLengthClass, manswer, mlabel, multiFieldDelimiter, fc, numFields));
                        addValidation(answerElemID + fldNameExtra, question, this._applicationType);
                    }
                    break;

                case "MultiNumber":
                    numFields = 1;
                    if (hasValue(question.AnswerTypeExtra))
                        numFields = parseInt(question.AnswerTypeExtra);
                    //get the labels for each field                    
                    if (hasValue(question.ExtendedDescription))
                        extendedDesc = question.ExtendedDescription.split("|");

                    multiFieldDelimiter = " ";

                    var sFieldLengthClass = "small";
                    answerItems = applicationAnswer.split(gftae_delimiter);
                    for (fc = 0; fc < numFields; fc++) {
                        fldNameExtra = "_multinumber_" + fc.toString();
                        manswer = (fc < answerItems.length) ? answerItems[fc] : "";
                        mlabel = hasValue(extendedDesc) ? extendedDesc[fc] : "";

                        writeInput(questionContainerID, makeMultiInput(groupElemID, question.QuestionHelp, answerElemID + fldNameExtra, answerElemID + fldNameExtra, "text", bDisabled, sClass + " text " + sFieldLengthClass, manswer, mlabel, multiFieldDelimiter, fc, numFields));
                        addValidation(answerElemID + fldNameExtra, question, null);
                    }
                    break;

                case "MultiZipCode":
                    numFields = 1;
                    if (hasValue(question.AnswerTypeExtra))
                        numFields = parseInt(question.AnswerTypeExtra);
                    //get the labels for each field                    
                    if (hasValue(question.ExtendedDescription))
                        extendedDesc = question.ExtendedDescription.split("|");

                    multiFieldDelimiter = "-";

                    var sFieldLengthClass = "small";
                    answerItems = applicationAnswer.split(gftae_delimiter);
                    for (fc = 0; fc < numFields; fc++) {
                        fldNameExtra = "_multinumber_" + fc.toString();
                        manswer = (fc < answerItems.length) ? answerItems[fc] : "";
                        mlabel = hasValue(extendedDesc) ? extendedDesc[fc] : "";

                        writeInput(questionContainerID, makeMultiInput(groupElemID, question.QuestionHelp, answerElemID + fldNameExtra, answerElemID + fldNameExtra, "text", bDisabled, sClass + " text " + sFieldLengthClass, manswer, mlabel, multiFieldDelimiter, fc, numFields));
                        addValidation(answerElemID + fldNameExtra, question, null);
                    }
                    break;


                case "MultiDate":
                    //override the class to always use the specific MultiDate class                                        
                    //always use 3 fields                    
                    numFields = 3;

                    extendedDesc = gftApp._dateFormat.toUpperCase().split("/");

                    multiFieldDelimiter = "/";

                    answerItems = applicationAnswer.split(gftae_delimiter);
                    for (fc = 0; fc < numFields; fc++) {
                        fldNameExtra = "_multidate_" + fc.toString();
                        manswer = (fc < answerItems.length) ? answerItems[fc] : "";
                        mlabel = hasValue(extendedDesc) ? translate(extendedDesc[fc]) : "";

                        writeInput(questionContainerID, makeMultiInput(groupElemID, question.QuestionHelp, answerElemID + fldNameExtra, answerElemID + fldNameExtra, "text", bDisabled, sClass + " text small", manswer, mlabel, multiFieldDelimiter, fc, numFields));
                        addValidation(answerElemID + fldNameExtra, question, null);
                    }
                    break;

                case "Currency":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text small", applicationAnswer));
                    break;

                //number                              
                case "Percent":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text small", applicationAnswer));
                    $("#" + question.QuestionID + "").append("%");
                    break;

                //text box                              
                case "CreditCard":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    break;

                //text box                              
                case "TextArea":
                    output = "<textarea id=\"" + answerElemID + "\" name=\"" + answerElemID + "\" " + sDisabled + " class=\"" + sClass + " textarea\">" + applicationAnswer + "</textarea>";
                    $("#" + questionContainerID).append(output);
                    break;

                case "AgreementText":
                    taText = question.QuestionDescription;
                    output = "<textarea onfocus=\"this.blur();\" " + sDisabled + " class=\"" + sClass + " gft-overview-special\">" + taText + "</textarea>";
                    $("#" + questionContainerID).append(output);

                    break;

                //mm/yyyy, no datepicker                              
                case "ShortDate":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text small", applicationAnswer));
                    break;

                //date picker                              
                case "Date":
                    var yearRange = (hasValue(question.AnswerTypeExtra)) ? question.AnswerTypeExtra : "-100:0";
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text small", applicationAnswer));

                    $("#" + answerElemID).datepicker({
                        changeMonth: true,
                        changeYear: true,
                        yearRange: yearRange,
                        defaultDate: null,
                        dateFormat: _thisapp._dateFormat
                    });

                    if (bDisabled) {
                        $("#" + answerElemID).datepicker("disable");
                    }

                    break;

                //phone number       //EXISTS TWICE!!!                         
                //                case "Phone":                     
                //                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text small", applicationAnswer));                     
                //                    break;                     

                //passport                              
                case "Passport":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text big", applicationAnswer));
                    break;

                //email                                           
                case "Email":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));
                    break;

                //AutoComplete                              
                case "AutoComplete":
                    writeInput(questionContainerID, makeInput(groupElemID, question.QuestionHelp, answerElemID, answerElemID, "text", bDisabled, sClass + " text", applicationAnswer));

                    //the description of the list is contained in
                    //tblQuestion.AnswerTypeExtra
                    switch (question.AnswerTypeExtra) {
                        case "State":
                            $("#" + answerElemID + "").autocomplete(stateList, {
                                minChars: 0,
                                width: 200,
                                matchContains: true,
                                mustMatch: true,
                                highlightItem: true,
                                formatItem: function(row, i, max, term) {
                                    return row.description;
                                },
                                formatResult: function(row, i, num) {
                                    return row.description;
                                }
                            });

                            break;

                        default:
                            $("#" + answerElemID + "").autocomplete(countryList, {
                                minChars: 0,
                                width: 200,
                                matchContains: true,
                                mustMatch: true,
                                highlightItem: true,
                                formatItem: function(row, i, max, term) {
                                    return row.country;
                                },
                                formatResult: function(row, i, num) {
                                    return row.country;
                                }
                            });

                            break;
                    }
                    break;


                default:
                    output = "";
                    break;
            }

            //since these are multiple controls we'll do the validation call 
            //inside the case statement for them        
            if (question.AnswerTypeName.indexOf("Multi") < 0 &&
                question.AnswerTypeName.indexOf("Phone") < 0 &&
                question.AnswerTypeName.indexOf("Social") < 0) {
                addValidation(answerElemID, question, null);
            }
        }

        //
        //put breaks after any elements that specify it. See tblQuestion.AnswerAlignment
        // specify multiple parameters with spaces
        //
        // parameters
        // ---------------------------------------------------------------
        // horizontal   == float the elements
        // break        == put a hard break after the question        
        //
        if (hasAttribute(question.AnswerAlignment, "break")) {
            //    $("#"+questionId+"").after("<div class=\"clear\" />");
        }
    };

       
    //
    // Look up the current answer for the specified question
    //
    this.verifyApplicantResponse = function(questionId)
    {
        return _thisapp.getApplicationAnswer(questionId, _thisapp._applicationId);    
    };           
    
    this.getApplicationAnswer = function(questionId, applicationId)
    {           
        var appAnswer = Array(null, null);
        
        if (answerCache[questionId] != null)
            appAnswer = answerCache[questionId];
        else {
        
            $.ajax({             
                data: "{questionId:'" + questionId +                   
                      "', applicationId:'" + applicationId + 
                      "'}",
                url: "Application.asmx/GetApplicationAnswer",          
                async: false, //we need to do this synchronously.
                success: function(response) {                
                    //var data = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
                    var data = eval('(' + response.d + ')');
                    if (data.length > 0) 
                    {
                        var item = data[0];
                        appAnswer[0] = (hasValue(item.AnswerValueText)) ? item.AnswerValueText : "";                    
                        
                        appAnswer[1] = item.AnswerTypeName;
                    }
                    else
                    {
                        appAnswer = Array(null, null);
                    }
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);
                }            
            });
        }

        if (appAnswer[0] != null)
            answerCache[questionId] = appAnswer;

        return appAnswer;         
    };

    this.saveApplicationStep = function(fnCallback) {
        //on the intital save of a new app we'll have an empty guid
        //if this is the case then generate a guid for our application
        //by trully saving the app now that have enough data to continue 


        //if (_thisapp._applicationSteps[_thisapp._currentStep].StepCode == "funding_credit_card")
        //{
        // get credit card info and send to cybersource/verify by visa
        // send to deposit service if it's been authenticated       
        //fundingStepTwo(_thisapp);                                                    
        //}

        if (_thisapp._applicationSteps[_thisapp._currentStep].StepCode == "funding_account_info") {
            //authenticate the user if they've entered a username and account number                             
            fundingStepOne(_thisapp, fnCallback);
        }
        else {
            //we need to gather the controls on the welcome page (the first step)
            //parse the data and do some magic
            if (_thisapp._applicationSteps[_thisapp._currentStep].StepCode == "welcome") {
                var isNew = false;
                var isPrivate = false;
                var welcomeFail = false;
                var welcomePageInputs = $("#gft-question-container input");

                jQuery.each(welcomePageInputs, function(index, item) {

                    //is this a new app?
                    switch (index) {
                        case 0: //new app        
                            isNew = $(item).attr("checked");
                            break;

                        case 1: //existing app
                            //we can skip this because we know the answer based on case 0                        
                            break;

                        case 2: //application id                 
                            if ($(item).css("display") != "none" && hasValue($(item).val())) {
                                _thisapp._applicationId = $(item).val();
                            }
                            break;

                        case 3:  //email                  
                            _thisapp._appemail = $(item).val();
                            break;

                        case 4: //private computer
                            isPrivate = $(item).attr("checked");
                            break;

                        case 5: //public computer
                            //we can skip this since we know based on Case 4
                            break;
                    }
                });

                //clear out the application id if they choose new application after having
                //tried to create a new app           
                if (isNew) {
                    _thisapp.generateNewApplication();
                }
                else {
                    //make sure this application exists and the types match or don't let them move on
                    $.ajax({
                        data: "{applicationId:'" + _thisapp._applicationId + "'}",
                        url: "Application.asmx/FindApplication",
                        async: false,
                        success: function(response) {
                            var data = eval('(' + response.d + ')');

                            var query = $.query(document.location.href);

                            //ApplicationTypeId == 0 means we didn't find an app
                            if (data.ApplicationTypeID == 0) {
                                ajaxAlert("LABEL_ERROR_APPID_NOTFOUND", "ERROR_APPID_NOTFOUND", null, true);
                                $("#jQueryAjaxAlert").dialog("open");

                                welcomeFail = true;
                            }
                            else if (data.ApplicationTypeID != _thisapp.getApplicationTypeID(query.applicationtype)) {
                                ajaxAlert("APPTYPE_NOT_MATCH_TITLE", "APPTYPE_NOT_MATCH", null, true);
                                $("#jQueryAjaxAlert").dialog("open");

                                welcomeFail = true;

                                return;
                            }

                            //see if the app is copmlete and send us to the documentation
                            //page if that's true.
                            _thisapp._isComplete = data.IsComplete;
                            _thisapp._applicationId = data.ApplicationID;
                        },
                        error: function(msg) {
                            ajaxError(this.url, msg, this.data);
                        }
                    });
                }


                if (!welcomeFail) {
                    //go get this apps properties since we are fetching an existing application
                    _thisapp.getApplicationProperties();

                    //set the private/public information            
                    if (isPrivate) {
                        makePrivate();
                    }
                    else {
                        makePublic();
                    }

                    if (_thisapp._isComplete) {
                        _thisapp._eventsInitialized = false;
                        fnConfirmAppFound();
                    }
                    else {
                        if (isNew) {
                            //if this is a new app we have to save the welcome step
                            _thisapp.saveApplication(fnCallback);
                        }
                        else {
                            //if we are returning to an app don't save the welcome step
                            //SMD - this was stupid so we don't do this anymore
                            _thisapp.saveApplication(fnCallback);
                            //_thisapp.stepApplication(1);
                        }
                    }
                }
                else {
                    //we failed the welcome checks so make sure we don't move on
                    _thisapp._applicationId = cEmptyGuid;
                }

            }
            else {
                _thisapp.saveApplication(fnCallback);
            }
        }
    };

    this.saveApplication = function(fnCallback) {
        $.ajax({
            data: "{applicationId:'" + _thisapp._applicationId +
                    "', stepId:'" + _thisapp._applicationSteps[_thisapp._currentStep].StepID +
                    "', applicationTypeId:'" + _thisapp._applicationTypeId +
                    "', rpid:\"" + _thisapp._referralId +
                    "\", aid:\"" + _thisapp._advertiserId +
                    "\", sid:\"" + _thisapp._salesId +
                    "\", tid:\"" + _thisapp._techVendorId +
                    "\", specTypeId:\"" + _thisapp._specTypeId +
                    "\", originUrl:'" + _thisapp._originUrl +
                    "', isComplete:'" + _thisapp._isComplete +
                    "', isVerified:'" + _thisapp._isVerified +
                    "', stepData:\"" + $("#" + _thisapp._formname).serializeAnything() +
                    "\"}",
            url: "Application.asmx/SaveApplicationStep",
            success: function(response) {
                // Cleanup any data from steps that have been set as InActive ??

                //2010-05-12 vshin: Clear the outdated answer cache:
                answerCache = new Array();

                var returnData = eval('(' + response.d + ')');

                if (typeof (returnData) == "boolean" && returnData == true) {
                    if (hasValue(fnCallback)) {
                        if (typeof fnCallback == "string") {
                            eval(fnCallback);
                        }
                        else {
                            fnCallback();
                        }

                        if (fnCallback == "gftApp.getStepsByApplicationType(true)") {
                            _thisapp.getApplicationProperties();
                        }
                        if (_thisapp._applicationSteps[_thisapp._currentStep].StepCode == "welcome") {
                            _thisapp.getApplicationProperties();
                        }
                    }
                    else {
                        $("#jQueryAjaxWorking").dialog("close");
                    }
                }
                else {
                    ajaxAlert("INVALID_INPUT", "INVALID_INPUT", fnStartOver, true);
                    $("#jQueryAjaxWorking").dialog("close");
                }
            },
            error: function(msg, reason, errorThrown) {
                ajaxError(this.url, msg, this.data);
            }
        });
    }
    
    
    this.removeInactiveStepAnswers = function()
    {           
        $.ajax({             
            data: "{applicationId:'" + _thisapp._applicationId +                  
                    "'}",
            url: "Application.asmx/RemoveInactiveStepAnswers",
            success: function(response) {
            },
            error: function(msg) {
                ajaxError(this.url, msg, this.data);
            }
        });               
    };

    //
    // Perform any actions linked with this question
    //
    
    //re-usable functions
    function fnConfirmAppFound()
    {
        var title = "APP_IN_PROGRESS";
        var msg = "QUESTION_RESUME_APP";
        var resume = "LABEL_RESUME";
        var startover = "LABEL_START_OVER";
        
        if (_thisapp._isComplete)
        {
            title = "COMPLETED_APP";
            msg = "VIEW_ADDITIONAL_DOCUMENTATION";
            resume = "LABEL_RESUME_VIEW_DOCUMENTS";
            startover = "LABEL_NEW_APPLICATION";
        }
        
        ajaxConfirm(title,
                    msg,
                    resume, fnResume, null,
                    startover, fnNew, null, 
                    null);
    }
            
    var fnDeleteApp = function()
    {        
        expireCookie();
        _thisapp.init();
    };
    
    var fnNew = function()
    {
        //TODO: CONFIRM!
        //TODO: Delete application from database:            
        ajaxConfirm("QUESTION_DELETE_APP_TITLE",
                    "QUESTION_DELETE_APP",
                    "LABEL_YES", fnDeleteApp, null,
                    "LABEL_CANCEL", fnConfirmAppFound, null,
                    "jQueryAjaxConfirmFinal");
    };
    
    var fnResume = function()
    {        
        _thisapp.getApplicationProperties();
        
        //this app is not new anymore
        _thisapp._newapp = false;
                    
        if (_thisapp._isComplete === true)
        {
            ajaxWorking("GETTING_APP_DOCS");
        }
        else
        {
            ajaxWorking("GETTING_APP_DATA");
            
        }
        $("#jQueryAjaxWorking").dialog("open");            
        _thisapp.getStepsByApplicationType(false);                                    
    };
    
    var fnStartOver = function()
    {             
         _thisapp._applicationId = null;
         expireCookie();             
         _thisapp.initializeApplication(); 
    }
    
    this.findExistingApplication = function(appId)
    {    
        var creatingNew = false;
        var msg = "LOADING_DATA";
                
        if (!_thisapp._eventsInitialized)
        {
            //we don't know the default language at this point so default to en-us
            //we should be able to find the default language based on the applicationType
            msg = "SEARCHING_FOR_APP";
        }        
        
        if (_thisapp._newapp === true)
        {
            msg = "Creating new application...";
        }             
        
        ajaxWorking(msg);
        $("#jQueryAjaxWorking").dialog("open");       
        
        $.ajax({ 
            data: "{applicationId:'" + appId + "'}",
            url: "Application.asmx/FindApplication",          
            success: function(response) {            
                //var data = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
                var data = eval('(' + response.d + ')');
                //if the count == 0 then the database does not have an
                //application with this id. Blank out the application id and kill
                //off any cookie, we'll make a new one
                 $("#jQueryAjaxWorking").dialog("close");
                
                //if there is no applicationtypeid then this is a new application               
                if (data.ApplicationTypeID == 0)
                {                              
                    if (!hasValue(_thisapp._language))      
                    {
                        _thisapp._language = _thisapp.getApplicationTypeLanguage(_thisapp._applicationTypeId);
                    }
                    _thisapp._newapp = true;
                }

                //if the applicationtype id of our appid doesn't match that of our found application
                //   then we've switched app types, so we want to dump and restart
                if (data.ApplicationTypeID != gftApp._applicationTypeId && gftApp._applicationId != cEmptyGuid) 
                {
                    ajaxAlert("APPTYPE_NOT_MATCH_TITLE", "APPTYPE_NOT_MATCH", fnStartOver, true);                    
                }
                else //otherwise resume and show some data
                {                
                    _thisapp._appProps = data;
                    
                    if (!hasValue(_thisapp._language))
                    {
                        _thisapp._language = hasValue(data.Language) ? data.Language : data.DefaultLanguage;
                    }
                    _thisapp._isComplete = hasValue(data.IsComplete) ? data.IsComplete : false;
                    
                    addValidators();
                    toggleStyleSheets();                        
                    
                    if (!_thisapp._newapp && !_thisapp._autoResume)
                    {                        
                        _thisapp._autoResume = false;
                        fnConfirmAppFound();
                    }
                    else
                    {
                        fnResume();
                    }
                }
            
            },
            error: function(msg) {           
                ajaxError(this.url, msg, this.data);
            }            
        }); 
    };

    this.fireAction = function(itemaction, parms) {
        var action = itemaction.QuestionLinkActionCode;
        var stepId;
        var questionId;
        var required;
        var answerId;
        var qstGroupId;
        var sUrl;

        switch (action) {
            case "DISABLESTEP":
                stepId = parms;
                //if we disable a step, we should delete all the data associated
                //with that step to keep things clean                                
                jQuery.each(_thisapp._applicationSteps, function(index, item) {
                    if (item.StepID == stepId) {
                        item.IsActive = false;
                        return false;
                    }
                    else {
                        return true;
                    }
                });

                break;

            case "ENABLESTEP":
                stepId = parms;

                jQuery.each(_thisapp._applicationSteps, function(index, item) {
                    if (item.StepID == stepId) {
                        item.IsActive = true;
                        return false;
                    }
                    else {
                        return true;
                    }
                });

                break;

            case "DISABLEQST":
                questionId = parms;

                jQuery.each($("#" + questionId + " input, #" + questionId + " textarea, #" + questionId + " select"), function(index, item) {

                    //$(item).addClass("ui-state-disabled");                    
                    $(item).attr("disabled", "true");

                    if (item.type == "radio" || item.type == "checkbox") {
                        if (!hasAttribute(itemaction.Format, "keepcheck")) {
                            $(item).attr("checked", false);
                        }
                    }
                    else {
                        clearInputsInElement(qstGroupId)
                    }
                });

                break;

            case "ENABLEQST":
                questionId = parms;

                jQuery.each($("#" + questionId + " input, #" + questionId + " textarea, #" + questionId + " select"), function(index, item) {
                    //radio boxes can have a input with a text box attached
                    //if this is the case do not enable that input
                    if ($(item).attr("name").indexOf("_text") == -1) {
                        $(item).attr("disabled", "");
                    }

                });

                break;

            case "HIDEQST":
                questionId = parms;
                $("#" + questionId).css("display", "none");
                clearInputsInElement(questionId);

                break;

            case "SHOWQST":
                questionId = parms;
                $("#" + questionId).css("display", "");

                break;

            //we're expecting a parameter of a number because   
            //we would only disable/enable an answer if a question could   
            //have multiple answers. This limits us to checkboxes/radio groups    
            case "DISABLEANSWER":
                answerId = "#answer_" + itemaction.LinkedQuestionID + "_" + itemaction.LinkedQuestionGroupID + "_" + parms;

                $(answerId).attr("disabled", "true");

                if (!hasAttribute(itemaction.Format, "keepcheck")) {
                    $(answerId).attr("checked", false);
                }

                break;

            case "ENABLEANSWER":
                answerId = "#answer_" + itemaction.LinkedQuestionID + "_" + itemaction.LinkedQuestionGroupID + "_" + parms;
                $(answerId).attr("disabled", "");
                break;


            case "ENABLEQSTGRP":
                qstGroupId = parms;
                jQuery.each($("#group_" + qstGroupId + " input, #group_" + qstGroupId + " textarea, #group_" + qstGroupId + " select"), function(index, item) {
                    var questionId = $(item).attr("id").split("_")[1];
                    $(item).attr("disabled", "");
                });
                break;

            case "DISABLEQSTGRP":
                qstGroupId = parms;
                jQuery.each($("#group_" + qstGroupId + " input, #group_" + qstGroupId + " textarea, #group_" + qstGroupId + " select"), function(index, item) {
                    $(item).attr("disabled", "true");

                    if (item.type == "radio" || item.type == "checkbox") {
                        if (!hasAttribute(itemaction.Format, "keepcheck")) {
                            $(item).attr("checked", false);
                        }
                    }
                    else {
                        clearInputsInElement(qstGroupId)
                    }
                });
                break;

            case "SHOWQSTGRP":
                qstGroupId = parms;
                $("#group_" + qstGroupId).css("display", "");
                break;

            case "HIDEQSTGRP":
                qstGroupId = parms;
                $("#group_" + qstGroupId).css("display", "none");
                clearInputsInElement(qstGroupId);
                break;

            case "ENABLEREQUIRED":
                questionId = parms;

                jQuery.each($("#" + questionId + " input, #" + questionId + " textarea, #" + questionId + " select"), function(index, item) {
                    addRequired(item);
                });

                break;

            case "DISABLEREQUIRED":
                questionId = parms;

                jQuery.each($("#" + questionId + " input, #" + questionId + " textarea, #" + questionId + " select"), function(index, item) {
                    removeRequired(item);
                });

                break;

            case "REDIRECT":
                sUrl = parms;
                _thisapp._redirectOnSubmit = sUrl;
                break;

            case "REDIRECTCONFIRM":
                if (hasValue(parms)) {
                    sUrl = parms.split("|");//http://marketsapplication.force.com/registration?cid=a0Q60000002TZpc

                    ajaxConfirm("QUESTION_REDIRECT",
                                sUrl[1],
                                null, function() {
                                    if (gftApp._inframe) {
                                        parent.location.href = sUrl[0];
                                    }
                                    else {
                                        document.location.href = sUrl[0];
                                    }
                                }, null,
                                null, function() {
                                    $("#answer_" + itemaction.QuestionID + "_" + itemaction.QuestionGroupID + "").val("");
                                    $.each($("#" + itemaction.QuestionID + " input"), function(index, item) {
                                        $(item).attr("checked", false);
                                    });
                                }, null,
                                null);
                }
                break;

            case "ROUTEENGINEV3":
                var selectedAccountType = $("input[name='answer_" + itemaction.QuestionID + "_" + itemaction.QuestionGroupID + "']:checked" );
                var selectedText = selectedAccountType.parent().text().toLowerCase();
                var sUrl = "https://marketsapplication.secure.force.com/registration/SL_SiteRegistration";
                var cid = "";
                var region = _thisapp._applicationType.toUpperCase();

                // commercial agreement
                if( region == "SG" ){
                    cid = "a0Q60000002Tn4e";
                } else if( region == "JP" ){
                    cid = "a0Q60000002TZqZ";
                } else { // default: UK
                    cid = "a0Q60000002TZpc";
                }
                sUrl += "?cid=" + cid;

                // tid, sid, aid
                if( _thisapp._advertiserId != 0 ){ sUrl += "&aid=" + _thisapp._advertiserId; }
                if( _thisapp._salesId != 0 ){ sUrl += "&sid=" + _thisapp._salesId; }
                if( _thisapp._techVendorId != 0 ){ sUrl += "&tid=" + _thisapp._techVendorId; }

                if ((selectedText == 'individual' || selectedText == '個人口座開設申込書および契約書') &&
                  ( _thisapp._referralId == "" ||
                    _thisapp._referralId == 0 ) && 
                  ( _thisapp._techVendorId == "" ||
                    _thisapp._techVendorId == 0 )
                  ){

                    // Do Redirect
                    var applyText = translate( "QUESTION_APPLY_AT_OTHER_APP_ENGINE" );
                    ajaxConfirm(
                        "HEADER_APPLY_AT_OTHER_GFTWEBSITE",
                        applyText,
                        null, 
                        function() {
                            if (gftApp._inframe) {
                                parent.location.href = sUrl; //+document.location.search;
                            } else {
                                document.location.href = sUrl; // +document.location.search;
                            }
                        }, 
                        null,                          
                        null, 
                        function() {
                            $("#answer_" + itemaction.QuestionID + "_" + itemaction.QuestionGroupID + "").val("0");
                            $.each($("#" + itemaction.QuestionID + " input"), function(index, item) {
                                $(item).attr("checked", false);
                            });
                        }, 
                        null, 
                        null
                    );  
                }

                break;

            case "ROUTEAPPLICATION":
                //fake out the app when we are in the middle east because they use either
                //the US or the UK app and it's ok.
                var countryRegion = GetCountryRegion(parms);
                var bOverride = false;

                if (countryRegion === "ME" && (gftApp._applicationType === "US" || gftApp._applicationType === "UK"))
                    bOverride = true;

                // Check if the application URL is set to "ANY".
                if (GetCountryApplicationUrl(parms, gftApp._applicationType) == "ANY")
                    bOverride = true;

                if (gftApp._applicationType == "SG")
                    bOverride = false;

                if ((countryRegion != gftApp._applicationType) && !bOverride) {

                    var applyText = '';
                    if( gftApp._applicationType == "SG" ){
                        applyText = translate("QUESTION_APPLY_AT_OTHER_GFTWEBSITE_SG");
                    } else {
                        applyText = translate("QUESTION_APPLY_AT_OTHER_GFTWEBSITE");
                    }

                    var sUrl = GetCountryApplicationUrl(parms, gftApp._applicationType);
                    ajaxConfirm(
                        "HEADER_APPLY_AT_OTHER_GFTWEBSITE",
                        applyText,
                        null, 
                        function() {
                            if (gftApp._inframe) {
                                parent.location.href = sUrl; //+document.location.search;
                            } else {
                                document.location.href = sUrl; // +document.location.search;
                            }
                        }, 
                        null,                          
                        null, 
                        function() {
                            $("#answer_" + itemaction.QuestionID + "_" + itemaction.QuestionGroupID + "").val("0");
                            $.each($("#" + itemaction.QuestionID + " input"), function(index, item) {
                                $(item).attr("checked", false);
                            });
                        }, 
                        null, 
                        null
                    );  
                }
                break;

            case "SETVALUE":
                $("input[name=answer_" + itemaction.LinkedQuestionID + "_" + itemaction.LinkedQuestionGroupID + "_phone_0]").val(executeFunction(itemaction, null)).attr("disabled", true);
                break;

            default:
                break;
        }

    };
            
    //
    // Determine everything we need to know about what to do now.
    //
    this.stepApplication = function(stepDirection)
    {
		ajaxWorking("LOADING_DATA");

        //2. If we can skip any steps based on the action then do we need to remove any
        //      data from the skipped step?           
      
        //if we're aren't going forward, don't redirect
        if ( stepDirection != 1 )
        {
            _thisapp._redirectOnSubmit = null;
        }

        //see if an answer requires us to redirect to some url. If this happens then we're done
        if ( hasValue(_thisapp._redirectOnSubmit) )
        {
            if (_thisapp._inframe)
            {
                parent.location.href = _thisapp._redirectOnSubmit;
            }
            else
            {
                document.location.href = _thisapp._redirectOnSubmit;
            }
        }
        else
        {
            //find the next step that is not being skipped            
            var nextStep = _thisapp._currentStep+stepDirection;
            while( nextStep >= 0 &&
                    _thisapp._applicationSteps[nextStep].IsActive === false &&
                    _thisapp._applicationSteps[_thisapp._currentStep+stepDirection].Sequence <= _thisapp.getLastStep() )
            {
                nextStep = nextStep+stepDirection;
            }
            
            //if < 0 then we hit the beginning
            //if > _thisapp._applicationSteps.length then we're done with the application
            if (nextStep >= 0 && nextStep < _thisapp._applicationSteps.length)
            {                
                _thisapp._currentStep = nextStep;
                _thisapp.drawApplication();
            }
            else 
            {
                $("#jQueryAjaxWorking").dialog("close");
            }             
        }
   
    };
    
    this.submitApplication = function()
    {
        /*****************************************************************
            TODO:
             1. Mark the application as IsComplete/IsVerified
                a. Do this inside the verification c# code?
             2. SalesForce integration
             3. Email the app to appropriate parties                     
             4. Delete the cookie, we don't want them resubmitting the app
             5. Navigate to a thank you page or somewhere else?
             6. Create hardcopy document pdf? (Future)
        ******************************************************************/
        
/*	2010-04-29 vshin:
		Change the submit application process into a single call of the related web service method.
		
	=== BEGIN COMBINING submitApplication to a single function ===================
*/
		function _submitApplication()
		{
			ajaxWorking("SUBMITTING_APPLICATION");
			$("#jQueryAjaxWorking").dialog("open");  

			$("#btnStepBack").attr("disabled", "true");            
            $("#btnSubmitApp").attr("disabled", "true");

			$.ajax({                     
				data: "{applicationId:'" + _thisapp._applicationId + 
						"', stepId:'" + _thisapp._applicationSteps[_thisapp._currentStep].StepID + 
						"', applicationTypeId:'" + _thisapp._applicationTypeId + 
						"', rpid:\"" + _thisapp._referralId + 
						"\", aid:\"" + _thisapp._advertiserId + 
						"\", sid:\"" + _thisapp._salesId +
                        "\", tid:\"" + _thisapp._techVendorId +
                        "\", specTypeId:\"" + _thisapp._specTypeId +
						"\", originUrl:'" + _thisapp._originUrl + 
						"', isComplete:'" + _thisapp._isComplete + 
						"', isVerified:'" + _thisapp._isVerified + 
						"', stepData:\"" + $("#"+_thisapp._formname).serializeAnything() +
						"\"}",
                url: "Application.asmx/SubmitApplication",
                success: function(response) {
                    var responseData = eval('(' + response.d + ')');
                    var data = responseData.results;

                    _thisapp._isVerified = true;

                    //this will make sure we redraw the whole app to
                    //move on to the thankyou step. Without this, we only end
                    //up redrawing the steps and not moving screens
                    _thisapp._eventsInitialized = false;

                    //mark the app as complete
                    _thisapp._isComplete = true;
                    _thisapp._autoResume = true;

					// _thisapp.initializeApplication():
					// _thisapp.findExistingApplication(_thisapp._applicationId):

                    addValidators();
                    toggleStyleSheets();

                    //this app is not new anymore
                    _thisapp._newapp = false;

                    // _thisapp.getStepsByApplicationType(false):
                    _thisapp._applicationSteps = data;

                    //parse the querystring and see if we are requesting a
                    //specific step
                    var query = $.query(document.location.href);
                    _thisapp._currentStep = (hasValue(query.step) && query.step <= _thisapp.getLastStep()) ? query.step : 0;
                    if (hasValue(query.inframe))
                    {
                        _thisapp._inframe = true;
                    }

                    //redraw everything to make sure we make it to the thank you step
                    _thisapp.drawApplication();

                    $("#jQueryAjaxWorking").dialog("close");

                    // If US, UK, AU app url (includes ME), allow account creation
                    var query = $.query( window.location.href );
                    if( 
                        query.applicationtype.toLowerCase() === "us"  || 
                        query.applicationtype.toLowerCase() === "uk"  || 
                        query.applicationtype.toLowerCase() === "au"
                    ){
                        _thisapp.InitCreateAccountForm( responseData.bopAvailable );
                        _thisapp.ShowCreateAccountForm();
                    }
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);
                    $("#jQueryAjaxWorking").dialog("close");
                }
            });
        }

        //call the single submit function
		ajaxConfirm("QUESTION_SUBMIT_APP_TITLE", 
					"QUESTION_SUBMIT_APP",
					"LABEL_YES", _submitApplication, null,
					"LABEL_NO", null, null,
					"jQueryAjaxConfirm");

/*
        function verifyApplication()
        {                       
            ajaxWorking("VERIFYING_DATA");
            $("#jQueryAjaxWorking").dialog("open");  
            
            _thisapp.saveApplication(null);
            
            if (!_thisapp._isVerified)
            {
                //this will verify the application
                $.ajax({                     
                    data: "{applicationId:'" + _thisapp._applicationId + "'}",
                    url: "Application.asmx/VerifyApplication",          
                    success: function(response) {                                            
                        var data = eval('(' + response.d + ')');                                                                
                        getSalesForceQuerystring();                        
                        _thisapp._isVerified = true;                        
                    },
                    error: function(msg) {
                        ajaxError(this.url, msg, this.data);
                        $("#jQueryAjaxWorking").dialog("close");
                    }
                });
            }
            else
            {
                getSalesForceQuerystring();
            }
        }
        
        //build a Sales Force Querystring
        function getSalesForceQuerystring()
        {            
            ajaxWorking("SUBMITTING_APPLICATION");
            $("#jQueryAjaxWorking").dialog("open");
                   
            //this will verify the application
            $.ajax({ 
                data: "{applicationId:'" + _thisapp._applicationId + "'}",
                url: "Application.asmx/SendApplicationToSalesForce",          
                success: function(response) {                    
                    var data = eval('(' + response.d + ')');
                    
                    if ( !_thisapp._isComplete )
                    {                                                 
                        sendNotification();
                    }
                    else
                    {
                        cleanupApplication();
                    }                                                                          
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);
                    $("#jQueryAjaxWorking").dialog("close");
                } 
            });            
        }               
        
        function sendNotification()
        {            
            ajaxWorking("SENDING_APP_NOTIFICATION");
            $("#jQueryAjaxWorking").dialog("open");
            
		    //submit the querystring we built to SalesForce website which
		    //will put our data into the SalesForce database
            $.ajax({ 
                data: "{applicationId:'" + _thisapp._applicationId + "'}",
                url: "Application.asmx/sendEmail",          
                success: function(response) {                    
                    var data = eval('(' + response.d + ')');
                    
                    try
                    {                    
                        if (data == "Complete")
                        {                    
                            cleanupApplication();
                        }
                        else
                        {
                            throw "sendNotification";                   
                        }
                    }
                    catch(er)
                    {
                        if (er == "sendNotification")
                        {
                            ajaxError("Application.asmx/sendEmail", data, "sendEmail expected response 'Complete', but got response '" + data + "'");                            
                        }                       
                        $("#jQueryAjaxWorking").dialog("close");                        
                    }
                    
                },
                error: function(msg) {                    
                    ajaxError(this.url, msg, this.data);
                } 
            });
        }               
        
        function cleanupApplication()
        {                       
            // 3/17/2008 SMH
            // instead of killing the cookie, always redirect them to the 
            // post submit steps. The cookie will only get cleared if they
            // choose the Start Over option. This way they can always get
            // back to the deposit help and documentation            
            
            $("#jQueryAjaxWorking").dialog("close");
            $("#jQueryAjaxWorking").dialog("open");
                                   
                      
            //this will make sure we redraw the whole app to
            //move on to the thankyou step. Without this, we only end
            //up redrawing the steps and not moving screens
            _thisapp._eventsInitialized = false;
                                     
            //mark the app as complete
            _thisapp._isComplete = true;
            _thisapp.setApplicationComplete();
                                    
            _thisapp._autoResume = true;
            _thisapp.initializeApplication();                       
        }
                
        //start calling the functions we declard to get us through the submission process
        ajaxConfirm("QUESTION_SUBMIT_APP_TITLE", 
                "QUESTION_SUBMIT_APP",
                "LABEL_YES", verifyApplication, null,
                "LABEL_NO", null, null,
                "jQueryAjaxConfirm");

	=== END COMBINING submitApplication to a single function =====================
*/
    };

    this.InitCreateAccountForm = function(bopAvailable) {
        $('#createAccountCheckUsername').click(function(e) {
            _thisapp.checkCreateAccountUsername($('#createAccountUsername').val());
        });

        $('#createAccountBOPAvailable').val(bopAvailable);

        // don't ask for password if we're queueuing
        if (!bopAvailable) {
            $('#createAccountCheckPassword').attr('disabled', 'disabled').hide();
        }

        // Apply arabic translations if necessary
        var helpText = translate( 'PASSWORD_HELP' );
        if (_thisapp._language != null && _thisapp._language.toLowerCase() == 'ar-ae') {
            _thisapp.ApplyTranslationsToCreateAccountForm();
            $('#createAccountForm .gft-container-left-form-question-information').remove(); // pull help out, don't currently have translation
        } 

        // Attach help handler
        $('#createAccountForm .gft-container-left-form-question-information').click(function(e) {
            ajaxAlert("Password Requirements", helpText);
            $("#jQueryAjaxAlert").dialog("open");
        });
    },

    this.ApplyTranslationsToCreateAccountForm = function() {
        // Heading
        $('#jQueryCreateAccount').attr('title', translate( 'CREATE_ACCOUNT' ));

        // Submit button
        // done on dialog creation

        // Check account button
        $('#createAccountCheckUsername').text(translate('CHECK_USERNAME'));

        // Checking message --> do on click
        var checkingMsg = translate( 'CHECKING_USERNAME' );
        $('#checkUsernameLoading').attr('title', checkingMsg).attr('alt', checkingMsg);

        // username field
        $('#jQueryCreateAccount label[for="createAccountUsername"]').text( translate( 'USERNAME' ));
        $('#createAccountUsername').attr('dir', 'rtl');

        // password field
        $('#jQueryCreateAccount label[for="createAccountPassword"]').text( translate( 'PASSWORD' ));
        $('#createAccountPassword').attr('dir', 'rtl');

        // confirm field
        $('#jQueryCreateAccount label[for="createAccountPasswordConfirm"]').text( translate( 'CONFIRM_PASSWORD' ));
        $('#createAccountPasswordConfirm').attr('dir', 'rtl');
    },

    this.ShowCreateAccountForm = function() {
        var buttons = {};

        var buttonText = translate('CREATE');
        buttons[buttonText] = function() {
            _thisapp.createAccount();
        };

        $("#jQueryCreateAccount").dialog({
            modal: true,
            closeOnEscape: false,
            buttons: buttons,
            width: 406
        });

        // Find and remove the close icon
        $("#jQueryCreateAccount").dialog().parents(".ui-dialog").find(".ui-dialog-titlebar-close").remove();
    },

    this.createAccount = function() {
        var bopAvailable = $('#createAccountBOPAvailable').val();
        bopAvailable = bopAvailable ? true : false; // Handle truth-y values for availability

        var pwOk = true; // if bop not availble, don't ask for password
        if (bopAvailable) {
            pwOk = _thisapp.validateNewPassword();
        }

        var username = $('#createAccountUsername').val();
        var usernameOk = true;
        if( !_thisapp.checkCreateAccountUsername( username )){
            usernameOk = false;
        }

        // Validate password
        if (pwOk && usernameOk) {

            $("#jQueryAjaxWorking").dialog("close");
            $("#jQueryAjaxWorking").dialog("open");

            var pw = $("#createAccountPassword").val();

            // Make create service call
            $.ajax({
                data: "{applicationId:'" + _thisapp._applicationId + "', username:'" + username + "', password:'" + pw + "', rpid:" + _thisapp._referralId + ", bopAvailable:" + bopAvailable + " }",
                url: "Application.asmx/CreateAccount",
                async: false,
                success: function(response) {
                    var data = eval('(' + response.d + ')');

                    $("#jQueryAjaxWorking").dialog("close");

                    var dialog = $('#jQueryCreateAccount');
                    var report = $('#createAccountReport');
                    var reportText = '';
                    report.empty();
                    if (data.created) {
                        reportText = translate('ACCOUNT_CREATED_OPEN');
                        reportText += data.accountNumber;
                        reportText = translate('ACCOUNT_CREATED_CLOSE');

                        // Send the account number along with funding engine links
                        appendParamToAnchors('a[href*="deposit"],a[href*="funding"],a[href*="Deposit"],a[href*="Funding"]', 'acct', data.accountNumber);
                    } else {
                        reportText = translate( 'ACCOUNT_QUEUED' );
                    }
                    report.html(reportText);

                    dialog.dialog('option', 'buttons', { 'Close': function() {
                        $(this).dialog('close');
                    }
                    });

                    report.show();
                    $('#createAccountForm').hide();
                },
                error: function(msg) {
                    $("#jQueryAjaxWorking").dialog("close");
                    ajaxError(this.url, msg, this.data);
                }
            });
        } else {
            if( !pwOk ){
                var passwordMsg = translate('INVALID_PASSWORD');
                $('#passwordCheckReport').removeClass('gft-error').removeClass('gft-success').addClass('gft-error').text(passwordMsg).show();
            }
        }
    },

    this.validateNewPassword = function() {
        var pw = $("#createAccountPassword").val();
        var pw2 = $("#createAccountPasswordConfirm").val();
        var username = $('#createAccountUsername').val();

        // Must match confirm
        if (pw != pw2) {
            return false;
        }

        // Cannot be shorter than 6
        if (pw.length < 6) {
            return false;
        }

        // Must contain 3 of [A, a, 9, $]
        var matches = 0;
        if (pw.match(/[A-Z]/)) { matches++; }
        if (pw.match(/[a-z]/)) { matches++; }
        if (pw.match(/\d/)) { matches++; }
        if (pw.match(/\W/)) { matches++; }
        if (matches < 3) {
            return false;
        }

        // Cannot contain any 3-character part of the username
        var slices = [];
        var i = 0;
        var matchedUsername = false;
        while (i <= (username.length - 3)) {
            slices.push(username.substr(i, 3));
            i++;
        }
        $.each(slices, function(index, value) {
            if (pw.indexOf(value) != -1) {
                matchedUsername = true;
                return false;
            }
        });
        return true;
    },


    this.checkCreateAccountUsername = function(username) {
        $("#jQueryCreateAccount").dialog('disable');
        var checkButton = $('#createAccountCheckUsername');
        var image = $('#checkUsernameLoading');

        checkButton.text(translate('CHECKING_USERNAME'));
        checkButton.attr('disabled', 'disabled');
        checkButton.css('cursor', 'progress');
        image.show();

        // MT4 requires numeric usernames
        if (this._techVendorId != null && this._techVendorId === 5) {
            if (!username.match(/^\d+$/)) {  // matches strings that have digits from beginning to end
                this.SetUsernameInvalid(translate('USERNAME_MUST_BE_NUMERIC'));
                return false;
            }
            if (username[0] == "0") {
                this.SetUsernameInvalid(translate('USERNAME_MUST_NOT_START_WITH_ZERO'));
                return false;
            }
            var numericUsername = parseInt( username );
            if( numericUsername == null || numericUsername <= 10000 || numericUsername >= 2147483647 ){
                this.SetUsernameInvalid(translate('USERNAME_IS_NOT_VALID'));
                return false;
            }
        }

        var bopValid = true;
        $.ajax({
            data: "{username:'" + username + "'}",
            url: "Application.asmx/CheckUsername",
            async: false,
            success: function(response) {
                var data = eval('(' + response.d + ')');

                if (data.isOk) {
                    _thisapp.SetUsernameValid();
                } else {
                    bopValid = false;
                    _thisapp.SetUsernameInvalid();
                }
            },
            error: function(msg) {
                ajaxError(this.url, msg, this.data);
            }
        });

        return bopValid;
    },

    this.SetUsernameValid = function() {
        var reportText = translate('USERNAME_IS_VALID');
        var buttonText = translate('CHECK_USERNAME');

        $('#usernameCheckReport').removeClass('gft-error').addClass('gft-success').text(reportText);

        var checkButton = $('#createAccountCheckUsername');
        checkButton.text(buttonText);
        checkButton.attr('disabled', '');
        checkButton.css('cursor', 'pointer');

        var image = $('#checkUsernameLoading');
        image.hide();
        $("#jQueryCreateAccount").dialog('enable');
    },
    this.SetUsernameInvalid = function() {
        var invalidMsg = translate('USERNAME_IS_NOT_VALID');
        var buttonText = translate('CHECK_USERNAME');

        var msg = arguments.length > 0 ? arguments[0] : invalidMsg;
        $('#usernameCheckReport').removeClass('gft-success').addClass('gft-error').text(msg);

        var checkButton = $('#createAccountCheckUsername');
        checkButton.text(buttonText);
        checkButton.attr('disabled', '');

        var image = $('#checkUsernameLoading');
        image.hide();
        $("#jQueryCreateAccount").dialog('enable');
    },


    this.submitDepositApplication = function() {

        _thisapp.saveApplicationStep(null)

        if (_thisapp._isVerified) {
            $("#jQueryAjaxWorking").dialog("close");
            $("#jQueryAjaxWorking").dialog("open");

            //this will make sure we redraw the whole app to
            //move on to the thankyou step. Without this, we only end
            //up redrawing the steps and not moving screens
            _thisapp._eventsInitialized = false;

            //mark the app as complete
            _thisapp._isComplete = true;
            _thisapp.setApplicationComplete();

            _thisapp._autoResume = true;
            _thisapp.initializeApplication();

        }
    };
                
    //repopulate the application properties to make sure we're up to date
    this.getApplicationProperties = function() {
        var retProp = "";
        $.ajax({
            data: "{applicationId:'" + _thisapp._applicationId +
                  "'}",
            url: "Application.asmx/FindApplication",
            async: false,
            success: function(response) {
                var data = eval('(' + response.d + ')');

                _thisapp._appProps = data;

                _thisapp._applicationId = data.ApplicationID;
                _thisapp._referralId = data.ReferralID;
                _thisapp._advertiserId = data.AdvertiserID;
                _thisapp._salesId = data.SalesID;
                _thisapp._techVendorId = data.TechVendorID;
                _thisapp._specTypeId = data.SpecTypeID;
                _thisapp._originUrl = data.OriginURL;
                _thisapp._isComplete = data.IsComplete;
                _thisapp._isVerified = data.IsVerified;
                _thisapp._appemail = data.Email;
                _thisapp._accountType = data.AccountTypeCode;

            },
            error: function(msg) {
                ajaxError(this.url, msg, this.data);
            }
        });

        return retProp;
    };
    
    //repopulate the application properties to make sure we're up to date
    this.getReferringPartyName = function()
    {
        var retProp = "";
        $.ajax({ 
            data: "{applicationId:'" + _thisapp._applicationId +                   
                  "'}",
            url: "Application.asmx/GetReferringPartyName",          
            async: false,
            success: function(response) {                                        
                retProp = response.d;
            },
            error: function(msg) {           
                ajaxError(this.url, msg, this.data);
                
                retProp = "Uknown";
            }            
        }); 
                
        return retProp;
    };
    
    
    this.setApplicationComplete = function()
    {
         $.ajax({ 
                data: "{applicationId:\"" + _thisapp._applicationId +                        
                        "\",isComplete:\"" + _thisapp._isComplete +
                        "\"}",
                url: "Application.asmx/SetApplicationComplete",          
                async: false,
                success: function(response) {                                
                },
                error: function(msg) {
                    ajaxError(this.url, msg, this.data);
                    _thisapp.doExit();
                }            
            });
    };          
}

