
Cof = Cof || {};

String.prototype.camelCase = function() {
    var s = this.replace(/^\s*|\s*$/g, "");
    return (/\S[A-Z]/.test(s))
    ? s.replace(/(.)([A-Z])/g, function(t,a,b) {
        return a + ' ' + b.toLowerCase();
    })
    : s.replace(/( )([a-z])/g, function(t,a,b) {
        return b.toUpperCase();
    });
};

/**
 * The main Homepage object
 *
 * @class Homepage
 */
Cof.Homepage = function() {

    /**
     * @description The id of the HTML element that will hold the Flash feature banners.
     * @property _featureContainerId
     * @private
     * @type String
     */
    var _featureContainerId = 'flash-container';

    /**
     * @description Flag to enable/disable X+1 functionality for the homepage ONLY.
     * @property _isHpXplusOneEnabled
     * @private
     * @type Boolean
     */
    var _isHpXplusOneEnabled = true;

    /**
     * @description Flag used to prevent the feature banner from being rendered more
     *      than once. Once the feature banner is rendered, it can not be rendered again.
     * @property _disableFeatureBannerRenderer
     * @private
     * @type Boolean
     */
    var _disableFeatureBannerRenderer = false;

    /**
     * @description A list of account login URLs for different platforms.
     * @property _loginUrls
     * @private
     * @type Object
     */
    var _loginUrls = {
        creditCards       : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_01_T_NTLOLB&dest=https://servicing.capitalone.com/c1/login.aspx',
        banking           : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_02_T_SPL&dest=https://onlinebanking.capitalone.com/capitalone/login.aspx',
        directBanking     : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_03_T_SPL&dest=https://onlinebanking.capitalone.com/capitalone/login.aspx',
        autoLoans         : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_04_T_OABK&dest=https://onlinebanking.capitalone.com/capitalone/Login.aspx?ori=coafPartner',
        rewardsNational   : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_05_T_RWSLG&dest=http://www.capitalone.com/rewards/service-login.php',
        rewardsRegional   : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_05_T_RWSLP&dest=http://www.capitalone.com/rewards/service-login-footprint.php',
        otherAccounts     : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_06_T_MISC&dest=http://www.capitalone.com/login.php',
        ukAccounts        : '/redirect.php?Log=1&linkid=WWW_Z_UK_Z_HOME_R1_07_T_OAUK&dest=http://www.capitalone.co.uk/web/MenuUrl?pageId=2020',
        towernet          : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_08_T_MYA&dest=http://towernet.capitalonebank.com',
        treasuryOptimizer : '/redirect.php?Log=1&linkid=WWW_Z_Z_Z_HOME_R1_09_T_MYA&dest=https://top.capitalonebank.com'
    };

    /**
     * @description Given an Atlas tag value this method will invoke AvenueA.
     * @private
     * @method _triggerTag
     * @param tagVal String
     * @returns void
     */
    var _triggerTag = function(tagVal) {
        var script = document.createElement('script');
        script.setAttribute('src', "http://view.atdmt.com/jaction/" + tagVal + "/v3/atz." + jQuery.cookie('v1st'));
        document.body.appendChild(script);
        void(script);
    };

    /**
     * @description This method will determine if a given string value
     *      is an integer or not.
     * @private
     * @method _isInteger
     * @param value String
     * @returns Boolean
     */
    var _isInteger = function(value) {
        for (i = 0; i < value.length; i++) {
            var c = value.charAt(i);

            if (!_isDigit(c)) {
                return false;
            }
        }

        return true;
    };

    /**
     * @description This method will look and return a given query string
     *      parameter's value.
     * @private
     * @method _getQueryStringParam
     * @param queryStrParam String
     * @returns String
     */
    var _getQueryStringParam = function(queryStrParam) {
        parts = window.location.search.substring(1);
        qparams = parts.split("&");

        for (i = 0; i < qparams.length; i++) {
            qparamPieces = qparams[i].split("=");

            if (qparamPieces[0] == queryStrParam) {
                return qparamPieces[1];
            }
        }

        return undefined;
    };

    /**
     * @description This variable will override the experience value sent by X+1. By default
     *      this variable's default value is pulled from the query string.
     * @property _forcedExperience
     * @private
     * @type String
     */
    var _forcedExperience = _getQueryStringParam('exp_set');

    /**
     * @description This method will determine whether or not a given string is a digit or not.
     * @private
     * @method _isDigit
     * @param value String
     * @returns Boolean
     */
    var _isDigit = function(value) {
        return ((value >= "0") && (value <= "9"))
    };

    /**
     * @description Formats a given integer into a string format with commas, decimal points, etc.
     * @private
     * @method _numberFormat
     * @param number Integer
     * @param decimals Integer
     * @param dec_point String
     * @param thousands_sep String
     * @returns String
     */
    var _numberFormat = function(number, decimals, dec_point, thousands_sep) {
        var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
        var d = dec_point == undefined ? "." : dec_point;
        var t = thousands_sep == undefined ? "," : thousands_sep, s = n < 0 ? "-" : "";
        var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;

        return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    };

    /**
     * @description Returns the feature banner experience value derived from the X+1
     *      experience variable value.
     * @private
     * @method _getXplusOneFeatureBannerExperience
     * @returns String
     */
    var _getXplusOneFeatureBannerExperience = function() {
        var experience = '';

        if (typeof _forcedExperience != 'undefined' && _forcedExperience != '') {
            experience = _forcedExperience;
        } else if (typeof xp_experience != 'undefined' && xp_experience != '') {
            experience = xp_experience.substr(0, 3) + '_' + xp_experience.substr(xp_experience.length - 4);
        }

        return experience;
    }

    /**
     * @description Determines whether or not X+1 content is needed based on the
     *      X+1 experience value.
     * @private
     * @method _isXplusOneContentNeeded
     * @returns Boolean
     */
    var _isXplusOneContentNeeded = function() {
        // Assume we need xplusone content unless proven otherwise
        var isContentNeeded = true;

        // If xplusone has been disabled, then we don't need xplusone content
        if (typeof disableXplusone != 'undefined' && disableXplusone === true) {
            isContentNeeded = false;
            return isContentNeeded;
        }

        // If the xplusone variable is undefined or the value contains BAU
        // then we do not need to make a request for the xplusone content
        if (typeof xp_experience == 'undefined' || xp_experience == '') {
            isContentNeeded = false;
        } else if (xp_experience.match(/bau/i)) {
            isContentNeeded = false;
        }

        // The _forcedExperience variable is a way to override the experience sent
        // by XplusOne. So, if this variable is set then we assume we will need
        // the associated content.
        if (typeof _forcedExperience != 'undefined' && _forcedExperience != '') {
            if (_forcedExperience.match(/bau/i)) {
                isContentNeeded = false;
            } else {
                isContentNeeded = true;
            }
        }

        return isContentNeeded;
    }

    /**
     * @description Loads the feature banner based on the X+1 variable. This method accepts a
     *      default flash config object that will display if the X+1 flash config object is not
     *      retrieved properly (e.g. an error).
     * @private
     * @method _loadXplusOneFeatureBanner
     * @param defaultConfig Object
     * @returns void
     */
    var _loadXplusOneFeatureBanner = function(defaultConfig) {
        var experience = _getXplusOneFeatureBannerExperience();

        // If banner experience is unknown then show the default banner content
        if (experience == '') {
            homepage.displayFeatureBanner(defaultConfig);
            return;
        }

        var serviceUrl = '/service/xplusone/homepage/';

        jQuery.ajax({
            url: serviceUrl,
            type: 'GET',
            data: {
                section: 'feature',
                experience: experience
            },
            dataType: 'json',
            success: function(data, status) {
                if (typeof data.resource != 'undefined' && typeof data.variables != 'undefined') {
                    // We received valid data so display the feature banners we received
                    homepage.displayFeatureBanner(data);
                } else {
                    // We received invalid data so show the default feature banners
                    homepage.displayFeatureBanner(defaultConfig);
                }
            },
            complete: function(xhr, status) {
                // If there is an error or anything other than a successful call
                // then show the default feature banners
                homepage.displayFeatureBanner(defaultConfig);
            }
        });
    }

    /**
     * @description Creates a new instance of a homepage object and sets up some event handlers
     * @private
     * @method _construct
     * @returns void
     */
    var _construct = function() {
        // Handles the Online Banking Login Form
        jQuery.elReady('#banking-login-form', function() {
            jQuery(this).submit(function() {
                if (jQuery('#olb-userid').val() === '') {
                    alert('Please enter a Username');
                    return false;
                }

                if (jQuery('#olb-password').val() === '') {
                    alert('Please enter a Password');
                    return false;
                }

                _triggerTag('NDB_Footprint_OLB_Tag');
                return true;
            });
        });

        // Handles the focus and blur of form input labels
        jQuery.elReady('#find-branch, #banking-login-form', function() {
            var formElem  = jQuery(this);
            var formInput = jQuery(this).find('input[type!=hidden]');

            jQuery(formInput).focus(function() {
                jQuery(formElem).find('label[for="' + jQuery(this).attr('id') + '"]').css('display', 'none');
            });

            jQuery(formInput).blur(function() {
                if (jQuery(this).val() == '') {
                    jQuery(formElem).find('label[for="' + jQuery(this).attr('id') + '"]').css('display', 'block');
                }
            });
        });

        jQuery(function() {
            jQuery('#use-debit-card').one('focus',function() {
                jQuery(this).val('');
            });
        });

        $(document).ready(function(){
            if (jQuery(this).find('input#olb-userid').val() != '') {
                jQuery().find('label[for="olb-userid"]').css('display', 'none');
            }
            if (jQuery(this).find('input#olb-password').val() != '') {
                jQuery().find('label[for="olb-password"]').css('display', 'none');
            }
            if (jQuery(this).find('input#branch-input').val() != '') {
                jQuery().find('label[for="branch-input"]').css('display', 'none');
            }
        });
    }

    // Run the constructor when a new instance of this object is created
    _construct();

    return {

        /**
         * @description Redirects the visitor's browser to the system login page of the selected
         *      account from the login badge dropdown.
         * @public
         * @method accountLogin
         * @returns Boolean
         */
        accountLogin: function() {
            var accountOption = jQuery('#select-account').val();

            if (accountOption == 'rewards') {
                if (c1region == 'national') {
                    accountOption += ' ' + c1region;
                } else {
                    accountOption += ' ' + 'regional';
                }
            }

            if (accountOption == 'credit cards' || accountOption == 'banking') {
                if (c1region == 'national') {
                    _triggerTag('NDB_National_OLB_Tag');
                } else {
                    _triggerTag('NDB_Footprint_OLB_Tag');
                }
            }

            var loginLocation = _loginUrls[accountOption.camelCase()];

            if (accountOption == 'other accounts' && Cof.Header.Zipcode.isZipNeeded()) {
                Cof.Header.Zipcode.askForZip(loginLocation);
                return;
            }

            return window.location = loginLocation;
        },

        /**
         * @description Renders the feature banner based on the given flash config object. Here
         *      are the accepted parameters:
         *      - nonFlashAlt -> {string} optional, contains the html content for visitors without flash
         *                       or the correct version of flash
         *      - accessibleAlt -> {string} optional, contains the accessiblity content for screen readers
         *                         to read to visitors that may be blind or disable
         *      - variables -> {object} optional, contains the variables that should be passed to the flash clip
         *                     This variable usually contains the paths to the child flash clips that should get rendered
         *      - params -> {object} optional, contains parameters for how the flash clip should behave
         *      - resource -> {string} required, contains the flash clip to render
         * @public
         * @method displayFeatureBanner
         * @param config Object
         * @returns void
         */
        displayFeatureBanner: function(config) {
            if (typeof config != 'object' ||
                typeof swfobject == 'undefined' ||
                _disableFeatureBannerRenderer == true) {
                return;
            }

            // Feature banner can only be rendered once, so we disable it
            // here from being called again
            _disableFeatureBannerRenderer = true;

            // Set the non-Flash alternate content
            if (typeof config.nonFlashAlt == 'string') {
                jQuery('#' + _featureContainerId).html(config.nonFlashAlt);
            }

            // Set the accessiblity alternate content
            if (typeof config.accessibleAlt == 'string') {
                jQuery('#section-4 .flash-alt').html(config.accessibleAlt);
            }

            var supportedFlashVersion = '9';

            // Checking to make sure the visitor has the right version of Flash or if
            // we are explicitly forcing the flash clip to not display via URL address
            if (!swfobject.hasFlashPlayerVersion(supportedFlashVersion) ||
                window.location.search.search('noflash') !== -1) {

                // Making sure the flash container content is visible
                jQuery('#' + _featureContainerId).css({visibility: 'visible'});
                return;
            }

            var flashVars   = config.variables;
            var flashParams = {
                wmode : 'transparent',
                menu  : false
            };

            isDomLoaded = true;
            jQuery.extend(flashParams, config.params);
            swfobject.embedSWF(config.resource, _featureContainerId, '650', '290', supportedFlashVersion, false, flashVars, flashParams);
        },

        /**
         * @description This method triggers the X+1 logic to wait for and retrieve the feature banner
         *      content based on the X+1 variable that's returned. Accepts a default flash config that will
         *      be used if unable to retrieve X+1 content.
         * @public
         * @method triggerXplusOneFeatureBanner
         * @param defaultConfig Object
         * @returns void
         */
        triggerXplusOneFeatureBanner: function(defaultConfig) {
            if (!_isHpXplusOneEnabled) {
                homepage.displayFeatureBanner(defaultConfig);
                return;
            }

            // Hiding the flash container content temporarily
            // until we get the real XplusOne content from the server
            jQuery('#' + _featureContainerId).css({visibility: 'hidden'});

            var featureBannerIntervalCount = 0;
            var featureBannerMaxIntervals  = 10;

            // Start an interval routine to check whether or not we have an xplusone variable
            var featureBannerIntervalId = setInterval(function() {
                if (typeof xp_experience == 'undefined' &&
                    (typeof disableXplusone == 'undefined' || disableXplusone != true) &&
                    featureBannerIntervalCount < featureBannerMaxIntervals) {

                    featureBannerIntervalCount += 1;
                    return;
                }

                // Clear out the interval since we either have the xplusone
                // variable or the interval count has timed out
                clearInterval(featureBannerIntervalId);

                // If xplusone content is not needed then show the default banner content
                if (!_isXplusOneContentNeeded()) {
                    homepage.displayFeatureBanner(defaultConfig);
                    return;
                }

                _loadXplusOneFeatureBanner(defaultConfig);

            }, 150);
        },

        /**
         * @description This method triggers the X+1 logic on the Credit Card primary nav
         *      dropdown menu. This method also listens for the replacement of the primary nav
         *      to perform some cleanup work.
         * @public
         * @method triggerXplusOneCardPrimaryNav
         * @param sectiondId String
         * @returns void
         */
        triggerXplusOneCardPrimaryNav: function(sectionId) {
            if (!_isHpXplusOneEnabled || typeof replaceSection != 'function') {
                return;
            }

            var cardPrimaryNavMenu = jQuery('#nav-primary li ul:first');

            // Calling the XplusOne replaceSection method to handle
            // grabbing the XplusOne content for the credit card primary nav
            replaceSection(sectionId);

            // Starting to listen for the primary nav drop down replacement so that
            // we can fix CSS and IE6 bugs/issues as soon as the replacement happens
            var primaryNavIntervalId = setInterval(function() {
                if (jQuery(cardPrimaryNavMenu).parent().css('visibility') != 'hidden') {

                    clearInterval(primaryNavIntervalId);

                    // Fixes the conflict with the primary nav menu and the form select dropdown in IE6
                    jQuery('#nav-primary li ul:first').css({width:'17.5833em'}).bgIframe({opacity:false}).find('iframe.bgiframe').each(function() {
                        var a = this.contentWindow.document;
                        var b = setInterval(function() {
                            if (typeof a != 'undefined') {
                                a.body.style.backgroundColor = '#1b4876';
                                clearInterval(b)
                            }
                        }, 100);
                    });

                }
            }, 100);
        },

        /**
         * @description Pops a new window for the NDB calculators on the homepage.
         * @public
         * @method openCalc
         * @param url String
         * @param name String
         * @returns void
         */
        openCalc: function(url, name) {
            popupWin = window.open(url, name, 'scrollbars,dependent,width=510,height=300,left=500,top=325');
        },

        /**
         * @description Calculates the totals for the rewards checking promo callout
         *      on the homepage.
         * @public
         * @method calcAmt
         * @returns void
         */
        calcAmt: function() {
            var useDebitCard   = jQuery('#use-debit-card').val();
            var payBillsOnline = jQuery('#pay-bills-online').val();
            var writeChecks    = jQuery('#write-checks').val();

            if (!_isInteger(useDebitCard)) {
                useDebitCard = 0;
            }

            if (!_isInteger(payBillsOnline)) {
                payBillsOnline = 0;
            }

            if (!_isInteger(writeChecks)) {
                writeChecks = 0;
            }

            var useDebitCardTotal = useDebitCard * 10 * 52;

            var payBillsOnlineTotal = payBillsOnline * 10 * 12;

            if (payBillsOnlineTotal > 1200) {
                payBillsOnlineTotal = 1200;
            }

            var writeChecksTotal = writeChecks * 5 * 12;

            if (writeChecksTotal > 600) {
                writeChecksTotal = 600;
            };

            var bonusMiles = 6000;
            var yearTotal  = useDebitCardTotal + payBillsOnlineTotal + writeChecksTotal + bonusMiles;

            jQuery('#use-debit-card-total').text(_numberFormat(useDebitCardTotal, 0, '.', ','));
            jQuery('#pay-bills-online-total').text(_numberFormat(payBillsOnlineTotal, 0, '.', ','));
            jQuery('#write-checks-total').text(_numberFormat(writeChecksTotal, 0, '.', ','));
            jQuery('#year-total').text(_numberFormat(yearTotal, 0, '.', ','));
        },

        /**
         * @description Given a CG5 variable, this method will ping VS (Visual Science) with that value
         * @public
         * @method trackCgVars
         * @param cg5Var String
         * @returns void
         */
        trackCgVars: function(cg5Var) {
            var _cg1 = unescape(cg1);
            var _cg2 = unescape(cg2);
            var _cg3 = unescape(cg3);
            var _cg4 = unescape(cg4);
            var _cg5 = unescape(cg5Var);

            var data = {
                pn : _cg1 + '_' + _cg2 + '_' + _cg3 + '_' + _cg4 + '_' + _cg5,
                cg1: _cg1,
                cg2: _cg2,
                cg3: _cg3,
                cg4: _cg4,
                cg5: _cg5
            };

            jQuery.vstrack(data);
        }
    }
}

// Create a new Homepage instance
var homepage = new Cof.Homepage();
