/* Minification failed. Returning unminified contents.
(1125,13-14): run-time error JS1005: Expected '(': {
(1136,5-7): run-time error JS1006: Expected ')': if
(1136,5-7): run-time error JS1008: Expected '{': if
(1136,85): run-time error JS1004: Expected ';'
(1397,37-38): run-time error JS1005: Expected '(': {
(1398,33-39): run-time error JS1009: Expected '}': window
(1398,33-39): run-time error JS1006: Expected ')': window
(1398,33-39): run-time error JS1008: Expected '{': window
(1398,39-40): run-time error JS1195: Expected expression: .
(1756,13-14): run-time error JS1005: Expected '(': {
(1759,1-2): run-time error JS1006: Expected ')': }
(1759,1-2): run-time error JS1008: Expected '{': }
(3260,1): run-time error JS1009: Expected '}'
(3260,1): run-time error JS1107: Expecting more source characters
(1739,1-28): run-time error JS1301: End of file encountered before function is properly closed: function InitializePaypal()
(3260,1): run-time error JS1107: Expecting more source characters
(1083,1-26): run-time error JS1301: End of file encountered before function is properly closed: function paymentOptions()
(3260,1): run-time error JS1107: Expecting more source characters
(1427,13,1452,14): run-time error JS1314: Implicit property name must be identifier: onInit(data, actions) {

                // using onInit might overwrite anything named 'data' later..
                // Disable the buttons
                actions.disable();


                // Listen for changes to the checkbox

                $('#customer-payment-form').find('select,input').on('change', function () {

                    let form = document.getElementById('customer-payment-form');

                    if (form.checkValidity() === false) {
                        // This is the magic function that displays the validation errors to the user
                        //form.reportValidity();
                        actions.disable();
                        return;

                    } else {
                        actions.enable();
                    }

                })

            }
(1456,12,1465,14): run-time error JS1314: Implicit property name must be identifier: onClick() {

               let form = document.getElementById('customer-payment-form');

               if (form.checkValidity() === false) {
                   // This is the magic function that displays the validation errors to the user
                   form.reportValidity();
                   return;
               }
            }
 */
/* =========== Plugin Initializers =========== */


$(document).ready(function () {
    /*Svg lib that allows using svgs externally and load them inline*/
    svg4everybody();

    /*Initialises IE9 placeholder polyfill*/
    $('input, textarea').placeholder();

    /*Initialises datepicker polyfill*/
    /*format is for what the user sees, formatsubmit is how it's handled in the back*/
    /*the data-value should be set on the input with the date in the formatSubmit format */
    $('input[type="date"]').pickadate({
        format: 'dd-mmm-yyyy',
        formatSubmit: 'yyyy/mm/dd'
    });

    window.cookieconsent.initialise({
        "palette": {
            "popup": {
                "background": "#193040"
            },
            "button": {
                "background": "#ffffff",
                "text": "#000000"
            }
        },
        "position": "top",
        "static": true,
        "content": {
            "message": "We use cookies and similar technologies on our website to enable some essential functions for you.",
            "dismiss": "I UNDERSTAND",
            "href": "/info/privacy-policy"
        }
    });
});

/*Helper Function Section*/

