/* Minification failed. Returning unminified contents.
(3676,32-37): run-time error JS1137: 'catch' is a new reserved word and should not be used as an identifier: catch
(3780,34-39): run-time error JS1137: 'catch' is a new reserved word and should not be used as an identifier: catch
 */


var openModalFunction = function (title, content, isStatic, showLoading, showOkCancel) {
    window.hideSpinner();
    var myModal = $('.modal[id="myModal"]:last');

    // we need to remove the widget first if it exists to alter the configuration 'backdrop'
    if (myModal && $(myModal).data('bs.modal')) {
        $(myModal).data('bs.modal', null);
    }

    $("#myModalLabel", myModal).html('');
    $("#myModalContent", myModal).html('');

    $("#myModalLabel", myModal).html($.trim(title.replace('*', '')));
    $("#myModalContent", myModal).html(content);

    // static hides close and stops user from clicking outside the dialog area
    if (isStatic || showOkCancel) {
        myModal.modal({ backdrop: "static" }).on('shown.bs.modal', function (e) {
            $("#modal-close", myModal).hide();
            if (isMobile()) {
                $("html").css('overflow', 'hidden');
            }
        }).on('hidden.bs.modal', function (e) {
            if (isMobile()) {
                $("html").css('overflow', 'auto');
            }
        });
    } else {
        myModal.modal().on('shown.bs.modal', function (e) {
            $("#modal-close", myModal).show();
            if (isMobile()) {
                $("html").css('overflow', 'hidden');
            }
        }).on('hidden.bs.modal', function (e) {
            if (isMobile()) {
                $("html").css('overflow', 'auto');
            }
        });
    }

    if (showLoading) {
        $("#modal-loading", myModal).show();
    } else {
        $("#modal-loading", myModal).hide();
    }

    if (showOkCancel) {
        $('#okcancel', myModal).show();
        $('#modal-close', myModal).hide();
    } else {
        $('#okcancel', myModal).hide();
        $('#modal-close', myModal).show();
    }
};

$("document").ready(function () {

    $("span.tooltip-image").attr('tabindex', 0);
    $("#main-container").on("keypress", "span.tooltip-image", function (e) {
        if (e.which == 13) {
            $(this).click();
        }
    });

    $(".close-this-page").click(function () { window.close(); });

    $(document).on('click', ".btn-show-map", function (e) {
        var container = $('#MapPopupDiv');
        container.modal();
        if ($("#map", container).height() == 0) {
            window.showSpinner($(".mapWrapper", container), 'bar', false);
        }

        var policy = PrismApi.policy.fn.toJSONForContext("getQuickQuote");
        PrismApi.Utils.ajaxCall(PrismApi.Client.serviceUrls.QuickQuote, policy, "POST")
            .done(function (response) {

                if (response.PricingRegions) {
                    PrismApi.policy.PricingRegions(ko.mapping.fromJS(response.PricingRegions)())
                }

                $$.fn.getDestinations().done(function () {
                    showMap();
                    window.hideSpinner();
                });
            })
            .fail($$.Client.displayError);
    });


    /*=============
    MODAL
    ==============*/
    openModal = openModalFunction;

    window.showSpinner = function (control, type, appendAfter) {
        if (Modernizr.touch) {
            $('#myModalSpinner').modal({ backdrop: "static" });
        } else {
            if (control.siblings('.spinner').length == 0 && control.find('.inplace-spinner').length == 0) {
                var elem = type == 'bar' ? spinnerBar : spinner;
                if (appendAfter) {
                    control.after(elem);
                } else {
                    control.before(elem);
                }
            }
            control.find(".inplace-spinner").css('visibility', 'visible');
        }
    };

    window.hideSpinner = function (control) {
        if (window.Modernizr && window.Modernizr.touch) {
            $('#myModalSpinner').modal('hide');
        } else {
            $(".appended-spinner.spinner").remove();
            $(".appended-spinner.spinner-bar").remove();
            $(".spinner").css('display', 'none');
            $(".spinner-bar").css('display', 'none');
            $(".inplace-spinner").css('visibility', 'hidden');
        }
    };

    window.openPurchaseModal = function () {
        openModal('Purchase request', 'Please wait… We are processing your purchase.<br/>', true, true);
    };

    window.openErrorModal = function (title, content) {
        openModal('<span style="color:#f54359">' + title + '</span>', content, false, false);
    };

    window.openPeModal = function (peSummary) {
        $('#peSummaryModal').modal();
    };

    window.openMessageBoxModal = function (title, content, acceptText, acceptAction, cancelText, cancelAction) {
        $("#modal-ok").unbind("click");
        $("#modal-cancel").unbind("click");
        if (acceptText) {
            $('#modal-ok').text(acceptText);
        } else {
            $('#modal-ok').text('Ok');
        }
        if (acceptAction) {
            $('#modal-ok').click(acceptAction);
        }
        if (cancelText) {
            $('#modal-cancel').text(cancelText);
        } else {
            $('#modal-cancel').text('Cancel');
        }
        if (cancelAction) {
            $('#modal-cancel').click(cancelAction);
        }
        openModal(title, content, false, false, true);
    };

    window.hideModal = function () {
        $('#myModal').modal("hide");
    };

});

function HideQuickQuotePlans(viewModel) {
    if (viewModel == null) viewModel = $$.policy;
    //$('#quickQuotePlans').hide();
    $$.policy.MetaData.quoteIsInvalid(true);
    viewModel.fn.updateQuickQuoteAssessment();
    return true;
}

function RemoveValidationElement(e) {
    var elem = e.currentTarget;
    $(elem).removeClass('validationElement');
}

var nextCounter = 0;
function GetNextCounter(reset) {
    if (reset) nextCounter = 0;
    return nextCounter++;
}

function fixBenefitTable() {
    if ($(this).width() >= 980) {
        $(".space-filler").remove();
    } else {
        if ($(".space-filler").length == 0) {
            $(".product-benefit-header").after("<div class='space-filler'></div>");
        }
    }
}

function fixQuestionItems() {
    // question-template needs different styles for quick quote/home and benefits questions
    $('.quickQuoteWidget .question-header').addClass('col-sm-5');
    $('.quickQuoteWidget .question-header span:last').hide();
    $('.quickQuoteWidget .question-body').addClass('col-sm-6');
    $('.benefit-row .question-header').addClass('col-sm-6 header');
    $('.benefit-row .question-body').addClass('col-sm-5 selectBox');
    $('.benefit-row .question-body select').addClass('pull-right');
    $('.benefit-row .question-header span:first').hide();
}

function RecalculateQuoteImmediate(doPageValidation, displayError, performRescore) {
    console.log('trigger recalculate quote immediate...');
    $$.policy.MetaData.isRecalculating(true);
    $$.fn.getFullQuote(false, doPageValidation, performRescore)
        .fail($$.Client.displayError)
        .always(function () {
            $$.policy.MetaData.isRecalculating(false);
        }
    );
}


//This function will throttle how often the getFullQuote is called so that we don't hit the server too hard.
function RecalculateQuote(doPageValidation, displayError, performRescore) {

    if (doPageValidation === undefined)
        doPageValidation = true;

    if (performRescore === undefined)
        performRescore = false;


    // prevent recalculate if the policy is invalid
    if ($$.policy.errors.visibleNotValidMessages().length > 0 && !doPageValidation) {
        var tripPurpose = ko.utils.arrayFirst($$.policy.Questions(), function (question) {
            return question.BriefCode() == 'TRIP'
        })
        tripPurpose.Answer.isModified(true);
        return;
    }    

    // trigger recalculate timer with options    
    $$.policy.MetaData.RecalculateTimer({
        "doPageValidation": doPageValidation, "displayError": displayError, "performRescore": performRescore
    });
}

function healixcallback() {
    // clear back/reload prevention
    window.onbeforeunload = null;
    
    if ($$.policy.PeOptions.FatalFlag() === false) {
        var policy = PrismApi.policy.fn.toJSONForContext("getFullQuote");
        $$.policy.fn.updateHolderScreening(policy, $$.Client.serviceUrls.HealixAssessResult.format('b2c')).done(function () {
            window.location.href = $$.baseUrl + "PreExisting/Assessment";
        });
    } else {
        window.location.href = $$.baseUrl + "PreExisting/Assessment";
    }
}

// Popover settings
var popoverSettings = {
    'html': true,
    'animation': false,
    'placement': 'bottom',
    'trigger': ($('html').hasClass('no-touch') && !navigator.userAgent.match(/(IEMobile)/i)) ? 'hover' : 'click',
    'container': '',
    template: $("#popoverTemplate").html()
};

var bootstrapSetup = function () {
    // remove other popovers on another one showing
    $(document).on('show.bs.popover', function (e) {
        $('.popover-holder').popover('hide');
    });
    // bootstrap wiring
    // Get rid of the left to make popover fit correctly
    $(document).on('shown.bs.popover', function (e) {
        // $('.popover').css('left', 0);

        if (popoverSettings.trigger == 'hover') {
            $('.popover .close').hide();
        } else {
            $('.popover .close').show();
        }

        $('.popover .close').click(function (event) {
            $('.popover-holder').popover('hide');
            $('.striped').popover('hide');
            return false; // stop propogation
        });
    });

    // Work around for reported bootstrap popover bug
    $(document).on('hidden.bs.popover', function () {
        $('.popover').removeClass('in').hide().detach();
    });
};

var fixTravellerTitle = function (item) {
    var itemTG = lookupTravellerTitleGroup(item)
    if (itemTG) {
        item.TitleGroup(itemTG.titleGroup);
    }

};

var lookupTravellerTitleGroup = function (item) {
    var titleAndGroup = null;
    // translate title / title group
    if (item.MetaData.TitleGroups && item.MetaData.TitleGroups()) {
        $.each(item.MetaData.TitleGroups(), function (index, itemTG) {
            var result = ko.utils.arrayFirst(itemTG.Titles, function (dataTitle) {
                return dataTitle.BriefCode == item.Title();
            });
            if (result) {
                titleAndGroup = { titleGroup: itemTG, title: result };
            }
        });
    }
    return titleAndGroup;
};

var getTravellerNameComputed = function (item, type, index) {
    return ko.computed(function () {
        var titleReplace = lookupTravellerTitleGroup(item);
        var titleOverride = { "DR": "Dr", "MSTR": "Mstr", "BLANK": "" };
        var title = titleReplace && titleReplace.title ? titleReplace.title.Description : (item.Title() ? item.Title().toLowerCase() : item.Title());
        if (title && titleReplace) {
            // check Display translation
            var override = titleOverride[titleReplace.title.BriefCode];
            if (override !== null && override !== undefined) {
                title = override;
            }
        }
        var nameFormatted = titleReplace ? title + $.camelCase(' -' + item.FirstName() + ' -' + item.LastName()) : $.camelCase('-' + title + ' -' + item.FirstName() + ' -' + item.LastName());
        return (title !== null && title !== undefined ? item.FirstName() ? item.LastName() ? nameFormatted : type + ' ' + (index + 1) : type + ' ' + (index + 1) : type + ' ' + (index + 1));
    }).extend({ throttle: $$.Client.Util.ThrottleTime });
};

/**
 * Project: Bootstrap Collapse Clickchange
 * Author: Ben Freke
 *
 * Dependencies: Bootstrap's Collapse plugin, jQuery
 *
 * A simple plugin to enable Bootstrap collapses to provide additional UX cues.
 *
 * License: GPL v2
 *
 * Version: 1.0.1
 */
(function ($) {

    var ClickChange = function () { };

    ClickChange.defaults = {
        'when': 'before',
        'targetclass': '',
        'parentclass': '',
        'iconchange': false,
        'iconprefix': 'glyphicon',
        'iconprefixadd': true,
        'iconclass': 'chevron-up chevron-down'
    };

    /**
     * Set up the functions to fire on the bootstrap events
     * @param options The options passed in
     * @param controller Optional parent which controls a groups options
     * @returns object For chaining
     */
    $.fn.bootstrapCollapseChange = function (options, controller) {
        // In a grouping, I've passed in the controller to get data from
        var settings = $.extend(
            {}
            , ClickChange.defaults
            , $(this).data()
            , (typeof controller == 'object' && controller) ? controller.data() : {}
            , typeof options == 'object' && options
        );

        // Now amend the icon class
        if (settings.iconclass.length && settings.iconprefixadd) {
            tmpArr = settings.iconclass.split(' ');
            settings.iconclass = '';
            for (elementIndex in tmpArr) {
                settings.iconclass += ' ' + settings.iconprefix + '-' + tmpArr[elementIndex];
            }
        }

        // When do we fire the event?
        var eventStart = (settings.when === 'after') ? 'shown' : 'show';
        var eventEnd = (settings.when === 'after') ? 'hidden' : 'hide';

        // Because it could be a group, we use each to iterate over the jQuery object
        $(this).each(function (index, element) {
            var clickElement = $(element);
            var targetID = clickElement.attr('id');
            // Get my target. This handles buttons and a
            var clickTarget = clickElement.attr('data-target') || clickElement.attr('href');

            // turn off previous events if we're re-initialising
            if (clickElement.data('clickchange')) {
                $(document).off('show.bs.collapse hide.bs.collapse', clickTarget);
                $(document).off('shown.bs.collapse hidden.bs.collapse', clickTarget);
            }
            clickElement.data('clickchange', 'yes');

            // As we're toggling, the same changes happen for both events
            $(document).on(eventStart + '.bs.collapse ' + eventEnd + '.bs.collapse', clickTarget, function (event) {
                var clickOrigin = clickElement;
                if (targetID) {
                    clickOrigin = $("#" + targetID);
                }

                // Stop the event bubbling up the chain to the parent collapse
                event.stopPropagation();

                // Toggle clickable element class?
                if (settings.parentclass) {
                    clickOrigin.toggleClass(settings.parentclass);
                }

                // Toggle the target class?
                if (settings.targetclass) {
                    $(event.target).toggleClass(settings.targetclass);
                }

                // Do I have icons to change?
                if (settings.iconchange && settings.iconclass.length) {
                    clickOrigin.find('.' + settings.iconprefix).toggleClass(settings.iconclass);
                }
            });
        });
        return this;
    };
}(jQuery));


(function ($, undefined) {
    'use strict';
    $$.Client = $$.Client || {};
    $$.Client.Util = $$.Client.Util || {};
    $$.Client.Util.PurchaseStepNames = { Home: "Home", QuickQuote: "QuickQuote", Options: "Options", Travellers: "Travellers", Payment: "Payment", Confirmation: "Confirmation" };
    $$.Client.Util.PurchaseSteps = { Home: '', QuickQuote: 'QuickQuote', Options: 'Options', Travellers: 'Travellers', Payment: 'Payment', Confirmation: 'Confirmation' };
    $$.Client.Util.IsCurrentPurchaseStep = function (step) {
        return $$.Client.Util.GetCurrentPurchaseStep() === step;
    };
    $$.Client.Util.GetCurrentPurchaseStep = function () {
        var lastSlashIndex = window.location.href.lastIndexOf('/');
        var stepFromUrl = window.location.href.substr(lastSlashIndex + 1);
        stepFromUrl = /\w+/.exec(stepFromUrl)[0];
        return stepFromUrl;
    };
    $$.Client.Util.sessionTimeoutHandler = function () {
        console.log("session timed out");
        $$.Client.Util.navigateToPurchaseStep('Home', true, undefined, true);
    };
    $$.Client.Util.resetSessionData = function () {

        _session.policy = undefined;

        if (typeof (Storage) !== "undefined")
            sessionStorage.clear();
        if (window.localStorage && window.localStorage.clear)
            window.localStorage.clear();

        console.log("the policy in session has been reset.");
    };

    // extend ajaxCall in prism api to handle when session has expired, needs to be setup before any ajax calls are made on the page
    $$.Client.Util.setupSessionExpiryHandler = function () {
        var existingAjaxCallFunction = PrismApi.Utils.ajaxCall;
        PrismApi.Utils.ajaxCall = function (url, data, httpMethod) {
            var prom = existingAjaxCallFunction(url, data, httpMethod);
            prom.fail(function (jqXHR, textStatus, errorThrown) {
                if (jqXHR.status === 410) {
                    $$.Client.Util.resetSessionData();
                    $$.Client.Util.sessionTimeoutHandler();
                }
            });
            return prom;
        }
    }
    $$.Client.Util.navigateToPurchaseStep = function (step, resetSession, queryString, overrideNavPrevent) {
        if (overrideNavPrevent === true) {
            // clear back/reload prevention
            window.onbeforeunload = null;
        }
        var url = ($$.baseUrl ? $$.baseUrl : '') + ($$.Client.Util.PurchaseSteps ? $$.Client.Util.PurchaseSteps[step] : '');
        var qs = (resetSession != undefined ? (resetSession === true ? '' : '?session=true') : '');
        if (queryString !== undefined) {
            qs += (qs.length == 0 ? '?' : '&') + queryString;
        }

        if ($$.policy.IsRetrieveQuote !== undefined && $$.policy.IsRetrieveQuote() && $$.Client.Util.GetCurrentPurchaseStep() == "Payment" && (step == "Travellers" || step == "Options")) {
            $$.fn.getFullQuote(false, false)
                .done(function() {
                    window.location.href = url +qs;
                });
        }
        else
        {
            window.location.href = url + qs;
        }
    };

    $$.Client.Util.setDefaultQuestions = function () {
        // Set default question answers to viewmodel
        if ($$.Client.QuestionDefaults && $$.Client.QuestionDefaults.length > 0) {
            $.each($$.Client.QuestionDefaults, function (index, questionItem) {
                var questionToDefault = ko.utils.arrayFirst($$.policy.Questions(), function (item) {
                    return item.BriefCode() === questionItem.QuestionBriefCode;
                });
                if (questionToDefault && questionToDefault.Answers()) {
                    var answerToDefault = ko.utils.arrayFirst(questionToDefault.Answers(), function (item) { return item.BriefCode() === questionItem.DefaultAnswerBriefCode.toUpperCase(); });

                    if (answerToDefault && !questionToDefault.Answer()) {
                        questionToDefault.Answer(answerToDefault);
                    }
                }

            });
        }
    };

    // blur handler to reset value
    $$.Client.Util.clearBlurHandler = function (data, event) {
        // check if there's a placeholder match if so reject it
        var placeholder = $(event.target).attr("placeholder");
        var currentValue = data();
        if (currentValue === "" || (placeholder && currentValue === placeholder) || currentValue === "OPTIONAL") {
            data(null);
        }
        return true;
    };

    $$.Client.Util.detectBootstrapViewSize = function () {
        var envs = ["xs", "sm", "md", "lg"];
        var envValues = ["xs", "sm", "md", "lg"];

        var el = $('<div>');
        el.appendTo($('body'));

        for (var i = envValues.length - 1; i >= 0; i--) {
            var envVal = envValues[i];

            el.addClass('hidden-' + envVal);
            if (el.is(':hidden')) {
                el.remove();
                return envs[i]
            }
        };
    };

    $$.Client.Util.Modal = $$.Client.Util.Modal || {};
    // Show the modal prompting user to agree to privacy used on home and select plan screens
    $$.Client.Util.Modal.PrivacyModal = function (policy) {
        var promPrivacy = $.Deferred();
        if (policy.MetaData.privacyAgree() !== true) {
            openMessageBoxModal('Agreement Declaration', $("#modal-privacydisclosure-agree").html(),
                'Accept', function () {
                    var modal = $('#myModal');
                    $("#okcancel", modal).hide();
                    policy.MetaData.privacyAgree(true);
                    $('#myModal').on('hidden.bs.modal', function () {
                        $(".modal-footer > div").attr('style', '');
                        $('#myModal').off('hidden.bs.modal');
                        promPrivacy.resolve();
                    });
                },
                'Decline', function () {
                    policy.MetaData.privacyAgree(false);
                    $('#myModal').on('hidden.bs.modal', function () {
                        $(".modal-footer > div").attr('style', '');
                        $('#myModal').off('hidden.bs.modal');
                        promPrivacy.reject();
                    });
                }
            );
        } else {
            promPrivacy.resolve();
        }
        return promPrivacy;
    };

})(jQuery);

