/*******************************************************************************
   Various LMB utility functions belong here.
   Do a thurough usage text search before editing this file.
********************************************************************************/
var lmbUtil = {
    loggerURL : "/servlet/LMBServlet?the_action=EventLogger&",
    isIE7 : navigator.userAgent.indexOf("MSIE 7.0") != -1,
    isFF : navigator.userAgent.indexOf("Firefox") >= 0,

    /*	Parses string to integer.	 In case of unparsable string returns 0.*/
    getInteger : function(str){
        try{
            //Issue 34648 - ParseInt will trucate the string-number when it encounters a comma
            //So remove the comma first and then parse into integer
            if (/\,/.test(str)) {
                str = str.replace(/\,/, "");
            }
            return parseInt(str);
        } 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) {
        hField.value = addCommasToNumString(getDecimalString(hField.value));
    },

    /*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){
        try {
            if(target.addEventListener){
                //Standard Browser (Firefox, Opera)
                target.addEventListener(evt, action, false);
            }
            else if(target.attachEvent){
                target.attachEvent("on" + evt, action);
            }
        } catch (exception) {}
    },

    /*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 ("0,8,9,16,17,18,38,39,40,46".indexOf(event.keyCode.toString()) != -1) {
                return;
            }

            var hField = Event.element(event);

            if (hField.value.length < getInteger(hField.getAttribute("maxlength"))) {
                return;
            }

            var form = Event.element(event).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, "");
    },

    /*Property needed for enabling popups.  This should be depricated after refactoring.*/
    popupsEnabled : true,

    /*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,"
    },

    /*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

            // only do it if popups are enabled
            if (!lmbUtil.popupsEnabled && isBlockable) {
                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"
        );
    },

    /*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;
    },

    /*Sets the form value.  Used by popWin*/
    /*TODO: This should be refactored.  This is a very complicated function for doing a simple thing.*/
    setFormFieldValue : function (hField, selectedValue) {
        if (!hField) {
            return;
        }

        try {
            if (hField.type) {
                if (hField.type == "radio") {
                    setRadioValue(hField.form.elements[hField.name], selectedValue);
                    return;
                } else {
                    hField.value = selectedValue;
                    return;
                }
            }
        } catch(ex) {}

        try {
            if (hField.length && hField[0] && (hField[0].type == "radio")) {
                setRadioValue(hField[0].form.elements[hField[0].name], selectedValue);
                return;
            }
        } catch(ex) {}
    },

    /*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 = {
    
    /*Uses DWR remote logger to log regular message, this is the preferred way.*/
    logMessage : function(msg) {
        try {
            var msgObj;
            if(typeof(msg) == Object) {
                msgObj = msg;
            } else {
                msgObj = {errorDetail : msg};
            }

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

        } 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;
            if(typeof(msg) == Object) {
                msgObj = msg;
            } else {
                msgObj = {errorDetail : msg};
            }

            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 automatically captures any window level javascript error events.
********************************************************************************/
window.onerror = function (msg, url, linenumber) {
    try{
        var failedFunc = arguments.callee.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() {}
}