/* Fades an element in and out visually but keeps it in place */
(function ($) {
    $.fn.invisible = function (duration, display) {
        return this.each(function () {
            $(this).stop(true, false).animate({
                opacity: 0
            }, duration, function(){
            });
        });
    };
    $.fn.visible = function (duration, display) {
        return this.each(function () {
            $(this).animate({
                opacity: 1
            }, duration);
        });
    };
} (jQuery));
;
function checkPostCode(toCheck) {
    // Permitted letters depend upon their position in the postcode.
    var alpha1 = "[abcdefghijklmnoprstuwyz]";                       // Character 1
    var alpha2 = "[abcdefghklmnopqrstuvwxy]";                       // Character 2
    var alpha3 = "[abcdefghjkpmnrstuvwxy]";                         // Character 3
    var alpha4 = "[abehmnprvwxy]";                                  // Character 4
    var alpha5 = "[abdefghjlnpqrstuwxyz]";                          // Character 5

    // Array holds the regular expressions for the valid postcodes
    var pcexp = [];

    // Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
    pcexp.push(new RegExp("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1,2})(\\s*)([0-9]{1}" + alpha5 + "{2})$", "i"));

    // Expression for postcodes: ANA NAA
    pcexp.push(new RegExp("^(" + alpha1 + "{1}[0-9]{1}" + alpha3 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$", "i"));

    // Expression for postcodes: AANA  NAA
    pcexp.push(new RegExp("^(" + alpha1 + "{1}" + alpha2 + "{1}" + "?[0-9]{1}" + alpha4 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$", "i"));

    // Exception for the special postcode GIR 0AA
    pcexp.push(/^(GIR)(\s*)(0AA)$/i);

    // Standard BFPO numbers
    pcexp.push(/^(bfpo)(\s*)([0-9]{1,4})$/i);

    // c/o BFPO numbers
    pcexp.push(/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);

    // Overseas Territories
    pcexp.push(/^([A-Z]{4})(\s*)(1ZZ)$/i);

    // Anguilla
    pcexp.push(/^(ai-2640)$/i);

    // Load up the string to check
    var postCode = toCheck;

    // Assume we're not going to find a valid postcode
    var valid = false;

    // Check the string against the types of post codes
    for (var i = 0; i < pcexp.length; i++) {
        if (pcexp[i].test(postCode)) {

            // The post code is valid - split the post code into component parts
            pcexp[i].exec(postCode);

            // Copy it back into the original string, converting it to uppercase and inserting a space
            // between the inward and outward codes
            postCode = RegExp.$1.toUpperCase() + " " + RegExp.$3.toUpperCase();

            // If it is a BFPO c/o type postcode, tidy up the "c/o" part
            postCode = postCode.replace(/C\/O\s*/, "c/o ");

            // If it is the Anguilla overseas territory postcode, we need to treat it specially
            if (toCheck.toUpperCase() == 'AI-2640') { postCode = 'AI-2640'; }

            // Load new postcode back into the form element
            valid = true;

            // Remember that we have found that the code is valid and break from loop
            break;
        }
    }

    // Return with either the reformatted valid postcode or the original invalid postcode
    if (valid) { return postCode; } else return false;
}
;
"use strict";
/*
    Product variant selection
    In here we keep all the selection and update logic for the product page

    For variants:
     * There's a json object for all the possible variations in the product template
     * When something is selected, we match that selection to a product from the json object
*/
/*Constants*/
var ID = 'Id';
var VARIATIONS = 'Variations';
var TYPE = 'Type';
var AMOUNT = 'Amount';
var POPUP_PARAMS = {
    type: 'image',
    preloader: true,
    mainClass: 'mfp-with-zoom',
    zoom: {
        enabled: true,
        duration: 300,
        easing: 'ease-in-out'
    }
};

$(document).ready(function () {
    if (typeof selectedProduct === 'undefined' || typeof variants === 'undefined') {
        return;
    }

    loadSlick(selectedProduct);
    $('#product-image').magnificPopup(POPUP_PARAMS);

    $('#product-title').on('copy', function (e) {
        $('#product-title-popover').collapse('show');
    });

    /* Variant selectors */
    $('div.select-variant').on('click', function () {
        if ($(this).hasClass('disabled')) {
            return;
        }
        var selectedType = $(this).data('type');
        var selectedId = $(this).data('id');
        $('.select-variant.selected').removeClass('selected');
        $(this).addClass('selected');
        selectVariant(selectedType, selectedId);
    });

    $('input.select-variant').on('change', function () {
        var selectedType = $(this).data('type');
        var selectedId = $(this).data('id');
        selectVariant(selectedType, selectedId);
    });

    $('select.select-variant').on('change', function () {
        var selectedType = $(this).find(':selected').data('type');
        var selectedId = $(this).find(':selected').data('id');
        selectVariant(selectedType, selectedId);
    });

    /* Essential selectors, updates price with the selected options*/
    $('input.select-essential').on('change', function () {
        var Price = parseFloat($(this).data('price'));
        var Id = $(this).data('id');
        var Id2 = $(this).val();
        var Selected = $(this).prop('checked');

        var changed = false;
        for (var i = 0; i < selectedEssentials.length; i++) {
            if (selectedEssentials[i][ID] == Id) {
                changed = true;
                if (Selected) {
                    selectedEssentials[i][AMOUNT] = Price;
                } else {
                    selectedEssentials.splice(i, 1);
                }
            }
        }
        if (!changed) {
            selectedEssentials.push({ Id: Id, Amount: Price });
        }
        renderProduct();
    });

    $(document).on('change mouseup', '#product-quantity', function () {
        var priceInfo = getPriceObject();
        renderPrice(priceInfo.Price, selectedProduct.Discontinued);
    });

    //Takes an object, composed of the node and id attributes
    //Node is used to get the ID and select an image
    //ID is used to select an image as backup
    function selectProductImage(attr) {
        $('.product-image.selected').removeClass('selected');
        var imageId = $(attr.node).data('id');
        if (imageId === undefined) {
            imageId = attr.id;
        }

        var selectedForImage = getImageSelectionProduct();
        var selectedImage = matchProduct(selectedForImage);

        var imageTemplate = _.template($('#product-image-template').html());
        $('#product-image-container').html(
            imageTemplate({
                Image: selectedImage.Gallery[imageId]
            })
        );

        //main image zoom selector
        $('#product-image').magnificPopup(POPUP_PARAMS);
        $(attr.node).addClass('selected');
    }

    function loadSlick(product) {
        //unload slick slider before reloading it
        if (window.ImageSlick != null) {
            $('.product-images').slick('unslick');
            var thumbnailTemplate = _.template($('#product-thumbnails-template').html());
            $('#product-thumbnails-container').html(
                thumbnailTemplate({
                    Product: product,
                })
            );
        }

        var imageCount = product.Gallery.length;
        window.ImageSlick = $('.product-images').slick({
            slidesToShow: 6,
            slidesToScroll: 1,
            variableWidth: true,
            prevArrow: '.image-control.previous',
            nextArrow: '.image-control.next',
            dots: false,
            focusOnSelect: true,
            swipeToSlide: true,
            infinite: true,
            responsive: [
                {
                    breakpoint: 1570,
                    settings: {
                        slidesToShow: 3
                    }
                },
                {
                    breakpoint: 1170,
                    settings: {
                        slidesToShow: 2
                    }
                }
            ]
        });
        $('.product-images').on('afterChange', function (event, slick, nextSlide) {
            selectProductImage({ node: slick.$slides[nextSlide], id: nextSlide });
        });
    }

    /*Select Product Variant*/
    /*Called when a field is changed/clicked, uses global variables defined in the page
     to fill in and change price, images, stock etc*/
    function selectVariant(type, id, input) {
        var multiSelect = _.contains(multiSelectType, type);
        //If the input we selected (or deselected) has multiple
        //  selections of the same type we need to handle
        //  updating the selected object differently
        var alreadySelected = false;

        if (multiSelect) {
            for (var i = 0; i < selected.length; i++) {
                if (selected[i][ID] == id) {
                    selected.splice(i, 1);
                    alreadySelected = true;
                    break;
                }
            }
        } else {
            for (var j = 0; j < selected.length; j++) {
                if (selected[j][TYPE] == type) {
                    selected[j][ID] = id;
                    alreadySelected = true;
                    break;
                }
            }
        }

        if (!alreadySelected) {
            selected.push({ Id: id, Type: type });
        }

        var selectedForImage = getImageSelectionProduct();

        selectedProduct = matchProduct(selected);
        var selectedImage = matchProduct(selectedForImage);

        loadSlick(selectedImage);
        validateVariations();

        //update the product page from the selected product
        $('#product-title').html(selectedProduct.UppercaseTitle);
        $('#product-sku').html(selectedProduct.SageSKU);

        //Stock view updated from template,
        var stockTemplate = _.template($('#product-stock-template').html());
        $('#product-stock-container').html(
            stockTemplate({
                Product: selectedProduct,
            })
        );

        $('#product-image').each(function (i) {
            selectProductImage({
                id: 0
            });
        });

        renderProduct();

        if (selectedProduct.Prices.length > 1) {
            var template = _.template($('#pricebreaks-template').html());
            $('#pricebreaks-wrapper').html(
                template({ Prices: selectedProduct.Prices })
            );
            $('#pricebreaks-wrapper').closest('.product-options').show();
        } else {
            $('#pricebreaks-wrapper').closest('.product-options').hide();
        }
    }

    //Counts down the time until 2pm on weekdays
    if (typeof countdownTime !== 'undefined') {
       window.countdownMoment = moment(window.countdownTime, 'hh:mm:ss');
        var currentDay = moment(countdownTime, 'hh:mm:ss').weekday();
        setInterval(function () {
            window.countdownMoment.subtract(1, 'seconds');
            $('.hours .countdown').html(window.countdownMoment.hour());
            $('.minutes .countdown').html(window.countdownMoment.minute());
            $('.seconds .countdown').html(window.countdownMoment.seconds());
            if (currentDay != window.countdownMoment.weekday()) {
                $('#countdown-container').hide();
            }
        }, 1000);
    } else {
        window.countdownMoment = null;
    }

    renderProduct();

    //Makes a copy of the Selected array without any multiselect Types
    function getImageSelectionProduct() {
        return window.selected.filter(function (item) {
            return !_.contains(multiSelectType, item[TYPE]);
        });
    }

    function getPriceObject() {
        var prices = selectedProduct.Prices;
        var quantity = parseInt($('#product-quantity').val()) || 1;
        var price = 0;
        //Get the appropriate price break for the inputted quantity
        for (var i = 0; i < prices.length; i++) {
            if (prices[i].Quantity <= quantity) {
                price = prices[i].Amount;
            } else {
                break;
            }
        }
        price *= quantity;

        //Add up the selectedEssentials prices if they're available
        if (typeof selectedEssentials !== 'undefined') {
            for (var j = 0; j < selectedEssentials.length; j++) {
                price += selectedEssentials[j].Amount;
            }
        }
        return {
            Price: price,
            Quantity: quantity
        };
    }

    //Updates the price field based on the globals prices[],
    //  selectedProduct{} and quantity input field
    function renderProduct() {
        var priceInfo = getPriceObject();

        renderPrice(priceInfo.Price, selectedProduct.Discontinued);
        renderAddToBasket(priceInfo.Quantity, priceInfo.Price, selectedProduct);
        renderPreReleaseBox(selectedProduct);
        renderQuantityBox(priceInfo.Quantity, priceInfo.Price, selectedProduct);
        renderCountdown(priceInfo.Price, selectedProduct);
    }

    function renderPrice(Price, Discontinued) {
        var priceTemplate = _.template($('#product-price-template').html());
        $('#product-price-container').html(
            priceTemplate({
                Price: Price,
                Discontinued: Discontinued
            })
        );
    }
    
    function renderAddToBasket(Quantity, Price, Product) {
        var productTemplate = _.template($('#add-to-basket-template').html());
        $('#add-to-basket-container').html(
            productTemplate({
                Quantity: Quantity,
                Price: Price,
                Product: Product
            })
        );
    }
    
    function renderPreReleaseBox(Product) {
        var preReleaseTemplate = _.template($('#unavailable-template').html());
        $('#unavailable-container').html(
            preReleaseTemplate({ Product: Product })
        );
    }

    function renderQuantityBox(Quantity, Price, Product) {
        var quantityTemplate = _.template($('#product-quantity-template').html());
        $('#product-quantity-container').html(
            quantityTemplate({
                Quantity: Quantity,
                Price: Price,
                Product: Product
            })
        );
    }

    function renderCountdown(Price, Product) {
        if ($('#countdown-template').get(0) !== undefined) {
            var countdownTemplate = _.template($('#countdown-template').html());
            $('#countdown-container').html(
                countdownTemplate({
                    Price: Price,
                    Product: Product
                })
            );
        }
    }

    //Takes a list of objects with Id and Type values, compares them with
    // variants and returns a matching variant on success. null on failure
    //The number of objects must match
    function matchProduct(variations) {
        for (var i = 0; i < variants.length; i++) {
            //Prevents a Mag from matching up with Mag + Mifare upgrade, for example
            if (variations.length != variants[i][VARIATIONS].length) {
                continue;
            }

            var match = true;
            for (var j = 0; j < variations.length; j++) {
                var innerMatch = false;
                for (var k = 0; k < variants[i][VARIATIONS].length; k++) {
                    if (variants[i][VARIATIONS][k][ID] == variations[j][ID]) {
                        innerMatch = true;
                        break;
                    }
                }
                //If the current ID doesn't match we'll exit early
                if (!innerMatch) {
                    match = false;
                    break;
                }
            }

            if (match) {
                return variants[i];
            }
        }
        return null;
    }

    //Goes through all the fields and checks if there is a variant that matches
    // the current selection. Then disables any variations with no variant match
    function validateVariations() {
        //reset the disabled state of our fields
        $('.select-variant .disabled, .select-variant.disabled, .variation-clip.disabled').each(function () {
            $(this).removeClass('disabled');
            $(this).prop('disabled', false);
        });

        //If we were to check another box we'll try to match that
        // up with a product; if unuccessful we disable it
        for (var i = 0; i < variationList.length; i++) {
            var multiSelect = _.contains(multiSelectType, variationList[i][TYPE]);

            //skip already selected variations
            var alreadySelected = function () {
                for (var j = 0; j < selected.length; j++) {
                    if (selected[j][ID] === variationList[i][ID]) {
                        return true;
                    }
                }
                return false;
            }();

            if (alreadySelected) {
                upgradeVariationPrice(variationList[i]);
                continue;
            }

            var matchedProduct;
            var selectedCopy = JSON.parse(JSON.stringify(selected));
            if (multiSelect) {
                matchedProduct = matchProduct(
                    selectedCopy.concat(
                        [{ Id: variationList[i][ID], Type: variationList[i][TYPE] }]
                    )
                );
            } else {
                for (var j = 0; j < selectedCopy.length; j++) {
                    if (selectedCopy[j][TYPE] == variationList[i][TYPE]) {
                        selectedCopy[j][ID] = variationList[i][ID];
                        break;
                    }
                }
                matchedProduct = matchProduct(selectedCopy);
            }

            toggleVariation(variationList[i], matchedProduct);
            upgradeVariationPrice(variationList[i], matchedProduct);
        }
    }

    function upgradeVariationPrice(variation, matchedProduct) {
        if (!variation.show_price_difference) {
            return;
        }

        var disabled = matchedProduct === null;
        var target = $('#variation-' + variation[ID]);
        if (disabled) {
            target.parent().find('.upgrade-price').text('');
        } else if (_.find(selected, function (_variation) {
            return _variation.Id == variation[ID]
        }
        )) {
            target.parent().find('.upgrade-price').text('');
        } else {
            if (matchedProduct.Prices[0].Amount < 0 || selectedProduct.Prices[0].Amount < 0) {
                target.parent().find('.upgrade-price').text('N/A');
            } else if (variation.selectionType === 0) {
                var price = matchedProduct.Prices[0].Amount;
                target.parent().find('.upgrade-price').html(formatPrice(price, currencySymbol));
            } else {
                var price = matchedProduct.Prices[0].Amount - selectedProduct.Prices[0].Amount;
                target.parent().find('.upgrade-price').html('+&nbsp;' + formatPrice(price, currencySymbol));
            }
        }
    }

    function toggleVariation(variation, matchedProduct) {
        var disabled = matchedProduct === null;
        var target = $('#variation-' + variation[ID]);

        if (disabled) {
            target.addClass('disabled');
            target.prop('disabled', true);
            target.closest('.variation-clip').addClass('disabled');
        } else {
            target.removeClass('disabled');
            target.prop('disabled', false);
            target.closest('.variation-clip').removeClass('disabled');
        }

    }

    validateVariations();
});
;
'use strict';


// Errors in card fields are displayed underneath the form and rendered as a list 
const makeCommaSeparatedString = (arr, useOxfordComma) => {
    const listStart = arr.slice(0, -1).join(', ')
    const listEnd = arr.slice(-1)
    const conjunction = arr.length <= 1
        ? ''
        : useOxfordComma && arr.length > 2
            ? ', and '
            : ' and '

    return [listStart, listEnd].join(conjunction)
}


// country and region need to be sent by the buttons/hosted fields api, so need functions to handle this..
function getRegion(regionId) {

    var regions =
        [
            { country_id: 223, region_id: 1, code: "AL", name: "Alabama" },
            { country_id: 223, region_id: 2, code: "AK", name: "Alaska" },
            { country_id: -1, region_id: 3, code: "AS", name: "American Samoa" },
            { country_id: 223, region_id: 4, code: "AZ", name: "Arizona" },
            { country_id: 223, region_id: 5, code: "AR", name: "Arkansas" },
            { country_id: -1, region_id: 6, code: "AF", name: "Armed Forces Africa" },
            { country_id: -1, region_id: 7, code: "AA", name: "Armed Forces Americas" },
            { country_id: -1, region_id: 8, code: "AC", name: "Armed Forces Canada" },
            { country_id: -1, region_id: 9, code: "AE", name: "Armed Forces Europe" },
            { country_id: -1, region_id: 10, code: "AM", name: "Armed Forces Middle East" },
            { country_id: -1, region_id: 11, code: "AP", name: "Armed Forces Pacific" },
            { country_id: 223, region_id: 12, code: "CA", name: "California" },
            { country_id: 223, region_id: 13, code: "CO", name: "Colorado" },
            { country_id: 223, region_id: 14, code: "CT", name: "Connecticut" },
            { country_id: 223, region_id: 15, code: "DE", name: "Delaware" },
            { country_id: 223, region_id: 16, code: "DC", name: "District of Columbia" },
            { country_id: -1, region_id: 17, code: "FM", name: "Federated States Of Micronesia" },
            { country_id: 223, region_id: 18, code: "FL", name: "Florida" },
            { country_id: 223, region_id: 19, code: "GA", name: "Georgia" },
            { country_id: -1, region_id: 20, code: "GU", name: "Guam" },
            { country_id: 223, region_id: 21, code: "HI", name: "Hawaii" },
            { country_id: 223, region_id: 22, code: "ID", name: "Idaho" },
            { country_id: 223, region_id: 23, code: "IL", name: "Illinois" },
            { country_id: 223, region_id: 24, code: "IN", name: "Indiana" },
            { country_id: 223, region_id: 25, code: "IA", name: "Iowa" },
            { country_id: 223, region_id: 26, code: "KS", name: "Kansas" },
            { country_id: 223, region_id: 27, code: "KY", name: "Kentucky" },
            { country_id: 223, region_id: 28, code: "LA", name: "Louisiana" },
            { country_id: 223, region_id: 29, code: "ME", name: "Maine" },
            { country_id: -1, region_id: 30, code: "MH", name: "Marshall Islands" },
            { country_id: 223, region_id: 31, code: "MD", name: "Maryland" },
            { country_id: 223, region_id: 32, code: "MA", name: "Massachusetts" },
            { country_id: 223, region_id: 33, code: "MI", name: "Michigan" },
            { country_id: 223, region_id: 34, code: "MN", name: "Minnesota" },
            { country_id: 223, region_id: 35, code: "MS", name: "Mississippi" },
            { country_id: 223, region_id: 36, code: "MO", name: "Missouri" },
            { country_id: 223, region_id: 37, code: "MT", name: "Montana" },
            { country_id: 223, region_id: 38, code: "NE", name: "Nebraska" },
            { country_id: 223, region_id: 39, code: "NV", name: "Nevada" },
            { country_id: 223, region_id: 40, code: "NH", name: "New Hampshire" },
            { country_id: 223, region_id: 41, code: "NJ", name: "New Jersey" },
            { country_id: 223, region_id: 42, code: "NM", name: "New Mexico" },
            { country_id: 223, region_id: 43, code: "NY", name: "New York" },
            { country_id: 223, region_id: 44, code: "NC", name: "North Carolina" },
            { country_id: 223, region_id: 45, code: "ND", name: "North Dakota" },
            { country_id: -1, region_id: 46, code: "MP", name: "Northern Mariana Islands" },
            { country_id: 223, region_id: 47, code: "OH", name: "Ohio" },
            { country_id: 223, region_id: 48, code: "OK", name: "Oklahoma" },
            { country_id: 223, region_id: 49, code: "OR", name: "Oregon" },
            { country_id: -1, region_id: 50, code: "PW", name: "Palau" },
            { country_id: 223, region_id: 51, code: "PA", name: "Pennsylvania" },
            { country_id: -1, region_id: 52, code: "PR", name: "Puerto Rico" },
            { country_id: 223, region_id: 53, code: "RI", name: "Rhode Island" },
            { country_id: 223, region_id: 54, code: "SC", name: "South Carolina" },
            { country_id: 223, region_id: 55, code: "SD", name: "South Dakota" },
            { country_id: 223, region_id: 56, code: "TN", name: "Tennessee" },
            { country_id: 223, region_id: 57, code: "TX", name: "Texas" },
            { country_id: 223, region_id: 58, code: "UT", name: "Utah" },
            { country_id: 223, region_id: 59, code: "VT", name: "Vermont" },
            { country_id: -1, region_id: 60, code: "VI", name: "Virgin Islands" },
            { country_id: 223, region_id: 61, code: "VA", name: "Virginia" },
            { country_id: 223, region_id: 62, code: "WA", name: "Washington" },
            { country_id: 223, region_id: 63, code: "WV", name: "West Virginia" },
            { country_id: 223, region_id: 64, code: "WI", name: "Wisconsin" },
            { country_id: 223, region_id: 65, code: "WY", name: "Wyoming" },
            { country_id: 38, region_id: 66, code: "AB", name: "Alberta" },
            { country_id: 38, region_id: 67, code: "BC", name: "British Columbia" },
            { country_id: 38, region_id: 68, code: "MB", name: "Manitoba" },
            { country_id: 38, region_id: 69, code: "NF", name: "Newfoundland" },
            { country_id: 38, region_id: 70, code: "NB", name: "New Brunswick" },
            { country_id: 38, region_id: 71, code: "NS", name: "Nova Scotia" },
            { country_id: 38, region_id: 72, code: "NT", name: "Northwest Territories" },
            { country_id: 38, region_id: 73, code: "NU", name: "Nunavut" },
            { country_id: 38, region_id: 74, code: "ON", name: "Ontario" },
            { country_id: 38, region_id: 75, code: "PE", name: "Prince Edward Island" },
            { country_id: 38, region_id: 76, code: "QC", name: "Quebec" },
            { country_id: 38, region_id: 77, code: "SK", name: "Saskatchewan" },
            { country_id: 38, region_id: 78, code: "YT", name: "Yukon Territory" },
            { country_id: 81, region_id: 79, code: "NDS", name: "Niedersachsen" },
            { country_id: 81, region_id: 80, code: "BAW", name: "Baden-W�rttemberg" },
            { country_id: 81, region_id: 81, code: "BAY", name: "Bayern" },
            { country_id: 81, region_id: 82, code: "BER", name: "Berlin" },
            { country_id: 81, region_id: 83, code: "BRG", name: "Brandenburg" },
            { country_id: 81, region_id: 84, code: "BRE", name: "Bremen" },
            { country_id: 81, region_id: 85, code: "HAM", name: "Hamburg" },
            { country_id: 81, region_id: 86, code: "HES", name: "Hessen" },
            { country_id: 81, region_id: 87, code: "MEC", name: "Mecklenburg-Vorpommern" },
            { country_id: 81, region_id: 88, code: "NRW", name: "Nordrhein-Westfalen" },
            { country_id: 81, region_id: 89, code: "RHE", name: "Rheinland-Pfalz" },
            { country_id: 81, region_id: 90, code: "SAR", name: "Saarland" },
            { country_id: 81, region_id: 91, code: "SAS", name: "Sachsen" },
            { country_id: 81, region_id: 92, code: "SAC", name: "Sachsen-Anhalt" },
            { country_id: 81, region_id: 93, code: "SCN", name: "Schleswig-Holstein" },
            { country_id: 81, region_id: 94, code: "THE", name: "Th�ringen" },
            { country_id: 14, region_id: 95, code: "WI", name: "Wien" },
            { country_id: 14, region_id: 96, code: "NO", name: "Nieder�sterreich" },
            { country_id: 14, region_id: 97, code: "OO", name: "Ober�sterreich" },
            { country_id: 14, region_id: 98, code: "SB", name: "Salzburg" },
            { country_id: 14, region_id: 99, code: "KN", name: "K�rnten" },
            { country_id: 14, region_id: 100, code: "ST", name: "Steiermark" },
            { country_id: 14, region_id: 101, code: "TI", name: "Tirol" },
            { country_id: 14, region_id: 102, code: "BL", name: "Burgenland" },
            { country_id: 14, region_id: 103, code: "VB", name: "Voralberg" },
            { country_id: 204, region_id: 104, code: "AG", name: "Aargau" },
            { country_id: 204, region_id: 105, code: "AI", name: "Appenzell Innerrhoden" },
            { country_id: 204, region_id: 106, code: "AR", name: "Appenzell Ausserrhoden" },
            { country_id: 204, region_id: 107, code: "BE", name: "Bern" },
            { country_id: 204, region_id: 108, code: "BL", name: "Basel-Landschaft" },
            { country_id: 204, region_id: 109, code: "BS", name: "Basel-Stadt" },
            { country_id: 204, region_id: 110, code: "FR", name: "Freiburg" },
            { country_id: 204, region_id: 111, code: "GE", name: "Genf" },
            { country_id: 204, region_id: 112, code: "GL", name: "Glarus" },
            { country_id: 204, region_id: 113, code: "JU", name: "Graub�nden" },
            { country_id: 204, region_id: 114, code: "JU", name: "Jura" },
            { country_id: 204, region_id: 115, code: "LU", name: "Luzern" },
            { country_id: 204, region_id: 116, code: "NE", name: "Neuenburg" },
            { country_id: 204, region_id: 117, code: "NW", name: "Nidwalden" },
            { country_id: 204, region_id: 118, code: "OW", name: "Obwalden" },
            { country_id: 204, region_id: 119, code: "SG", name: "St. Gallen" },
            { country_id: 204, region_id: 120, code: "SH", name: "Schaffhausen" },
            { country_id: 204, region_id: 121, code: "SO", name: "Solothurn" },
            { country_id: 204, region_id: 122, code: "SZ", name: "Schwyz" },
            { country_id: 204, region_id: 123, code: "TG", name: "Thurgau" },
            { country_id: 204, region_id: 124, code: "TI", name: "Tessin" },
            { country_id: 204, region_id: 125, code: "UR", name: "Uri" },
            { country_id: 204, region_id: 126, code: "VD", name: "Waadt" },
            { country_id: 204, region_id: 127, code: "VS", name: "Wallis" },
            { country_id: 204, region_id: 128, code: "ZG", name: "Zug" },
            { country_id: 204, region_id: 129, code: "ZH", name: "Z�rich" },
            { country_id: 195, region_id: 130, code: "A Coru�a", name: "A Coru�a" },
            { country_id: 195, region_id: 131, code: "Alava", name: "Alava" },
            { country_id: 195, region_id: 132, code: "Albacete", name: "Albacete" },
            { country_id: 195, region_id: 133, code: "Alicante", name: "Alicante" },
            { country_id: 195, region_id: 134, code: "Almeria", name: "Almeria" },
            { country_id: 195, region_id: 135, code: "Asturias", name: "Asturias" },
            { country_id: 195, region_id: 136, code: "Avila", name: "Avila" },
            { country_id: 195, region_id: 137, code: "Badajoz", name: "Badajoz" },
            { country_id: 195, region_id: 138, code: "Baleares", name: "Baleares" },
            { country_id: 195, region_id: 139, code: "Barcelona", name: "Barcelona" },
            { country_id: 195, region_id: 140, code: "Burgos", name: "Burgos" },
            { country_id: 195, region_id: 141, code: "Caceres", name: "Caceres" },
            { country_id: 195, region_id: 142, code: "Cadiz", name: "Cadiz" },
            { country_id: 195, region_id: 143, code: "Cantabria", name: "Cantabria" },
            { country_id: 195, region_id: 144, code: "Castellon", name: "Castellon" },
            { country_id: 195, region_id: 145, code: "Ceuta", name: "Ceuta" },
            { country_id: 195, region_id: 146, code: "Ciudad Real", name: "Ciudad Real" },
            { country_id: 195, region_id: 147, code: "Cordoba", name: "Cordoba" },
            { country_id: 195, region_id: 148, code: "Cuenca", name: "Cuenca" },
            { country_id: 195, region_id: 149, code: "Girona", name: "Girona" },
            { country_id: 195, region_id: 150, code: "Granada", name: "Granada" },
            { country_id: 195, region_id: 151, code: "Guadalajara", name: "Guadalajara" },
            { country_id: 195, region_id: 152, code: "Guipuzcoa", name: "Guipuzcoa" },
            { country_id: 195, region_id: 153, code: "Huelva", name: "Huelva" },
            { country_id: 195, region_id: 154, code: "Huesca", name: "Huesca" },
            { country_id: 195, region_id: 155, code: "Jaen", name: "Jaen" },
            { country_id: 195, region_id: 156, code: "La Rioja", name: "La Rioja" },
            { country_id: 195, region_id: 157, code: "Las Palmas", name: "Las Palmas" },
            { country_id: 195, region_id: 158, code: "Leon", name: "Leon" },
            { country_id: 195, region_id: 159, code: "Lleida", name: "Lleida" },
            { country_id: 195, region_id: 160, code: "Lugo", name: "Lugo" },
            { country_id: 195, region_id: 161, code: "Madrid", name: "Madrid" },
            { country_id: 195, region_id: 162, code: "Malaga", name: "Malaga" },
            { country_id: 195, region_id: 163, code: "Melilla", name: "Melilla" },
            { country_id: 195, region_id: 164, code: "Murcia", name: "Murcia" },
            { country_id: 195, region_id: 165, code: "Navarra", name: "Navarra" },
            { country_id: 195, region_id: 166, code: "Ourense", name: "Ourense" },
            { country_id: 195, region_id: 167, code: "Palencia", name: "Palencia" },
            { country_id: 195, region_id: 168, code: "Pontevedra", name: "Pontevedra" },
            { country_id: 195, region_id: 169, code: "Salamanca", name: "Salamanca" },
            { country_id: 195, region_id: 170, code: "Santa Cruz de Tenerife", name: "Santa Cruz de Tenerife" },
            { country_id: 195, region_id: 171, code: "Segovia", name: "Segovia" },
            { country_id: 195, region_id: 172, code: "Sevilla", name: "Sevilla" },
            { country_id: 195, region_id: 173, code: "Soria", name: "Soria" },
            { country_id: 195, region_id: 174, code: "Tarragona", name: "Tarragona" },
            { country_id: 195, region_id: 175, code: "Teruel", name: "Teruel" },
            { country_id: 195, region_id: 176, code: "Toledo", name: "Toledo" },
            { country_id: 195, region_id: 177, code: "Valencia", name: "Valencia" },
            { country_id: 195, region_id: 178, code: "Valladolid", name: "Valladolid" },
            { country_id: 195, region_id: 179, code: "Vizcaya", name: "Vizcaya" },
            { country_id: 195, region_id: 180, code: "Zamora", name: "Zamora" },
            { country_id: 195, region_id: 181, code: "Zaragoza", name: "Zaragoza" },
            { country_id: 222, region_id: 182, code: "EN", name: "Great Britain" },
            { country_id: 222, region_id: 183, code: "NI", name: "Northern Ireland" },
            { country_id: 222, region_id: 184, code: "GG", name: "Channel Islands (Guernsey)" },
            { country_id: 222, region_id: 185, code: "JE", name: "Channel Islands (Jersey)" },
            { country_id: 103, region_id: 186, code: "IE", name: "Republic Of Ireland" },
            { country_id: 222, region_id: 188, code: "IM", name: "Isle of Man" },
            { country_id: 222, region_id: 189, code: "SI", name: "Scottish Islands (Hebrides)" },
            { country_id: 222, region_id: 190, code: "ZE", name: "Scottish Islands (Shetland)" },
        ];

    var region = regions.find(x => (x.region_id == regionId));
    if (region.country_id == 223) { return region.code; }
    else return region.name;
}

function getPaypalCountryCode(id) {

    var paypalCountryCodes =
        [
            { id: 1, code: 'AF' }
            , { id: 2, code: 'AL' }
            , { id: 3, code: 'DZ' }
            , { id: 4, code: 'AS' }
            , { id: 5, code: 'AD' }
            , { id: 6, code: 'AO' }
            , { id: 7, code: 'AI' }
            , { id: 8, code: 'AQ' }
            , { id: 9, code: 'AG' }
            , { id: 10, code: 'AR' }
            , { id: 11, code: 'AM' }
            , { id: 12, code: 'AW' }
            , { id: 13, code: 'AU' }
            , { id: 14, code: 'AT' }
            , { id: 15, code: 'AZ' }
            , { id: 16, code: 'BS' }
            , { id: 17, code: 'BH' }
            , { id: 18, code: 'BD' }
            , { id: 19, code: 'BB' }
            , { id: 20, code: 'BY' }
            , { id: 21, code: 'BE' }
            , { id: 22, code: 'BZ' }
            , { id: 23, code: 'BJ' }
            , { id: 24, code: 'BM' }
            , { id: 25, code: 'BT' }
            , { id: 26, code: 'BO' }
            , { id: 27, code: 'BA' }
            , { id: 28, code: 'BW' }
            , { id: 29, code: 'BV' }
            , { id: 30, code: 'BR' }
            , { id: 31, code: 'IO' }
            , { id: 32, code: 'BN' }
            , { id: 33, code: 'BG' }
            , { id: 34, code: 'BF' }
            , { id: 35, code: 'BI' }
            , { id: 36, code: 'KH' }
            , { id: 37, code: 'CM' }
            , { id: 38, code: 'CA' }
            , { id: 39, code: 'CV' }
            , { id: 40, code: 'KY' }
            , { id: 41, code: 'CF' }
            , { id: 42, code: 'TD' }
            , { id: 43, code: 'CL' }
            , { id: 44, code: 'CN' }
            , { id: 45, code: 'CX' }
            , { id: 46, code: 'CC' }
            , { id: 47, code: 'CO' }
            , { id: 48, code: 'KM' }
            , { id: 49, code: 'CG' }
            , { id: 50, code: 'CK' }
            , { id: 51, code: 'CR' }
            , { id: 52, code: 'CI' }
            , { id: 53, code: 'HR' }
            , { id: 54, code: 'CU' }
            , { id: 55, code: 'CY' }
            , { id: 56, code: 'CZ' }
            , { id: 57, code: 'DK' }
            , { id: 58, code: 'DJ' }
            , { id: 59, code: 'DM' }
            , { id: 60, code: 'DO' }
            , { id: 61, code: 'TP' }
            , { id: 62, code: 'EC' }
            , { id: 63, code: 'EG' }
            , { id: 64, code: 'SV' }
            , { id: 65, code: 'GQ' }
            , { id: 66, code: 'ER' }
            , { id: 67, code: 'EE' }
            , { id: 68, code: 'ET' }
            , { id: 69, code: 'FK' }
            , { id: 70, code: 'FO' }
            , { id: 71, code: 'FJ' }
            , { id: 72, code: 'FI' }
            , { id: 73, code: 'FR' }
            , { id: 75, code: 'GF' }
            , { id: 76, code: 'PF' }
            , { id: 77, code: 'TF' }
            , { id: 78, code: 'GA' }
            , { id: 79, code: 'GM' }
            , { id: 80, code: 'GE' }
            , { id: 81, code: 'DE' }
            , { id: 82, code: 'GH' }
            , { id: 83, code: 'GI' }
            , { id: 84, code: 'GR' }
            , { id: 85, code: 'GL' }
            , { id: 86, code: 'GD' }
            , { id: 87, code: 'GP' }
            , { id: 88, code: 'GU' }
            , { id: 89, code: 'GT' }
            , { id: 90, code: 'GN' }
            , { id: 91, code: 'GW' }
            , { id: 92, code: 'GY' }
            , { id: 93, code: 'HT' }
            , { id: 94, code: 'HM' }
            , { id: 95, code: 'HN' }
            , { id: 96, code: 'HK' }
            , { id: 97, code: 'HU' }
            , { id: 98, code: 'IS' }
            , { id: 99, code: 'IN' }
            , { id: 100, code: 'ID' }
            , { id: 101, code: 'IR' }
            , { id: 102, code: 'IQ' }
            , { id: 103, code: 'IE' }
            , { id: 104, code: 'IL' }
            , { id: 105, code: 'IT' }
            , { id: 106, code: 'JM' }
            , { id: 107, code: 'JP' }
            , { id: 108, code: 'JO' }
            , { id: 109, code: 'KZ' }
            , { id: 110, code: 'KE' }
            , { id: 111, code: 'KI' }
            , { id: 112, code: 'KP' }
            , { id: 113, code: 'KR' }
            , { id: 114, code: 'KW' }
            , { id: 115, code: 'KG' }
            , { id: 116, code: 'LA' }
            , { id: 117, code: 'LV' }
            , { id: 118, code: 'LB' }
            , { id: 119, code: 'LS' }
            , { id: 120, code: 'LR' }
            , { id: 121, code: 'LY' }
            , { id: 122, code: 'LI' }
            , { id: 123, code: 'LT' }
            , { id: 124, code: 'LU' }
            , { id: 125, code: 'MO' }
            , { id: 126, code: 'MK' }
            , { id: 127, code: 'MG' }
            , { id: 128, code: 'MW' }
            , { id: 129, code: 'MY' }
            , { id: 130, code: 'MV' }
            , { id: 131, code: 'ML' }
            , { id: 132, code: 'MT' }
            , { id: 133, code: 'MH' }
            , { id: 134, code: 'MQ' }
            , { id: 135, code: 'MR' }
            , { id: 136, code: 'MU' }
            , { id: 137, code: 'YT' }
            , { id: 138, code: 'MX' }
            , { id: 139, code: 'FM' }
            , { id: 140, code: 'MD' }
            , { id: 141, code: 'MC' }
            , { id: 142, code: 'MN' }
            , { id: 143, code: 'MS' }
            , { id: 144, code: 'MA' }
            , { id: 145, code: 'MZ' }
            , { id: 146, code: 'MM' }
            , { id: 147, code: 'NA' }
            , { id: 148, code: 'NR' }
            , { id: 149, code: 'NP' }
            , { id: 150, code: 'NL' }
            , { id: 151, code: 'AN' }
            , { id: 152, code: 'NC' }
            , { id: 153, code: 'NZ' }
            , { id: 154, code: 'NI' }
            , { id: 155, code: 'NE' }
            , { id: 156, code: 'NG' }
            , { id: 157, code: 'NU' }
            , { id: 158, code: 'NF' }
            , { id: 159, code: 'MP' }
            , { id: 160, code: 'NO' }
            , { id: 161, code: 'OM' }
            , { id: 162, code: 'PK' }
            , { id: 163, code: 'PW' }
            , { id: 164, code: 'PA' }
            , { id: 165, code: 'PG' }
            , { id: 166, code: 'PY' }
            , { id: 167, code: 'PE' }
            , { id: 168, code: 'PH' }
            , { id: 169, code: 'PN' }
            , { id: 170, code: 'PL' }
            , { id: 171, code: 'PT' }
            , { id: 172, code: 'PR' }
            , { id: 173, code: 'QA' }
            , { id: 174, code: 'RE' }
            , { id: 175, code: 'RO' }
            , { id: 177, code: 'RW' }
            , { id: 178, code: 'KN' }
            , { id: 179, code: 'LC' }
            , { id: 180, code: 'VC' }
            , { id: 181, code: 'WS' }
            , { id: 182, code: 'SM' }
            , { id: 183, code: 'ST' }
            , { id: 184, code: 'SA' }
            , { id: 185, code: 'SN' }
            , { id: 186, code: 'SC' }
            , { id: 187, code: 'SL' }
            , { id: 188, code: 'SG' }
            , { id: 189, code: 'SK' }
            , { id: 190, code: 'SI' }
            , { id: 191, code: 'SB' }
            , { id: 192, code: 'SO' }
            , { id: 193, code: 'ZA' }
            , { id: 194, code: 'GS' }
            , { id: 195, code: 'ES' }
            , { id: 196, code: 'LK' }
            , { id: 197, code: 'SH' }
            , { id: 198, code: 'PM' }
            , { id: 199, code: 'SD' }
            , { id: 200, code: 'SR' }
            , { id: 201, code: 'SJ' }
            , { id: 202, code: 'SZ' }
            , { id: 203, code: 'SE' }
            , { id: 204, code: 'CH' }
            , { id: 205, code: 'SY' }
            , { id: 206, code: 'TW' }
            , { id: 207, code: 'TJ' }
            , { id: 208, code: 'TZ' }
            , { id: 209, code: 'TH' }
            , { id: 210, code: 'TG' }
            , { id: 211, code: 'TK' }
            , { id: 212, code: 'TO' }
            , { id: 213, code: 'TT' }
            , { id: 214, code: 'TN' }
            , { id: 215, code: 'TR' }
            , { id: 216, code: 'TM' }
            , { id: 217, code: 'TC' }
            , { id: 218, code: 'TV' }
            , { id: 219, code: 'UG' }
            , { id: 220, code: 'UA' }
            , { id: 221, code: 'AE' }
            , { id: 222, code: 'GB' }
            , { id: 223, code: 'US' }
            , { id: 224, code: 'UM' }
            , { id: 225, code: 'UY' }
            , { id: 226, code: 'UZ' }
            , { id: 227, code: 'VU' }
            , { id: 228, code: 'VA' }
            , { id: 229, code: 'VE' }
            , { id: 230, code: 'VN' }
            , { id: 231, code: 'VG' }
            , { id: 232, code: 'VI' }
            , { id: 233, code: 'WF' }
            , { id: 234, code: 'EH' }
            , { id: 235, code: 'YE' }
            , { id: 236, code: 'YU' }
            , { id: 237, code: 'ZR' }
            , { id: 238, code: 'ZM' }
            , { id: 239, code: 'ZW' }
            , { id: 240, code: 'RS' }
            , { id: 241, code: 'ME' }
            , { id: 242, code: 'TL' }
            , { id: 243, code: 'AX' }
            , { id: 244, code: 'PS' }
            , { id: 245, code: 'RU' }
            , { id: 246, code: 'BL' }
            , { id: 247, code: 'MM' }
            , { id: 248, code: 'BV' }
            , { id: 249, code: 'MF' }
            , { id: 250, code: 'CD' }
            , { id: 251, code: 'IC' }
        ];

    var code = paypalCountryCodes.find(x => (x.id == id)).code;
    return code;
}


function paymentOptions() {
    // There are three different payment options, cards (default) paypal, and account.
    // these are chosen with radio buttons
    // Listen for changes to the radio buttons
    try {
        document.querySelectorAll('input[name=payment-option]')

            .forEach(function (el) {

                el.addEventListener('change', function (event) {


                    // If PayPal is selected, show the PayPal button
                    if (event.target.value === 'paypal') {
                        $('#paypal-container').show()
                        $('#card-container').hide()
                        $('#account-container').hide()
                    }


                    // If alternate funding is selected, show a different button

                    if (event.target.value === 'card') {
                        $('#paypal-container').hide()
                        $('#card-container').show()
                        $('#account-container').hide()
                    }

                    if (event.target.value === 'account') {
                        $('#paypal-container').hide()
                        $('#card-container').hide()
                        $('#account-container').show()
                    }

                });

            });

        // pay by card is the default options
        $('#paypal-container').hide()
        $('#account-container').hide()

    } catch {
        // this is just to avoid showing errors if the elements aren't on the page...
    }

    // Paypal integration

    //
    // BASKET CHECKOUT
    // buttons - for the 'Pay with PayPal' option
    //

    if (typeof paypal !== 'undefined' && $("#paypal-buttons-container").length == 1) {

        var orderID;

        //console.log("button")

        paypal.Buttons({
            style: { label: "pay" }, // needs to be pay so it says 'pay with paypal' rather than just 'paypal'
            fundingSource: paypal.FUNDING.PAYPAL, // only show the paypal wallet option as we're using 'hosted fields' for cards

            onError: function (err) {
                // if we've missed any other errors.. handle them here
                window.location.href = "/basket/PaymentOptions?error=undefined-error";
            }, 

            createOrder: () => {
                // get everything from the form...
                var customerPaymentFormData = {};
                $("#customer-payment-form").serializeArray().map(function (x) { customerPaymentFormData[x.name] = x.value; });

                //console.log("buttons basket")

                return fetch("/basket/CreatePaypalOrder?redirect=false",
                    {
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json",
                        },
                        body: JSON.stringify(
                            customerPaymentFormData
                        )
                    })
                    .then((response) => {
                            return response.json();
                        }
                    )
                    .then((orderData) => {
                            orderID = orderData.id;
                            return orderID;
                    });
            },
            onApprove: function (data) {
                try {
                    fetch("/basket/CapturePaypalPayment?id=" + orderID + "&paymentMethod=2", {
                        method: "POST",
                    })
                        .then((response) => {
                            return response.json();
                        })
                        .then((orderData) => {

                            if (orderData.hasOwnProperty("status") && orderData.status == "COMPLETED") {

                                const transaction = orderData.purchase_units[0].payments.captures[0];
                                var transactionOrderId = transaction.custom_id.substring(0, transaction.custom_id.indexOf("-"));

                                if (transaction.status == "COMPLETED") {
                                    window.location.href = "/basket/Complete/" + transactionOrderId
                                }
                                else {
                                    window.location.href = "/basket/PaymentOptions?error=undefined-error"
                                }
                            } else {
                                window.location.href = "/basket/PaymentOptions?error=undefined-error"
                            }

                        });
                } catch (err) {
                    window.location.href = "/basket/PaymentOptions?error=undefined-error"
                }
            }
        }).render('#paypal-buttons-container');

    }

    //
    // BASKET CHECKOUT
    // HOSTED FIELDS - for the 'debit/credit card' options
    //

    if (typeof paypal !== 'undefined' && paypal.HostedFields.isEligible() && $("#pay-by-card-button").length == 1) {
        var orderID;

        // validate form fields

        paypal.HostedFields.render({
            // Call your server to set up the transaction

            onError: function (err) {
                // if we've missed any other errors.. handle them here
                window.location.href = "/basket/PaymentOptions?error=undefined-error";
            }, 

            createOrder: () => {

                //console.log("hosted fields basket")

                var customerPaymentFormData = {};
                $("#customer-payment-form").serializeArray().map(function (x) { customerPaymentFormData[x.name] = x.value; });
                return fetch("/basket/CreatePaypalOrder", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify(customerPaymentFormData)
                })
                    .then((response) => {
                        if (response.redirected) {
                            window.location = response.url;
                        } else {
                            return response.json();
                        }
                    })
                    .then((orderData) => {
                        orderID = orderData.id;
                        return orderID;
                    });
            },
            styles: {
                '.invalid': {
                    color: 'red'
                }
            },
            fields: {
                number: {
                    selector: "#number",

                },
                cvv: {
                    selector: "#cvv",

                },
                expirationDate: {
                    selector: "#expirationDate",
                }
                /*postalCode: {
                    selector: "#postalCode",
                }*/

            }
        }).then(function (hostedFieldsInstance) {

            //handleBlurAndFocus(hostedFieldsInstance); // remove this as it's a potential source of issues

            document.querySelector("#pay-by-card-button").addEventListener("click", (event) => {
                //console.log("clicked pay by card button")

                $("#card-errors").text("")


                // show a different message and a loading spinner so it's clear we're processing the payment
                $("#pay-by-card-button").html("<span>PROCESSING</span><span class='loader'></span>");
                $("#pay-by-card-button").attr("disabled", true);
                $("#pay-by-card-button").attr("value", "PROCESSING");

                var nameOnCard = $("#card-holder-name").val().trim();

                // check for validation issues..
                var state = hostedFieldsInstance.getState();
                var errors = [];

                if (!nameOnCard) { errors.push("cardholder name") } // add an error if we don't have a card holder name'

                Object.keys(state.fields).forEach(function (key) {
                    //console.log(key)
                    if (!state.fields[key].isValid) {
                        if (key == "number") errors.push("card number")
                        else if (key == "expirationDate") errors.push("expiration date")
                        else if (key == "postalCode") errors.push("expiration date")
                        else errors.push(key)
                    }
                })

                // check we have stuff in the billing address
                // these could potentially be checked and added as errors..

                var streetAddress = document.getElementById(
                    "BillingAddress_Address1"
                ).value;

                var extendedAddress = document.getElementById(
                    "BillingAddress_Address2"
                ).value;

                // region needs to be either what's in the textbox 'BillingAddress_Region' or.. either the 'name' or 'code'
                // of whatever BillingAddress_RegionId points to depending on if it's US

                var region;

                if ($('#BillingAddress_Region').val()) {
                    region = $('#BillingAddress_Region').val()
                }

                else {
                    var regionId = document.getElementById("BillingAddress_RegionId").value; 
                    region = getRegion(regionId) 
                }

                var locality = document.getElementById("BillingAddress_TownCity").value;

                var countryCodeAlpha2 = getPaypalCountryCode(document.getElementById(
                    "BillingAddress_CountryId"
                ).value)

                var postalCode = document.getElementById("BillingAddress_PostCode").value; // using this from the paypal form...

                if ( errors.length > 0) {
                    $("#card-errors").text("Please correct/complete " + makeCommaSeparatedString(errors) + " to continue")

                    $("#pay-by-card-button").attr("disabled", false);
                    $("#pay-by-card-button").html("<span>MAKE A SECURE PAYMENT</span>");
                    $("#pay-by-card-button").attr("value", "MAKE A SECURE PAYMENT");

                }
                else {

                    // submit the hostedFields stuff with additional parameters tokenised in..
                    hostedFieldsInstance
                        .submit({
                            //UserId: document.getElementById("UserId").value, // email
                            cardholderName: nameOnCard,  // Cardholder's first and last name
                            // Billing Address
                            billingAddress: {
                                streetAddress: streetAddress, // Street address, line 1
                                extendedAddress: extendedAddress, // Street address, line 2 (Ex: Unit, Apartment, etc.)
                                region: region,// State
                                locality: locality,// City
                                postalCode: postalCode, // Postal Code
                                countryCodeAlpha2: countryCodeAlpha2 // Country Code
                            },
                        })
                        .then(() => {

                            try {
                                fetch("/basket/CapturePaypalPayment?id=" + orderID + "&paymentMethod=1", {
                                    method: "POST",
                                })
                                    .then((response) => {
                                        return response.json();
                                    }
                                    )
                                    .then((orderData) => {

                                        if (orderData.hasOwnProperty("status") && orderData.status == "COMPLETED") {

                                            const transaction = orderData.purchase_units[0].payments.captures[0];

                                            var transactionOrderId = transaction.custom_id.substring(0, transaction.custom_id.indexOf("-"));

                                            if (transaction.status == "COMPLETED") {
                                                window.location.href = "/basket/Complete/" + transactionOrderId
                                            }
                                            else {
                                                window.location.href = "/basket/PaymentOptions?error=undefined-error"
                                            }
                                        }
                                        else {
                                            window.location.href = "/basket/PaymentOptions?error=undefined-error"
                                        }

                                    });
                            } catch {
                                window.location.href = "/basket/PaymentOptions?error=undefined-error"
                            }
                        })
                } // end of if bit for validation errors
            }) // end of button event listener
        }) // end of then...
    } // end of the hosted fields bit


    //
    // PAYMENT LINKS
    // buttons - for the 'Pay with PayPal' option
    //

    if (typeof paypal !== 'undefined' && $("#paypal-buttons-container-payments").length == 1) {

        var orderID;

        paypal.Buttons({
            style: { label: "pay" }, // needs to be pay so it says 'pay with paypal' rather than just 'paypal'
            fundingSource: paypal.FUNDING.PAYPAL, // only show the paypal wallet option as we're using 'hosted fields' for cards

            onError: function (err) {
                // if we've missed any other errors.. handle them here
                window.location.href = "/payments/paymentfailure";
            },


            // Make sure that we don't allow the paypal button to work if there are validation errors in the form
            onInit(data, actions) {

                // using onInit might overwrite anything named 'data' later..
                // Disable the buttons
                actions.disable();


                // Listen for changes to the checkbox

                $('#customer-payment-form').find('select,input').on('change', function () {

                    let form = document.getElementById('customer-payment-form');

                    if (form.checkValidity() === false) {
                        // This is the magic function that displays the validation errors to the user
                        //form.reportValidity();
                        actions.disable();
                        return;

                    } else {
                        actions.enable();
                    }

                })

            },


            // onClick is called when the button is clicked
           onClick() {

               let form = document.getElementById('customer-payment-form');

               if (form.checkValidity() === false) {
                   // This is the magic function that displays the validation errors to the user
                   form.reportValidity();
                   return;
               }
            },

            createOrder: () => {
                // get everything from the form...

                //console.log("paypal button payments")

                var customerPaymentFormData = {}; // if this is called 'data'... everything breaks!
                $("#customer-payment-form").serializeArray().map(function (x) { customerPaymentFormData[x.name] = x.value; });

                return fetch("/payments/CreatePaypalOrder",
                    {
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json",
                        },
                        body: JSON.stringify(customerPaymentFormData)
                    })
                    .then((response) => {
                            return response.json();
                    })
                    .then((orderData) => {
                        if (orderData.hasOwnProperty('id')) {
                            orderID = orderData.id;
                            return orderID;
                        } else {
                            window.location.href = "/payments/paymentfailure";
                        }
                    });
            },
            onApprove: function (data) {

                try {

                    fetch("/payments/CapturePaypalPayment?id=" + orderID, {
                        method: "POST",
                    })
                        .then((response) => {
                            if (response.redirected) {
                                window.location = response.url;
                            } else {
                                return response.json();
                            }
                        })
                        .then((orderData) => {


                            if (orderData.hasOwnProperty("status") && orderData.status == "COMPLETED") {

                                const transaction = orderData.purchase_units[0].payments.captures[0];

                                //var transactionOrderId = transaction.custom_id.substring(0, transaction.custom_id.indexOf("-"));

                                if (transaction.status == "COMPLETED") {
                                    window.location.href = "/payments/paymentcompleted"
                                }
                                else {
                                    window.location.href = window.location.href = "/payments/paymentfailure";
                                }
                            } else {
                                window.location.href = window.location.href = "/payments/paymentfailure";
                            }
                        });
                } catch (err) {
                    window.location.href = window.location.href = "/payments/paymentfailure";
                }
            }
        }).render('#paypal-buttons-container-payments');

    }


    //
    // Payment Links
    // HOSTED FIELDS - for the 'debit/credit card' options
    //

    if (typeof paypal !== 'undefined' && paypal.HostedFields.isEligible() && $("#pay-by-card-button-payments").length == 1) {
        var orderID;

        paypal.HostedFields.render({
            // Call your server to set up the transaction

            onError: function (err) {
                // if we've missed any other errors.. handle them here
                window.location.href = "/payments/paymentfailure";
            },

            createOrder: () => {

                //console.log("hosted fields payments")

                var customerPaymentFormData = {};
                $("#customer-payment-form").serializeArray().map(function (x) { customerPaymentFormData[x.name] = x.value; });
                return fetch("/payments/CreatePaypalOrder", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify(customerPaymentFormData)
                })
                    .then((response) => {
                        if (response.redirected) {
                            window.location = response.url;
                        } else {
                            return response.json();
                        }
                    })
                    .then((orderData) => {
                        orderID = orderData.id;
                        return orderID;
                    });
            },
            styles: {
                '.invalid': {
                    color: 'red'
                }
            },
            fields: {
                number: {
                    selector: "#number",

                },
                cvv: {
                    selector: "#cvv",

                },
                expirationDate: {
                    selector: "#expirationDate",
                }
                /*postalCode: {
                    selector: "#postalCode",
                }*/

            }
        }).then(function (hostedFieldsInstance) {

            //handleBlurAndFocus(hostedFieldsInstance); // remove this as it's a potential source of issues

            document.querySelector("#pay-by-card-button-payments").addEventListener("click", (event) => {

                // we are no longer submitting the form so need to check the address form is valid here ..

                let form = document.getElementById('customer-payment-form');

                if (form.checkValidity() === false) {
                    // This is the magic function that displays the validation errors to the user
                    form.reportValidity();
                    return;
                }

                $("#card-errors").text("")

                // show a different message and a loading spinner so it's clear we're processing the payment
                $("#pay-by-card-button-payments").html("<span>PROCESSING</span><span class='loader'></span>");
                $("#pay-by-card-button-payments").attr("disabled", true);
                $("#pay-by-card-button-payments").attr("value", "PROCESSING");

                var nameOnCard = $("#card-holder-name").val().trim();

                // check for validation issues..
                var state = hostedFieldsInstance.getState();
                var errors = [];

                if (!nameOnCard) { errors.push("cardholder name") } // add an error if we don't have a card holder name'

                Object.keys(state.fields).forEach(function (key) {
                    //console.log(key)
                    if (!state.fields[key].isValid) {
                        if (key == "number") errors.push("card number")
                        else if (key == "expirationDate") errors.push("expiration date")
                        else if (key == "postalCode") errors.push("expiration date")
                        else errors.push(key)
                    }
                })

                // check we have stuff in the billing address
                // these could potentially be checked and added as errors..

                var streetAddress = document.getElementById(
                    "BillingAddress_Address1"
                ).value;

                var extendedAddress = document.getElementById(
                    "BillingAddress_Address2"
                ).value;

                // region needs to be either what's in the textbox 'BillingAddress_Region' or.. either the 'name' or 'code'
                // of whatever BillingAddress_RegionId points to depending on if it's US

                var region;

                if ($('#BillingAddress_Region').val()) {
                    region = $('#BillingAddress_Region').val()
                }

                else {
                    var regionId = document.getElementById("BillingAddress_RegionId").value;
                    region = getRegion(regionId)
                }

                var locality = document.getElementById("BillingAddress_TownCity").value;

                var countryCodeAlpha2 = getPaypalCountryCode(document.getElementById(
                    "BillingAddress_CountryId"
                ).value)

                var postalCode = document.getElementById("BillingAddress_PostCode").value; // using this from the paypal form...

                if (errors.length > 0) {
                    $("#card-errors").text("Please correct/complete " + makeCommaSeparatedString(errors) + " to continue")

                    $("#pay-by-card-button-payments").attr("disabled", false);
                    $("#pay-by-card-button-payments").html("<span>MAKE A SECURE PAYMENT</span>");
                    $("#pay-by-card-button-payments").attr("value", "MAKE A SECURE PAYMENT");

                }
                else {

                    // submit the hostedFields stuff with additional parameters tokenised in..
                    hostedFieldsInstance
                        .submit({
                            //UserId: document.getElementById("UserId").value, // email
                            cardholderName: nameOnCard,  // Cardholder's first and last name
                            // Billing Address
                            billingAddress: {
                                streetAddress: streetAddress, // Street address, line 1
                                extendedAddress: extendedAddress, // Street address, line 2 (Ex: Unit, Apartment, etc.)
                                region: region,// State
                                locality: locality,// City
                                postalCode: postalCode, // Postal Code
                                countryCodeAlpha2: countryCodeAlpha2 // Country Code
                            },
                        })
                        .then(() => {

                            try {
                                fetch("/payments/CapturePaypalPayment?id=" + orderID, {
                                    method: "POST",
                                })
                                    .then((response) => {
                                            return response.json();
                                    })
                                    .then((orderData) => {

                                        if (orderData.hasOwnProperty("status") && orderData.status == "COMPLETED") {
                                            const transaction = orderData.purchase_units[0].payments.captures[0];

                                            //var transactionOrderId = transaction.custom_id.substring(0, transaction.custom_id.indexOf("-"));

                                            if (transaction.status == "COMPLETED") {
                                                window.location.href = "/payments/paymentcompleted"
                                            }
                                            else {
                                                window.location.href = "/payments/paymentfailure";
                                            }
                                        } else {
                                            window.location.href = "/payments/paymentfailure";
                                        }

                                    });
                            } catch (err) {
                                window.location.href = "/payments/paymentfailure";
                            }
                        })
                } // end of if bit for validation errors
            }) // end of button event listener
        }) // end of then...
    } // end of the hosted fields bit


} // end of the paymentOptions functions