// Sidebar quotesummary scroller
(function ($, undefined) {
    'use strict';
    var currentQuoteOffset, currentQuoteDiv;
    var isIE8 = false;
    $$.Client = $$.Client || {};
    $$.Client.Util = $$.Client.Util || {};
    $$.Client.Util.initialiseQuoteSummaryScroller = function () {
        isIE8 = $(".ie8").length > 0;
        currentQuoteDiv = $('#divScroller');
        if (currentQuoteDiv.length > 0) {
            currentQuoteOffset = currentQuoteDiv.offset().top - (isIE8 ? 180 : 160);
            scrollCurrentQuote(false, false);
            var positionQuoteSummary = function (force) {
                if ($(document).width() > 768) {
                    scrollCurrentQuote(true, force);
                }
            };
            if ($$.Client.Util.PostionQuoteSummary) $$.Client.Util.PostionQuoteSummary = positionQuoteSummary;
            $(window).scroll(function () { positionQuoteSummary(false); });
            positionQuoteSummary(true);
        } else if ($('.top-widget-wrapper').length > 0) {

            //Calculate Height of elements on top of top Widget

            var navbarHeight = $('.navbar').outerHeight(true);
            var breadcrumbHeight = $('.nav-progress').outerHeight(true);

            var distance = navbarHeight + breadcrumbHeight;

            $(window).scroll(function () {
                var scrollTop = $(window).scrollTop();

                if (scrollTop < distance) {
                    $('.purchase-path').css('margin-top', '');
                    $('.top-widget-wrapper').css('position', 'relative');
                    $('.top-widget-wrapper').css('top', '');
                }
                else {
                    $('.purchase-path').css('margin-top', $('.top-widget-wrapper').height() + 15 + 'px');
                    $('.top-widget-wrapper').css('position', 'fixed');
                    $('.top-widget-wrapper').css('top', '0');
                    $('.top-widget-wrapper').css('width', $('.purchase-path').width());
                }
            });
        }
    };

    function currentQuoteEndRequest(sender, args) {
        currentQuoteDiv = $('#divScroller');
        scrollCurrentQuote(false);

    }

    var scrollCurrentQuoteTimeout;
    function scrollCurrentQuote(animate, force) {
        if (scrollCurrentQuoteTimeout != null) {
            clearTimeout(scrollCurrentQuoteTimeout);
        }
        scrollCurrentQuoteTimeout = setTimeout(function () {
            scrollCurrentQuoteTimeout = null;
            if (force === true) {
                currentQuoteDiv.css({ top: 0 + 'px' });
            }
            if ($('#divScroller').height() + 42 >= $('#main-container').height()) {
                currentQuoteDiv.css({ top: 0 + 'px' });
                return;
            }
            currentQuoteDiv.stop(true, false);
            var scrollTop = $(window).scrollTop();
            var topBarOffset = $('#main-container').offset().top + $(".nav-progress").height();
            var offset = scrollTop > (topBarOffset + currentQuoteOffset) ? scrollTop - (topBarOffset + currentQuoteOffset) : 0;

            var atBottom = (offset + $('#divScroller').height() + 42) >= $('#main-container').height();
            if (atBottom && force !== true) {
                offset = $('#main-container').height() - $('#divScroller').height() - 42;
            }

            if (animate && scrollTop > 0) {
                currentQuoteDiv.animate({ top: offset + 'px' }, 'slow');
            }
            else {
                currentQuoteDiv.css('top', offset + 'px');
            }
        }, 100);
    }

})(jQuery);;
/*=============
PRISM API SETUP
==============*/
$("document").ready(function() {

    $$.Client.spinner = ".api-spinner";
    $$.Client.Util.ThrottleTime = 2000;

    if (window.todayUtc) $$.Client.todayDateString = window.todayUtc;

    //ko validation settings
    $$.Validation.koValidationConfiguration = {
        decorateElement: true,
        insertMessages: false,
        registerExtenders: true
    };

    if (!isLocalStorageNameSupported()) {
        openErrorModal("Private Browsing Detected",
            "Private browsing has been enabled. This site cannot be used while private browsing has been enabled. <br/>Please disable private browsing in your browser settings and try again.");
    }

    if (!isCookieSupported()) {
        openErrorModal("Cookies are Disabled",
            "This site uses cookies and cannot be used with browsers that have disabled thier use. <br/>Please enable cookies in your browser settings and try again.");
    }

    // when a FPE error code is returned, check the list of handled errors and also look for the label definition of this
    $$.Client.handleMappedFPEError = function(error) {
        var item = ko.utils.arrayFilter($$.Client.FPEErrorMappings,
            function(item) {
            return item.Code === error.MessageCode;
        });
        if (item.length == 1) {
            var targetLabel = "";
            var foundElem = null;
            // find the input
            if (error.ExceptionMessage && error.ExceptionMessage.indexOf(":") > 0) {
                var valueOfError = error.ExceptionMessage.substring(error.ExceptionMessage.indexOf(":") + 2);
                $("[data-fpe-code='" + item[0].Code + "']").each(function(index, item) {
                    foundElem = $(item);
                    if (foundElem.val() == valueOfError) {
                        foundElem.addClass("validationNotValid").addClass("validationElement");
                        if (foundElem.attr("data-fpe-label")) {
                            targetLabel = foundElem.attr("data-fpe-label");
                        }
                    }
                });
            }
            var errorFromServer = item[0].Message.format(targetLabel);
            if (foundElem) {
                foundElem.attr("title", errorFromServer);
                foundElem.attr("name", targetLabel);
            }
            return errorFromServer;
        } else {
            return error.ExceptionMessage;
        }
    }

    //ERROR HANDLING
    $$.Client.displayError = function(apiError) {
        if (apiError !== undefined) {
            if (apiError.StatusCode == 0) { //Call aborted
                return;
            }
            if (apiError.StatusCode == 400 && apiError.ModelState != null) { //Bad request
                var message = JSON.stringify(apiError.ModelState);
                dataLayer.push({
                    'event': 'prismError',
                    'eventCategory': 'PRISM API Data Error',
                    'eventAction': message
                });
                openErrorModal("Invalid data", message);
                return;
            }
            if (apiError.StatusCode == 422) { //Processing Error
                var msgs = "<ul>";
                if (apiError.Messages) {
                    ko.utils.arrayForEach(apiError.Messages,
                        function(error) {
                        msgs += "<li>{0}</li>".format(error);
                    });
                    msgs += "</ul>";
                } else {
                    msgs = '';
                }

                var errorMessage = apiError.ExceptionMessage;
                if (errorMessage.indexOf("Sorry, policy cannot be purchased") > -1) {
                    openModal('Your travel insurance enquiry',
                        "<p>Thank you for using our online quote facility. Unfortunately we are unable to offer you insurance online. If we are unable to offer you the cover you seek, it will be because the particular product offered is not designed to cover a particular risk or risks including, but not limited to, some geographical regions, some pre-existing medical conditions or some ages. In such a case, if you would like to discuss your options please <a href='" + $$.baseUrl + "ContactUs'>contact us</a>.</p>",
                        false,
                        false);
                    return;
                }

                errorMessage = $$.Client.handleMappedFPEError(apiError);

                dataLayer.push({
                    'event': 'prismError',
                    'eventCategory': 'PRISM API Processing Error',
                    'eventAction': errorMessage
                });

                openErrorModal("Processing Error", errorMessage + msgs);
                return;
            }
            if (apiError.StatusCode == 500 && apiError.StackTrace != null) { //Server error		    
                var msgs = "<ul>";
                if (apiError.Messages) {
                    ko.utils.arrayForEach(apiError.Messages,
                        function(error) {
                        msgs += "<li>{0}</li>".format(error);
                    });
                    msgs += "</ul>";
                } else {
                    msgs = '<br>';
                }

                dataLayer.push({
                    'event': 'prismError',
                    'eventCategory': 'PRISM API Server Error',
                    'eventAction': apiError.ExceptionMessage,
                    'eventLabel': apiError.StackTrace
                });

                openErrorModal("Error",
                    apiError.ExceptionMessage +
                    msgs +
                    "==============<br>" +
                    apiError.StackTrace);
                return;
            }
            if (apiError.StatusCode == null && apiError.ExceptionMessage == null) { //JavaScript error.

                if (ko.utils.arrayFirst($$.policy.MetaData.AllTravellers(),
                        function(traveller) { return traveller.MetaData.age() > $$.policy.MetaData.MaxAdultAge(); }) !=
                    null) {
                    openModal('Your travel insurance enquiry', $('#modal-enquiry').html(), false, false);
                    return;
                }

                var msgs = "<ul>";
                ko.utils.arrayForEach(apiError.Messages,
                    function(error) {
                    dataLayer.push({
                        'event': 'prismError',
                        'eventCategory': 'PRISM API Validation Error',
                        'eventAction': error.Message !== undefined ? error.Message : error,
                    });

                    var msg;
                    if (error.Message) {
                        msg = "<li>{0}</li>\n".format(error.Message);
                    } else {
                        msg = "<li>{0}</li>\n".format(error);
                    }
                    //Only add an error message once
                    if (msg && msgs.indexOf(msg) < 0) msgs += msg;
                });
                msgs += "</ul>";

                openErrorModal("Validation Error",
                    'The following items need to be checked before continuing:<br/>' + msgs);
                return;
            }
        }

        dataLayer.push({
            'event': 'prismError',
            'eventCategory': 'PRISM API Unexpected Error',
            'eventAction': "An error has occurred.",
        });

        PrismApi.Utils.logError(apiError);

        //catch-all
        openErrorModal("Error",
			"<p>An error has occurred. Please try again.</p><p>If this error persists, please contact us for assistance. Our details can be located on the <a href='" + $$.baseUrl + "ContactUs'>Contact Us Page</a>.</p>");
    };

    $$.Client.extendClientSettings = function(viewModel) {
        $$.Client.QuickQuoteSettings = $$.Client.QuickQuoteSettings || {};
        $$.Client.QuickQuoteSettings = $.extend({},
            $$.Client.QuickQuoteSettings,
            { UseDobInput: false, MinAdults: 1, MinDependants: 1 });
        $$.Client.QuestionDefaults = $.extend([],
            $$.Client.QuestionDefaults,
            PartnerConfiguration.QuestionConfigurations);
        $$.Client.QuickQuoteSettings = $$.Client.FPEErrorMappings || {};
        $$.Client.FPEErrorMappings = $.extend([],
            $$.Client.FPEErrorMappings,
            [
			{ Code: "FPPF_ADJ_PF_DUMMY", Message: PrismApi.Validation.messages.adjustments.invalidPromoCode },
                {
                    Code: "FPPF_CALC_ADJ_VALUE",
                    Message: PrismApi.Validation.messages.adjustments.invalidMemberAdjustment
                }
        ]);
    }

    //site specific view model extension
    $$.Client.extendViewModel = function(viewModel) {

        //Run the shared bit first
        sharedExtendViewModel(viewModel);

        $$.Client.extendClientSettings(viewModel);
        //Setup site url

        $$.fn.CopyQuoteDataToQuote = function(from, to) {
            for (var i = 0; i < from.MetaData.AdultAges().length; i++) {
                var traveller = from.MetaData.AdultAges()[i];
                var existingTraveller = to.MetaData.AdultAges()[i];
                if (!existingTraveller) {
                    existingTraveller = new PrismApi.Data.Customer(null, 'adult');
                    to.MetaData.AdultAges.push(existingTraveller);
                }
                existingTraveller.MetaData.age(traveller.MetaData.age());
            }
            for (var i = 0; i < from.MetaData.DependantAges().length; i++) {
                var traveller = from.MetaData.DependantAges()[i];
                var existingTraveller = to.MetaData.DependantAges()[i];
                if (!existingTraveller) {
                    existingTraveller = new PrismApi.Data.Customer(null, 'dependant');
                    to.MetaData.DependantAges.push(existingTraveller);
                }
                existingTraveller.MetaData.age(traveller.MetaData.age());
            }
            to.StartDate(from.StartDate());
            to.EndDate(from.EndDate());
            to.CoverStartDate(undefined);
            to.CoverEndDate(undefined);
            to.MetaData.Countries(from.MetaData.Countries());
            ko.utils.arrayForEach(from.Adjustments(),
                function(adjustment) {
                    var toAdjustment = ko.utils.arrayFirst(to.Adjustments(),
                        function(toAdjust) {
                    return ko.unwrap(toAdjust.BriefCode) == ko.unwrap(adjustment.BriefCode);
                })
                if (toAdjustment) {
                    toAdjustment.Value(adjustment.Value());
                    toAdjustment.Question.Answer(adjustment.Question.Answer());
                }
            });
        };

        viewModel.MetaData.AdultAges = ko.observableArray();
        viewModel.MetaData.DependantAges = ko.observableArray();

        viewModel.MetaData.hasQuestionsForOptionPage = ko.computed(function() {
            var questions = _session.fullQuoteOptions || $$.fullQuoteOptions;
            if (questions == null)
                return false;
            return !ko.utils.arrayFirst($$.Client.QuestionDefaults || [],
                    function(item) { return item.QuestionBriefCode === 'TRIP'; }) ||
                !(ko.utils.arrayFilter(questions.Questions, function(item) { return item.BriefCode == 'TRIP'; })
                    .length ==
                    1 &&
                    questions.Questions.length == 1);
        });

        $$.baseUrl = PartnerConfiguration.SiteUrl;

        viewModel.StartDate.subscribe(function(newValue) {
            //If we are in multi-trip, recalculate the end date using the api.
            if ($("#multiTripTab").parent().hasClass('active') || viewModel.MetaData.multiTripChecked()) {
                $$.fn.calculateMultiTripEndDate();
            } else {
                var newDate = Date.create(newValue);
                // set end date to + 1 day if only it is not set
                if (viewModel.EndDate() == undefined) {
                viewModel.EndDate(newDate.advance({ days: 1 }).toISOString());
            }

            }
        });

        //Set start / end date validation
        viewModel.StartDate.formattedDate.rules(ko.utils.arrayFilter(viewModel.StartDate.formattedDate.rules(),
            function(data) {
            return data.rule !== "required";
        }));
        viewModel.StartDate.formattedDate.extend({
            required: {
                params: true,
                message: PrismApi.Validation.messages.requiredStartDate
            }
        });
        viewModel.EndDate.formattedDate.rules(ko.utils.arrayFilter(viewModel.EndDate.formattedDate.rules(),
            function(data) {
            return data.rule !== "required";
        }));
        viewModel.EndDate.formattedDate.extend({
            required: {
                params: true,
                message: PrismApi.Validation.messages.requiredEndDate
            }
        });
        viewModel.EndDate.formattedDate.rules(ko.utils.arrayFilter(viewModel.EndDate.formattedDate.rules(),
            function(data) {
            return data.rule !== "moreThan";
        }));
        viewModel.EndDate.formattedDate.extend({
            moreThan: {
                params: function() {
                    return viewModel.StartDate() == null ? Date.create('today') : Date.create(viewModel.StartDate());
                },
                message: PrismApi.Validation.messages.startDateIsAfterEndDate
            }
        });

        if (_session.quickQuote && _session.quickQuote.BulkPremiums) {
            PrismApi.bulkQuickQuote = _session.quickQuote;
            PrismApi.policy.fn.applyBulkPremiumsToViewModel();
        }

        viewModel.PartnerCode(PartnerConfiguration.PartnerCode);

        viewModel.MetaData.RecalculateTimer = ko.observable();

        viewModel.MetaData.RecalculateTimer.subscribe(function(newValue) {
            $$.policy.MetaData.isRecalculating(newValue != null);
        });

        // throttle getFullQuote to prevent multiple ajax calls
        ko.computed(function() {
            var options = viewModel.MetaData.RecalculateTimer();
            if (options !== undefined) {
                $$.policy.MetaData.isRecalculating(true);
                // needs to set timeout on ajax call to not block IE8 thread that shows 
                if (viewModel.MetaData.IsIE8()) {
                    setTimeout(function() {
                        $$.fn.getFullQuote(false, options.doPageValidation, options.performRescore)
                                .fail(typeof (options.displayError) == "function"
                                    ? options.displayError
                                    : $$.Client.displayError)
                                .always(function() {
						    $$.policy.MetaData.isRecalculating(false);
                                    if (options == viewModel.MetaData.RecalculateTimer()
                                    ) viewModel.MetaData.RecalculateTimer(undefined);
						});
                        },
                        $$.Client.Util.ThrottleTime);
                } else {
                    $$.fn.getFullQuote(false, options.doPageValidation, options.performRescore)
                        .fail(typeof (options.displayError) == "function"
                            ? options.displayError
                            : $$.Client.displayError)
                        .always(function() {
			    $$.policy.MetaData.isRecalculating(false);
			    viewModel.MetaData.RecalculateTimer(undefined)
			});
                }
            }
        }).extend({ throttle: $$.Client.Util.ThrottleTime });

        // Disabled navigation buttons when recalculating
        viewModel.MetaData.PreventNavigationOnRecalc = ko.observable(false);

        viewModel.MetaData.MaxProductBenefits = ko.observableArray();

        viewModel.MetaData.multiTripChecked = ko.observable(function() {
            var question = ko.utils.arrayFirst(viewModel.Questions(),
                function(question) {
                return question.BriefCode() == 'MULTI'
            });
            return (question && question.Answer && question.Answer().BriefCode() === "Y");
        }());

        viewModel.MetaData.multiTripChecked.subscribe(function(newValue) {
            HideQuickQuotePlans();

            //If we are in multi-trip, recalculate the end date using the api.
            if (newValue) {
                $$.fn.calculateMultiTripEndDate();
            } else {
                if (viewModel.StartDate()) {
                    // set end date to + 5 days
                    viewModel.EndDate(new Date(viewModel.StartDate()).advance({ days: 5 }).toISOString());
                }
            }

            var multitripQuestion = ko.utils.arrayFirst(viewModel.Questions(),
                function(question) {
                return question.BriefCode() == 'MULTI'
            });

            multitripQuestion.Answer().BriefCode(newValue ? 'Y' : 'N');

        });

        // validation rule for privacy on payment page
        viewModel.MetaData.privacyAgree = ko.observable();
        if (!$('#paymentForm').length > 0) {
            viewModel.MetaData.privacyAgree(true);
            window.localStorage.privacyAgree = 'true';
        }
        viewModel.MetaData.privacyAgree.extend({
            equal: { params: true, message: PrismApi.Validation.messages.equalTruePrivacyAgree }
        });
        viewModel.MetaData.privacyAgree.subscribe(function(val) {
            if (window.localStorage) {
                if (val === true) {
                    window.localStorage.privacyAgree = 'true';
                } else if (window.localStorage.privacyAgree) {
                    window.localStorage.privacyAgree = undefined;
                }
            }
        });

        viewModel.MetaData.havePromoCode = ko.observable(ko.utils
            .arrayFirst(viewModel.MetaData.PromoAdjustments(), function(item) { return item.Value() }) !=
            null
            ? 1
            : 0);
        viewModel.MetaData.havePromoCode.subscribe(function(val) {
            if (val === "0") {
                var hasChanged = false;
                ko.utils.arrayForEach(viewModel.MetaData.PromoAdjustments(),
                    function(item) {
                    if (item.Value) hasChanged = true;
                    return item.Value(null);
                })
                if (hasChanged) {
                    RecalculateQuote(false);
                }
            }
        });

        for (var adult = 0; adult < viewModel.PolicyHolders().length; adult++) {
            var adultAge = viewModel.PolicyHolders()[adult].MetaData.age();
            if ($.isNumeric(adultAge)) {
                var newAdult = new PrismApi.Data.Customer(null, 'adult');
                newAdult.MetaData.age(adultAge);
                viewModel.MetaData.AdultAges.push(newAdult);
            }

        }
        for (var dependant = 0; dependant < viewModel.PolicyDependants().length; dependant++) {
            var dependantAge = viewModel.PolicyDependants()[dependant].MetaData.age();
            if ($.isNumeric(dependantAge)) {
                var newDependant = new PrismApi.Data.Customer(null, 'dependant');
                newDependant.MetaData.age(dependantAge);
                viewModel.MetaData.DependantAges.push(newDependant);
            }
        }

        if ($$.quickQuoteOptions()) {
            for (var travellerIndex = 0; travellerIndex < $$.quickQuoteOptions().MinAdults; travellerIndex++) {
                viewModel.MetaData.AdultAges()[travellerIndex].MetaData.age
                    .extend({
                        required: {
                            params: true,
                            message: PrismApi.Validation.messages.travellers.invalidMinAdults
                                .format($$.quickQuoteOptions().MinAdults)
            }
                    });
            }
            for (var travellerIndex = 0; travellerIndex < $$.quickQuoteOptions().MinDependants; travellerIndex++) {
                viewModel.MetaData.DependantAges()[travellerIndex].MetaData.age
                    .extend({
                        required: {
                            params: true,
                            message: PrismApi.Validation.messages.travellers.invalidMinDependants
                                .format($$.quickQuoteOptions().MinDependants)
            }
                    });
            }
        }

        /* Set Date of birth validation min max rule to match quoted age */
        $.each(viewModel.PolicyHolders(),
            function(index, item) {
                item.Title.subscribe(function(title) {
                if ($.inArray(title, ["MR", "MSTR"]) != -1) {
                    item.Gender("M");
                } else if ($.inArray(title, ["MRS", "MS", "MISS"]) != -1) {
                    item.Gender("F");
                } else {
                    item.Gender(undefined);
                    item.Gender.isModified(false);
                }
            });

            var today = Date.create('today');
            var birthYear = today.getFullYear() - item.MetaData.age();
            item.DateOfBirth.formattedDate.extend({
                min: {
                        params: function() {
                        var today = new Date();
                        var minDate = new Date(birthYear - 1, today.getMonth(), today.getDate() + 1);
                        return minDate;
                        },
                        message: PrismApi.Validation.messages.travellers.invalidDobRange
                    },
                    max: {
                        params: function() {
                        var today = new Date();
                        var maxDate = new Date(birthYear, today.getMonth(), today.getDate());
                        return maxDate
                        },
                        message: PrismApi.Validation.messages.travellers.invalidDobRange
                }
            });

                $("#travellersForm").each(function() {
                // Check for PE loading / HealixAssessment mismatch and remove  HealixAssessment
                    if (item.HealixAssessment() &&
                        item.HealixAssessment().ScreeningResult &&
                        item.HealixAssessment().ScreeningResult.ScreeningStatus &&
                        item.HealixAssessment().ScreeningResult.ScreeningStatus()) {
                    // attempt to find localstorage flag accepting healix assessment
                    var hasClickedNext = false
                        if (window.localStorage &&
                            window.localStorage['Traveller' + (index + 1).toString() + 'PeAccepted'])
                        hasClickedNext = true;
                    // verify user has accepted their offer and clicked next or just clicked next for ones that dont require acceptance.
                        if ((item.HealixAssessment().ScreeningResult.ScreeningStatus() === 'APPPP' &&
                            (item.HealixAssessment().CalculationOption
                                .AcceptOffer() !==
                                true ||
                                !hasClickedNext)) ||
                            item.HealixAssessment().ScreeningResult.ScreeningStatus() === 'DECNP' &&
                            (item.HealixAssessment().CalculationOption.AcceptOffer() !== true || !hasClickedNext) ||
                            !hasClickedNext) {
                            
                            if (_session != null &&
                                _session.policy != null &&
                                _session.policy.IsRetrieveQuote !== undefined &&
                                _session.policy.IsRetrieveQuote) {
                                
                            } else {
                                
                        resetHealixForTraveller(item);
                            }
                        window.localStorage.removeItem('Traveller' + (index + 1).toString() + 'PeAccepted');
                    }
                }
            });
            item.MetaData.FormattedName = getTravellerNameComputed(item, "Adult", index);
        });
        $.each(viewModel.PolicyDependants(),
            function(index, item) {
                item.Title.subscribe(function(title) {
                if ($.inArray(title, ["MR", "MSTR"]) != -1) {
                    item.Gender("M");
                } else if ($.inArray(title, ["MRS", "MS", "MISS"]) != -1) {
                    item.Gender("F");
                } else {
                    item.Gender(undefined);
                    item.Gender.isModified(false);
                }
            });

            var today = Date.create('today');
            var birthYear = today.getFullYear() - item.MetaData.age();
            item.DateOfBirth.formattedDate.extend({
                min: {
                        params: function() {
                        var today = new Date();
                        var minDate = new Date(birthYear - 1, today.getMonth(), today.getDate() + 1);
                        return minDate;
                        },
                        message: PrismApi.Validation.messages.travellers.invalidDobRange
                    },
                    max: {
                        params: function() {
                        var today = new Date();
                        var maxDate = new Date(birthYear, today.getMonth(), today.getDate())
                        return maxDate
                        },
                        message: PrismApi.Validation.messages.travellers.invalidDobRange
                }
            });

                $("#travellersForm").each(function() {
                // Check for PE loading / HealixAssessment mismatch and remove  HealixAssessment
                    if (item.HealixAssessment &&
                        item.HealixAssessment.ScreeningResult &&
                        item.HealixAssessment.ScreeningResult.ScreeningStatus) {
                    var hasClickedNext = false
                        if (window.localStorage &&
                            window.localStorage['Dependant' + (index + 1).toString() + 'PeAccepted'])
                        hasClickedNext = true;
                    // verify user has accepted their offer and clicked next or just clicked next for ones that dont require acceptance.
                        if (item.HealixAssessment.ScreeningResult.ScreeningStatus() === 'APPPP' &&
                            (item.HealixAssessment.CalculationOption.AcceptOffer() !== true || !hasClickedNext) ||
                            !hasClickedNext) {
                            if (_session != null &&
                                _session.policy != null &&
                                _session.policy.IsRetrieveQuote !== undefined &&
                                _session.policy.IsRetrieveQuote) {

                            } else {
                        resetHealixForTraveller(item);
                            }
                        window.localStorage.removeItem('Dependant' + (index + 1).toString() + 'PeAccepted');
                    }
                }
            });
            item.MetaData.FormattedName = getTravellerNameComputed(item, "Dependant", index);
        });

        ko.utils.arrayForEach(viewModel.MetaData.AllTravellers(),
            function(traveller) {

                traveller.DateOfBirth.hasEntered.subscribe(function(newValue) {
                    window
                        .sessionStorage['Travellers[' + traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] =
                        newValue;
            });

            // To handle an F5 refresh before date has been persisted to policy object
                if (window
                    .sessionStorage['Travellers[' + traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] ==
                    'true' &&
                    traveller.FirstName() == null) {
                    window
                        .sessionStorage['Travellers[' + traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] =
                        'false';
            }
        });


        while (viewModel.MetaData.AdultAges().length < 2) {
            viewModel.MetaData.AdultAges.push(new PrismApi.Data.Customer(null, 'adult'));
        }

        if (_session.quickQuoteOptions) {
            for (var travellerIndex = 0; travellerIndex < _session.quickQuoteOptions.MinAdults; travellerIndex++) {
                viewModel.MetaData.AdultAges()[travellerIndex].MetaData.age
                    .extend({
                        required: {
                            params: true,
                            message: PrismApi.Validation.messages.travellers.invalidMinAdults
                                .format(_session.quickQuoteOptions.MinAdults)
            }
                    });
            }
            for (var travellerIndex = 0; travellerIndex < _session.quickQuoteOptions.MinDependants; travellerIndex++) {
                viewModel.MetaData.DependantAges()[travellerIndex].MetaData.age
                    .extend({
                        required: {
                            params: true,
                            message: PrismApi.Validation.messages.travellers.invalidMinDependants
                                .format(_session.quickQuoteOptions.MinDependants)
            }
                    });
            }
        }

        while (viewModel.MetaData.DependantAges().length < 2) {
            viewModel.MetaData.DependantAges.push(new PrismApi.Data.Customer(null, 'dependant'));
        }

        //Trigger a re-quote when the benefits are enabled
        for (var i = 0; i < viewModel.Benefits().length; i++) {
            var benefit = viewModel.Benefits()[i];
            benefit.Option = ko.observable();
            benefit.MetaData.IsEnabled.subscribe(function (newValue) {
                var benefit = this;
                    setTimeout(function() {
                    if (!benefit.MetaData.removePack()) {
                        // adjust detail visiblility based on checkbox
                        benefit.MetaData.showDetail(newValue);
                    }
                    benefit.MetaData.removePack(false);
                        },
                        0);
                },
                benefit);

            // extend benefit to have a show/hide benefit detail
            benefit.MetaData.showDetail = ko.observable(false);
            benefit.MetaData.checkboxHasFocus = ko.observable(false);
            benefit.MetaData.removePack = ko.observable(false);
            benefit.MetaData.removePack.subscribe(function(newValue) {
                // unselects option but leaves details visible
                if (newValue) {
                    this.MetaData.IsEnabled(false);
                }
                },
                benefit);
            benefit.MetaData.IsEnabled.subscribe(function (newValue) {
                var benefit = this;

                if (benefit.BriefCode() === 'SNOW') {
                    if (ko.utils.arrayFirst((benefit.MetaData.IsPerAdultOnly
                            ? viewModel.PolicyHolders()
                            : viewModel.MetaData.AllTravellers()),
                        function(traveller) {
							return ko.utils.arrayFirst(benefit.MetaData.Values || new Array(),
                                function(item) {
                                    return item.Value != 'Covered' &&
                                        item.MetaData.MinAge !== undefined &&
                                        item.MetaData.MaxAge !== undefined &&
                                        item.MetaData.MinAge <= traveller.MetaData.age() &&
                                        item.MetaData.MaxAge >= traveller.MetaData.age();
                    });
                    })) {
                        var modal = $('#modal-snow');
                        openModal(modal.data('title'), modal.html(), false, false);
                    }
                }

                if (benefit.BenefitItems().length > 0 &&
                    (benefit.BriefCode() === 'BIKE' || benefit.BriefCode() === 'RNTVX' || benefit.BriefCode() === 'RVEIN')) {
                    if (benefit.MetaData.ValueDataType === 'CURRENCY') {
                        benefit.BenefitItems()[0].Value.subscribe(function () {
                            var benefit = this;

                            if (benefit.MetaData.ValueDataType !== 'STRING') {
                                benefit.BenefitItems()[0].Value(parseFloat(benefit.BenefitItems()[0].Value()));
                            }
                            RecalculateQuote();

                        }, benefit);
                    } else {
                        benefit.BenefitItems()[0].ValueText.subscribe(function () {
                            var benefit = this;

                            if (benefit.MetaData.ValueDataType !== 'STRING') {
                                benefit.BenefitItems()[0].Value(parseFloat(benefit.BenefitItems()[0].ValueText()));
                }
                            RecalculateQuote();

                        }, benefit);
                    }
                } else {
                RecalculateQuoteImmediate();
                }

                return true;
            }, benefit);
            // sort specific items benefit items
            benefit.MetaData.SortedSpecificItems = ko.computed(function() {
                    var sortedItems = this.BenefitItems();
                    return sortedItems.sort(function(a, b) {
                    return a.CustomerIndex() > b.CustomerIndex();
                });
                },
                benefit).extend({ throttle: $$.Client.Util.ThrottleTime });

            // determine traveller options for benefit
            benefit.MetaData.TravellerOptions = ko.computed(function() {
                if (this.MetaData.IsPerPerson) {
                        return this.MetaData
                            .IsPerAdultOnly
                            ? viewModel.PolicyHolders()
                            : viewModel.MetaData.AllTravellers();
                }
                return [];
                },
                benefit).extend({ throttle: $$.Client.Util.ThrottleTime });
        }


        // Indicated to template when options loaded via ajax
        viewModel.MetaData.TravellerOptionsReady = ko.observable(false);
        viewModel.MetaData.TravellerOptionsReady.subscribe(function() {
            // set summary sidbar collapse summary has been set visible
            setTimeout(function() {
                window.checkWidthQuickQuote('.quote-summary', '#quote-summary-body', true);
                },
                500);
        });
        viewModel.MetaData.QuickQuoteOptionsReady = ko.observable(false);

        // Indicate to do a rescore on recalculate
        viewModel.MetaData.RecalculatePERescore = ko.observable(false);

        var travellersHavePE = undefined;
        if (window.localStorage) {
            if (window.localStorage.travellersHavePE === 'true') {
                travellersHavePE = true;
            } else if (window.localStorage.travellersHavePE === 'false') {
                travellersHavePE = false;
            }
        }

        //resetting Healix and premium price when user clicks on NO to hasPECondition
        viewModel.MetaData.travellersHavePE = ko.observable(travellersHavePE);
        viewModel.MetaData.travellersHavePE.extend({ required: true });
        viewModel.MetaData.travellersHavePE.subscribe(function(newValue) {

            if (window.localStorage) {
                if (newValue) {
                    window.localStorage.travellersHavePE = 'true';
                } else if (newValue === false) {
                    window.localStorage.travellersHavePE = 'false';
                } else {
                    window.localStorage.travellersHavePE = undefined;
                }
            }

            if (newValue === false) {
                var travellers = ko.utils.arrayFilter(viewModel.MetaData.AllTravellers(),
                    function(traveller) {
                    return traveller.HealixAssessment().ScreeningId() !== 0;
                });
                ko.utils.arrayForEach(viewModel.MetaData.AllTravellers(),
                    function(traveller) {
                    traveller.MetaData.HasPeCondition(undefined);
                    traveller.MetaData.ReAssessment('true');
                    traveller.MetaData.HasPeCondition.isModified(false);
                    if (traveller.HasPeCondition)
                        traveller.HasPeCondition(undefined);
                    resetHealixForTraveller(traveller, true);
                });
                $$.policy.MetaData.RecalculatePERescore(true);
            }
        });

        viewModel.quoteRetrieve = {
            dob: ko.observable(null).extend({
                required: true,
                max: { params: new Date() },
                message: PrismApi.Validation.messages.travellers.invalidDobRange
            }),
            surname: ko.observable("").extend({ required: true }),
            quoteNumber: ko.observable("").extend({ required: true }),
            retrieveQuote: function() {
                viewModel.errors.showAllMessages();
                return viewModel.quoteRetrieve.dob.isValid() &&
                    viewModel.quoteRetrieve.surname.isValid() &&
                    viewModel.quoteRetrieve.quoteNumber.isValid();
            }
        }
    };

    //HEALIX INTEGRATION
    $$.Client.showHealixAssessment = function(self, value) {

        var okFunction = function() {
            var modal = $('#myModal');
            $(this).removeAttr('data-dismiss');

            $("#okcancel", modal).hide();
            if (ko.unwrap($$.policy.PeOptions) != null && $$.policy.PeOptions.PESystem() == "HEALX") {

                $("#myModalLabel", modal).html("Pre-existing medical assessment");
                $("#myModalContent", modal).html("Please wait… We are preparing your pre-existing medical assessment.");

                $('#modal-loading', modal).show();

                if ($$.policy.PeOptions.FirstHolderFlag()) {
                    $$.fn.retrieveHealixAssessment()
                        .done(function() {
						    window.location.href = $$.baseUrl + 'PreExisting/Screening'
						})
                        .always(function() {
						    $('#modal-ok', modal).attr('data-dismiss', 'modal').removeClass('pe-visible');
						})
					.fail($$.Client.displayError);
                } else {
                    $$.fn.retrieveHealixFatalCondition()
                        .done(function() {
					    window.location.href = $$.baseUrl + 'PreExisting'
					})
                        .always(function() {
					    $('#modal-ok', modal).attr('data-dismiss', 'modal').removeClass('pe-visible');
					})
					.fail($$.Client.displayError);
                }

            }
        };

        var bootstrapViewSize = $$.Client.Util.detectBootstrapViewSize();
        var skipWarning = $$.policy.MetaData.AllTravellers().length == 1 && bootstrapViewSize !== "xs";
        // skip PE privacy warning if only one traveller
        if (skipWarning) {
            openMessageBoxModal('', '');
            okFunction();
        } else {
            $("#modal-ok").addClass('pe-visible');
            openMessageBoxModal(skipWarning ? '' : 'Warning',
                skipWarning ? '' : $('#modal-peRequired').html(),
				'Ok',
                okFunction,
                'Cancel',
                function() {
				    $("#modal-ok").removeClass('pe-visible');
                    if (self.MetaData &&
                        self.MetaData.HasPeCondition() !== undefined &&
                        self.MetaData.HasPeCondition()) {
                    } else {
				    self.MetaData.HasPeCondition(value);
				}
                }
			);
        }
    };

    //DATEPICKERS
    if (isMobile()) {
        var defaultDateFormat = PrismApi.Client.datepicker.getDateFormat();
        var defaultDateOrder = 'D ddmmyy';
        var defaultDisplay = 'bottom';
        var defaultshowLabel = false;
        var now = new Date;

        var beforeShowFunc = function(input, inst) {
            var formattedDate = PrismApi.Utils.formattedStringToDate(this.value);
            if (formattedDate) {
                input.setDate(formattedDate);
            }
        }
        var setEndYearFunc = function(input, inst) {
            $("#endDate").mobiscroll('option', 'endYear', $("#startDate").mobiscroll('getDate').getFullYear() + 1);
        }
        if (window.innerWidth <= 480 || window.innerHeight < 400) {
            defaultDisplay = 'bottom';
        }

        $("#startDate").mobiscroll().date({
            theme: 'ios7',
            dateFormat: defaultDateFormat,
            dateOrder: defaultDateOrder,
            display: defaultDisplay,
            showLabel: defaultshowLabel,
            onBeforeShow: beforeShowFunc,
            onSelect: setEndYearFunc,
            minDate: new Date()
        });
        $("#endDate").mobiscroll().date({
            theme: 'ios7',
            dateFormat: defaultDateFormat,
            dateOrder: defaultDateOrder,
            display: defaultDisplay,
            showLabel: defaultshowLabel,
            onBeforeShow: beforeShowFunc,
            minDate: new Date()
        });
        $("#dateOfBirth").mobiscroll().date({
            theme: 'ios7',
            dateFormat: defaultDateFormat,
            dateOrder: defaultDateOrder,
            display: defaultDisplay,
            showLabel: defaultshowLabel,
            onBeforeShow: beforeShowFunc
        });

        $("input.dobAdults, input.dobDependants").prop('readonly', true);

        $(document).on("focus",
            "input.dobAdults",
            function() {
            if (!this.id) { //only add it once        
                var today = new Date();
                var birthYear = today.getFullYear() - $(this).data('age');
                var mindate = new Date(birthYear - 1, now.getMonth(), now.getDate() + 1);
                var maxdate = new Date(birthYear, now.getMonth(), now.getDate());
                    $(this).mobiscroll().date({
                        theme: 'ios7',
                        dateFormat: defaultDateFormat,
                        dateOrder: defaultDateOrder,
                        display: defaultDisplay,
                        showLabel: defaultshowLabel,
                        onBeforeShow: beforeShowFunc,
                        minDate: mindate,
                        maxDate: maxdate
                    });
            }
        });
        $(document).on("focus",
            "input.dobDependants",
            function() {
            if (!this.id) { //only add it once                
                var today = new Date();
                var birthYear = today.getFullYear() - $(this).data('age');
                var mindate = new Date(birthYear - 1, now.getMonth(), now.getDate() + 1);
                var maxdate = new Date(birthYear, now.getMonth(), now.getDate());
                    $(this).mobiscroll().date({
                        theme: 'ios7',
                        dateFormat: defaultDateFormat,
                        dateOrder: defaultDateOrder,
                        display: defaultDisplay,
                        showLabel: defaultshowLabel,
                        onBeforeShow: beforeShowFunc,
                        minDate: mindate,
                        maxDate: maxdate
                    });
            }
        });
        // fix calendar click with live event
        $(document).on('click',
            '#startDate, #endDate',
            function(e) {
            $(this).mobiscroll('show');
        });
        $(document).on('click',
            '.datepane span.input-group-addon',
            function(e) {
            var input = $(this).prev('input').mobiscroll('show');
            input.focus();
        });
        $(document).on('tap',
            '.datepane span.input-group-addon',
            function(e) {
            var input = $(this).prev('input').mobiscroll('show');
            input.focus();
        });
    } else {
        // fix calendar click with live event
        $(document).on('click',
            '.datepane span.input-group-addon',
            function(e) {
            var input = $(this).prev('input');
            if (input.length === 0) {
                input = $(this).prev().prev('input');
            }
            if (!input.hasClass('hasDatepicker')) {
                // match up type to input               
                    var typeFound = "_anyDate";
                if (input.hasClass('startDate')) {
                    typeFound = "_startDate";
                }
                if (input.hasClass("endDate")) {
                    typeFound = "_endDate";
                }
                if (input.hasClass("dobAdults") || input.hasClass("dobDependants")) {
                    if (input.attr('disabled') !== 'disabled') {
                        input.focus();
                        return true;
                    }
                }

                // find options, currently either start or end date
                var options = $$.Client.datepicker.getType(typeFound).options;
                input.datepicker(options);
            }
            if (input.attr('disabled') !== 'disabled')
                input.datepicker('show');
        });

        var adultType = $$.Client.datepicker.getType("_dobAdults");
        var dependantType = $$.Client.datepicker.getType("_dobDependants");

        //  For Travellers, set ui to show year/month dropdowns with a max selectable year this year
        var restrictToSameYearOptions = function(input) {
            return {
                maxDate: new Date(),
                changeYear: true,
                changeMonth: true,
                yearRange: PrismApi.Utils.getDatepickerYearRange("adult")
            };
        };
        var restrictToSameYearOptionsDependant = function(input) {
            return {
                maxDate: new Date(),
                changeYear: true,
                changeMonth: true,
                yearRange: PrismApi.Utils.getDatepickerYearRange("dependant")
            };
        };

        adultType.options = restrictToSameYearOptions;
        dependantType.options = restrictToSameYearOptionsDependant;

        var endDateOption = null;
        // Override datepicker ui settings to show year/month dropdowns and only one year advance on dropdown
        $.each($$.Client.datepicker.types,
            function(index, item) {
            if (item.key === '_startDate' || item.key === '_endDate') {
                item.options.changeMonth = true;
                item.options.changeYear = true;
                var currentdate = Date.create('today').addYears(1).addDays(-1);

                if (item.key === '_startDate') {
                    item.options.yearRange = "-0:+1";
                    item.options.maxDate = currentdate;
                } else {
                    item.options.yearRange = "-0:+2";
                    item.options.maxDate = currentdate;
                    endDateOption = item.options;
                }
            }
            if (item.key === '_startDate') {
                    item.options.onClose = function(dateText, data) {
                    if (data.lastVal != dateText) {
                        // set focus to next datepicker
                            setTimeout(function() {
                                    var currentStartDate = $$.newPolicy == null
                                        ? $$.policy.StartDate()
                                        : $$.newPolicy.StartDate();
                            endDateOption.minDate = Date.create(currentStartDate);
                            endDateOption.maxDate = Date.create(currentStartDate).addYears(1).addDays(-1);
                            $(".endDate:visible").datepicker("destroy");
                            $(".endDate:visible").datepicker(endDateOption);
                            $(".endDate:visible").datepicker('show');
                            $(".endDate:visible").focus();
                                },
                                100);
                    }
                };
            }
        });

        $$.Client.datepicker.apply_jQueryUIDatepickers();
    }

    //COMMON SETUP
    var commonSetup = function() {
        //ToolTips
        $(document).on('click',
            '.tooltip-image:not(.popover-tooltip)',
            function() {
            var text = $(this).closest('label').text();
            if (!text) text = $(this).prev('label').first().text();
            if (!text) text = $(this).parent().find('label').first().text();
            if (!text) text = $(this).parent().parent().find('label').first().text();
            if (!text) text = $(this).data('header');

            var titleOverride = $(this).data('title');
                if (titleOverride) {
                    text = titleOverride;
                }

            var content = $(this).data('content');
            if (!content) content = $('.tooltip-content', this).html();

            openModal(text, content, false, false);
        });

        $(document).on('click',
            '.toggleDiv',
            function() {
            $(this).parent().next('div').toggle();
            $(this).find('.show-hide-button-detail').toggle();
        });

        $("#healixForm").on('click',
            '.btn-next',
            function() {
            var errorMessage = $('.healixError').text();
            if (errorMessage.length > 0) {
                openErrorModal('Validation Error', $.camelCase('-' + errorMessage.toLowerCase()), false, false);
            }
        });

        var fixDestinations = function(destinations, viewModel) {
            ko.utils.arrayForEach(destinations,
                function(destination) {
                    var region = ko.utils.arrayFirst(viewModel.MetaData.Regions(),
                        function(r) {
                            return ko.utils.unwrapObservable(r.BriefCode) ==
                                ko.utils.unwrapObservable(destination.BriefCode);
                });
                if (!region) {
                    viewModel.MetaData.Regions.push(destination);
                    region = destination;
                    } else {
                    if (region.Countries) region.Countries.length = 0;
                    region.Countries = ko.observableArray();
                    ko.utils.arrayPushAll(region.Countries, destination.Countries || []);
                }
                if (viewModel.Destinations()) {
                        ko.utils.arrayForEach(viewModel.Destinations(),
                            function(selectedDestination) {
                        if (ko.utils.unwrapObservable(selectedDestination.BriefCode) == destination.BriefCode) {
                            if (!selectedDestination.Description) {
                                selectedDestination.Description = ko.observable()
                            }
                            selectedDestination.Description(destination.Description);
                            if (selectedDestination.Country) {
                                        var country = ko.utils.arrayFirst(destination.Countries,
                                            function(country) {
                                                return ko.utils
                                                    .unwrapObservable(selectedDestination.Country.BriefCode) ==
                                                    country.BriefCode
                                });
                                if (country) {
                                    if (!selectedDestination.Country.Description) {
                                        selectedDestination.Country.Description = ko.observable()
                                    }
                                    selectedDestination.Country.Description(country.Description)
                                }
                                if (country && country.Locations && selectedDestination.Country.Location) {
                                            var location = ko.utils.arrayFirst(country.Locations,
                                                function(location) {
                                                    return ko.utils
                                                        .unwrapObservable(selectedDestination.Country.Location
                                                            .BriefCode) ==
                                                        location.BriefCode
                                    });
                                    if (location) {
                                        if (!selectedDestination.Country.Location.Description) {
                                            selectedDestination.Country.Location.Description = ko.observable()
                                        }
                                        if (country) {
                                                    selectedDestination.Country.Location
                                                        .Description(location.Description)
                                        }
                                    }
                                }
                            }
                        }
                    })
                }
            })
        };

        $("#quickQuoteForm .top-widget-wrapper, .current-quote .top-widget-wrapper").first().each(function() {
            if ($$.newPolicy == null) {
                var newPolicy = new PrismApi.Data.Policy(_session.policy);
                PrismApi.Client.extendViewModel(newPolicy);

                fixDestinations($$.policy.Destinations(), newPolicy);
                newPolicy.errors = ko.validation.group(newPolicy, { deep: true });
                $$.newPolicy = newPolicy;

                $$.fn.getDestinations().done(function(result) {
                    //move the destinations
                    function moveDestinations(viewModel) {
                        var destinations = [];
                        ko.utils.arrayForEach(viewModel.Destinations(),
                            function(destination) {
                            if (ko.utils.unwrapObservable(destination.BriefCode)) {
                                    destinations
                                        .push(EncodeRegion(destination,
                                            destination.Country,
                                            destination.Country.Location));
                            }
                        });
                        viewModel.MetaData.Countries(destinations.join(','));
                    }

                    if (newPolicy.Destinations()) {
                        moveDestinations($$.policy);
                        moveDestinations($$.newPolicy);
                    }
                    fixDestinations(result.Regions, newPolicy);
                    if ($('.top-widget-toggle-wrapper').length > 0) {
                        ko.cleanNode($('.top-widget-toggle-wrapper')[0]);
                        ko.applyBindings(newPolicy, $('.top-widget-toggle-wrapper')[0]);
                    }
                    if ($('#quote-body').length > 0) {
                        ko.cleanNode($('#quote-body')[0]);
                        ko.applyBindings(newPolicy, $('#quote-body')[0]);
                    }
                });

                if (window.localStorage && window.localStorage.privacyAgree === "true") {
                    $$.newPolicy.MetaData.privacyAgree(true);
                }
            }
        });

        //submit quickQuote
        $(document).on("click",
            ".top-widget-wrapper #topWidget-quickQuote-submit",
            function(e) {
            var self = this;
            // show spinner
            showSpinner($(self), 'spinner', true);
            $(self).siblings('.spinner').addClass('pull-right');

            if (window.localStorage) {
                window.localStorage.travellersHavePE = undefined;
            }

            if (window.sessionStorage && window.sessionStorage['FullAddress'] !== undefined) {
                window.sessionStorage.removeItem('FullAddress');
            }

            moveDataFromTempArray($$.newPolicy);

            $$.newPolicy.errors.showAllMessages();

                $$.newPolicy.errors.visibleMessages = function() {
                var configuration = ko.validation.utils.getConfigOptions($$.newPolicy);
                var errors = [];
                    $('.top-widget-wrapper').find('.' + configuration.errorElementClass + ':visible').each(function() {
                    errors.push(new PrismApi.Data.ErrorMessage($(this).attr('name'), $(this).attr('title')))
                });
                return errors;
            }

            if ($$.newPolicy.errors.visibleMessages().length > 0) {
                var apiError = new PrismApi.Data.ApiError(null, $$.newPolicy.errors.visibleMessages(), null);
                $$.Client.displayError(apiError);
                hideSpinner(this)
                return;
            } else {
                    var RedirectToChosenaPlanPage = function() {
                    var defPrivModal = $$.Client.Util.Modal.PrivacyModal($$.newPolicy);
                        defPrivModal.promise().done(function() {
                            $$.fn.getQuickQuoteOptions().done(function() {
                            $$.fn.getBulkQuickQuoteWithQuote($$.newPolicy, true, false, false)
                                    .done(function(bqq) {
                                        var qs = (PrismApi.bulkQuickQuote.PricingLogId !== undefined &&
                                            PrismApi.bulkQuickQuote.AccessCode !== undefined
                                            ? 'id=' +
                                            PrismApi.bulkQuickQuote.PricingLogId +
                                            '&accessCode=' +
                                            PrismApi.bulkQuickQuote.AccessCode +
                                            '&session=true'
                                            : 'session=true');

							    window.top.location.href = $$.baseUrl + "QuickQuote?" + qs;
							})
							.fail($$.Client.displayError)
                                    .always(function() {
							    hideSpinner(this)
							});
                        });
                    });
                };
                // show a warning to user if the first adult age is less than 13                
                    if ($$.newPolicy.MetaData.Adults() > 0 &&
                        $$.newPolicy.PolicyHolders()[0].MetaData.age() < $$.policy.MetaData.DefaultUnaccompaniedAge() &&
                        ($$.newPolicy.MetaData.Adults() == 1 ||
                        ($$.newPolicy.MetaData.Adults() == 2 &&
                            $$.newPolicy.PolicyHolders()[1].MetaData.age() <
                            $$.policy.MetaData.DefaultUnaccompaniedAge()))) {
                        window.openMessageBoxModal('WARNING',
                            $('#modal-unaccompanied-child').html(),
                            'Ok',
                            RedirectToChosenaPlanPage,
                            'Cancel',
                            function() {});
                    return;
                    } else {
                    RedirectToChosenaPlanPage();
                }
            }
        });

        $(window).resize(function() {
            //force the scroll to re-evaluate to push the page down if required.
            setTimeout(function() { $(window).scroll() }, 100);
        });
    }

    var checkWidthQuickQuote = function(widget, body, summary) {
        // show QuickQuote widget expanded for the choose a plan page
        var showExpanded = $("#paymentForm").length > 0;
        var quoteWidget = $(widget);
        var widthTest = quoteWidget.parents('.container');
        if (summary && showExpanded && widthTest.width() < 962) {
            $(body).addClass('collapse');
            $("#quoteSummaryToggle").trigger('click');
        } else {
            if (widthTest.width() > 961) // large viewport starts at 962
            {
                $(body).removeClass('collapse');
            } else {
                if ($('#quoteToggle').hasClass('collapsed') || $('#quoteSummaryToggle').hasClass('collapsed'))
                    $(body).addClass('collapse');
            }
        }
    }

    window.checkWidthQuickQuote = checkWidthQuickQuote;

    // Reset healix assessment for traveller/dependant, used when changing plans or aborting pe assessment forcefully
    var resetHealixForTraveller = function(item) {
        if (item.HealixAssessment()) {
            item.HealixAssessment().ScreeningId(0);
            item.HealixAssessment().ScreeningRev(0);
            item.HealixAssessment().PeId(0);
            item.HealixAssessment().ScreeningResult = null;
            item.HealixAssessment().CalculationOption = [];

        }
        if (item.MetaData && item.MetaData.HasPeCondition() !== undefined) {
            item.MetaData.HasPeCondition(undefined);
            if (item.HasPeCondition)
                item.HasPeCondition(undefined);
        }
    }

    //This method will extract querystring values form URL
    function getParameterByName(name) {
        name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
        var regex = new RegExp("[\\?&]" + name + "=([^&#]*)", "i")
        results = regex.exec(location.search);
        return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    // SAVE QUOTE SETUP
    var saveQuoteSetup = function() {

        var saveQuoteViewModel = null;

        function applyBindings() {
            var modalContent = $('#myModalContent .saveQuoteModalContent')[0];

            saveQuoteViewModel = {
                dob: ko.observable(null),
                email: ko.observable("")
            };

            var mainTraveller = $$.policy.PolicyHolders()[0];
            var existingDob = mainTraveller.MaskedDateOfBirth();
            if (!existingDob) existingDob = mainTraveller.DateOfBirth();
            var existingEmail = $$.policy.Email != null ? $$.policy.Email.EmailAddress() : null;

            if (existingDob) {
                saveQuoteViewModel.dob(existingDob);
            }
            if (existingEmail != null) {
                saveQuoteViewModel.email(existingEmail);
            }
            saveQuoteViewModel.dob.subscribe(function(newDOB) {
                var existingDobParsed = new Date(Date.parse(newDOB));
                var existingDobFormatted = existingDobParsed
                    .toFormattedString(PrismApi.Client.datepicker.getDateFormat())
                $$.policy.PolicyHolders()[0].DateOfBirth(existingDobFormatted);
            });

            ko.cleanNode(modalContent);
            ko.applyBindings(saveQuoteViewModel, modalContent);
        }

        $(document).on("click",
            ".closeModal",
            function(e) {
                hideModal();
            });

        $(document).on("click",
            "#btnSaveQuote",
            function(e) {
                $("#btnSaveQuote").attr('disabled', true);
                var self = this;
                // show spinner
                showSpinner($(self), 'spinner');

                $$.fn.unauthenticated.saveFullQuote($$.Client.Util.GetCurrentPurchaseStep())
                    .done(function() {
                        hideModal();

                        $$.fn.unauthenticated.sendQuoteEmail();

                        // This is a temporary solution with setTimeout to bypass the ugly behaviour of the hideModal function.
                        // TODO: Please feel free to change it.
                        setTimeout(function() {
                                var title = 'Your quote has been saved (' + PrismApi.policy.QuoteReference() + ')';
                                var content = '<p>Thank you. Your quote has been saved and sent to you.</p>' +
                                    '<p>Your quote is valid until the earlier of:</p>' +
                                    '<ul><li>14 days from today;</li>' +
                                    '<li>commencement of your journey;</li>' +
                                    '<li>expiry of any promo code used in this quote; and</li>' +
                                    '<li>your selected plan being amended or becoming unavailable.</li><ul>';
                                openModal(title, content);
                            },
                            1000);
                    })
                    // TODO: Enrich the dialog box with validation and error messages displayed to the customer
                    .fail($$.Client.displayError)
                    .always(function() {
                        hideSpinner(self);
                        $("#btnSaveQuote").attr('disabled', false);
                    });
            });
    };

    //QUICK QUOTE SETUP
    var quickQuoteSetup = function() {

        var oldWidth = 0;

        $("#quickQuoteForm").each(function() {

            if (isMobile()) {
                // need to remove for mobile version
                $(".spinner-bar").remove();
                $(window).click(function(e) {
                    try {
                        if ($(e.target).is('li')) {
                            $('li.highlighted').removeClass('highlighted');
                        }

                        var element = $(e.target).closest('li.highlighted');
                        if (element.length == 0) {
                            $('#PolicyBenefitPopupDiv:visible').hide();
                            $('li[data-feature-row=' + element.data('featureRow') + ']').removeClass('highlighted');
                        }

                        if ($(e.target).parents('benefit-div.highlighted').length == 0) {
                            $('#BenefitPopupDiv:visible').hide();
                            $('benefit-div.highlighted').removeClass('highlighted');
                        }
                    } catch (error) {

                    }
                });
            }

            var hasPlansDisplayed = $("#quickQuotePlans").length > 0;
            if (hasPlansDisplayed) {
                checkWidthQuickQuote('#quickQuoteForm', '#quote-body', true);
            }

            $(window).resize(function() {
                if (oldWidth == $(this).width()) return;
                oldWidth = $(this).width();
                fixBenefitTable();
                prepareShowFeature();
                // only collapse if on plans screen
                if (hasPlansDisplayed) {
                    checkWidthQuickQuote('#quickQuoteForm', '#quote-body');
                }
                checkWidthQuickQuote('.quote-summary', '#quote-summary-body');
            });

            $$.policy.CoverStartDate(undefined);
            $$.policy.CoverEndDate(undefined);

            $$.policy.MetaData.travellersHavePE(undefined);

            $$.fn.getQuickQuoteOptions()
				.fail($$.Client.displayError)
                .done(function() {
				    afterQuickQuoteOptionsLoaded($$.quickQuoteOptions());

				    // Set any default answers to questions
				    $$.Client.Util.setDefaultQuestions();

				    if (PrismApi.policy.MetaData.Adults() < 2) {
				        PrismApi.policy.MetaData.Adults(2);
				    }
				    if (PrismApi.policy.MetaData.Dependants() < 2) {
				        PrismApi.policy.MetaData.Dependants(2);
				    }
				    if (!PrismApi.policy.PolicyHolders()[0].DateOfBirth()) {
				        //Set default values
                        (function() {
				            if (Modernizr.inputtypes.date && Modernizr.touch) {
                                PrismApi.policy.PolicyHolders()[0].DateOfBirth
                                    .formattedDate('' + (new Date().getFullYear() - 35) + '-01-01');
				            } else {
                                PrismApi.policy.PolicyHolders()[0].DateOfBirth
                                    .formattedDate('1/1/' + (new Date().getFullYear() - 35));
				            }
				        })();
				    }
				    $(".quick-quote-overlay").show();

				    // set promo code value (uppercase) if value passed by edm querystring
                    var promoCodeAdjustment = ko.utils
                        .arrayFirst($$.policy.Adjustments(),
                            function(adjustments) { return adjustments.BriefCode() == 'DUMMY'; });
				    if (promoCodeAdjustment) {
				        var promoCode = getParameterByName('edm');
				        if (promoCode && promoCode.length > 0) {
				            promoCodeAdjustment.Value(promoCode.toUpperCase());
				        }
				    }

				    //set affiliate code AFFCD if value passed by affcd querystring
				    var source = getParameterByName('affcd');
				    if (source && source.length > 0) {
				        var ppei = $$.Utils.arrayFirstBriefCode($$.policy.PremiumExtraInfo(), 'AFFCD');
				        if (!ppei) {
				            ppei = new PrismApi.Data.Question({
				                'BriefCode': 'AFFCD'
				            });
				            $$.policy.PremiumExtraInfo.push(ppei);
				        }
				        ppei.Answer({
				            'BriefCode': source.toUpperCase()
				        });
				    }

				    //set source code SRCCD if value passed by source querystring
				    var source = getParameterByName('source');
				    if (source && source.length > 0) {
				        var ppei = $$.Utils.arrayFirstBriefCode($$.policy.PremiumExtraInfo(), 'SRCCD');
				        if (!ppei) {
				            ppei = new PrismApi.Data.Question({ 'BriefCode': 'SRCCD' });
				            $$.policy.PremiumExtraInfo.push(ppei);
				        }
				        ppei.Answer({
				            'BriefCode': source.toUpperCase()
				        });
				    }
				    if ($$.ApiVersion != '2.1') {
				        $$.fn.getDestinations()
							.fail($$.Client.displayError)
                            .done(function() {
							    //move the destinations
							    if ($$.policy.Destinations()) {
							        var destinations = [];
                                    ko.utils.arrayForEach($$.policy.Destinations(),
                                        function(destination) {
							            if (ko.utils.unwrapObservable(destination.BriefCode)) {
                                                destinations
                                                    .push(EncodeRegion(destination,
                                                        destination.Country,
                                                        destination.Country.Location));
							            }
							        });
							        $$.policy.MetaData.Countries(destinations.join(','));
							        $$.policy.fn.updateQuickQuoteAssessment();
							    }
							    if ($$.policy.errors.visibleNotValidMessages().length == 0) {
							        var useSession = $$.policy.MaxTripDuration() ? false : true;
							        quickQuoteClick(null, true, useSession);
							    }

							    //Set promo code value if value passed by edm querystring
                                var promoCodeAdjustment = ko.utils
                                    .arrayFirst($$.policy.Adjustments(),
                                        function(adjustments) { return adjustments.BriefCode() == 'DUMMY'; });
							    if (promoCodeAdjustment) {
							        var promoCode = getParameterByName('edm');
							        if (promoCode && promoCode.length > 0) {
							            promoCodeAdjustment.Value(promoCode);
							        }
							    }

							    hideSpinner();

							});
				    } else {
				        $('#quickQuoteForm').show();
				        if ($$.policy.errors.visibleNotValidMessages().length == 0) {
				            var useSession = $$.policy.MaxTripDuration() ? false : true;
				            quickQuoteClick(null, true, useSession);
				        }

				        hideSpinner();
				    }
				})
                .always(function() {
				    $$.fn.getProductDescriptions();

				    // show pe not availble block at bottom
				    if (isMobile()) {
				        $(".peNotAvailable").addClass("visible-xs");
				    }
				    $("#quickQuoteForm").fadeIn();
				    $(".quick-quote-overlay").hide();
				});

            //back to top
            $(document).on('click',
                '.footer-back-to-top-span',
                function() {
                $('body,html').animate({ scrollTop: $(this).closest('div.column.thumbnail').offset().top }, 800);
            });
            $(document).on('click',
                '.back-to-top-span',
                function() {
                $('body,html').animate({ scrollTop: 0 }, 800);
            });

            //show/hide policy benifit
            $('#showpolicybenefit').click(function() {
                $('.policy-benefits-section').toggle();
                $('#features-div-discover').show();
                $('.pricing-table', $(this).parent()).slideToggle(400);

                $('.show-hide-button-detail').toggle();

                if ($('#showpolicybenefit .pricing-accordion').hasClass('pricing-accordion-hide')) {
                    $('#showpolicybenefit .pricing-accordion').removeClass('pricing-accordion-hide')
                        .addClass('pricing-accordion-show');
                } else {
                    $('#showpolicybenefit .pricing-accordion').removeClass('pricing-accordion-show')
                        .addClass('pricing-accordion-hide');
                }
            });

            //show/hide term & condition
            $('#showtermcondition').click(function() {
                $('.policy-termcondition-section').slideToggle(400);
                $('.show-hide-button-termcondition').toggle();
                ($('#showtermcondition .pricing-accordion').hasClass('pricing-accordion-hide')
                    ? $('#showtermcondition .pricing-accordion').removeClass('pricing-accordion-hide')
                    .addClass('pricing-accordion-show')
                    : $('#showtermcondition .pricing-accordion').removeClass('pricing-accordion-show')
                    .addClass('pricing-accordion-hide'));
            });

            //submit quickQuote
            $(document).on("click",
                "#quickQuote-submit",
                function (e) {
                    
                var self = this;
                var onPlansPage = $("#quickQuotePlans").length > 0;
                if (typeof HideQuickQuotePlans === 'function') HideQuickQuotePlans();
                //Force the EndDate to validate when the StartDate changes even if it hasn't been set.
                $$.policy.EndDate.formattedDate.isModified(true);

                if (onPlansPage) {
                    showSpinner($("#quickQuotePlans"), 'bar', false);
                    $(".spinner-bar").css('display', 'block');
                    if ($$.newPolicy) {
                        $$.fn.CopyQuoteDataToQuote($$.newPolicy, $$.policy);
                    }
                    quickQuoteClick(null, true);
                } else {
                    // show spinner
                    showSpinner($(self), 'spinner', true);
                    $(self).siblings('.spinner').addClass('pull-right');
                    quickQuotePost();
                }
            });

            //show more detail
            $(document).on('click',
                '.show-more-detail',
                function() {
                fixBenefitTable();
                $(this).closest('.column.thumbnail').find('.features-div').slideToggle(400);
                $(this).find('i[class^=icon]').toggle();
            });

            //show feature
            $(document).on('click',
                '.show-features-toggle',
                function() {
                fixBenefitTable();
                $('.features-div').slideToggle(400);
                $('.icon-plus').toggle();
                $('.icon-minus').toggle();
            });
            //show feature mobile
            $(document).on('click',
                '.show-features-toggle-mobile',
                function() {
                fixBenefitTable();
                $(this).closest('.column.thumbnail').find('.features-div').slideToggle(400);
                $(this).find('.show-hide-button-detail').toggle();
                if ($('.pricing-accordion', this).hasClass('pricing-accordion-hide')) {
                        $('.pricing-accordion', this).removeClass('pricing-accordion-hide')
                            .addClass('pricing-accordion-show');
                } else {
                        $('.pricing-accordion', this).removeClass('pricing-accordion-show')
                            .addClass('pricing-accordion-hide');
                }
            });

            //buy now
            $(document).on("click",
                ".quickQuote-buyNow",
                function() {
                var self = this;
                // prevent buying until privacy agreed and multi trip accepted if selected
                var promPrivacy = $$.Client.Util.Modal.PrivacyModal($$.policy);
                var promMultiTripAgree = $.Deferred();

                    promPrivacy.promise().done(function() {
                    if ($(self).data("planbriefcode") === "MULTI") {
                            openMessageBoxModal('Multi Trip Confirmation',
                                $("#modal-multitripplan-agree").html(),
                                'Confirm',
                                function() {
							    var modal = $('#myModal');
							    $("#okcancel", modal).hide();
                                    $('#myModal').on('hidden.bs.modal',
                                        function() {
							        $(".modal-footer > div").attr('style', '');
							        $('#myModal').off('hidden.bs.modal');
							        promMultiTripAgree.resolve();
							    });
							},
                                'Cancel',
                                function() {
                                    $('#myModal').on('hidden.bs.modal',
                                        function() {
							        $(".modal-footer > div").attr('style', '');
							        $('#myModal').off('hidden.bs.modal');
							        promMultiTripAgree.reject();
							    });
							}
						);
                    } else {
                        promMultiTripAgree.resolve();
                    }
                });

                    $.when(promMultiTripAgree.promise(), promPrivacy.promise()).done(function() {
                    $(self).parent().find($$.Client.spinner).show();
                    showSpinner($(self), 'spinner', true);
                    var siblings = $(self).siblings('.spinner')
                    siblings.css('position', 'absolute').css('margin-top', '10px');
                        if ($$.policy.MetaData
                            .BulkPremiums !=
                            undefined &&
                            $$.policy.MetaData.BulkPremiums().length > 3)
                        siblings.css('right', '-4px');

                    $$.fn.setPlan($(self).data("planid"))
                            .done(function() {
                                var plan = ko.utils
                                    .arrayFirst($$.policy.MetaData.BulkPremiums(),
                                        function(bulkPremium) {
                                            return bulkPremium.Plan.PlanId() == $$.policy.Plan().PlanId();
                                        }).Plan;

                                var dummyAdjustment = ko.utils
                                    .arrayFirst($$.policy.Adjustments(),
                                        function(adj) {
                                            return adj.BriefCode() == "DUMMY" && ko.unwrap(adj.Value) != null
                                        });
						    if (dummyAdjustment) {
						        // remove 'DUMMY' adjustment in policy if not in bulk premium result
                                    var adjustment = ko.utils
                                        .arrayFirst(ko.unwrap(plan.Adjustments) || [],
                                            function(adj) {
                                                return adj.MetaData != null &&
                                                    ko.unwrap(adj.MetaData.InputBriefCode) == "DUMMY" &&
                                                    ko.unwrap(adj.Value) == dummyAdjustment.Value()
                                            });
						        if (!adjustment) {
						            ko.utils.arrayRemoveItem($$.policy.Adjustments(), dummyAdjustment);
						        }
						    }

						    // clear pe data
						    $$.policy.PeOptions.PESystem(null);
						    if ($$.policy.PolicyHolders) {
                                    $.each($$.policy.PolicyHolders(),
                                        function(index, item) {
						            if (item.PECover && item.PECover.PESystem)
						                item.PECover.PESystem(null);
						            resetHealixForTraveller(item);
						        });
						    }
						    if ($$.policy.PolicyDependants) {
                                    $.each($$.policy.PolicyDependants(),
                                        function(index, item) {
						            if (item.PECover && item.PECover.PESystem)
						                item.PECover.PESystem(null);
						            resetHealixForTraveller(item);
						        });
						    }

						    $$.policy.CoverStartDate($$.policy.StartDate());
						    $$.policy.CoverEndDate($$.policy.EndDate());

						    if ($$.policy.MaxTripDuration()) {
                                    var region = ko.utils
                                        .arrayFirst($$.policy.MetaData.Regions(),
                                            function(region) { return region.BriefCode() == "WORLD" })
						        $$.policy.Region().BriefCode(region.BriefCode());
						        $$.policy.Region().Description(region.Description());

						        var startDate = $$.policy.StartDate().fromISOString();
                                    var endDate = new Date(startDate.getFullYear() + 1,
                                        startDate.getMonth(),
                                        startDate.getDate() - 1);
						        $$.policy.EndDate(endDate.toISOString());
						    }

						    $$.fn.getFullQuoteOptions()
								.done(function () {
                                        if ($(self).data("planbriefcode") != "NONMD") {
                                            window.localStorage.removeItem("IsNonMedicalPlanPath");
                                        }

                                        if (($$.policy.Benefits() && $$.policy.Benefits().length > 0) ||
                                            $$.policy.MetaData.hasQuestionsForOptionPage()) {
								        window.location.href = $$.baseUrl + "Options";
								    } else {
								        window.location.href = $$.baseUrl + "Travellers";
								    }
								})
								.fail($$.Client.displayError)
                                    .always(function() {
								    $(self).parent().find($$.Client.spinner).hide();
								    hideSpinner($(self));
								});
						})
						.fail($$.Client.displayError);
                });
            });
            if (/[?&]clearCache/.test(location.search)) {
                window.localStorage.removeItem("travellersHavePE");
                window.localStorage.removeItem("privacyAgree");
            }

            // restore session for privacy agreement if set            
            if (window.localStorage && window.localStorage.privacyAgree === "true") {
                $$.policy.MetaData.privacyAgree(true);
            }


            $(".btn-previous").click(function(e) {
                // navigate allow
                backClickOn();
                showSpinner($(this), 'spinner');
                window.location.href = $$.baseUrl + "?session=true";
            });

        });

    };

    var moveDataFromTempArray = function(policy) {
        if (!policy) policy = $$.policy;

        //move adult ages from temp array to the policy
        var adults = ko.utils.arrayFilter(policy.MetaData.AdultAges(),
            function(item) {
                if (item != null) {
            return $.isNumeric(item.MetaData.age());
                }
        });
        policy.MetaData.Adults(adults.length);
        for (var i = 0; i < adults.length; i++) {
            if (!ko.unwrap(policy.PolicyHolders()[i].DateOfBirth) ||
                policy.PolicyHolders()[i].MetaData.age() != adults[i].MetaData.age()) {
                policy.PolicyHolders()[i].MetaData.age(adults[i].MetaData.age());
                window.sessionStorage['Travellers[' +
                    policy.PolicyHolders()[i].MetaData.TravellerIndex +
                    '].HasEnteredDOB'] = 'false';

            }
        }

        //move dependant ages from temp array to the policy
        var dependants = ko.utils.arrayFilter(policy.MetaData.DependantAges(),
            function(item) {
                if (item != null) {
            return $.isNumeric(item.MetaData.age());
                }
        });
        policy.MetaData.Dependants(dependants.length);
        for (var i = 0; i < dependants.length; i++) {
            if (!ko.unwrap(policy.PolicyDependants()[i].DateOfBirth) ||
                policy.PolicyDependants()[i].MetaData.age() != dependants[i].MetaData.age()) {
                policy.PolicyDependants()[i].MetaData.age(dependants[i].MetaData.age());
                window.sessionStorage['Travellers[' +
                    policy.PolicyDependants()[i].MetaData.TravellerIndex +
                    '].HasEnteredDOB'] = 'false';

            }
        }

        fixDestinations(policy);
    }

    var quickQuotePost = function() {

        moveDataFromTempArray();

        // to do: Post data to Session via API
        $$.policy.errors.showAllMessages();

        var pageErrorMessages = PrismApi.Validation.validatePolicyAgainstPage(PrismApi.policy);

        if ($$.policy.errors.visibleMessages().length > 0) {
            var apiError = new PrismApi.Data.ApiError(null, $$.policy.errors.visibleMessages(), null);
            $$.Client.displayError(apiError);
            hideSpinner(this)
            return;
        } else {
            if (window.location.href.indexOf("accessCode=") < 0) {
                // show a warning to user if the first adult age is less than 13
                if ($$.policy.MetaData.Adults() > 0 &&
                    $$.policy.PolicyHolders()[0].MetaData.age() < $$.policy.MetaData.DefaultUnaccompaniedAge() &&
                    ($$.policy.MetaData.Adults() == 1 ||
                    ($$.policy.MetaData.Adults() == 2 &&
                        $$.policy.PolicyHolders()[1].MetaData.age() < $$.policy.MetaData.DefaultUnaccompaniedAge()))) {
                    window.openMessageBoxModal('WARNING',
                        $('#modal-unaccompanied-child').html(),
                        'Ok',
                        bulkQuotePost,
                        'Cancel',
                        function() {});
                    return;
                }
            }

            var defPrivModal = $$.Client.Util.Modal.PrivacyModal($$.policy);
            defPrivModal.promise().done(function() {
                bulkQuotePost();
            });
        }
    };

    var bulkQuotePost = function() {
        var multiTripOptions = null;
        if ($("#multiTripTab").parent().hasClass('active')) {
            multiTripOptions = { CoverLevelBriefCode: 'MULTI', CoverTypeBriefCode: 'POLLM' };
        }
        $$.fn.getBulkQuickQuote(true, true, false, multiTripOptions)
            .done(function() {
                var qs = (PrismApi.bulkQuickQuote.PricingLogId !== undefined &&
                    PrismApi.bulkQuickQuote.AccessCode !== undefined
                    ? 'id=' +
                    PrismApi.bulkQuickQuote.PricingLogId +
                    '&accessCode=' +
                    PrismApi.bulkQuickQuote.AccessCode +
                    '&session=true'
                    : 'session=true');

			    if (promoApplied() == true) {
			        window.top.location.href = $$.baseUrl + "QuickQuote?" + qs;
			    }
			})
			.fail($$.Client.displayError)
            .always(function() {
			    hideSpinner(this)
			});
    };

    var quickQuoteClick = function(control, suppressScroll, useSessionIfPossible) {

        var useSession = useSessionIfPossible && _session.policy;

        moveDataFromTempArray();

        var fatalFlag;
        if (ko.unwrap($$.policy.PeOptions) != null) {
            var totalHolders = $$.policy.MetaData.Adults() + $$.policy.MetaData.Dependants();
            if (totalHolders === 1 && $$.policy.PeOptions.FatalFlag() === true && PrismApi.nonMedical !== true) {
                fatalFlag = true;
            }
        }

        // reset max trip duration
        $$.policy.MaxTripDuration("");

        var doneFunction = function() {
            // show Privacy confirmation before showing plans
            // when land from aggregators, do not display agreement Declaration light box
            var promPriv = $.Deferred();
            if (window.localStorage.privacyAgree == "undefined" ||
                window.localStorage.privacyAgree == '' ||
                window.localStorage.privacyAgree == undefined) {
                $$.policy.MetaData.privacyAgree(false);
                promPriv = promPriv.resolve();
            } else {
                promPriv = $$.Client.Util.Modal.PrivacyModal($$.policy);
            }
            promPriv.promise().done(function() {

                // sort bulk premium
                $$.policy.MetaData.BulkPremiums($$.policy.MetaData.BulkPremiums().sort(
                    function(a, b) {
                        return parseFloat(a.Premium.SellingGross()) - parseFloat(b.Premium.SellingGross());
                    }));

                // load data to show
                $$.fn.getProductDescriptions().always(function() {
                    $$.fn.getPlanDescriptions().always(function() {
                        $$.fn.getProductBenefits().always(function() {
                            $$.fn.getPaymentOptions().always(function() {
                            });
                        });
                    });
                });

                // assign row index for product benefit			    
                $$.policy.MetaData.MaxProductBenefits.removeAll();
                $$.policy.MetaData.MaxProductBenefits.push(0);
                var maxProdBenefits = $$.policy.MetaData.MaxProductBenefits();
                var _accProductBenefit = 0;
                if (ko.isObservable($$.policy.MetaData.ProductBenefits)) {
                    for (var i = 0; i < $$.policy.MetaData.ProductBenefits().length; i++) {
                        _accProductBenefit = _accProductBenefit +
                            $$.policy.MetaData.ProductBenefits()[i].Benefits().length;
                        maxProdBenefits.push(_accProductBenefit);
                    }
                }
                $$.policy.MetaData.MaxProductBenefits.valueHasMutated();
                hideSpinner(this);

                if (fatalFlag) {
                    openModal($('#modal-peFatal .modal-header').html(), $('#modal-peFatal .modal-body').html(), true, false);
                    return;
                }

                $$.policy.MetaData.IsEditingTrip(false);
                $("#quickQuotePlans").fadeIn();
                if (!suppressScroll) {
                    $(document.body).animate({
                        'scrollTop': $('#quickQuotePlans').offset().top
                        },
                        500);
                }


                if ($("#multiTripTab").parent().hasClass("active")) {

                    $("is-single-plan").hide();
                    $("#endDate").attr('disabled', 'true');
                    $("#endDate").siblings().attr('disabled', 'true');
                } else {

                    $("is-single-plan").show();
                }
                $$.policy.MetaData.quoteIsInvalid(false);
            });
        };

        var callWebService = function(multiTripOptions) {
            $$.fn.getBulkQuickQuote(true, true, fatalFlag, multiTripOptions)
                .done(function() {
								    doneFunction();
								})
								.fail($$.Client.displayError)
                .always(function() {
								    hideSpinner(this)
								});
        };

        if (useSession) {
            doneFunction();
        } else {
            if (window.location.href.indexOf("accessCode=") < 0) {
                // show a warning to user if the first adult age is less than 13
                if ($$.policy.MetaData.Adults() > 0 &&
                    $$.policy.PolicyHolders()[0].MetaData.age() < $$.policy.MetaData.DefaultUnaccompaniedAge() &&
                    ($$.policy.MetaData.Adults() == 1 ||
                    ($$.policy.MetaData.Adults() == 2 &&
                        $$.policy.PolicyHolders()[1].MetaData.age() < $$.policy.MetaData.DefaultUnaccompaniedAge()))) {
                    window.openMessageBoxModal('WARNING',
                        $('#modal-unaccompanied-child').html(),
                        'Ok',
                        function() {
                            callWebService();
						},
                        'Cancel',
                        function() {
						});
                    return;
                }
            }

            var multiTripOptions = null;
            if ($("#multiTripTab").parent().hasClass('active')) {
                multiTripOptions = { CoverLevelBriefCode: 'MULTI', CoverTypeBriefCode: 'POLLM' };
            }
            callWebService(multiTripOptions);
        }
    };

    var promoApplied = function() {
        // if promo code has entered, check that bulk premium has promo code applied or not
        var dummyAdjustment = ko.utils.arrayFirst($$.policy.Adjustments(),
            function(adj) { return adj.BriefCode() == "DUMMY" && ko.unwrap(adj.Value) != null });
        var promApplied = false;
        if (dummyAdjustment) {
            for (var i = 0; i < PrismApi.bulkQuickQuote.BulkPremiums.length; i++) {
                var bulkPremium = PrismApi.bulkQuickQuote.BulkPremiums[i];
                if (bulkPremium.Plan.Adjustments != null) {
                    var adjustments = bulkPremium.Plan.Adjustments;
                    for (var j = 0; j < adjustments.length; j++) {
                        if (adjustments[j] != null &&
							adjustments[j].MetaData.InputBriefCode == dummyAdjustment.BriefCode() &&
							adjustments[j].Value == dummyAdjustment.Value()) {
                            promApplied = true;
                            if (promApplied)
                                break;
                        }
                    }
                }
            }
        } else {
            promApplied = true;
        }
        if (!promApplied) {
            openErrorModal("Validation Error",
                'The following items need to be checked before continuing:<br/><ul><li>' +
                PrismApi.Validation.messages.adjustments.invalidPromoCode +
                "</li></ul>");
        }
        return promApplied;
    }

    //OPTIONS SETUP
    var optionsSetup = function() {
        $("#optionsForm").each(function() {
            // backspace prevent
            //backClickOff();
            var self = this;

            $$.fn.getQuickQuoteOptions()
				.fail($$.Client.displayError)
                .done(function() {
				    afterQuickQuoteOptionsLoaded($$.quickQuoteOptions());
				    $$.Client.Util.setDefaultQuestions();

				});


            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }

            if (!(($$.policy.Benefits() && $$.policy.Benefits().length > 0) ||
                ($$.fullQuoteOptions.Questions && $$.fullQuoteOptions.Questions.length > 0))) {
                window.location.href = $$.baseUrl + "Travellers";
            }

            $$.fn.getProductDescriptions()
                .done(function() {
			    $$.fn.getProductBenefits()
                        .done(function() {
				    $$.fn.getOptionBenefits()
                                .done(function() {
                                    ko.utils.arrayForEach($$.policy.Benefits(),
                                        function(benefitItem) {
					        if (benefitItem.MetaData.IsEnabled() == true) {
					            benefitItem.MetaData.showDetail(true);
					        }
					    });
					    $$.fn.getTravellerOptions()
							.fail($$.Client.displayError)
                                        .done(function() {
							    //  translate titlegroups 
                                            $.each($$.policy.MetaData.AllTravellers(),
                                                function(index, item) {
							        fixTravellerTitle(item);
							    });
							    $$.policy.MetaData.TravellerOptionsReady(true);
							    $(self).fadeIn();
							    $('.quote-summary').fadeIn();
							});

					}).fail($$.Client.displayError)
				}).fail($$.Client.displayError)
			}).fail($$.Client.displayError)

            $(".spinner-bar").remove();

            //specified items
            var benefit = $$.policy.fn.getBenefit("SPITM");
            if (benefit) {
                var e = benefit.fn.hasBenefitItems() ? "#specifiedYes" : "#specifiedNo";
                $(e).attr("checked", "checked");
            }

            $(".btn-previous").click(function(e) {
                // navigate allow
                backClickOn();
                showSpinner($(this), 'spinner');
                window.location.href = $$.baseUrl + "QuickQuote?session=true";
            });

            $(".btn-next").click(function(e) {
                e.preventDefault();
                var self = this;

                // set timeouts to prevent script blocks
                var defValidate = $.Deferred();
                setTimeout(function() {
                    var pageErrorMessages = PrismApi.Validation.validatePolicyAgainstPage(PrismApi.policy);
                    defValidate.resolve();
                    },
                    0);
                defValidate.promise().done(function() {
                    setTimeout(function() {
                        if ($$.policy.errors.visibleMessages().length > 0) {
                                var apiError = new PrismApi.Data
                                    .ApiError(null, $$.policy.errors.visibleMessages(), null);
                            $$.Client.displayError(apiError);
                            return;
                        } else {

                            // navigate allow
                            backClickOn();
                            var spitm = PrismApi.Utils.arrayFirstBriefCode($$.policy.Benefits(), 'SPITM');
                            if (spitm) {
                                for (var i = 0; i < spitm.BenefitItems().length; i++) {
                                    var item = spitm.BenefitItems()[i];
                                    if ((!item.Name()) && (!item.Value())) {
                                        spitm.fn.removeBenefitItem(i);
                                    }
                                }
                            }

                            showSpinner($(self), 'spinner', true);
                            $(self).siblings('.spinner').addClass('pull-right');
                            $$.fn.getFullQuote(false, false)
                                    .done(function() {
								    window.location.href = $$.baseUrl + "Travellers";
                                    }).always(function() {
								    hideSpinner($(this));
								}).fail($$.Client.displayError);
                        }
                        },
                        0);
                });

                return true;
            });

            // Set any default answers to questions
            $$.Client.Util.setDefaultQuestions();

            // handle scroller for special page changes
            $(document).on("click",
                ".recalculate, .benefit-showhide",
                function() {
                //$('#divScroller').css({ top: 0 + 'px' });
                    setTimeout(function() {
                    if ($$.Client.Util.PostionQuoteSummary) {
                        $$.Client.Util.PostionQuoteSummary(false);
                    }
                        },
                        0);
                return true;
            });
        });
    };

    //TRAVELLERS SETUP
    var travellersSetup = function() {
        $("#travellersForm").each(function() {
            var self = this;
            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }
            if (ko.unwrap($$.policy.PeOptions) != null && $$.policy.PeOptions.FatalFlag != null) {
                $$.policy.PeOptions.FatalFlag(false);
            }


            $$.fn.getProductBenefits()
                .done(function() {
				    $$.fn.getOptionBenefits()
                        .done(function() {
                            ko.utils.arrayForEach($$.policy.Benefits(),
                                function(benefitItem) {
					        if (benefitItem.MetaData.IsEnabled() == true) {
					            benefitItem.MetaData.showDetail(true);
					        }
					    });

					}).fail($$.Client.displayError)
				}).fail($$.Client.displayError)

            var promQQOptions = $.Deferred();
            var promTravellerOptions = $.Deferred();

            $$.fn.getQuickQuoteOptions()
			.fail($$.Client.displayError)
                .done(function() {
			    afterQuickQuoteOptionsLoaded($$.quickQuoteOptions());
			    $$.Client.Util.setDefaultQuestions();

                }).always(function() {
			    promQQOptions.resolve();
			});

            $$.fn.getTravellerOptions()
			 .fail($$.Client.displayError)
                .done(function() {
			     //  translate titlegroups 
                    $.each($$.policy.MetaData.AllTravellers(),
                        function(index, item) {
			         fixTravellerTitle(item);
			     });
			     $$.policy.fn.FixTravellers();
			     $$.policy.MetaData.TravellerOptionsReady(true);
                }).always(function() {
			     promTravellerOptions.resolve();
			 });

            $.when.apply($, [promQQOptions, promTravellerOptions]).done(function() {
                $(self).fadeIn();
                $('.quote-summary').fadeIn();
                $(".spinner-bar").remove();
            });

            if (window.sessionStorage && window.sessionStorage['showManual'] !== undefined) {
                $('.address-manual').removeClass('hidden');
                $('.address-auto').addClass('hidden');
            }

            //for data prepop purposes, on the traveller details page if a name has been entered then a date of birth value 
            ko.utils.arrayForEach($$.policy.MetaData.AllTravellers(),
                function(traveller) {
                    if (window.sessionStorage && traveller.FirstName()) {
                        if (window.sessionStorage['Travellers[' + traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] !== undefined && window.sessionStorage['Travellers[' +traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] == "false") {

                        } else {
                            window.sessionStorage['Travellers[' + traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] = true;
                        }
                    }
                }
            );


            $(document).on('click',
                '.tt-footer > u',
                function() {
                $('.address-manual').removeClass('hidden');
                $('.address-auto').addClass('hidden');
            });

            $(".btn-previous").click(function(e) {
                showSpinner($(this), 'spinner');
                $$.fn.getFullQuote(false)
                    .done(function() {
                        if (($$.policy.Benefits() && $$.policy.Benefits().length > 0) ||
                            ($$.policy.MetaData.hasQuestionsForOptionPage())) {
					        window.location.href = $$.baseUrl + "Options";
					    } else {
					        window.location.href = $$.baseUrl + "QuickQuote?session=true";
					    }
					})
                    .always(function() {
					    hideSpinner($(this));
					})
					.fail($$.Client.displayError);
            });

            $(".btn-next").click(function(e) {
                e.preventDefault();
                var hasError = false;
                var PEYesTravellersNo = true;
                var numberTravellersPENo = 0;
                if ($$.policy.PeOptions.PESystem() !== null) {
                    if ($$.policy.MetaData.travellersHavePE() === undefined &&
                        $$.policy.MetaData.forceHasOtherTravellers() === false) {
                        if ($$.policy.MetaData.forceHasOtherTravellers() === false) {
                            openModal('Please complete a medical assessment',
                                '<p>Please advise if any traveller has a Pre-existing medical condition.</p>');
                            hasError = true;
                            PEYesTravellersNo = false;
                            return;
                        }
                    } else {
                        ko.utils.arrayForEach($$.policy.MetaData.AllTravellers(),
                            function(traveller) {
                            if (hasError === false) {
                                    if ($$.policy.MetaData.travellersHavePE() === true ||
                                        $$.policy.MetaData.travellersHavePE() === undefined) {
                                        if (traveller.MetaData.PeOptionsEnforced() === true &&
                                            ko.unwrap(traveller.HealixAssessment().ScreeningResult) === null) {
                                            openModal('Please complete a medical assessment',
                                                '<p>A Pre-existing medical condition assessment must be conducted for travellers aged ' + $$.policy.PeOptions.MetaData.MandatoryAssessmentAge() + ' or older.</p>');
                                        hasError = true;
                                        PEYesTravellersNo = false;
                                        return;
                                        } else {
                                            if (traveller.MetaData.HasPeCondition() === 'true' &&
                                                ko.unwrap(traveller.HealixAssessment().ScreeningResult) === null) {
                                            openModal('Please confirm the information you are providing about a pre-existing medical condition', '<p>You have answered "Yes" to ' + traveller.MetaData.FormattedName() + ' having a pre-existing medical condition(s); however you have not completed the medical assessment.</p><p>Please select the ‘Assess Now’ button to complete medical assessment.</p>');
                                            hasError = true;
                                            PEYesTravellersNo = false;
                                            return;
                                        }
                                    }
                                    if (traveller.MetaData.HasPeCondition() === 'false') {
                                        numberTravellersPENo = numberTravellersPENo + 1;
                                    }
                                }
                            }

                        });
                        if ($$.policy.MetaData.AllTravellers().count() === numberTravellersPENo &&
                            PEYesTravellersNo === true &&
                            $$.policy.MetaData.travellersHavePE() === true) {
                            openModal('Please confirm the information you are providing about a pre-existing medical condition', '<p>You have answered "Yes" to traveller(s) having a pre-existing medical condition(s); however you have not indicated which traveller(s) have these condition(s).</p><p>Please check and update the details you have entered before you can proceed.</p>');
                            hasError = true;
                        }

                        if (hasError) return;
                    }
                }

                // Set isModified on enteredDOB fields as the validation traversal won't 
                // traverse and observable in an observable unless it's in an array
                ko.utils.arrayForEach($$.policy.MetaData.AllTravellers(),
                    function(traveller) {
                    traveller.DateOfBirth.enteredDOB.isModified(true);
                        if (window.sessionStorage && traveller.FirstName()) {
                            window
                                .sessionStorage['Travellers[' + traveller.MetaData.TravellerIndex + '].HasEnteredDOB'] =
                                true;
                        }
                });

                showSpinner($(this), 'spinner', true);
                $(this).siblings('.spinner').addClass('pull-right');
                $$.fn.getFullQuote(false, true)
                    .done(function() {
					    window.location.href = $$.baseUrl + "Payment";
					})
                    .always(function() {
					    $('.spinner').hide();
					})
					.fail($$.Client.displayError);
            });

            // set datepicker min max date restrictions
            var adultType = $$.Client.datepicker.getType("_dobAdults");
            var dependantType = $$.Client.datepicker.getType("_dobDependants");

            var restrictSameYearRangeForTraveller = function(input) {
                var today = new Date();
                var birthYear = today.getFullYear() - $(input).data('age');
                return {
                    changeYear: true,
                    changeMonth: true,
                    minDate: new Date(birthYear - 1, today.getMonth(), today.getDate() + 1),
                    maxDate: new Date(birthYear, today.getMonth(), today.getDate())
                };
            };
            adultType.options = restrictSameYearRangeForTraveller;
            dependantType.options = restrictSameYearRangeForTraveller;
        });
    };


    var backClickOff = function() {
        // prevent navigating away from page
        window.onbeforeunload = function(e) {
            if (e && e.preventDefault)
                e.preventDefault();
            return 'Are you sure you want to cancel your travel insurance purchase? By continuing all current information will be lost.';
        }
        // bind buttons to ignoe this rule
        $(document).on('click',
            '.ignoreNavigationPrevention',
            function(e) {
            backClickOn();
        });
    };

    var backClickOn = function() {
        // clear back/reload prevention
        window.onbeforeunload = null
    };


    //pe-Fatal SETUP
    var peFatalSetup = function() {
        $("#peFatalForm").each(function() {
            var self = this;
            backClickOn();
            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }

            $$.fn.getQuickQuoteOptions()
                .fail($$.Client.displayError)
                .done(function() {
                    afterQuickQuoteOptionsLoaded($$.quickQuoteOptions());
                    $$.Client.Util.setDefaultQuestions();
                });

            $$.fn.getProductBenefits()
                .done(function() {
				    $$.fn.getOptionBenefits()
                        .done(function() {
                            ko.utils.arrayForEach($$.policy.Benefits(),
                                function(benefitItem) {
					        if (benefitItem.MetaData.IsEnabled() == true) {
					            benefitItem.MetaData.showDetail(true);
					        }
					    });

					}).fail($$.Client.displayError)
				}).fail($$.Client.displayError);


            $$.fn.getTravellerOptions()
				.fail($$.Client.displayError)
                .done(function() {
				    //  translate titlegroups 
                    $.each($$.policy.MetaData.AllTravellers(),
                        function(index, item) {
				        fixTravellerTitle(item);
				    });
				    $$.policy.MetaData.TravellerOptionsReady(true);
				    $(".spinner-bar").remove();
				    $(self).fadeIn();
				    $('.quote-summary').fadeIn();
				});

            $(".btn-no").click(function(e) {
                $(".btn-next").prop('disabled', true);
                $('.spinner').show();
                $$.policy.PeOptions.FatalFlag(false);
                $$.fn.retrieveHealixAssessment()
                    .done(function() {
					       window.location.href = $$.baseUrl + "PreExisting/Screening";
					   })
                    .always(function() {
					       hideSpinner($(this));
					   })
                    .fail(function(status) {
						     if (status && status.StatusCode && status.StatusCode === 200) {
						         window.location.href = $$.baseUrl + "PreExisting/Screening";
						     } else {
						         $$.Client.displayError
						         $(".btn-next").prop('disabled', false);
						     }
						 });
            });

            $(".btn-yes").click(function(e) {
                $(".btn-next").prop('disabled', true);
                $('.spinner').show();
                $$.policy.PeOptions.FatalFlag(true);
                $$.fn.persistAssessment()
                    .done(function() {
					    window.location.href = $$.baseUrl + "PreExisting/Assessment";
					})
                    .always(function() {
					    hideSpinner($(this));
					})
                    .fail(function(status) {
					     if (status && status.StatusCode && status.StatusCode === 200) {
					         window.location.href = $$.baseUrl + "PreExisting/Assessment";
					     } else {
					         $$.Client.displayError
					         $(".btn-next").prop('disabled', false);
					     }
					 });
            });
        });
        $("#myModal").on("shown.bs.modal",
            function() {
                $("#modal-peFatal").each(function() {

                    if ($$.policy != null &&
                        ko.unwrap($$.policy.PeOptions) != null &&
                        $$.policy.PeOptions.FatalFlag() == true &&
                        $$.policy.PeOptions.PeFatalQuestion() == null) {
                    $$.fn.retrieveHealixFatalCondition();
                }
                    $(".btn-no").click(function(e) {
                    $$.policy.PeOptions.FatalFlag(false);

                    $$.fn.persistAssessment()
                            .done(function() {
						    quickQuoteClick();
						})
                            .always(function() {
						    hideSpinner($(this));
						})
                            .fail(function(status) {
						     if (status && status.StatusCode && status.StatusCode === 200) {
						         quickQuoteClick();
						     } else {
						         $$.Client.displayError
						     }
						 });
                });

                    $(".btn-yes").click(function(e) {
                    $$.policy.PeOptions.FatalFlag(true);
                    PrismApi.nonMedical = true;
                    $$.fn.persistAssessment()
                            .done(function() {
					       quickQuoteClick();
					   })
                            .always(function() {
					       hideSpinner($(this));
					   })
                            .fail(function(status) {
					       if (status && status.StatusCode && status.StatusCode === 200) {
					           quickQuoteClick();
					       } else {
					           $$.Client.displayError
					       }
					   });
                });
            });
        });
    };

    var backspaceOverride = function(event) {
        var doPrevent = false;
        if (event.keyCode === 8) {
            var d = event.srcElement || event.target;
            if ((d.tagName.toUpperCase() === 'INPUT' &&
                    (d.type.toUpperCase() === 'TEXT' || d.type.toUpperCase() === 'PASSWORD')) ||
                d.tagName.toUpperCase() === 'TEXTAREA') {
                doPrevent = d.readOnly || d.disabled;
            } else {
                doPrevent = true;
            }
        }

        if (doPrevent) {
            event.preventDefault();
        }
    };

    //Data Prepopulation SETUP
    var dataPrepopulationSetup = function() {
        if (_session.MaskingSettings != null) {
            //Setting the departure date for the policy and ensuring validation is enforced.
            var coverageInceptionDate = $$.policy.StartDate();
            $$.policy.StartDate(null);
            $$.policy.StartDate(coverageInceptionDate);
        }
    };
   
    //Healix SETUP
    var healixSetup = function () {
        $("#healixForm").each(function () {
            var self = this;
            // backspace prevent
            backClickOff();
            $(".progress-item").removeClass("ignoreNavigationPrevention");

            $(document).off('keydown').on('keydown', backspaceOverride);
            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }

            $$.fn.getQuickQuoteOptions()
                .fail($$.Client.displayError)
                .done(function () {
                    afterQuickQuoteOptionsLoaded($$.quickQuoteOptions());
                    $$.Client.Util.setDefaultQuestions();
                });

            $$.fn.getProductBenefits()
				.done(function () {
				    $$.fn.getOptionBenefits()
					.done(function () {
					    ko.utils.arrayForEach($$.policy.Benefits(), function (benefitItem) {
					        if (benefitItem.MetaData.IsEnabled() == true) {
					            benefitItem.MetaData.showDetail(true);
					        }
					    });

					}).fail($$.Client.displayError)
				}).fail($$.Client.displayError);



            $$.fn.getTravellerOptions()
				.fail($$.Client.displayError)
				.done(function () {
				    //  translate titlegroups 
				    $.each($$.policy.MetaData.AllTravellers(), function (index, item) {
				        fixTravellerTitle(item);
				    });
				    $$.policy.MetaData.TravellerOptionsReady(true);
				    $(self).fadeIn();
				    $(".spinner-bar").remove();
				});

            /* healix Tabs ***********/
            $(".tab_contents").hide();
            var tabLinks = $('#tabHealix li');
            // Add active class, could possibly go in markup
            // Show all active tabs
            $('ul.nav-tabsh li a').each(function () {
                var target = $(this).attr('href');
                $(target).hide();
            });
            tabLinks.eq(0).addClass('active');


            $('ul.nav-tabsh li.active a').each(function () {
                var target = $(this).attr('href');
                $(target).addClass('active').addClass('in');
                $(target).show();
            });
            // Hide all .tab-content divs
            $("#mainDivHealix").fadeIn();
            $('.quote-summary').fadeIn();
            $('iframe', this).each(function () {
                keepAlive();
                window.healixAlive = setInterval(keepAlive, keepAliveInterval * 1000 * 60);
            });

            $('.btn-change').on('click', function () {
                // healix frames prevent opendialog being overriden for openmodalmessage
                if (openModalFunction)
                    window.openModal = openModalFunction;
            });
        });
    };

    //Pre-result SETUP
    var healixResultSetup = function () {
        $("#healixResultForm").each(function () {
            // backspace prevent
            backClickOff();

            // Stop navigation on recalc
            $$.policy.MetaData.PreventNavigationOnRecalc(true)

            $(document).off('keydown').on('keydown', backspaceOverride);
            $(".progress-item").removeClass("ignoreNavigationPrevention");

            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }

            $$.fn.getProductBenefits()
				.done(function () {
				    $$.fn.getOptionBenefits()
					.done(function () {
					    ko.utils.arrayForEach($$.policy.Benefits(), function (benefitItem) {
					        if (benefitItem.MetaData.IsEnabled() == true) {
					            benefitItem.MetaData.showDetail(true);
					        }
					    });

					}).fail($$.Client.displayError)
				}).fail($$.Client.displayError);

            // now Get titles for lookup to display Persons name details
            $(".spinner-bar").remove();
            $("#healixResultForm").fadeIn();
            $('.quote-summary').fadeIn();
            $$.fn.getTravellerOptions()
            .fail($$.Client.displayError)
            .done(function () {
                //  translate titlegroups 
                $.each($$.policy.MetaData.AllTravellers(), function (index, item) {
                    item.MetaData.FormattedName = getTravellerNameComputed(item);
                    fixTravellerTitle(item);
                });
                $$.policy.MetaData.TravellerOptionsReady(true);
            });


            var traveller = -1;
            var dependant = -1;
            $.each($$.policy.PolicyHolders(), function (index, item) {
                
                if (item.HealixAssessment() && item.HealixAssessment().PeId() == 1) {
                    traveller = index;
                    window.localStorage.removeItem('Traveller' + (index + 1).toString() + 'PeAccepted');
                    item.HealixAssessment().MetaData.ResetSelectPremium = function () {
                        item.HealixAssessment().MetaData.SelectPremium.isModified(false);
                    };
                }
            });
            $.each($$.policy.PolicyDependants(), function (index, item) {
                
                if (item.HealixAssessment() && item.HealixAssessment().PeId() == 1) {
                    dependant = index;
                    window.localStorage.removeItem('Dependant' + (index + 1).toString() + 'PeAccepted');
                }
            });


            $("#healixResultForm").on('click', '.peResultPeOptOut', function (e) {
                processDeclined(this, '#modal-peOptOut');
            });
            $("#healixResultForm").on('click', '.peResultDeclineOption', function (e) {
                processDeclined(this, '#modal-peDeclineOption');
            });
            var processDeclined = function (el, modelId) {
                var element = $(el);
                var data = ko.dataFor(el);
                var value = element.val();
                // display PE declined warning 
                openMessageBoxModal('Warning', $(modelId).html(),
					'Ok', function () {
					    var modal = $('#myModal');
					    $("#okcancel", modal).hide();
					},
					'Cancel', function () {
					    data.MetaData.IsEnabled(undefined);
					    data.MetaData.IsEnabled.isModified(false);//reset the value
					    $("input[type=radio]").removeAttr('checked').removeClass('checked');
					}
				);
            };


            $(".btn-next").click(function (e) {
                showSpinner($(this), 'spinner');
                // set timeouts as to not block scripts when validating or 
                var defValidate = $.Deferred();
                setTimeout(function () {
                    // dirty Date of Births for validation incase a new traveller added, done here instead of add so input not marked invalid immediately
                    $.each($$.policy.MetaData.AllTravellers(), function (index, item) {
                        //dirty PE questions
                        if (item.HealixAssessment()) {
                            item.HealixAssessment().MetaData.IsEnabled.isModified(true);
                        }
                    });
                    $$.policy.errors.showAllMessages();
                    var pageErrorMessages = PrismApi.Validation.validatePolicyAgainstPage(PrismApi.policy);
                    defValidate.resolve();
                }, 0);
                defValidate.promise().done(function () {
                    setTimeout(function () {
                        if ($$.policy.errors.visibleMessages().length > 0) {
                            var apiError = new PrismApi.Data.ApiError(null, $$.policy.errors.visibleMessages(), null);
                            $$.Client.displayError(apiError);
                            return;
                        } else {

                            backClickOn();
                            if (window.localStorage) {
                                // search through travellers and dependants for healix accepted
                                if (traveller > -1) {
                                    window.localStorage['Traveller' + (traveller + 1).toString() + 'PeAccepted'] = true;
                                }
                                else if (dependant > -1) {
                                    window.localStorage['Dependant' + (dependant + 1).toString() + 'PeAccepted'] = true;
                                }
                            }
                            $('.spinner').show();
                            // indicate in meta data for traveller PE data finalised
                            $.each(PrismApi.policy.PolicyHolders(), function (index, value) {
                                $$.policy.fn.updateScreeningSessionResult(value, '.spinner', "b2c", "Travellers");
                            });

                            $.each(PrismApi.policy.PolicyDependants(), function (index, value) {
                                $$.policy.fn.updateScreeningSessionResult(value, '.spinner', "b2c", "Travellers");
                            });
                        }
                    }, 0);
                });
                e.preventDefault();
                return true;
            });
            // lock down links/buttons
            $('.progress-new .button').off('click').attr('onclick', '').attr('target', '').attr('href', '#');
            $('.logo a').off('click').attr('onclick', '').attr('target', '').attr('href', '#');

            $('.btn-change').on('click', function () {
                // healix frames prevent opendialog being overriden for openmodalmessage
                if (openModalFunction)
                    window.openModal = openModalFunction;
            });
        });

    };

    //PAYMENT SETUP
    var paymentSetup = function () {
        $("#paymentForm").each(function () {
            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }

            $.when.apply($, [
                $$.fn.getQuickQuoteOptions(),
                $$.fn.getTravellerOptions(),
                $$.fn.getOptionBenefits(),
                $$.fn.getPaymentOptions()
            ]).done(function () {
                var selectedPaymentOption = $$.policy.fn.getPaymentOption();
                if (selectedPaymentOption.takesCreditCard) {

                    if (selectedPaymentOption.PCIStrategy === "OnePayHostedFields") {

                        $$.Client.Util.HostedFields = {
                            validateOnEvents: ["blur", "stateChanged"],
                            getFieldMappedValidators: function () {
                                var fieldMappedValidators = {};
                                fieldMappedValidators[PaymentService.config.cardNumber.id] = "isCardNumberValid";
                                fieldMappedValidators[PaymentService.config.securityCode.id] = "isSecurityCodeValid";
                                return fieldMappedValidators;
                            },
                            handleFieldEvent: function (event) {
                                if ($.inArray(event.eventType, $$.Client.Util.HostedFields.validateOnEvents) > -1) {
                                    var validatorName = $$.Client.Util.HostedFields.getFieldMappedValidators()[event.field.id];
                                    $$.policy.CreditCard.MetaData.HostedFields[validatorName](event.field.state === "valid");
                                }

                                if (event.field.id === PaymentService.config.securityCode.id) {
                                    $$.policy.CreditCard.CardSecurityCode(event.field.state === "empty" ? "" : "***");
                                }
                            },
                            handleCardTypeChanged: function (event) {
                                $$.policy.CreditCard.CardNumber(event.panMask);
                                $$.policy.CreditCard.CardType($$.payment.cardType(event.panMask));
                            }
                        };

                        var merchantId = $$.policy.MetaData.MerchantId;
                        $$.fn.createPaymentSession(merchantId).done(function (session) {

                            var defaultStyle = { fontFamily: 'Arial', color: '#555555', fontSize: '12px', padding: '0' };

                            PaymentService.configure({
                                url: session.BaseUrl,
                                styles: {
                                    default: defaultStyle,
                                    success: defaultStyle,
                                    error: defaultStyle
                                },
                                cardNumber: { placeholder: '' },
                                securityCode: { placeholder: '' },
                                onFieldEvent: $$.Client.Util.HostedFields.handleFieldEvent,
                                onCardTypeChangeEvent: $$.Client.Util.HostedFields.handleCardTypeChanged,
                            }).then(function () {

                                $$.policy.CreditCard.MetaData.HostedFields.isEnabled(true);
                                $$.policy.CreditCard.PaymentSessionId(session.SessionId);
                                console.log("hosted payment fields initialized successfully")
                                $('.quote-summary').fadeIn();
                                $("#paymentForm").fadeIn();
                                $(".spinner-bar").remove();

                            }).catch(function (error) {
                                console.log("failed to initialize hosted payment fields - " + error.message);
                                $$.Client.displayError(new PrismApi.Data.ApiError(500, null, "Failed to initialize hosted payment fields.", null, error.message));
                            });

                        }).fail($$.Client.displayError);

                    } else {
                        $$.payment.fn.updateCardTypes();

                        $('#cc_number').payment('formatCardNumber');
                        $('#cc_number').on('payment.cardType', function (a, b) {
                            var cardType = b === 'unknown' ? undefined : b;
                            $$.policy.CreditCard.CardType(cardType);
                        });
                        $('.quote-summary').fadeIn();
                        $("#paymentForm").fadeIn();
                        $(".spinner-bar").remove();
                    }

                    $$.policy.CreditCard.CardType.subscribe(function (a, b, c) {
                        applyCreditCardPromo($$.policy);
                        $$.policy.MetaData.isRecalculating(true);
                        $$.fn.getFullQuote(false, false, false)
                            .always(function () {
                                $$.policy.MetaData.isRecalculating(false);
                            });
                    });
                }

                afterQuickQuoteOptionsLoaded($$.quickQuoteOptions());
                $$.Client.Util.setDefaultQuestions();

                $.each($$.policy.MetaData.AllTravellers(), function (index, item) {
                    fixTravellerTitle(item);
                });
                $$.policy.MetaData.TravellerOptionsReady(true);

                ko.utils.arrayForEach($$.policy.Benefits(), function (benefitItem) {
                    if (benefitItem.MetaData.IsEnabled() == true) {
                        benefitItem.MetaData.showDetail(true);
                    }
                });
            })
                .fail($$.Client.displayError);

            $(".btn-previous").click(function (e) {
                window.location.href = $$.baseUrl + "travellers";
            });

            $(".btn-purchase").click(function () {
                setTimeout(function () {
                    var errorMessages = PrismApi.fn._validatePolicy();
                    if (errorMessages.length > 0) {
                        var apiError = new PrismApi.Data.ApiError(null, errorMessages, null);
                        $$.Client.displayError(apiError);
                        return;
                    }

                    // default timeout to 5 minutes
                    var ajaxTimeout = 300000;
                    if (apiAjaxTimeout)
                        ajaxTimeout = apiAjaxTimeout;
                    $.ajaxSetup({ timeout: ajaxTimeout });

                    applyCreditCardPromo($$.policy);

                    var purchaseFn = function () {
                        openPurchaseModal();
                        $$.fn.purchase()
                            .done(function () {
                                window.location.href = $$.baseUrl + "receipt";
                            })
                            .fail(function (error, reason) {
                                $('#myModal').on('hidden.bs.modal', function () {
                                    $('#myModal').off('hidden.bs.modal');
                                    if (reason === "timeout") {
                                        // clear session data as the user should not be allowed to resubmit
                                        $$.Client.Util.resetSessionData();
                                        // any click should send user back to quick quote  (apart from contact page link)
                                        $(document).on('click', function () {
                                            window.location.href = $$.baseUrl;
                                        });
                                    }
                                    $$.Client.displayError(error);
                                });
                                hideModal();
                            });
                    };

                    var selectedPaymentOption = $$.policy.fn.getPaymentOption();
                    if (selectedPaymentOption.takesCreditCard) {
                        var cardInformation = {
                            expiryMonth: $$.policy.CreditCard.CardExpiryMonth(),
                            expiryYear: $$.policy.CreditCard.CardExpiryYear(),
                            cardHolderName: $$.policy.CreditCard.CardHolder()
                        };

                        if (selectedPaymentOption.PCIStrategy === "OnePayHostedFields") {
                            PaymentService.submit(cardInformation)
                                .then(function () {
                                    console.log("credit card information submit successfully via hosted payment fields");
                                    purchaseFn();
                                })
                                .catch(function (error) {
                                    console.log("failed to submit credit card information - " + error.message);
                                    $$.Client.displayError(new PrismApi.Data.ApiError(422, null, "An error occurred processing your payment. We have not processed a payment and you have not been charged. Please try again."));
                                });
                        } else {
                            purchaseFn();
                        }
                    }

                }, 0);
                return true;
            });
        });
    };

    var applyCreditCardPromo = function (viewModel) {

        //First, clear out any credit card promos
        ko.utils.arrayForEach($$.paymentOptions()[0].CreditCardTypes, function (card) {
            var adjustment = ko.utils.arrayFirst(viewModel.Adjustments(), function (item) {
                return ko.unwrap(item.BriefCode) == card.AdjustmentType;
            });

            if (adjustment) {
                adjustment.Value(null);
            }
        });
        //Put the first part of the credit card into the adjustment specified in the card type
        var card = ko.utils.arrayFirst($$.paymentOptions()[0].CreditCardTypes, function (card) {
            return card.BriefCode == viewModel.CreditCard.CardType();
        });
        if (card && card.AdjustmentType) {
            var adjustment = ko.utils.arrayFirst(viewModel.Adjustments(), function (item) {
                return ko.unwrap(item.BriefCode) == card.AdjustmentType;
            });

            if (adjustment) {
                if (viewModel.CreditCard.CardNumber()) {
                    adjustment.Value(viewModel.CreditCard.CardNumber().substr(0, 6));
                } else {
                    adjustment.Value('123456');
                }
            }
        }
    }

    var prepareShowFeature = function () {
        if ($(this).width() >= 480) {
            fixBenefitTable();
            $('.features-div').hide();
            $('.icon-plus').show();
            $('.icon-minus').hide();
        }
    };

    //CONFIRMATION SETUP
    var confirmationSetup = function () {
        $("#confirmationForm").each(function () {
            // backspace prevent
            backClickOff();

            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }
            $(this).fadeIn();
            $(".spinner-bar").remove();

            $(".purchase-path > div.button").not('.home')
				.removeClass("is-clickable")
				.click(function () {
				    return false;
				});

            $("#btn-print").click(function () {
                $$.fn.getDocument($$.policy.ClientReference());
            });

            $(".purchase-path .home").attr('onclick', 'window.location.href=$$.baseUrl');
            if (window.localStorage)
                window.localStorage.clear();
        });
    };
    var faqSetup = function () {
        $("#faqs-init").each(function () {
            $('.faq-question').click(function () {          // Attach behavior
                $(this).children(":first").toggleClass('fa-minus');   // Swap the icon
                $(this).next().toggle();                    // Hide/show the text
            });
        });
    };

    var quoteSummarySetup = function () {
        $$.Client.Util.initialiseQuoteSummaryScroller();
        // check for travellers that have pe show warning before allowing quickquote navigation
        $(document).on('click', '.quote-summary .btn-change', function () {
            var foundPE = false;
            $.each($$.policy.PolicyHolders(), function (index, item) {
                if (item.MetaData.HasPeCondition() === 'true')
                    foundPE = true;
            });
            $.each($$.policy.PolicyDependants(), function (index, item) {
                if (item.MetaData.HasPeCondition() === 'true')
                    foundPE = true;
            });
            if (foundPE) {
                window.openMessageBoxModal('WARNING', PrismApi.Validation.messages.warningPEChange,
				   'Ok', function () {
				       window.location.href = $$.baseUrl + "QuickQuote?session=true";
				   },
				   'Cancel', function () {
				   });
                return;
            } else {
                window.location.href = $$.baseUrl + "QuickQuote?session=true";
                return;
            }
        });

        checkWidthQuickQuote('.quote-summary', '#quote-summary-body', true);

        $(window).resize(function () {
            checkWidthQuickQuote('.quote-summary', '#quote-summary-body');
        });
    };

    //INITIALIZE PRISM API
    (function () {
        //SESSION HANDLING
        $("#quickQuoteForm").each(function () {
            //Clear policy in session if the server hasn't supplied it.
            if (!_session.policy) {
                $$.Client.Util.resetSessionData();
            }

            _session.fullQuoteOptions = undefined;

        });

        $$.fn.init()
			.done(function () {
			    $$.Client.Util.setupSessionExpiryHandler();
			    quickQuoteSetup();
			    saveQuoteSetup();
			    optionsSetup();
			    fixQuestionItems();
			    travellersSetup();
			    peFatalSetup();
			    healixSetup();
			    healixResultSetup();
			    paymentSetup();
			    confirmationSetup();
			    commonSetup();
			    faqSetup();
			    quoteSummarySetup();
			    bootstrapSetup();
			    dataPrepopulationSetup();
			})
			.fail($$.Client.displayError);
    })();


});;
/* 
 * Name: B2C-validation-messages.js
 * Description: Override PrismApi.Validation.Messages and shared-validation-messages extend with new messages for B2C
 *
 */
