/*************************************
    * Various LMB utility functions belong here.
    * Do a thurough usage text search before editing this file.
    * <p>
    * <small>
    * $$File: //depot/Java/production-2010.02.03/www/loans/resources/lmbUtil.js $$ <br>
    * $$Change: 78916 $$ submitted by $$Author: scm $$ at $$DateTime: 2010/02/02 16:33:26 $$ <br>
    * </small>
    * @author ${user}
    * @version $$Revision: #1 $$
**************************************/

    var lmbUtil = {
        loggerURL : "/servlet/LMBServlet?the_action=EventLogger&",

        /*Browser product detection.*/
        isIE6: /MSIE 6.0/.test(navigator.userAgent),
        isIE7: /MSIE 7.0/.test(navigator.userAgent),
        isFF: /Firefox/.test(navigator.userAgent),

        /*Creates a proper iframe for IE and FF.  IE does not properly set the name
        property of the iframe, which is needed for the target submission.*/
        createIFrame: function(name) {
            var iframe = (lmbUtil.isIE6 || lmbUtil.isIE7) ?
                   document.createElement('<iframe name="' + name + '">')
                    : document.createElement('iframe');
            iframe.name = name;

            return iframe;
        },

        /*	Parses string to integer.	 In case of unparsable string returns 0.*/
        getInteger : function(str){
            try{
                if(!isNaN(parseInt(str))) {
                    return parseInt(str);
                } else {
                    return 0;
                }
            } catch(e) {
                return 0;
            }
        },

        /*Adds thousanths place commas to a number string*/
        addCommasToNumString : function (strIn) {
            var arrTemp = strIn.split("");
            var i = strIn.length - 4;
            var iPoint = strIn.indexOf(".");
            if (iPoint > -1) {
                i -= (strIn.length - iPoint);
            }
            for (i; i >= 0; i -= 3) {
                arrTemp[i] += ",";
            }
            return arrTemp.join("");
        },

        /*Filter decimals, and adds commas*/
        filterDecimalAddCommas : function (hField) {
            var strIn = hField.value;
            var arrTemp = strIn.split("");
            var i = strIn.length - 4;
            var iPoint = strIn.indexOf(".");
            if (iPoint > -1) {
                i -= (strIn.length - iPoint);
            }
            for (i; i >= 0; i -= 3) {
                arrTemp[i] += ",";
            }
            hField.value = arrTemp.join("");
        },

        /*TODO: this should be depricated and replaced with DWR RemoteLogger*/
        /*Logs error event*/
        log : function(msg){
            lmbUtil.logEvent(msg, "js_error", true);
        },

        /*Encodes the object*/
        encodeObject : function(obj, namespace){
            var str = "";
            for(prop in obj){
                if((typeof obj[prop]) == "object"){
                    str += lmbUtil.encodeObject(obj[prop], namespace + "." + prop);
                } else if((typeof obj[prop]) == 'function') {
                    //do nothing.
                } else {
                    var name = namespace + "." + prop;
                    var value = "" + obj[prop];
                    try{
                        str = str + "&" + escape(name) + "=" + escape(value);
                    } catch(e){}
                }
            }
            return str;
        },

        /*TODO: this should be depricated and replaced with DWR RemoteLogger*/
        /*Logs generic event*/
        logEvent : function(msg, eventType, appendForm){
            try{
                var src = lmbUtil.loggerURL + "&eventType=" + escape(eventType);
                if(((typeof msg) == "string") || ((typeof msg) == "number")){
                    src += "&message=" + escape(msg);
                }
                else if((typeof msg) == "object"){
                    src += lmbUtil.encodeObject(msg, "message");
                }
                if(appendForm && document.forms) {
                    form = document.forms[0];
                    src += "&" + lmbFormUtil.getFormData(form) + Math.random();
                }
                src += "&browser=" + escape(navigator.userAgent);
                lmbAJAXUtil.sendGetRequest(
                    src,
                    true,
                    function(){},
                    function(){
                        var img = new Image();
                        img.src = src;
                    }
                );
            } catch(e) {
            //error sending request or accessing the data
            //No way to recover.  Abort logging
            }
        },

        /*Fires pixel*/
        recordDecision : function(form, uri, decision, amount) {
            var submitPixel = new Image();
            uri += "?app_user_id=" + getFormFieldValue(form.app_user_id);
            uri += "&verticalVisitorId=" + getFormFieldValue(form.verticalVisitorId);
            uri += "&presentationId=<%= presentationId %>";
            uri += "&decision=" + decision;
            uri += "&amount=" + amount;
            uri += "&time=" + new String(new Date().getTime());
            submitPixel.src = pixelURI;
        },

        /*TODO: this should be depricated and replaced with prototype*/
        /*Adds event listeners.  Deals with differences in standard and IE*/
        addEventListener : function(target, evt, action){
            if(target.addEventListener){
                //Standard Browser (Firefox, Opera)
                target.addEventListener(evt, action, false);
            }
            else if(target.attachEvent){
                target.attachEvent("on" + evt, action);
            }
        },

        /*TODO: this should be depricated and replaced with prototype*/
        /*Removes event listeners.  Deals with differences in standard and IE*/
        removeEventListener : function(target, evt, action){
            if(target.removeEventListener){
                //Standard Browser (Firefox, Opera)
                target.removeEventListener(evt, action, false);
            }
            else if(target.detachEvent){
                target.detachEvent("on" + evt, action);
            }
        },

        /*TODO: this should be depricated and replaced with prototype*/
        /*Calculates absolute position of the element on the page*/
        getAbsolutePosition : function (element){
            var position = new Object();
            position.x = 0;
            position.y = 0;
            if (element.offsetParent) {
                position.x = element.offsetLeft;
                position.y = element.offsetTop;
                while (element = element.offsetParent) {
                    position.x += element.offsetLeft;
                    position.y += element.offsetTop;
                }
            }
            return position;
        },

        /*TODO: this should be depricated and replaced with scriptaculous*/
        fadeTrans : function (id, opacStart, opacEnd, millisec) {
            try {
                var speed = Math.round(millisec / 100);
                var timer = 0;
                if (opacStart > opacEnd) {
                    for (i = opacStart; i >= opacEnd; i--) {
                        setTimeout("lmbUtil.changeOpac(" + i + ",'" + id + "')", timer * speed);
                        timer++;
                    }
                } else if (opacStart < opacEnd) {
                    for (i = opacStart; i <= opacEnd; i++) {
                        setTimeout("lmbUtil.changeOpac(" + i + ",'" + id + "')", timer * speed);
                        timer++;
                    }
                }
            } catch (ex) {}
        },
        changeOpac : function (opacity, id) {
            var object = document.getElementById(id).style;
            object.opacity = opacity / 100;
            object.MozOpacity = opacity / 100;
            object.KhtmlOpacity = opacity / 100;
            object.filter = "alpha(opacity=" + opacity + ")";
        },

        /*Auto tabs to next field*/
        autoTab : function(event) {
            try {
                // Automatically focuses the next form field if you reach the maxlength of a text input while typing.
                if (event.keyCode
                        && "0,8,9,16,17,18,38,39,40,46".indexOf(event.keyCode.toString()) != -1) {
                    return;
                }

                var hField = Event.element(event);

                if (hField != null
                        && hField.value.length < lmbUtil.getInteger(hField.getAttribute("maxlength"))) {
                    return;
                }

                var form = hField ? hField.form : undefined;
                if(form) {
                    for (var i = 0; i < form.length; i++) {
                        if ((hField == form[i]) && (i < form.length - 1)) {
                            form[i + 1].focus();
                            return;
                        }
                    }
                }
            } catch(ex) {
                lmbLogger.logError({
                    error : "lmbUtil.autoTab",
                    stackTrace: ex
                });
            }
        },

        /*Filter integer values only*/
        filterInteger : function(event) {
            Event.element(event).value = Event.element(event).value.replace(/[^0-9]/g, "");
        },

        /*Properties for opening a new window*/
        WinProps : {
            FEATURES_FULL : "toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,resizable=yes,",
            FEATURES_INFO : "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,alwaysRaised,dependent,",
            FEATURES_POPUPFORM : "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,",
            SIZE_FULL : "width=800,height=600,"
        },

        /*Property needed for enabling popups.  If popups are surpessed by sourceid,
        this property is set to false.  This should be depricated after refactoring.*/
        isPopupSuppressed : false,

        /*Inits exit pop suppression logic, and sets isPopupSuppressed.  This is a special
        case where the lending bo object is passed this deep.  Normally the lending
        bo object should be handled at the PageUtil level, and no deeper.
            @params data - the lending bo object.
        */
        initExitPopSuppression : function(data) {
            try {
                /*set exit pop suppression flag*/
                if(data.suppressExitPop) {
                    lmbUtil.isPopupSuppressed = true;
                }

                /*This is supposedly an old hack to suppress popups
                if you click on a hypertext link.  Not sure if this is still
                a valid problem.*/
                $A(document.links).each(function(link) {
                    Event.observe(link, 'click', function(event) {
                        lmbUtil.isPopupSuppressed = true;
                    });
                });
            } catch(ex) {
                lmbLogger.logError({
                    error: "lmbUtil.initExitPopSuppression",
                    stackTrace: ex
                });
            }
        },

        /*The preferred way to open new windows*/
        popWin : function() {
            try {
                var url				= arguments[0]; // required - url
                var name			= arguments[1]; // required - window name
                var winProperties	= arguments[2];	// required - window properties
                var isBlockable		= arguments[3]; // required - is the popup blockable ?
                var under			= arguments[4]; // optional - boolean for popunder
                var form			= arguments[5]; // optional - form object

                /*Don't open new window if popups are suppressed.*/
                if (lmbUtil.isPopupSuppressed) {
                    return null;
                }

                /*This appends all the parameters in the form as a query string
                for a "GET" type request.  Should consider doing a "POST" type
                request to avoid complicated javascript functions.*/
                if (form) {
                    url += (url.indexOf("?")==-1) ? "?" : "&";
                    url += lmbUtil.getFormValueQueryString(form);
                }

                // open the window
                var win = window.open(
                    url,
                    name,
                    winProperties
                );

                // is it a popunder?
                if (under) {
                    try { win.blur(); } catch(ex) {}
                    self.focus();
                }

                // return
                return win;
            } catch(ex) {
                /*too many things can go wrong here.  Log if they do.*/
                lmbLogger.logError({
                    error: "lmbUtil.popWin",
                    stackTrace: ex
                });
            }
        },

        /*Opens a small window*/
        opensmallWindow : function(url) {
            lmbUtil.popWin(
                url,
                "wSmInfoPopup",
                "width=350,height=225,scrollbars=yes,alwaysRaised,dependent",
                false
            );
        },

        /*Opens a big window*/
        openbigWindow : function (url) {
            var newBigWindow = window.open(
                url,
                "client3",
                "width=700,height=450,scrollbars=yes,alwaysRaised,resizable=yes,toolbar,dependent"
            );
        },

        /*Opens class page exit form*/
        openClassicExitForm : function() {
            var w = lmbUtil.popWin(
                "/servlet/LMBServlet?the_action=Load&next_page=/fh/homeLoans/popUps/exitForm_ulf_pg4.jsp",
                "exitForm",
                "width=730,height=465," + lmbUtil.WinProps.FEATURES_POPUPFORM,
                true,
                true,
                document.forms[0]
            );
        },

        /*Opens class page exit form*/
        openRatesInfo : function(url) {
            var w = lmbUtil.popWin("/servlet/LMBServlet?the_action=Load&next_page=/loans/lp/1624/staterates.jsp","silverPop", "width=390,height=240,scrollbars=yes,alwaysRaised,resizable=yes,dependent");
        },

        /*Opens advantage / premier plus mini OCP exit form*/
        openAdvantageOrPremierMiniOCPExitForm : function() {
            var w = lmbUtil.popWin(
                "/servlet/LMBServlet?the_action=Load&next_page=/fh/popUps/premier_exit_pop/premier_match_page5_exit.jsp?keepOpen=yes",
                "exitForm",
                "width=700,height=500," + lmbUtil.WinProps.FEATURES_POPUPFORM,
                true,
                true,
                document.forms[0]
            );
        },

        /*Opens advantage / premier plus mini Lead Scrub exit form*/
        openAdvantageOrPremierMiniLeadScrubOCPExitForm : function() {
            var w = lmbUtil.popWin(
                "/servlet/LMBServlet?the_action=Load&next_page=/fh/popUps/lead_scrub_exit_pop/lead_scrub_exit_pop.jsp?keepOpen=yes",
                "exitForm",
                "width=700,height=311," + lmbUtil.WinProps.FEATURES_POPUPFORM,
                true,
                true,
                document.forms[0]
            );
        },

        /*Opens the landing page exit form*/
        openLandingPageExitForm : function() {
            var w = lmbUtil.popWin(
                "/servlet/LMBServlet?the_action=Load&next_page=/fh/homeLoans/popUps/exitForm_ulf_pg1.jsp",
                "exitForm",
                "width=730,height=465,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,",
                true,
                true,
                document.forms[0]
            );
        },

        /*Opens the landing page entry pop under*/
        openLandingPageEntryPopUnder : function(data) {
            function writeSessionCookie (cookieName, cookieValue) {
                document.cookie = escape(cookieName) + "=" + escape(cookieValue) + "; path=/";
            }

            function getCookieValue (cookieName) {
                var exp = new RegExp (escape(cookieName) + "=([^;]+)");
                if (exp.test (document.cookie + ";")) {
                    exp.exec (document.cookie + ";");
                    return unescape(RegExp.$1);
                } else {
                    return false;
                }
            }

            var popUnderUrl = "/servlet/LMBServlet?the_action=HomeLoansEntryPopunder";
            popUnderUrl += "&sourceid=" + requestParameters.sourceid;
            popUnderUrl += "&sub_dmn=" + requestParameters.sub_dmn;
            popUnderUrl += "&visitorId=" + abTestMetaInfo.verticalVisitorId;

            if (!getCookieValue("hpPOP") && !lmbUtil.isPopupSuppressed) {
                if (window.parent) {
                    window.parent.name = 'lmbwindow';
                } else {
                    window.name = 'lmbwindow';
                }

                var lrePop = window.open(popUnderUrl, "lrepg1", "width=724,height=550,resizable=no,scrollbars=no,menubar=no");
                try { lrePop.blur(); } catch(ex) {}
                self.focus();
                writeSessionCookie("hpPOP", "true");
            }
        },

        /*Gets the query string.  Used by popWin*/
        /*TODO: This should be refactored.  This is a very complicated function for doing a simple thing.*/
        getFormValueQueryString : function (form) {
            var i, j, val, name, arrParams = new Array();
            for (i = 0; i < form.elements.length; i++) {
                try {
                    if (((form.elements[i].type == "checkbox")
                            || (form.elements[i].type == "radio"))
                            && (form.elements[i].checked == false)) {
                        continue;
                    }
                } catch(ex) {}
                name = form.elements[i].name;
                val = lmbUtil.getFormFieldValue(form.elements[i]);
                if (typeof(val) == "object") {
                    for (j = 0; j < val.length; j++) {
                        val[j] = name + "=" + escape(val[j]);
                    }
                    arrParams[i] = val.join("&");
                } else {
                    arrParams[i] = name + "=" + escape(val);
                }
            }
            return arrParams.join("&");
        },

        /*Gets the form value.  Used by popWin*/
        /*TODO: This should be refactored.  This is a very complicated function for doing a simple thing.*/
        getFormFieldValue : function(hField) {
            if (!hField) {
                return undefined;
            }
            try {
                if (hField.type) {
                    if (hField.type == "radio") {
                        return lmbUtil.getRadioValue(hField.form.elements[hField.name]);
                    } else if (hField.type == "select-multiple") {
                        return lmbUtil.getMultipleSelectBoxValues(hField);
                    } else {
                        return hField.value;
                    }
                }
            } catch (ex) {}
            try {
                if (hField.length && hField[0] && (hField[0].type == "radio")) {
                    return getRadioValue(hField[0].form.elements[hField[0].name]);
                }
            } catch(ex) {}
            return undefined;
        },

        /*Gets value from select element.  Used by popWin*/
        /*TODO: This should be refactored.  This is a very complicated function for doing a simple thing.*/
        getMultipleSelectBoxValues : function (hSelect) {
            var i, option, arrSelected = new Array();
            while (hSelect.selectedIndex >= 0) {
                arrSelected[arrSelected.length] = hSelect.selectedIndex;
                hSelect.options[hSelect.selectedIndex].selected = false;
            }
            for (i = 0; i < arrSelected.length; i++) {
                option = hSelect.options[arrSelected[i]];
                option.selected = true;
                arrSelected[i] = option.value;
            }
            return arrSelected;
        },

        /*Gets value from radio elements.  Used by popWin*/
        /*TODO: This should be refactored.  This is a very complicated function for doing a simple thing.*/
        getRadioValue : function (hRadioGroup) {
            // Gets the selected value of a radio button group. If no radio button is selected, returns an empty string.
            for (var i = 0; i < hRadioGroup.length; i++) {
                if (hRadioGroup[i].checked) {
                    return hRadioGroup[i].value;
                }
            }
            return "";
        }
    }//End lmbUtil


 /*******************************************************************************
    Interface to log messages to server using DWR RemoteLogger.
    This is the preferred way.
 ********************************************************************************/
    var lmbLogger = {
        PAGE_VISIT_EVENT: "page_visit_event",
        VALIDATION_ERROR_EVENT: "validation_error_event",
        USER_DATA_ENTRY_EVENT: "user_data_entry_event",
        USER_ACTION_EVENT: "user_action_event",
        JS_ERROR: "js_error",
        VALIDATION_ERROR_REQUEST_PARAM: "validation_error_request_param",
        PHONE_VALIDATION_ERROR: "phone_validation_error",
        EXPERIAN_VTS_EVENT: "experian_vts_event",
        VISITOR_INFO: "visitor_info",
        REDIRECT_EVENT: "redirect_event",

        /*Uses DWR remote logger to log regular message, this is the preferred way.*/
        logMessage : function(eventType, msg) {
            try {
                RemoteLogger.logEvent(
                    eventType,
                    abTestMetaInfo.verticalVisitorId,
                    abTestMetaInfo.presentationId,
                    abTestMetaInfo.pageID,
                    msg
                );

            } catch(ex) {
                //error sending request or accessing the data
                //No way to recover.  Abort logging
            }
        },

        /*Uses DWR remote logger to log error messages, this is the perferred way.*/
        logError : function(msg) {
            try {
                var msgObj = {
                    errorDetail : Object.toJSON(msg).substring(0,4000),
                    browser: navigator.userAgent
                };

                RemoteLogger.logError(
                    abTestMetaInfo.verticalVisitorId,
                    abTestMetaInfo.presentationId,
                    abTestMetaInfo.pageID,
                    msgObj
                );

            } catch(ex) {
                //error sending request or accessing the data
                //No way to recover.  Abort logging
            }
        }
    };