function InitializePaypal() {

    paymentOptions();


    try {
        $('#PO_toggler').on('click', function () {
            var enabled = $(this).is(':checked');
            var target = $(this).data('target');

            if ($(target).hasClass('collapsing')) {
                return false;
            }

            $(target).collapse('toggle');
            //console.log("here")
        });
    } catch {
        // don't show errors..
    }
}


$(document).ready(function () {

    $('.checkout-sidebar-affix').each(function () {
        var top = ($(this).offset().top) || 0;

        $(this).on('affix.bs.affix', function () {
            $(this).removeAttr('style');
            $(this).css({
                'width': $(this).parent().width()
            });
        }).on('affix-top.bs.affix', function () {
            $(this).removeAttr('style');
        });

        $(this).affix({
            offset: {
                top: top
            }
        });
    });

    //Set a listener on the select address dialog from basket/editaddress
    $(document).on('change', '#address-select', {}, function (evt) {
        var AddressId = parseInt($(this).val());
        if (AddressId == -1) {
            $('.checkout-step-button').val('Continue');
            $('#address-form').collapse('hide');
            return;
        }

        var type = $(this).data('type');
        UpdateAddressFields(AddressId, type);

        $('.checkout-step-button').val('Submit Changes');
        $('#address-form').collapse('show');
    });

    $('.address-edit').on('click', function (evt) {
        if ($('#address-form').hasClass('collapsing')) {
            return false;
        }

        var action = $(this).data('action');
        var type = $(this).data('type');

        //hidden = false, Edit.
        var isHidden = $('#address-select-container').is(':hidden');

        //If the form is hidden, show it, update it and exit
        if ($('#address-form').is(':hidden')) {

            $('#address-form').collapse('show');

            if (action === 'edit') {
                $('#address-select').val(window.ShippingAddress.AddressId);
                UpdateAddressFields(window.ShippingAddress.AddressId, type);
                $('.checkout-step-button').val('Submit Changes');
            } else if (action === 'new') {
                $('#address-select').val(0);
                UpdateAddressFields(0, type);
                $('.checkout-step-button').val('Create Address');
            }
            return;
        }

        //Don't hide if edit or new is pressed (unless edit or new is the current selection, respectively)
        var SelectedAddressId = parseInt($('#address-select').val());
        if (action === 'edit') {
            if (window.ShippingAddress.AddressId !== SelectedAddressId) {
                $('#address-select').val(window.ShippingAddress.AddressId);
                UpdateAddressFields(window.ShippingAddress.AddressId, type);
                $('.checkout-step-button').val('Submit Changes');
                return;
            } else {
                $('#address-select').val(-1);
            }
        } else if (action === 'new') {
            if (SelectedAddressId !== 0) {
                $('#address-select').val(0);
                UpdateAddressFields(0, type);
                $('.checkout-step-button').val('Create Address');
                return;
            } else {
                $('#address-select').val(-1);
            }
        }

        $('.checkout-step-button').val('Continue');
        $('#address-form').collapse('hide');
    });

    $('#address-form').on("show.bs.collapse", function () {
        $(this).find('input, select').each(function (item) {
            $(this).prop('disabled', false);
        });
    });
    $('#address-form').on("hidden.bs.collapse", function () {
        $(this).find('input, select').each(function (item) {
            $(this).prop('disabled', true);
        });
    });
    /*
        $(document).on('change click', '.delivery-row input', {}, function(evt) {
            evt.preventDefault();
            return false;
            if($('#SameDayWarningContainer').hasClass('collapsing')) {
                return false;
            }
    
            var $row = $(this).closest('.delivery-row');
            var checked = $(this).is(':checked');
    
            $('.delivery-row.selected').removeClass('selected');
            $row.addClass('selected');
    
            if(checked) {
                //set selected,
    
                var selectedShippingCode = $(this).val();
                var samedayShippingCode = 999;
                if(selectedShippingCode == samedayShippingCode) {
                    $('#SameDayWarningContainer').collapse('show');
                } else {
                    $('#SameDayWarningContainer').collapse('hide');
                }
            }
        });*/

    $(document).on('click', '.delivery-row input', {}, function (evt) {
        evt.preventDefault();
    });

    $(document).on('click', '.delivery-row', {}, function () {
        if ($('#SameDayWarningContainer').hasClass('collapsing')) {
            return false;
        }

        $('.delivery-row.selected').each(function () {
            $(this).removeClass('selected');
            $(this).find('input').each(function () {
                $(this).prop('checked', false);
            });
        });

        $(this).addClass('selected');

        //Show a warning if same day shipping is selected
        $(this).find('input').each(function () {
            var selectedShippingCode = $(this).val();
            var samedayShippingCode = 999;
            $(this).prop('checked', true);
            if (selectedShippingCode == samedayShippingCode) {
                $('#SameDayWarningContainer').collapse('show');
                $('#SameDayWarningContainer input').attr('required', true);
            } else {
                $('#SameDayWarningContainer').collapse('hide');
                $('#SameDayWarningContainer input').attr('required', false);
            }

            var shippingCode = parseInt($(this).val());
            var template = _.template($('#order-fragment-template').html());
            var model = {};
            var shippingItem;
            for (var i = 0; i < upsDeliveryRates.length; i++) {
                if (upsDeliveryRates[i].Code === shippingCode) {
                    shippingItem = upsDeliveryRates[i];
                    break;
                }
            }
            model.VAT = roundPrice(subTotalVAT + shippingItem.Cost * vatRate);
            model.Subtotal = subTotal;

            model.ShippingCost = roundPrice(shippingItem.Cost);
            model.ShippingText = shippingItem.DeliveryText;

            $('#order-fragment').html(
                template({ model: model })
            );
        });
    });

    InitializeBilling();


    var detailRequest = null;
    var Stages = {
        'ContactDetails': 1,
        'DeliveryDetails': 2,
        'DeliveryOptions': 3,
        'PaymentOptions': 4
    };

    var StageList = [
        'ContactDetails',
        'DeliveryDetails',
        'DeliveryOptions',
        'PaymentOptions'
    ];

    $(document).on('submit', '.checkout-form', {}, function (evt) {
        evt.preventDefault();
        var form = $(this);

        // If someone clicks the delivery address dropdown and selects an address, then clicks again and selects the
        // SELECT CURRENT ADDRESS option, we dsiplay multiple errors on the delivery option page.
        // This is to try and avoid the situation.
        var sform = form.serialize();
        if (sform.indexOf("CurrentStage=DeliveryDetails") > 0 && sform.indexOf("ShippingAddress.AddressId=-1") > 0 && sform.indexOf("ShippingAddress.Firstname") < 0) {
            if (detailRequest !== null) {
                detailRequest.abort();
                detailRequest = null;
            }
            return;
        }

        if (detailRequest !== null) {
            detailRequest.abort();
            detailRequest = null;
        }

        detailRequest = $.ajax({
            url: this.action,
            type: 'post',
            dataType: 'json',
            data: form.serialize(),
            beforeSend: function () {
                //Show loading animation and disable form
                form.closest('.main-slide').animate({
                    opacity: 0.2
                }, 1500, function () {
                });
            },
            success: function (data) {
                //If there are no errors
                if (data.Status === 'SUCCESS') {
                    var NewStage = StageList[data.StageId];
                    var OldStage = StageList[data.PreviousStageId];

                    var OldSlide = $('#' + OldStage + ' .main-slide');
                    var NewSlide = $('#' + OldStage + ' .secondary-slide');


                    if (OldStage == 'DeliveryOptions') {

                        var ga4products = window.analyticsCart.map(p => ProductToGA4Product(p, "shipping_products", "Shipping Products"))
                        sendToAnalytics({
                            event: "add_shipping_info",
                            ecommerce: {
                                currency: "GBP",
                                value: Number($(".price").first().text().substring(1)),
                                coupon: "",
                                shipping_tier: $(":radio:checked")[0].id,
                                items: [
                                    ga4products
                                ]
                            }
                        })
                    }

                    //Load html into new slide
                    NewSlide.html(data.PreviousView);
                    //get height of new slide
                    var NewHeight = NewSlide.outerHeight();

                    //when animation finishes, toggle old slide off and set the new slide to position: relative

                    //animate old slide to the height of the new slide and fade out
                    OldSlide.stop(true, false).animate({
                        height: NewHeight,
                        opacity: 0
                    }, 400, function () {
                        OldSlide.css('display', 'none');
                    });
                    //fade new slide in
                    NewSlide.animate({
                        opacity: 1
                    }, 400, function () {
                        NewSlide.css('position', 'relative');
                    });

                    var NewStep = $('#' + NewStage + ' .main-slide').html(data.View);
                    NewStep.css('height', 0)
                        .collapse('show');

                    //First step (guest details) shouldn't update the title and URL, because the promotional code logic relies on the forms being stateless
                    if (OldStage != StageList[0]) {
                        window.history.pushState(null, null, NewStage);
                        document.title = data.Title;
                    }

                    var NewUrl = '/basket/' + NewStage;
                    ga('set', 'page', NewUrl);
                    ga('send', 'pageview');


                } else if (data.Status === 'FAILURE') {
                    var Stage = StageList[data.StageId];
                    $('#' + Stage + ' .main-slide').html(data.View);
                    $('#' + Stage + ' .main-slide').stop(true, false).animate({
                        opacity: 1
                    }, 400);
                }

                InitializeBilling(); // safest to just call this on each transition too and on each page load
                

                //if (data.StageId === Stages.DeliveryOptions) {
                //    InitializeBilling(); // It is possible for this not to fire if the user click around a lot...
                //}

                // Hopefully this reloads the sidebar with the basket details including any change in VAT content from a shipping address to/from uk to non-uk and vice versa.
                $("#toggle-basket-review").load(location.href + " #toggle-basket-review>*", "");

                var Stage = StageList[data.StageId];
                $(document).scrollTo('#' + Stage + ' .main-slide', 400);

                detailRequest = null;
            }
        });
    });
});