var PrismApi = PrismApi || {};
PrismApi.Validation = PrismApi.Validation || {};
PrismApi.Validation.messages = $.extend({}, PrismApi.Validation.messages, {
    // overwrite the API error messages
    requiredEndDate: 'Please enter your return date.',
    requiredStartDate: 'Please enter your departure date.',
    dateShouldBeAfterToday: '{1} cannot be earlier than today.', /* fieldname */
    startDateIsAfterEndDate: 'Return date cannot be earlier than the Departure date.',
    requiredEmailDocuments: "You must agree to receive the PDS and Certificate of Insurance by email before continuing.If you would like to update your email then please return to the Your Details screen.",
    equalTruePrivacyAgree: "You must agree to having your personal information collected.",
    warningPEChange: 'By choosing to change your quote you will be required to conduct the Pre-Existing Medical assessment again for each traveller that has a Pre-Existing medical condition.'
});
PrismApi.Validation.messages.payment = $.extend({}, PrismApi.Validation.messages.payment, {
    // overwrite the API error messages
    requiredCardType: "Please enter your payment card type.",
    requiredCardNumber: "Please enter your credit card number.",
    requiredCardHolderName: "Please enter the name on your credit card.",
    requiredCardMonth: "Please select the credit card expiry month.",
    requiredCardYear: "Please select the credit card expiry year.",
    requiredCVV: "Please enter the credit card CVV value.",
    creditCardNotValid: "Please enter a valid credit card.",
    CVVLength: "Please enter a valid credit card CVV value.",
    CVVNumber: "Please enter a valid credit card CVV value."
});

;