/*******************************************************************************
    This is transformes the Object graph into prototype Hash
 *******************************************************************************/
    Object.flat = function(obj, prefix){
        obj = (obj == null) ? this : obj;
        prefix = (prefix == null) ? "" : prefix + ".";
        var a = {};
        for(prop in obj){
            var value = obj[prop];
            if((typeof value) == "object"){
                a = Object.extend(a, Object.flat(value, prefix + prop));
            } else if((typeof value) == "function") {
                //do nothing.
            } else {
                a [prefix + prop] = value;
            }
        }
        return a;
    }

    
/*******************************************************************************
    This automatically captures any window level javascript error events.
********************************************************************************/
    window.onerror = function (msg, url, linenumber) {
        try{
            var failedFunc = window.onerror.caller.toString();
            lmbUtil.log({errorType : "window.onerror", errorMessage : msg, url : url, line : linenumber, failedFunction : failedFunc});
        } catch(e){}
    };


/*******************************************************************************
    Creates an empty console object if one doesn't exist.  This is to prevent IE
    from throwing an error is the console object doesn't exist.
********************************************************************************/
    if (!("console" in window) || !("firebug" in console)){
        var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
            "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

        window.console = {};
        for (var i = 0; i < names.length; ++i)
            window.console[names[i]] = function() {}
    }