//Billing address starts as collapsed with
function InitializeBilling() {

    InitializePaypal();

    if (!window.HasErrors) {
        $('#billingAddress-toggle').find('input, select').each(function (item) {
            $(this).prop('disabled', true);
        });
    }

    $('#BillingAddress_SameShipping').on('click', function () {
        var enabled = $(this).is(':checked');
        var target = $(this).data('target');

        if ($(target).hasClass('collapsing')) {
            return false;
        }

        $(target).collapse('toggle');
    });

    $('#billingAddress-toggle').on("show.bs.collapse", function () {
        $(this).find('input, select').each(function (item) {
            $(this).prop('disabled', false);
        });
    });
    $('#billingAddress-toggle').on("hidden.bs.collapse", function () {
        $(this).find('input, select').each(function (item) {
            $(this).prop('disabled', true);
        });
    });
    //console.log("initilize billing")
}

function UpdateAddressFields(addressId, type) {
    //$('#address-select').val(addressId);
    var address = _.findWhere(addressList, { 'AddressId': addressId });
    if (address) {
        $.each(address, function (_key, _value) {
            if (_key === 'Region' || _key === 'RegionId') {
                return;
            }
            var target = $('#' + type + 'Address_' + _key);
            target.val(_value);
            if (_key !== 'CountryId') {
                target.change();
            }
        });
        var callback = function () {
            var Address = address;
            var Type = type;
            var regionId = getAddressFieldID(Type, 'RegionId');
            if ($(regionId).length > 0) {
                $(regionId).val(address.RegionId)
                    .change();
            }
            var region = getAddressFieldID(Type, 'Region');
            if ($(region).length > 0) {
                $(region).val(address.Region)
                    .change();
            }
        };
        updateRegionWithType(type, address.CountryId, callback);
    } else {
        alert('Invalid Address Selected.');
    }
}

