/* Minification failed. Returning unminified contents.
(2878,32-37): run-time error JS1137: 'catch' is a new reserved word and should not be used as an identifier: catch
(2983,36-41): 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(); });

    $("#singleTripTab").click(function () {
        if (typeof HideQuickQuotePlans === 'function') HideQuickQuotePlans();
        $("#endDate").removeAttr('disabled');
        $("#endDate").siblings().removeAttr('disabled');
        if (sessionStorage)
            sessionStorage.multiSelected = false;
        $("#singleTripTab").parent().removeClass("active");
        $("#singleTripTab").parent().addClass("active");
        $("#multiTripTab").parent().removeClass("active");
        $(".quoteTabBottomRight").removeClass('quoteTabBottomRightMulti');
        if (sessionStorage && sessionStorage.tempUserEndDate)
            $$.policy.EndDate(sessionStorage.tempUserEndDate);
    });

    $("#multiTripTab").click(function () {
        if (sessionStorage)
            sessionStorage.tempUserEndDate = $$.policy.EndDate();
        if (typeof HideQuickQuotePlans === 'function') HideQuickQuotePlans();
        $("#endDate").attr('disabled', 'true');
        $("#endDate").siblings().attr('disabled', 'true');
        if (sessionStorage)
            sessionStorage.multiSelected = true;

        $("#multiTripTab").parent().removeClass("active");
        $("#multiTripTab").parent().addClass("active");
        $("#singleTripTab").parent().removeClass("active");
        $(".quoteTabBottomRight").addClass('quoteTabBottomRightMulti');
        $$.fn.calculateMultiTripEndDate();
    });

    $(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) {
        var spinnerBar = "<img class=\"spinner-bar\" src=\"{0}Content/img/ajax-loader-bar.gif\" />".format(PrismApi.baseUrl);
        var spinner = "<img class=\"spinner\" style=\"padding: 6px\" src=\"{0}Content/img/ajax-loader-small.gif\" />".format(PrismApi.baseUrl);
        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() {
    $('#quickQuotePlans').hide();
    $$.policy.fn.updateQuickQuoteAssessment();
    return true;
}

function RemoveValidationElement(e) {
    var o = e.currentTarget;
    console.log(o);
    $(o).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...');
    $('.spinner').show();
    $$.fn.getFullQuote(false, doPageValidation, performRescore)
        .fail($$.Client.displayError)
        .always(function() {
              hideSpinner($(this))
        }
    );
}

//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.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;
        }
        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; })
                }
                if (questionToDefault && answerToDefault) {
                    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)) {
            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 () {
        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) {
                //console.log("summary height: " + currentQuoteDiv.height() + "scrolltop: " + $(window).scrollTop() + " window height: " + $(window).height() + " doc height: " + $(document).height())
                if ($(document).width() > 768) {
                    scrollCurrentQuote(true, force);
                }
            };
            $$.Client.Util.PostionQuoteSummary = positionQuoteSummary;
            $(window).scroll(function () { positionQuoteSummary(false); });
            positionQuoteSummary(true);
           
        }
    };

    function currentQuoteEndRequest(sender, args) {
        currentQuoteDiv = $('#divScroller');
        scrollCurrentQuote(false);
	
    }

    function scrollCurrentQuote(animate, force) {
        if (force === true) {
            currentQuoteDiv.css({ top: 0 + 'px' });
        }
        currentQuoteDiv.stop(true, false);
        var scrollTop = $(window).scrollTop();
        var offset = scrollTop > currentQuoteOffset ? scrollTop - currentQuoteOffset : 0;
        var notAtBottom = ($(window).scrollTop() + $('#divScroller').height() + $("#footer").height() + 20) < $(document).height();
        if (!notAtBottom) {
            offset = $(document).height() - ($('#divScroller').height() + $("#footer").height() + 220);
            notAtBottom = true;
        }

        //if ((!notAtBottom || force === true) && (offset + $('#divScroller').height() + $("#footer").height() + 20) > $(window).height()) {
        //    console.log("existing: " + offset);
        //    offset = ($(document).height() - ($('#divScroller').height() + $("#footer").height() + 420));
        //    offset = offset < 200 ? currentQuoteOffset : offset;
        //    console.log("new: " + offset);
        //}
        if (notAtBottom || force === true) {
            if (animate) {
                currentQuoteDiv.animate({ top: (offset > 10 ? offset + 20 : offset) + 'px' }, 'slow');
            }
            else {
                currentQuoteDiv.css('top', offset + 'px');
            }
        }
    }

})(jQuery);;
/*=============
PRISM API SETUP
==============*/
$("document").ready(function () {

    //AJAX SPINNERS
    var spinner = "<img class=\"spinner\" src=\"{0}Content/img/ajax-loader-small.gif\" />".format(PrismApi.baseUrl);
    var spinnerBar = "<img class=\"spinner-bar\" src=\"{0}Content/img/ajax-loader-bar.gif\" />".format(PrismApi.baseUrl);

    $$.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': 'prism.apiError',
                    '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': 'prism.apiError',
                    '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': 'prism.apiError',
                    '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': 'prism.apiError',
                        '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;
            }
        }

        PrismApi.Utils.logError(apiError);

        dataLayer.push({
            'event': 'prism.apiError',
            'eventCategory': 'PRISM API Unexpected Error',
            'eventAction': "An error has occurred.",
        });

        //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, viewModel.MetaData.Partner().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

        $$.baseUrl = $$.policy.MetaData.Partner().SiteUrl;

        $$.policy.StartDate.subscribe(function (newValue) {
            //If we are in multi-trip, recalculate the end date using the api.
            if ($("#multiTripTab").parent().hasClass('active')) {
                $$.fn.calculateMultiTripEndDate();
            } else {
                var newDate = Date.create(newValue);
                // set end date to + 1 day
                $$.policy.EndDate(newDate.advance({ days: 1 }).format(Date.ISO8601_DATE));
            }
        });

        //Set start / end date validation
        $$.policy.StartDate.formattedDate.rules(ko.utils.arrayFilter($$.policy.StartDate.formattedDate.rules(), function (data) {
            return data.rule !== "required";
        }));
        $$.policy.StartDate.formattedDate.extend({
            required: {
                params: true, message: PrismApi.Validation.messages.requiredStartDate
            }
        });
        $$.policy.EndDate.formattedDate.rules(ko.utils.arrayFilter($$.policy.EndDate.formattedDate.rules(), function (data) {
            return data.rule !== "moreThan";
        }));
        $$.policy.EndDate.formattedDate.extend({
            moreThan: {
                params: function () {
                    return $$.policy.StartDate() == null ? new Date() : $$.policy.StartDate;
                }, message: PrismApi.Validation.messages.startDateIsAfterEndDate
            }
        });

        if (_session.quickQuote && _session.quickQuote.BulkPremiums) {
            PrismApi.bulkQuickQuote = _session.quickQuote;
            PrismApi.policy.fn.applyBulkPremiumsToViewModel();
        }

        if ($$.policy.PartnerCode() && $$.policy.PartnerCode() != $$.policy.MetaData.Partner().PartnerCode) {
            window.location.href = $$.baseUrl + "QuickQuote";
        }

        $$.policy.PartnerCode($$.policy.MetaData.Partner().PartnerCode);

        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) } });
            }
        }

        viewModel.MetaData.RecalculateTimer = ko.observable();

        // throttle getFullQuote to prevent multiple ajax calls
        ko.computed(function () {
            var options = viewModel.MetaData.RecalculateTimer();
            if (options !== undefined) {
                // reset recalculate timer
                viewModel.MetaData.RecalculateTimer(undefined);
                // 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);
                    }, $$.Client.Util.ThrottleTime);
                } else {
                    $$.fn.getFullQuote(false, options.doPageValidation, options.performRescore)
                        .fail(typeof (options.displayError) == "function" ? options.displayError : $$.Client.displayError);
                }
            }
        }).extend({ throttle: $$.Client.Util.ThrottleTime });

        // Disabled navigation buttons when recalculating
        viewModel.MetaData.PreventNavigationOnRecalc = ko.observable(false);

        viewModel.MetaData.MaxProductBenefits = ko.observableArray();

        // 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.AdultAges = ko.observableArray();
        viewModel.MetaData.DependantAges = ko.observableArray();

        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);
            }
        }

        /* Set Date of birth validation min max rule to match quoted age */
        $.each(viewModel.PolicyHolders(), function (index, item) {
            var today = new Date();
            var birthYear = today.getFullYear() - item.MetaData.age();
            item.DateOfBirth.formattedDate.extend({
                min: {
                    params: function () {
                        var minDate = new Date(birthYear - 1, today.getMonth(), today.getDate() + 1);
                        return minDate;
                    }, message: PrismApi.Validation.messages.travellers.invalidDobRange
                }, max: {
                    params: function () {
                        var maxDate = new Date(birthYear, today.getMonth(), today.getDate() + 1);
                        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) {
                        resetHealixForTraveller(item);
                        window.localStorage.removeItem('Traveller' + (index + 1).toString() + 'PeAccepted');
                    }
                }
            });
            item.MetaData.FormattedName = getTravellerNameComputed(item, "Adult", index);
        });
        $.each(viewModel.PolicyDependants(), function (index, item) {
            var today = new Date();
            var birthYear = today.getFullYear() - item.MetaData.age();
            item.DateOfBirth.formattedDate.extend({
                min: {
                    params: function () {
                        var minDate = new Date(birthYear - 1, today.getMonth(), today.getDate() + 1);
                        return minDate;
                    }, message: PrismApi.Validation.messages.travellers.invalidDobRange
                }, max: {
                    params: function () {
                        var maxDate = new Date(birthYear, today.getMonth(), today.getDate() + 1)
                        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) {
                        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) } });
            }
        }

        viewModel.fn.addDependant = function () {
            var customer = new PrismApi.Data.Customer(null, 'dependant');

            // override max age validation for dependant in quick quote form
            ko.utils.arrayForEach(customer.MetaData.age.rules(), function (r) {
                if (r.rule == "max") {
                    r.message = function () { return PrismApi.Validation.messages.travellers.invalidDependantMaxAge.format(customer.MetaData.MaxAge(), customer.MetaData.MaxAge() + 1); };
                }
            });
            viewModel.MetaData.DependantAges.push(customer);
        };

        while (viewModel.MetaData.DependantAges().length < 2) {
            viewModel.fn.addDependant();
        }

        //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 () {
                    // adjust detail visiblility based on checkbox
                    benefit.MetaData.showDetail(newValue);
                }, 0);
            }, benefit);
            // extend benefit to have a show/hide benefit detail
            benefit.MetaData.showDetail = ko.observable(false);
            benefit.MetaData.IsEnabled.subscribe(function (newValue) {
                var benefit = this;
                if (benefit.BriefCode() === 'SNOW') {
                    if (ko.utils.arrayFirst((benefit.MetaData.IsPerAdultOnly ? $$.policy.PolicyHolders() : $$.policy.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()));
                            }
                            RecalculateQuoteImmediate();

                        }, 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()));
                            }
                            RecalculateQuoteImmediate();

                        }, benefit);
                    }
                }
                else {
                    RecalculateQuoteImmediate(false);
                }
                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 ? $$.policy.PolicyHolders() : $$.policy.MetaData.AllTravellers();
                }
                return [];
            }, benefit).extend({ throttle: $$.Client.Util.ThrottleTime });
        }

        $$.Client.serviceUrls.HealixPersistScreening = ($$.policy.MetaData.Partner().SiteUrl && $$.policy.MetaData.Partner().SiteUrl.length > 0 ? $$.policy.MetaData.Partner().SiteUrl.substring(0, $$.policy.MetaData.Partner().SiteUrl.length - 1) : "") + $$.Client.serviceUrls.HealixPersistScreening;

        // 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
        $$.policy.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 (window.localStorage.travellersHavePE) {
                    window.localStorage.travellersHavePE = 'false';
                }
            }

            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);
                RecalculateQuoteImmediate(false, false, true);
            }
        });
    };

    //HEALIX INTEGRATION
    $$.Client.showHealixAssessment = function (self, value) {

        var okFunction = function () {
            var modal = $('#myModal');
            $(this).removeAttr('data-dismiss');

            $("#okcancel", modal).hide();
            if ($$.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');
                    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';
        }

        var minDate = Date.create(PrismApi.Client.todayDateString).getDateOnly();

        $("#startDate").mobiscroll().date({ theme: 'ios7', dateFormat: defaultDateFormat, dateOrder: defaultDateOrder, display: defaultDisplay, showLabel: defaultshowLabel, onBeforeShow: beforeShowFunc, onSelect: setEndYearFunc, minDate: minDate });
        $("#endDate").mobiscroll().date({ theme: 'ios7', dateFormat: defaultDateFormat, dateOrder: defaultDateOrder, display: defaultDisplay, showLabel: defaultshowLabel, onBeforeShow: beforeShowFunc, minDate: minDate });

        $("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 = "_startDate";
                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) {
            var today = new Date();
            var birthYear = today.getFullYear() - $(input).data('age');
            return {
                minDate: new Date(birthYear - 1, today.getMonth(), today.getDate() + 1),
                maxDate: new Date(birthYear, today.getMonth(), today.getDate())
            };
        };
        var restrictToSameYearOptionsDependant = function (input) {
            var today = new Date();
            var birthYear = today.getFullYear() - $(input).data('age');
            return {
                minDate: new Date(birthYear - 1, today.getMonth(), today.getDate() + 1),
                maxDate: new Date(birthYear, today.getMonth(), today.getDate())
            };
        };
        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;

                item.options.minDate = Date.create(PrismApi.Client.todayDateString).getDateOnly();
                item.options.maxDate = Date.create(PrismApi.Client.todayDateString).advance({ day: -1, year: 1 }).getDateOnly();

                if (item.key === '_startDate') {
                    item.options.yearRange = "-0:+1";
                } else {
                    item.options.yearRange = "-0:+2";
                    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 = Date.create($$.policy.StartDate());
                            endDateOption.maxDate = new Date(currentStartDate.getFullYear() + 1, currentStartDate.getMonth(), currentStartDate.getDate() - 1)
                            $(".endDate").datepicker("destroy");
                            $(".endDate").datepicker(endDateOption);
                            $(".endDate").datepicker('show');
                            $(".endDate").focus();
                        }, 100);
                    }
                };
            }
        });

        $$.Client.datepicker.apply_jQueryUIDatepickers();
    }

    //COMMON SETUP
    var commonSetup = function () {
        //ToolTips
        $(document).on('click', '.tooltip-image', 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 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 {
                $(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);
        }
    }

    //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(null);
            $$.policy.CoverEndDate(null);

            $$.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();
                    $$.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(','));
                            }
                            if ($$.policy.errors.visibleNotValidMessages().length == 0) {
                                var useSession = $$.policy.MaxTripDuration() ? false : true;
                                quickQuoteClick(null, true, useSession);
                            }
                            hideSpinner();

                        })
                })
                .always(function () {
                    // 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');
                    quickQuoteClick();
                } 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();
                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');
                                    if (sessionStorage)
                                        sessionStorage.tempUserEndDate = $$.policy.EndDate();
                                    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 () {
                    var premium = ko.utils.unwrapObservable($$.policy.Premium().SellingGross);
                    if (premium == null || !isNaN(parseFloat(premium))) {
                        $(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 () {
                                // 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 newEndDate = PrismApi.Utils.formattedStringToDate($$.policy.StartDate()).advance({ year: 1, day: -1 });
                                    $$.policy.EndDate(newEndDate.format(Date.ISO8601_DATE));
                                }

                                $$.fn.getFullQuoteOptions()
                                    .done(function () {
                                        if (($$.policy.Benefits() && $$.policy.Benefits().length > 0) || ($$.fullQuoteOptions.Questions && $$.fullQuoteOptions.Questions.length > 0)) {
                                            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);
                    }
                });
            });
            // restore session for privacy agreement if set
            if (window.localStorage && window.localStorage.privacyAgree) {
                $$.policy.MetaData.privacyAgree(true);
            }

            $(".btn-previous").click(function (e) {
                // navigate allow
                backClickOn();
                showSpinner($(this), 'spinner');
                window.location.href = $$.baseUrl;
            });

        });
    };

    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) {
            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) {
            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();
            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');

                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 ($$.policy.PeOptions) {
            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
            var promPriv = $$.Client.Util.Modal.PrivacyModal();
            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;
                }

                $("#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();
                }
                // load plan descriptions to show 
                $$.fn.getPlanDescriptions().done(function () {
                }).fail($$.Client.displayError).always(function () {
                });

            });
        };

        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 () {
                            $$.fn.getBulkQuickQuote(true, true, fatalFlag)
                                .done(function () {
                                    doneFunction();
                                })
                                .fail($$.Client.displayError)
                                .always(function () {
                                    hideSpinner(this)
                                });
                        },
                        'Cancel', function () {
                        });
                    return;
                }
            }

            var multiTripOptions = null;
            if ($("#multiTripTab").parent().hasClass('active')) {
                multiTripOptions = { CoverLevelBriefCode: 'MULTI', CoverTypeBriefCode: 'POLLM' };
            }
            $$.fn.getBulkQuickQuote(true, true, fatalFlag, multiTripOptions)
                .done(function () {
                    doneFunction();
                })
                .fail($$.Client.displayError)
                .always(function () {
                    hideSpinner(this);
                });
        }
    };

    //OPTIONS SETUP
    var optionsSetup = function () {
        $("#optionsForm").each(function () {
            // backspace prevent
            backClickOff();
            var self = this;
            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)

            $$.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)

            $(".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 scoller for special page changes
            $(document).on("click", ".recalculate, .benefit-showhide", function () {
                //$('#divScroller').css({ top: 0 + 'px' });
                setTimeout(function () {
                    $$.Client.Util.PostionQuoteSummary(true);
                }, 0);
                return true;
            });
        });
    };

    //TRAVELLERS SETUP
    var travellersSetup = function () {
        $("#travellersForm").each(function () {
            var self = this;
            if (!$$.fullQuoteOptions) {
                $$.Client.Util.sessionTimeoutHandler();
                return;
            }
            if ($$.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());
                }).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();
            });

            $(document).on('click', '.tt-footer > u', function () {
                $('.address-manual').removeClass('hidden');
                $('.address-auto').addClass('hidden');
            });

            if ($$.policy.Address.MetaData.FullAddress.isValid != undefined) {
                $$.policy.Address.MetaData.FullAddress.isValid.subscribe(function (val) {
                    window.sessionStorage["FullAddress"] = val ? $('#address').val() : '';
                });
            }
            $(".btn-previous").click(function (e) {
                showSpinner($(this), 'spinner');
                $$.fn.getFullQuote(false)
                    .done(function () {
                        if (($$.policy.Benefits() && $$.policy.Benefits().length > 0) || ($$.fullQuoteOptions.Questions && $$.fullQuoteOptions.Questions.length > 0)) {
                            window.location.href = $$.baseUrl + "Options";
                        } else {
                            window.location.href = $$.baseUrl + "";
                        }
                    })
                    .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
                $.each($$.policy.MetaData.AllTravellers(), function (index, item) {
                    item.DateOfBirth.enteredDOB.isModified(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 {
                    minDate: new Date(birthYear - 1, today.getMonth(), today.getDate() + 1),
                    maxDate: new Date(birthYear, today.getMonth(), today.getDate())
                };

            };
            adultType.options = restrictSameYearRangeForTraveller;
            dependantType.options = restrictSameYearRangeForTraveller;
        });
    };

    //Pre-existing eVIVA SETUP
    var peSetup = function () {
        $("#peForm").each(function () {

            $(this).fadeIn();
            $(".spinner-bar").remove();

            /* Pe Tabs ***********/

            // Hide all .tab-content divs
            $('.tab-content').hide();

            // Show all active tabs
            $('ul.tab-header li.active a').each(function () {
                var target = $(this).attr('href');
                $(target).show();
            });

            // Add click eventhandler
            $('ul.tab-header li').each(function () {
                $(this).click(function () {
                    var item = $(this);
                    var target = item.find('a').attr('href');

                    item.siblings().each(function () {
                        if ($(this).hasClass("active")) {
                            $(this).removeClass('active');
                            $(this).addClass("complete");
                        }
                    });
                    item.addClass('active');

                    item.parents('.box').find('.tab-content').hide();
                    $(target).show();

                    if (UserHasReadAllPeTabs()) {
                        $("#next").removeAttr('disabled');
                        $("#next").removeClass('disabled');
                        $(".pe-form").fadeIn();
                        $('.body-wrapper').animate({ scrollTop: $("ul.tab-header").offset().top }, 1000);
                    }

                    return false;
                });
            });

            //pe button next
            $(".preexisting-next").click(function () {
                if (!UserHasReadAllPeTabs()) {
                    $('.tab-header').find('li:not(.complete):not(.active)').first().click();
                    return false;
                }
                if (!PeDropdownsAreValid()) {
                    window.TravelApi.displayError("Answer YES or NO for each traveller before continuing.");
                    return false;
                }
                return true;
            });


            $(".btn-previous").click(function (e) {
                $$.fn.getFullQuote(false)
                    .done(function () {
                        if ($$.policy.Benefits() && $$.policy.Benefits().length > 0) {
                            window.location.href = $$.baseUrl + "Travellers/";
                        } else {
                            window.location.href = $$.baseUrl;
                        }
                    })
                    .fail($$.Client.displayError);
            });

            $(".btn-next").click(function (e) {
                e.preventDefault();
                $('.spinner').show();
                $$.fn.getFullQuote(false, true)
                    .done(function () {
                        window.location.href = $$.baseUrl + "Payment";
                    })
                    .always(function () {
                        hideSpinner($(this));
                    })
                    .fail($$.Client.displayError);
            });
        });

        function UserHasReadAllPeTabs() {
            var hasReadAll = true;
            $(".tab-header li").each(function () {
                if (!$(this).hasClass("complete") && !$(this).hasClass("active")) {
                    hasReadAll = false;
                }
            });
            if (!hasReadAll) {
                return false;
            }
            return true;
        }

        function PeDropdownsAreValid() {
            var dropdowns = $(".peDropdown");
            for (var i = 0; i < dropdowns.length; i++) {
                //if is visible and value is empty
                if ($(dropdowns[i]).parents(".travellerRow").is(":visible") && $(dropdowns[i]).val() == "") {
                    return false;
                }
            }
            return true;
        }

    };

    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.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();
                });

            $$.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)


            $(".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 && $$.policy.PeOptions && $$.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();
        }
    };
    //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.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();
                });


            $$.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)

            /* 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("fai.led 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) {
                        //TODO both these are not functions
                        //applyCreditCardPromo($$.policy); TODO applicable to defence?
                        //$$.policy.MetaData.isRecalculating(true); TODO applicable to defence?
                        $$.fn.getFullQuote(false, false, false)
                            .always(function () {
                                //$$.policy.MetaData.isRecalculating(false); TODO applicable to defence?
                            });
                    });
                }

                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);      //TODO applicable to defence?

                    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 () {
                                    window.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 prepareShowFeature = function () {
        if ($(this).width() >= 480) {
            fixBenefitTable();
            $('.features-div').hide();
            $('.icon-plus').show();
            $('.icon-minus').hide();
        }
    };

    //CONFIRMATION SETUP
    var confirmationSetup = function () {
        $("#confirmationForm").each(function () {

            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 () {
            //ALWAYS clear policy in session UNLESS specified through querystring: ?session=true.
            if (!(/^true$/i).test($$.Utils.getQueryString("session"))) {
                $$.Client.Util.resetSessionData();
            }

            _session.fullQuoteOptions = undefined;

            // restore PrismApi.policy, PrismApi.regionCountries and PrismApi.bulkQuickQuote from session storage
            if (typeof (Storage) !== "undefined" && sessionStorage.length > 0) {
                console.log("restore data from session storage.")

                if (sessionStorage.regionCountries) {
                    _session.regionCountries = JSON.parse(sessionStorage.regionCountries);
                }

                if (sessionStorage.tempUserEndDate && $("#singleTripTab, #multiTripTab").length == 0)
                    _session.policy.EndDate = sessionStorage.tempUserEndDate;

                if (sessionStorage.multiSelected == 'true') {
                    $("#singleTripTab").parent().removeClass();
                    $("#multiTripTab").parent().removeClass().addClass('active');
                    $(".quoteTabBottomRight").addClass('quoteTabBottomRightMulti');
                }
                else {
                    $("#multiTripTab").parent().removeClass();
                    $("#singleTripTab").parent().removeClass().addClass('active');
                }

                _session.multiSelected = sessionStorage.multiSelected;
                // sessionStorage.clear();
            }
        });

        $$.fn.init()
            .done(function () {
                $$.Client.Util.setupSessionExpiryHandler();
                quickQuoteSetup();
                optionsSetup();
                fixQuestionItems();
                travellersSetup();
                peSetup();
                peFatalSetup();
                healixSetup();
                healixResultSetup();
                paymentSetup();
                confirmationSetup();
                commonSetup();
                faqSetup();
                quoteSummarySetup();
                bootstrapSetup();
            })
            .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."
});
PrismApi.Validation.messages.travellers = $.extend({}, PrismApi.Validation.messages.travellers, {
    // B2C only entry of traveller dob on traveller details page 
    invalidTravellerDOB: "Please enter a date of birth that reflects the quoted age of the traveller. Alternatively please update quote.",
    invalidDependantMaxAge: "The maximum age for a dependant when purchasing online is {0} years old. If your dependant is aged {1} years or over, call us to get a quote."
});;