/*
$(document).ready(function () {

    $('input[name="PaymentMethodId"]').click(function () {
        var value = parseInt($(this).val());
        updatePaymentButtonImage(value);
    });

    (function () {
        var value = $('input[name="PaymentMethodId"]:checked').val();
        if (value) {
            var paymentMethodId = parseInt(value);
            updatePaymentButtonImage(paymentMethodId);
        }
    })();

    function updatePaymentButtonImage(paymentMethodId) {
        switch (paymentMethodId) {
            case 1:
                $('#payment-button-image').attr('src', '/content/img/menu/checkout/sagepayWhite.svg')
                    .show();
                break;

            case 2:
                $('#payment-button-image').attr('src', '/content/img/menu/checkout/paypalWhite.svg')
                    .show();
                break;

            default:
                $('#payment-button-image').attr('src', '')
                    .hide();
                break;
        }
    }

    $('.checkout-quotes input[name="PaymentMethodId"]').on('change', function () {
        var value = $(this).val();
        var newText = $(this).data('button-text');
        updatePaymentButton(value, newText);
    });

    // PIN is Proforma Invoice used in Quote Payments
    function updatePaymentButton(paymentMethod, newText) {
        $('#payment-button').html(newText);
        switch (paymentMethod) {
            case 'POA':
                $('#POA-show').collapse('show');
                break;
            case 'PAL':
                $('#POA-show').collapse('hide');
                break;
            case 'SAG':
                $('#POA-show').collapse('hide');
                break;
            case 'PIN':
                $('#POA-show').collapse('hide');
                break;
        }
    }
});
*/;
$(document).ready(function () {
  //  $("#PaymentOnAccount").submit(function () {
  //      $("#PaymentMethodId").val("3")
  //      return false;
  //  });


    /*
    $(document).on('change', 'input[name="PaymentMethodId"]', {}, function() {
        var value = parseInt($(this).val());
        updatePaymentButtonImage(value);
    });

    (function() {
        var value = $('input[name="PaymentMethodId"]:checked').val();
        if(value) {
            var paymentMethodId = parseInt(value);
            updatePaymentButtonImage(paymentMethodId);
        }
    })();

    function updatePaymentButtonImage(paymentMethodId) {
        switch (paymentMethodId) {
            case 1:
                $('#payment-button-image').attr('src', '/content/img/menu/checkout/sagepayWhite.svg')
                    .show();
                break;

            case 2:
                $('#payment-button-image').attr('src', '/content/img/menu/checkout/paypalWhite.svg')
                    .show();
                break;

            default:
                $('#payment-button-image').attr('src', '')
                    .hide();
                break;
        }
    }

    $('.checkout-quotes input[name="paymentMethod"]').on('change', function() {
        var value = $(this).val();
        var newText = $(this).data('button-text');
        updatePaymentButton(value, newText);
    });

    // PIN is Proforma Invoice used in Quote Payments
    function updatePaymentButton(paymentMethod, newText) {
        $('#payment-button').html(newText);
        switch(paymentMethod) {
            case 'POA':
                $('#POA-show').collapse('show');
                break;
            case 'PAL':
                $('#POA-show').collapse('hide');
                break;
            case 'SAG':
                $('#POA-show').collapse('hide');
                break;
            case 'PIN':
                $('#POA-show').collapse('hide');
                break;
        }
    }
    */
});
;

$(document).ready(function () {
    if (typeof RibbonFinderData === 'undefined') {
        return;
    }

    $('#RibbonManufacturers').on('change', function(){
        var $RibbonVersions = $('#RibbonVersions');
        $RibbonVersions.prop('disabled', false).removeClass('disabled');

        var selectedId = parseInt($(this).val());
        if(selectedId === -1) {
            removeVersionOptions(true);
            addVersionOptions(selectedId, true);
        } else {
            removeVersionOptions(false);
            addVersionOptions(selectedId, false);
        }

        if($RibbonVersions.children().length === 0){
            $RibbonVersions.prop('disabled', true).addClass('disabled');
            var field = '<option value="-1">N/A</option>';
            $RibbonVersions.append(field);
        } else {
            var field2 = '<option value="-1" selected>Select Printer Model</option>';
            $RibbonVersions.prepend(field2);
        }

    });

    $('#RibbonVersions').on('change', function () {
        $('#RibbonFinder').trigger('submit');
    });

    function addVersionOptions(selectedId, addAll){
        for(var i = 0; i < RibbonFinderData.Children.length; i++){
            if(addAll || RibbonFinderData.Children[i].Id === selectedId){
                var ribbonData = RibbonFinderData.Children[i].Children;
                for(var j = 0; j < ribbonData.length; j++){
                    var field = '<option value="' + ribbonData[j].Id + '">' + ribbonData[j].Title + '</option>';
                    $('#RibbonVersions').append(field);
                }
            }
        }
    }

    function removeVersionOptions(removeAll){
        $('#RibbonVersions option').each(function(){
            $(this).remove();
        });
        if(removeAll){
            var field = '<option value="-1">Printer Model</option>';
            $('#RibbonVersions').append(field);
        }
    }

});
;
$(document).ready(function () {
    (function(){
        "use strict";
        if (typeof printersToCompare === 'undefined') {
            return;
        }

        $('.brand-selection input, .level-selection input').on('change', function(){
            var $this = $(this);
            $this.prop('checked', true);
            var printers = $this.data('printers');
            var model = createModel(printers);
            renderPrinters(model);

            updateDescription($this.data('application'));
        });

        var $selected = $('input[name="options"]:checked');
        updateDescription($selected.data('application'));

        var model = createModel($selected.data('printers'));
        renderPrinters(model);

        function createModel(printerNames) {
            var printers = printersToCompare;
            var _printers = [];
            for(var i = 0; i < printerNames.length; i++) {
                _printers.push(printers[printerNames[i]]);
            }
            return {
                'Order' : fieldOrder,
                'Fields' : fields,
                'Printers' : _printers
            };
        }

        function updateDescription(Application) {
            var k = {'Application': Application};
            var template = _.template($('#applications-template').html());
            $('#application-wrapper').html(
                template(k)
            );
        }
        function renderPrinters(model){
            var template = _.template($('#printer-comparison-template').html());
            $('#printer-comparison-wrapper').html(
                template(model)
            );

            var template2 = _.template($('#printer-template').html());
            $('#printer-wrapper').html(
                template2(model)
            );
        }
    }());

});
;
"use strict";

$(document).ready(function () {

    function stageController() {
        this.currentStage = 0;
        this.stageContainers = [
            '#manufacturer-section-container',
            '#model-section-container',
            '#ribbon-section-container'];
        this.stageRenderContainers = [
            '#manufacturer-section-container',
            '#model-section-container',
            '#ribbon-render-container'];
        this.stages = [
            'Stage-Brand',
            'Stage-Model',
            'Stage-Ribbon'];
        this.stageClasses = [
            '.brand-stage',
            '.model-stage',
            '.final-stage'
        ];

        //Control loop that's responsible for keeping event listeners up to date
        //and transitioning between stages
        this.setStage = function (newStage, newHtml, stageName) {
            //unbind events from the current stage
            this.unbind(this.currentStage);

            var newStageNode = $(this.stageContainers[newStage]);
            var newStageContainer = $(this.stageRenderContainers[newStage]);
            if (newStage > this.currentStage) {
                newStageContainer.html(newHtml);
            }
            newStageNode.show();


            $(this.stageContainers[this.currentStage]).hide();

            //transition from old stage
            //transition to new stage

            $('.ribbon-stage.active').removeClass('active');
            $('.ribbon-stage').each(function (element) {
                var stageId = $(this).data('stage-id');
                if (newStage <= stageId) {
                    $(this).html($(this).data('default-text'));
                }
                if (stageId === newStage) {
                    $(this).addClass('active');
                }
            });
            if (this.currentStage < newStage) {
                $(this.stageClasses[this.currentStage]).html(stageName);
            }


            $('.ribbon-stage-container').attr('id', this.stages[newStage]);

            //bind new events
            this.bind(newStage);

            this.currentStage = newStage;
        };

        this.unbind = function (oldStage) {
            switch (oldStage) {
                case 0:
                    $('.ribbon-manufacturer-box a').off('click', this.manufacturerListeners);
                    break;

                case 1:
                    $('.printer-models').off('click', this.modelListeners);
                    break;
            }

            $('.ribbon-back-box a').off('click', this.backListener);
        };

        var context = this;
        this.bind = function (newStage) {
            switch (newStage) {
                case 0:
                    $('.ribbon-manufacturer-box a').on('click', this.manufacturerListeners);
                    break;

                case 1:
                    $('.printer-models').on('click', this.modelListeners);
                    break;
            }

            $('.ribbon-back-box a').on('click', this.backListener);
        };

        this.manufacturerListeners = function (evt) {
            evt.preventDefault();

            var target = $(this).attr('href');
            var brandName = $(this).data('brand-name');

            var html = $(target).html();
            context.setStage(1, html, brandName);
        };

        this.modelListeners = function (evt) {
            evt.preventDefault();

            var categoryRequest = null;
            var categoryId = $(this).data('category-id');
            var categoryName = $(this).data('category-name');

            if (categoryRequest !== null) {
                categoryRequest.abort();
                categoryRequest = null;
            }

            categoryRequest = $.ajax({
                url: 'category/' + categoryId + '/GetRibbonProducts',
                type: 'post',
                dataType: 'json',
                success: function (data) {
                    //Stock view updated from template,
                    var productTemplate = _.template($('#ribbon-product-template').html());
                    var newHtml = productTemplate({
                        Products: data
                    });
                    categoryRequest = null;
                    context.setStage(2, newHtml, categoryName);
                }
            });
        };

        this.backListener = function (evt) {
            evt.preventDefault();
            context.setStage(context.currentStage - 1, '');
        };

        $('.ribbon-stage').on('click', function (evt) {
            evt.preventDefault();
            var stageId = parseInt($(this).data('stage-id'));

            if (context.currentStage > stageId) {
                context.setStage(stageId, '');
            }
        });
    }

    var _stageController = new stageController();
    _stageController.bind(0);
});
;


var MegamenuNavigation = function () {
    var navigationTimeout = null;

    var config = $.extend({
        activateDelay: 200,
        deactivateDelay: 300
    }, arguments[0]);

    var parent = $('.navbar-default .navbar-nav');
    $('.navbar-default .navbar-nav > li').on('mouseenter', function (e) {
        var $this = $(this);
        var delay = config.activateDelay;
        if($('.navbar-toggle').is(":visible")) {
            return;
        }
        //if we recently opened a mega menu set delay to 0
        if( $('.navbar-default .navbar-nav > li.deactivating').length > 0 ) {
            delay = 0;
        }

        ////delay showing the mega menu
        //delay is dependent on the state of navigation.
        //If we're already hovering over we will immediately open it
        if(delay === 0) {
            $this.addClass('active');
        } else {
            navigationTimeout = setTimeout(function(){
                $this.addClass('active');
            }, delay);
        }

    }).on('mouseleave', function (e) {
        if($('.navbar-toggle').is(":visible")) {
            return;
        }
        var $this = $(this);
        //to track the state of the navigation we apply an intermediary class
        // so we can hover over another element and immediately open it
        $(this).addClass('deactivating').removeClass('active');

        setTimeout(function() {
            $this.removeClass('deactivating');
        }, config.deactivateDelay);
        clearTimeout(navigationTimeout);

    }).on('click', function(e) {
        if((Modernizr.touch && !$('.navbar-toggle').is(":visible")) ||
            $('.navbar-toggle').is(":visible")) {
            var $this = $(this);
            $('.navbar-default .navbar-nav > li.active').each(function() {
                if($this.is($(this))) {
                    return false;
                }
                $(this).removeClass('active');
            });

            if(!$this.hasClass('active')) {
                e.preventDefault();
                $this.addClass('active');
            }
        }
    });

    $('.menu-section > b, .menu-section > a').on('click', function (e) {
        if($('.navbar-toggle').is(":visible")) {
            e.preventDefault();
            $('.menu-section.active').removeClass('active');

            $(this).parent().addClass('active');

        }
    });
};
;
function getskus() {
    var skus = document.getElementById('SKU').value;
    var voucher = document.getElementById('VoucherId').value;
    $.post("/Vouchers/ProductResults", { Skus: skus, vid: voucher }, function (response) {
        $("#results").html(response);
    });
}

function usesClick(i) {
    if ((document.getElementById('tr_' + i).style.display == 'none')) {
        $.post("/Vouchers/Users", { vid: i }, function (response) {
            $('.tr_' + i).empty().append(response);
        });
        document.getElementById('tr_' + i).style.display = ''
        event.preventDefault()
    } else {
        document.getElementById('tr_' + i).style.display = 'none';
        event.preventDefault()
    }
}

function getcompanies() {
    var c = document.getElementById('CompanyName').value;
    $.post("/Vouchers/Companies", { Company: c }, function (response) {
        $("#companies").html(response);
    });
};
/*Categories and landing page js */
$(document).ready(function () {

    $('.filter-wrapper .filter-affix').each(function () {
        var top = ($('#Product-Wrapper').offset().top - 10) || 0;
        var foot;
        if ($('#false-footer').length > 0)
            foot = $('#false-footer');
        else
            foot = $('#footer');
        var bottom = $(document).height() - foot.offset().top + 36;
        $(this).affix({
            offset: {
                top: top,
                bottom: bottom
            }
        }).on('affix.bs.affix', function () {
            $(this).removeAttr('style');

            $('#Product-Wrapper').css('min-height', $(this).height());

        }).on('affix-top.bs.affix', function () {
            $(this).removeAttr('style');
        });
    });

    /*Category Page Filter Method to change the displayed products */
    var filterRequest = null;
    $('.filter-wrapper input').change(function (evt) {
        evt.preventDefault();
        var form = $(this.form);
        if (filterRequest !== null) {
            filterRequest.abort();
            filterRequest = null;
        }
        filterRequest = $.ajax({
            url: this.form.action,
            type: 'post',
            dataType: 'json',
            data: form.serialize(),
            beforeSend: function () {
                $('.product-wrapper').css('opacity', '0.5');
            },
            success: function (data) {
                if (data.response) {
                    $('.product-wrapper')
                        .html(data.view)
                        .removeAttr('style');
                    if ($('#loadmore-shown')) {
                        $('#loadmore-shown').html(data.inview.toString() );
                        $('#loadmore-total').html(data.count.toString());
                        if (data.count > data.inview) {
                            if ($('#loadmore-bar').hasClass('hidden'))
                                $('#loadmore-bar').removeClass('hidden');
                        } else {
                            if (!$('#loadmore-bar').hasClass('hidden'))
                                $('#loadmore-bar').addClass('hidden');

                        }
                    }
                    filterRequest = null;
                }
            }
        });
    });

    //A user can go back to a category page and the browser will retain the state of the inputs but not the HTML
    //So we check if any inputs are checked and trigger an update if any are
    if ($('.filter-wrapper input[type=checkbox]').is(':checked')) {
        $('.filter-wrapper input[type=checkbox]:checked').first().change();
    }

    $('.printer-fragments-wrapper').slick({
        slidesToShow: 4,
        infinite: true,
        prevArrow: '.printer-control.previous',
        nextArrow: '.printer-control.next',
        settings: 'unslick',
        responsive: [
            {
                breakpoint: 1600,
                settings: {
                    slidesToShow: 3
                }
            },
            {
                breakpoint: 1200,
                settings: {
                    slidesToShow: 2
                }
            },
            {
                breakpoint: 992,
                settings: {
                    slidesToShow: 1
                }
            }
        ]
    });


});

//Category Edit page js

//Bind the event listener to the given nodes
function BindTagListener(node) {
    node.on('change', function (evt) {
        evt.preventDefault();
        //If we select an empty value, we remove the empty value select if another empty tag exists.
        //Otherwise we do nothing.
        if ($(this).val() === '-1') {
            if (EmptyTagExists()) {
                $(this).closest('.form-group').slideUp({
                    complete: function () {
                        $(this).remove();
                    }
                });
            }
        } else {
            //If we've selected a value, we add another select element if no empty tag exists
            if (!EmptyTagExists()) {
                var tagTemplate = _.template($('#product-tag-selection-template').html());
                $('#product-tag-selection-container').append(
                    tagTemplate()
                );
                var newNode = $('.js-tag-select').last();
                newNode.closest('.form-group').css('display', 'none').slideDown();
                BindTagListener(newNode);
            }
        }
    });
}

function EmptyTagExists() {
    return $('.js-tag-select').filter(function () { return $(this).val() === '-1'; }).length > 0;
};

$(document).ready(function () {

    //Set a listener on the country selection in forms
    $(document).on('change', '.CountryId', {}, function(evt) {
        var targetType = $(this).data('type');
        var CountryId = $(this).val();
        if($(this).attr('disabled') === 'disabled') {
            return;
        }
        var targetPostcodeButton = $(getAddressFieldID(targetType, 'PostCodeButton'));
        updateRegionWithType(targetType, CountryId);
        togglePostCodeButton(CountryId, targetPostcodeButton);
    });
    togglePostCodeButton($('.CountryId').val(), $('.PostCodeButton'));

    //Set a listener on the postcode submit in address forms
    $(document).on('click', '.PostCodeButton', {}, function(evt) {
        var type = $(this).data('type');
        //var model = $(this).data('model');
        updateAddressesWithType(type);
    });
});

//Address Form Section
//Sets a listener to the select field returned from the postcode lookup
//  that sets the fields from the address you select
function setAddressListenersWithType(type) {
    var prefix = "#" + type + "Address_";
    $(prefix + "addresses").change(function () {
        var cn = $(prefix + "CompanyName").val();
        var addr = $(this).val();
        var addressArray = addr.split(",");
        for (var i = 0; i < addressArray.length; i++) {
            addressArray[i] = addressArray[i].trim();
        }
        if (addressArray.length == 3) {
            $(prefix + "CompanyName").val(addressArray[0]);
            $(prefix + "Address1").val(addressArray[1]);
            $(prefix + "Address2").val(addressArray[2]);
        } else if (addressArray.length == 2) {
            $(prefix + "CompanyName").val(addressArray[0]);
            $(prefix + "Address1").val(addressArray[1]);
            $(prefix + "Address2").val('');
        } else {
            $(prefix + "CompanyName").val(cn);
            $(prefix + "Address1").val(addressArray[0]);
            $(prefix + "Address2").val('');
        }
    });
}


//Gets all addresses for a postcode and renders a partial inside a target container
function updateAddressesWithType(type) {
    var postCode = $('[name="' + type + 'Address.PostCode"]').val();
    if (checkPostCode(postCode)) {
        $.post('/Account/GetPostcodeAddresses', { PostCode: postCode, Type: type }, function (response) {
            $('#' + type + "Address_container").html(response);
            setAddressListenersWithType(type);
        });
    } else {
        alert('Invalid Postcode');
    }
}

function getAddressFieldID(type, name) {
    return '#' + type + 'Address_' + name;
}

AddressZoneRequest = null;
//Gets the zones available for the selected country and address type
//  then renders the partial inside #zones for the appropriate type
function updateRegionWithType(fieldType, CountryId, callback) {
    var disabled = $(getAddressFieldID(fieldType, 'CountryId')).prop('disabled');
    if(AddressZoneRequest !== null) {
        AddressZoneRequest.abort();
        AddressZoneRequest = null;
    }
    AddressZoneRequest = $.post('/Account/GetZones', {
        CountryId: CountryId, type: fieldType },
        function (response) {
            var fieldId = getAddressFieldID(fieldType, 'zones');
            $(fieldId).html(response);
            $(fieldId).children().prop('disabled', disabled);

            if(callback) {
                callback();
            }

            AddressZoneRequest = null;
        }
    );
}

function togglePostCodeButton(CountryId, tThis) {
    if (CountryId != 222) {
        $(tThis).hide()
            .closest('.input-group').css('display', 'block');
    } else {
        $(tThis).show()
            .closest('.input-group').css('display', '');
    }
}
;
/* File Created: October 12, 2016 */
$(document).ready(function () {
    'use strict';
    //Submit form
    //if the model is invalid update the sections html to show the errors
    //if it's valid and returns success hide and display complete message

    /*
        configuration-form
            *Toggled off before the form is posted

        configuration-complete
            *Toggled on when the form is posted successfully

        configuration-wrapper
            *data.view re-rendered to show the errors inline
            *any elements inside will need their listeners bound to the document or re-added after rendering

    */

    (function bindFormEvents() {
        $(document).on('submit', '.configuration-form form', {}, function(event) {
            event.preventDefault();
            $.ajax({
              type: "POST",
              data: $(this).serialize(),
              beforeSend: function () {
                  $('.configuration-form').css('opacity', 0.5);
              }
            })
            .done(function (data) {
                if (data.code == 'success') {
                    $('.configuration-form').hide();
                    $('.configuration-complete').show();
                } else if (data.code == 'failure') {
                    $('.configuration-form').css('opacity', 1);
                    $('.configuration-wrapper').html(data.view);
                } else {
                    $('.configuration-form').css('opacity', 1);
                    $('.configuration-wrapper').html(data.view);
                }
            })
            .fail(function (data) {
                alert('Sorry, something went wrong with your request. Please try again or give us a call at 0800 988 2095');
            });
        });

        $('.configuration-complete .btn').on('click', function(event) {
            event.preventDefault();
            $('.configuration-form').show();
            $('.configuration-complete').hide();
            $('.configuration-form').css('opacity', 1);
        });
    })();
});

/* Visitorpass book*/
$(document).ready(function () {
    'use strict';

    var VisitorPassRequest = null;
    window.VisitorpassFormData = null;

    function UpdateVisitorpassPrices(element) {
        if(!element.form.checkValidity()) {
            element.form.reportValidity();
            return false;
        }

        var newVisitorpassData = $(element.form).serialize();
        if (newVisitorpassData == window.VisitorpassFormData) {
            return false;
        } else {
            window.VisitorpassFormData = newVisitorpassData;
        }

        if (VisitorPassRequest !== null) {
            VisitorPassRequest.abort();
            VisitorPassRequest = null;
        }


        VisitorPassRequest = $.ajax({
          type: "POST",
          dataType: 'json',
          url: '/printing-services/visitor-pass-book-prices',
          data: $(element.form).serialize(),
          beforeSend: function (e) {
              $('#visitorpass-unit-price').css('opacity', 0.5);
              $('#visitorpass-total-price').css('opacity', 0.5);
              $('#visitorpass-total-price-VAT').css('opacity', 0.5);
          }
        })
        .done(function (model) {
            if(model.data.Price < 0) {
                alert('Failed to get price for the current selection.');
            } else {
                $('#visitorpass-unit-price')
                    .html(formatPrice(model.data.UnitPrice, CurrencySymbol))
                    .removeAttr('style');
                $('#visitorpass-total-price')
                    .html(formatPrice(model.data.Price, CurrencySymbol))
                    .removeAttr('style');
                $('#visitorpass-total-price-VAT')
                    .html(formatPrice(model.data.VATPrice, CurrencySymbol))
                    .removeAttr('style');
            }
            VisitorPassRequest = null;
        });
    }
    $('#visitorpass-book-form input').on('change', function(event) {
        event.preventDefault();
        UpdateVisitorpassPrices(this);
    });
    $('#visitorpass-book-form input[type=number]').on('mouseup keyup', function(event) {
        UpdateVisitorpassPrices(this);
    });
});
;
/* =========== Main JS =========== */

/* Constants */
$(document).ready(function () {

    $('.select-all').on('change', function (event) {
        var checked = $(this).prop('checked');
        $(this.form).find('input:checkbox').each(function (element) {
          $(this).prop('checked', checked);
        });
    });

    $(document).on('change', '.type-selection input', {}, function() {
        var hideSelector = $(this).data('hide');
        var showSelector = $(this).data('show');
        $(showSelector).find('input').removeAttr('disabled');
        $(hideSelector).find('input').attr('disabled', true);

        $(hideSelector).hide();
        $(showSelector).show().find('.active input').change();
    });

    $('.affix-to-self').each(function() {
        var bottomTarget = $(this).data('bottom-target');

        var topOffset = $(this).data('offset-top') || 0;
        var bottomOffset = $(this).data('offset-bottom') || 0;

        var viewportHeight = document.documentElement.clientHeight;

        var top = $(this).offset().top + topOffset - viewportHeight;

        $(this).affix({
          offset: {
            top: function () {
                return (this.top = top)
            }
          }
        }).on('affix.bs.affix', function () {
            $(this).css({
                'width': $(this).outerWidth()
            });
        });
    });

    //Generic listener that smooth scrolls # links
    $('a[href^="#"][data-action="scroll"]').on('click', function (e) {
        e.preventDefault();
        var maxSpeed = 500; //pixels per second
        var minTime = 500; //Short movements look jerky, so we force a minimum time in ms

        var target = this.hash;
        var $target = $(target);
        var $this = $(this);
        var distance = Math.abs($target.offset().top - $this.offset().top);
        var speed = Math.max(distance / maxSpeed * 100, minTime);

        $('html, body').stop().animate({
            'scrollTop': $target.offset().top
        }, speed, 'swing', function () {
            window.location.hash = target;
        });
    });

    $('.btn-collapse').on('click', function (e) {
      e.preventDefault();
      var $this = $(this);
      var text = "";
      if($this.hasClass('collapsed')) {
          $this.removeClass('collapsed');
          text = $this.data('text');
      } else {
          $this.addClass('collapsed');
          text = $this.data('collapsed-text');
      }

      if(text.length > 0) {
          $this.html(text);
      }
      var target = $this.data('target');
      $(target).collapse();
    });

    var megamenuNavigation = new MegamenuNavigation({});

    $(document).on('click', '.open-chat-link', {}, function (e) {
        e.preventDefault();

        LC_API.open_chat_window();
    });

    //Copy promotion text to clipboard
    $('.copy-text').click(function (e) {
        e.preventDefault();
        var target = $(this).data('target');
        var $target = $(target);
        $target.select();

        try {
            document.execCommand('copy');
        } catch (err) {
            console.log('Oops, unable to copy');
        }
    });

    //Lanyard landing page
    $('.stats-body span').each(function () {
        var $this = $(this);
        var targetNumber = parseFloat($this.data('target'));
        var digits = parseInt($this.data('digits') || 0);
        var variation = 1000;
        var duration = 1000 + variation * Math.random();
        var startNumber = $this.data('start');

        countUp($this, targetNumber, startNumber, digits, duration);
    });


    $('.confirm-modal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget);
        var dataId = button.data('id');
        var modal = $(this);
        modal.find('.delete-id').val(dataId);
    });
});

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, '\\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

function openWindow(connectionString, parameters, specs) {
    var _specConfig = {
        width: 200,
        height: 200,
        toolbar: 1,
        menubar: 0,
        location: 0,
        status: 0,
        resizable: 1
    };
    $.extend(_specConfig, specs);

    var _parameterConfig = {
    }
    $.extend(_parameterConfig, parameters);

    var screenX = 'screenX' in window ? window.screenX : window.screenLeft;
    var screenY = 'screenY' in window ? window.screenY : window.screenTop;
    var screenWidth = 'outerWidth' in window ? window.outerWidth : document.documentElement.clientWidth;
    var screenHeight = 'outerHeight' in window ? window.outerHeight : document.documentElement.clientHeight - 22;
    _specConfig.left = Math.floor(screenX + (screenWidth - _specConfig.width) / 2);
    _specConfig.top = Math.floor(screenY + (screenHeight - _specConfig.height) / 2.5);

    connectionString += '?' + $.param(_parameterConfig);

    var _arguments = [];
    $.each(_specConfig, function(key, value) {
        _arguments.push(key + '=' + value);
    });


    window.open(connectionString, '_blank', _arguments);
    return false;
}

function countUp(node, targetNumber, startNumber, digits, duration) {
    var $selector = $(node);
    $selector.addClass('counting');
    var counter = $({ number: startNumber }).animate({
        number: targetNumber
    }, {
        duration: duration,
        //easing: 'linear',
        step: function (now) {
            $selector.text(formatNumber(now, digits));
        },
        complete: function () {
            $selector.text(formatNumber(this.number, digits));
            $selector.removeClass('counting');
        }
    });

    $selector.data('counter', counter);
}

function calculateEmptySpace(ProductCount, RowSize, MinimumRows) {
    if(ProductCount > RowSize * MinimumRows) {
        var modResult = ProductCount % RowSize;
        if(modResult == 0) {
            return 0;
        } else {
            return RowSize - modResult;
        }
    } else {
        return RowSize * MinimumRows - ProductCount;
    }
}

function formatNumber(number, digits) {
    return accounting.formatNumber(number, digits);
}

//Format a given floating point price given the currency symbol as string
function formatPrice(price, currency, decimalPlaces) {
    decimalPlaces = decimalPlaces === 'undefined' ? 2 : decimalPlaces;
    return accounting.formatMoney(price, currency, decimalPlaces);
}

//might be change'able to toFixed. Needs testing though
function roundPrice(Price) {
    return Math.round(Price * 100) / 100;
}

// Floating input field labels
$(document).on('blur change', '.floating-label-field, .floating-label-textarea', {}, function(evt) {
    if($(this) == null || $(this).val() == null) {
        return false;
    }

    if ($(this).val().length === 0) {
        $(this).removeClass('has-value');
    } else {
        $(this).addClass('has-value');
    }
});

// EasyBadge Lite to Pro Upgrade
function easyUP(Qty, Id) {
    /*var url = '/basket/easybadgeupgrade?Qty=' + Qty + "&Id=" + Id;
    $.ajax({
        url: url,
        contentType: "application/json",
        type: 'post',
        success: function (response) {
            window.location.href = "/basket";
        }
    });*/
    $.post("/Basket/EasybadgeUpgrade", { qty: Qty, id: Id }, function (response) {
        window.location.href = "/Basket";
    });
};
