/* Fehler bei der Verkleinerung. Der Inhalt wird unverkleinert zurückgegeben.
(1915,10): run-time error JS1004: Expected ';'
(2106,54-55): run-time error JS1195: Expected expression: ^
(2106,55-56): run-time error JS1195: Expected expression: ]
(2106,55-56): run-time error JS1006: Expected ')': ]
(2107,5-6): run-time error JS1195: Expected expression: )
(2107,6-7): run-time error JS1195: Expected expression: )
(2106,53-54): run-time error JS1013: Syntax error in regular expression: +
 */
var bundle = {
    baseProductId: -1,
    //baseProductName: '',
    //baseProductPriceRetailGrossFormatted: '',
    //categoryId: 1217,
    bundleItems: new Array(),
    bundlePriceNormalGross: 0.00,
    bundlePriceNormalGrossFormatted: '',
    bundlePriceGross: 0.00,
    bundlePriceGrossFormatted: '',
    bundlePriceDiscountGross: 0.00,
    bundlePriceDiscountGrossFormatted: '',
    isLegit: false,
    bundleError: '',
    shippingTime: '',
};

var selectedCategory = -1,
    urlCalculate = '',
    urlProductDetail = '',
    modalTitle = '';


function initBundleTool(baseProductId, routeUrlCalculate, routeUrlProductDetail, resourceProperties) {

    bundle.baseProductId = baseProductId;
    urlCalculate = routeUrlCalculate;
    urlProductDetail = routeUrlProductDetail;
    modalTitle = resourceProperties;

    // bind dropdown
    $('#bt-htmlselect').ddslick({
        //data: ddData,
        selectText: 'Kategorie wählen',
        embedCSS: false,
        width: '100%',
        onSelected: function (data) {

            //console.log('data: ', data);

            if (selectedCategory > 0) {
                $(document).scrollTop($('#bt-container').offset().top - 20);
            }

            selectedCategory = parseInt(data.selectedData.value);
            //console.log('selectedCategory', selectedCategory);

            //var url = data.selectedItem.data('bundle-product-url');
            var url = $('#cat-url-' + selectedCategory).val();

            //console.log('url: ', url);

            loadBundleProducts(url);

            // reset filter
            filters = [];
        },
        background: '#fff'
    });

    // handle the back button for android
    document.addEventListener("backbutton", onBackKeyDown, false);
    window.onhashchange = onBackKeyDown;

    $(document).bind('PgwModal::PushContent', function () {
        // Your code when the content (Div reference, HTML code or Ajax result) is pushed into the modal.

        $('#pgwModal').scrollTop(0);
    });

    $(document).bind('PgwModal::Close', function () {
        // Your code when the modal is closed.

        // remove entire hash
        //history.pushState("", document.title, window.location.pathname + window.location.search);
        window.history.go(-1);
    });

    // startup
    $(document).scrollTop(0);
    bundleToolSnapping();

    // add base bundle item to array
    addBundleItem({ productId: baseProductId, quantity: 1 });

    updateBundleSummary();
}

function initBundleToolProductList() {

    $('.bt-cta input').off('click.bundletool').on('click.bundletool', function (e) {

        var $this = $(this),
            productId = $this.parent().data('product-id');

        // switch button
        switchBundleCtaButton($this);

        // add to bundle
        var bundleItem = { productId: productId, quantity: 1 };

        if ($this.attr('name') === 'add') {
            addBundleItem(bundleItem);

            // highlight item in summary
            //var $parent = $this.parent().parent();
            //$parent.off('mouseenter').off('mouseleave');
            //$parent.on({
            //    mouseenter: function () {
            //        console.log('enter');
            //        $('#bt-summary-items input[data-product-id="' + productId + '"]').parent().parent().css('background-color', '#ffc800');
            //    },
            //    mouseleave: function () {
            //        console.log('leave');
            //        $('#bt-summary-items input[data-product-id="' + productId + '"]').parent().parent().css('background-color', '');
            //    }
            //});
        }
        else {
            if (!removeBundleItem(bundleItem)) {
                // abort
                switchBundleCtaButton($this.parent().find('input').not($this));
                return;
            }
        }

        updateBundleSummary();
    });

    $('#filter-submit').off('submit.bundletool').on('submit.bundletool', function (e) {
        e.preventDefault();
        return false;
    });

}

function initBundleToolProductDetail(name) {
    $('#bt-product-detail-images').owlCarousel({
        items: 1,
        margin: 25,
        autoHeight: true,
        nav: true,
        navText: [
            '<i class="fa fa-chevron-left"></i>',
            '<i class="fa fa-chevron-right"></i>'
        ],
        lazyLoad: true,
        smartSpeed: 200,
        slideBy: 'page',
    });

    $('.pm-title').html(name);

    $('#pgw-close').on('click.bundletool', function (e) {
        $.pgwModal('close');
    });
}


function addBundleItem(bundleItem) {
    bundle.bundleItems.pushIfNotExist(bundleItem, function (e) {
        return e.productId == bundleItem.productId;
    });
}

function removeBundleItem(bundleItem) {
    if (bundleItem.productId == bundle.baseProductId) {
        alert('Der Hauptartikel darf nicht entfernt werden.');
        return false;
    }

    // filter returns all items with a different productId
    bundle.bundleItems = bundle.bundleItems.filter(function (el) {
        return el.productId !== bundleItem.productId;
    });

    return true;
}

function updateBundleSummary() {
    $.ajax({
        url: urlCalculate,
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(bundle)
    })
    .done(function (result) {
        //console.log('AJAX DONE', result);
        bundle = result;

        var summaryItemsHtml = '';

        for (var i = 0; i < bundle.bundleItems.length; i++) {
            var bundleItem = bundle.bundleItems[i];

            summaryItemsHtml += '<tr>';
            summaryItemsHtml += '<td><input class="form-control" type="tel" value="' + bundleItem.quantity + '" data-product-id="' + bundleItem.productId + '"></td>';
            summaryItemsHtml += '<td class="name">' + bundleItem.productName + '</td>';
            summaryItemsHtml += '<td class="price">' + bundleItem.priceNormalGrossTotalFormatted + '</td>';

            if (bundleItem.productId == bundle.baseProductId) {
                summaryItemsHtml += '<td>&nbsp;</td>';
            }
            else {
                summaryItemsHtml += '<td><i class="fa fa-trash-o" data-product-id="' + bundleItem.productId + '"></i></td>';
            }

            summaryItemsHtml += '</tr>';
        }

        //$('#bt-summary-items tr').not('tr.baseProduct').remove();
        $('#bt-summary-items tr').remove();
        $('#bt-summary-items').append(summaryItemsHtml);

        // select content of input field when it is clicked
        $('#bt-summary-items input[type="tel"]').off('click.bundletool').on('click.bundletool', function (e) {
            $(this).select();
        });

        $('#add-to-cart-items').empty();
        $('#bundle-error').hide().empty();

        if (bundle.isLegit && bundle.bundleError == null) {
            $('#bt-summary-bundle-price-normal').text(bundle.bundlePriceNormalGrossFormatted).data('bundle-price-normal', bundle.bundlePriceNormalGross);
            $('#bt-summary-bundle-price').text(bundle.bundlePriceGrossFormatted).data('bundle-price', bundle.bundlePriceGross);
            $('#bt-summary-bundle-price-discount').text(bundle.bundlePriceDiscountGrossFormatted).data('bundle-price-discount', bundle.bundlePriceDiscountGross);
            $('#bt-summary-bundle-shipping-time').html(bundle.shippingTime);

            $('#add-to-cart').css('opacity', '1');
            $('#add-to-cart').on('click.bundletool', function (e) {
                if (bundle.bundleItems.length <= 0) {
                    return false;
                }

                for (var i = 0; i < bundle.bundleItems.length; i++) {
                    var bi = bundle.bundleItems[i];
                    $('#add-to-cart-items').append('<input type="hidden" name="items[' + i + '].Key" value="' + bi.productId + '" />');
                    $('#add-to-cart-items').append('<input type="hidden" name="items[' + i + '].Value" value="' + bi.quantity + '" />');
                }

                // submit form
                document.forms['form-add-bundle-to-cart'].submit();

                return false;
            });
        }
        else {
            $('#bt-summary-bundle-price-normal').text('--.--').data('bundle-price-normal', 0);
            $('#bt-summary-bundle-price').text('--.--').data('bundle-price', 0);
            $('#bt-summary-bundle-price-discount').text('--.--').data('bundle-price-discount', 0);
            $('#bt-summary-bundle-shipping-time').text('--.--');

            $('#add-to-cart').css('opacity', '0.5');
            $('#add-to-cart').off('click.bundletool');

            if (bundle.bundleError != null && bundle.bundleError.length > 0) {
                $('#bundle-error').show().text(bundle.bundleError);
            }
        }

        $('#bt-summary-items input').off('change.bundletool').on('change.bundletool', function (e) {
            var $this = $(this),
                productId = parseInt($(this).data('product-id')),
                quantity = parseInt($(this).val());

            //console.log('productId', productId);
            //console.log('quantity', quantity);

            var bundleItem = bundle.bundleItems.filter(function (el) {
                return el.productId === productId;
            })[0];

            //console.log('bundleItem', bundleItem);

            bundleItem.quantity = quantity;

            //console.log('bundleItem', bundleItem);
            //console.log('bundleItems', bundle.bundleItems);
            //console.log('bundle', bundle);

            updateBundleSummary();

            //e.preventDefault();
            //alert('efefe');
        });

        $('#bt-summary-items i.fa-trash-o').off('click.bundletool').on('click.bundletool', function (e) {
            var $this = $(this),
                productId = parseInt($(this).data('product-id'));

            var bundleItem = bundle.bundleItems.filter(function (el) {
                return el.productId === productId;
            })[0];

            removeBundleItem(bundleItem);

            var $item = $('#product-list a[data-product-id="' + productId + '"]'),
                $ctaButton = $item.parent().find('.bt-remove');

            switchBundleCtaButton($ctaButton);

            updateBundleSummary();
        });
    })
    .fail(function () {
        alert("Es ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut / An error occured, please try again later");
        //console.log('AJAX fail');
    })
    .always(function () {
        //console.log('AJAX always');
    });
}

function switchBundleCtaButton($ctaButton) {
    $ctaButton.addClass('hddn');
    $ctaButton.parent().find('input').not($ctaButton).removeClass('hddn');
}

function switchBundleButtons() {
    var loadedProductIds = $('#product-list a').map(function() {
        return $(this).data('product-id');
    }).toArray();

    var bundleProductIds = $.map(bundle.bundleItems, function(el) {
        return el.productId;
    });

    var intersectedProductIds = $.map(loadedProductIds, function(el) {
        return $.inArray(el, bundleProductIds) < 0 ? null : el;
    });

    for (var i = 0; i < intersectedProductIds.length; i++) {
        var productId = intersectedProductIds[i],
            $item = $('#product-list a[data-product-id="' + productId + '"]'),
            $ctaButton = $item.parent().find('.bt-add');

        switchBundleCtaButton($ctaButton);
    }
}

function onBackKeyDown() {
    if ($.pgwModal('isOpen') && window.location.hash === '') {
        window.history.pushState({state:1}, "State 1", "?state=1");
        $.pgwModal('close');
    }
}

function loadBundleProducts(url) {

    url = url.toLowerCase();

    //$('#bt-articles').html('<p class="ta-center"><i class="fa fa-spinner fa-pulse fa-2x"></i></p>');
    $('#bt-articles').css('opacity', '0.3');
    $('#bt-loading').show();

    $.ajax({
        url: url,
        type: 'POST',
        //data: $('#form-price-proposal').serialize()
    })
    .done(function (result) {
        //console.log('AJAX DONE');

        // destroy everything, otherwise the ui might stutter
        $('#bt-articles .button a, #pagination a').off('click.bundletool');
        $('#pagination select').off('change.bundletool');
        $('#bt-articles #product-list .col a').off('click.bundletool');
        $('#product-list .col .name').dotdotdot('destroy.dot');

        $('#bt-articles').empty().html(result);

        $('#bt-articles .button a, #pagination a, #grid-sorting a').not('.show-filter').on('click.bundletool', function (e) {
            e.preventDefault();
            url = $(this).attr('href');
            loadBundleProducts(url);
        });

        $('#pagination select').on('change.bundletool', function () {
            // DJL CHANGE
            //url = $(':selected', this).find('a').attr('href');
            url = $(':selected', this).data('location');
            loadBundleProducts(url);
        });

        $('#ddlSortBy').on('change.bundletool', function (e) {
            var selectedValue = $(':selected', this).val(),
                url = $('#grid-sorting a[data-sortBy="' + selectedValue + '"]').attr('href');

            loadBundleProducts(url);
        });

        $('#bt-articles #product-list .col a').on('click.bundletool', function (e) {
            e.preventDefault();

            var btProductDetailUrl = urlProductDetail,
                productId = $(this).data('product-id');

            btProductDetailUrl = btProductDetailUrl.replace('/0/', '/' + productId + '/');

            $.pgwModal({
                target: '#bt-product-detail-overlay',
                title: modalTitle,
                url: btProductDetailUrl,
                maxWidth: 960,
                loadingContent: '<p class="ta-center"><i class="fa fa-spinner fa-pulse fa-2x"></i></p>'
            });

            window.location.hash = productId;
        });

        // apply dotdotdot to product names to shorten them
        $('#bt-articles #product-list .col .name').dotdotdot({
            watch: true
        });

        // apply hover effect to highlight the same item in summary
        //$('#bt-articles #product-list .col a').off('hover').on('hover', function(e) {

        //});

        // switch buttons for products that are already in the bundle
        switchBundleButtons();

        // show the stuff
        $('#bt-articles').css('opacity', '1');
        $('#bt-loading').hide();

        if (isMobileViewport()) {
            $(document).scrollTop($('#bt-left').offset().top - 65);
        }
        else {
            $(document).scrollTop($('#bt-left').offset().top - 10);
        }
    })
    .fail(function () {
        alert("Es ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut / An error occured, please try again later");
        //console.log('AJAX fail');
    })
    .always(function () {
        //console.log('AJAX always');
    });

}

function bundleToolSnapping() {
    var $btContainer = $('#bt-container'),
        $btLeft = $('#bt-left'),
        $btRight = $('#bt-right'),
        $btSummary = $('#bt-summary'),
        $h1 = $('h1'); // DJL CHANGE

    var btSummaryCalcFix = parseInt($btSummary.css('padding-top').replace('px', '')) + parseInt($btSummary.css('padding-bottom').replace('px', '')) + parseInt($btSummary.css('borderTopWidth').replace('px', '')) + parseInt($btSummary.css('borderBottomWidth').replace('px', '')),
        enableSnappingBuffer = 15;

    // snap summaryDiv for desktop
    $(window).scroll(function () {

        if (!isTabletViewport()) {

            var windowHeight = $(window).height(),
                btContainerOffsetY = parseInt($btContainer.offset().top),
                posY = parseInt($(window).scrollTop()),
                h1Margin = parseInt($h1.css('margin-bottom').replace('px', '')),
                btLeftHeight = parseInt($btLeft.outerHeight()),
                btSummaryHeight = parseInt($btSummary.outerHeight());

            if (btSummaryHeight + enableSnappingBuffer < windowHeight) {
                var snapStart = btContainerOffsetY - h1Margin,
                    snapEnd = btLeftHeight - btSummaryCalcFix, // 47 = 2x margin von pagination (15px) + margin + 2x border 1px
                    paddingTop = posY - btContainerOffsetY + h1Margin;

                if (posY <= snapStart) {
                    //console.log('no snap 1');
                    $btRight.css('padding-top', 0);
                }
                else if (posY > snapStart) {
                    //console.log('posY', posY, 'snapEnd', snapEnd, 'paddingTop', paddingTop, 'btSummaryHeight', btSummaryHeight, 'btLeftHeight', btLeftHeight, 'btRightHeight', btRightHeight);
                    if (posY < snapEnd && paddingTop + btSummaryHeight < snapEnd) {
                        //console.log('snap');
                        $btRight.css('padding-top', paddingTop);
                    }
                    else {
                        //console.log('no snap 2');
                        $btRight.css('padding-top', snapEnd - btSummaryHeight + h1Margin + 2);
                    }
                }
            }
            else {
                $btRight.css('padding-top', 0);
            }
        }
        else {
            $btRight.css('padding-top', 0);
        }

    });
}



/* OVERRIDE (filter.js) */

function submitFilterResult() {

    var filterUrl = filterBaseUrl;

    for (var i = 0; i < filters.length; i++) {
        var f = filters[i];
        filterUrl += "&f" + (i + 1) + "=" + f.filter;
    }

    loadBundleProducts(filterUrl);

}
var filterBaseUrl = '',
    filters = [];

function prepareFilter(baseUrl, filterUrl, categoryId, queryString) {

    filterBaseUrl = baseUrl;

    $('.show-filter').click(function (e) {
        $('#grid-filtering').toggle();
        $('#grid-sorting').toggleClass('filtering');

        if ($('#grid-filtering').is(':visible')) {
            $('.show-filter i').removeClass('fa-filter').addClass('fa-caret-up');
            $('#product-list .grid').css('opacity', '0.3');

            if ($('#grid-filtering').children('#grid-filtering-container').length == 0) {
                loadFilter(filterUrl, categoryId, queryString);
            }
        }
        else {
            $('.show-filter i').removeClass('fa-caret-up').addClass('fa-filter');
            $('#product-list .grid').css('opacity', '1');
        }

        e.preventDefault();
    });

}

function prepareFilterSearch(baseUrl, filterUrl, search, categoryId, queryString) {

    filterBaseUrl = baseUrl;

    $('.show-filter').click(function (e) {
        $('#grid-filtering').toggle();
        $('#grid-sorting').toggleClass('filtering');

        if ($('#grid-filtering').is(':visible')) {
            $('.show-filter i').removeClass('fa-filter').addClass('fa-caret-up');
            $('#product-list .grid').css('opacity', '0.3');

            if ($('#grid-filtering').children('#grid-filtering-container').length == 0) {
                loadFilterSearch(filterUrl, search, categoryId, queryString);
            }
        }
        else {
            $('.show-filter i').removeClass('fa-caret-up').addClass('fa-filter');
            $('#product-list .grid').css('opacity', '1');
        }

        e.preventDefault();
    });

}

function loadFilter(url, categoryId, queryString) {

    $.ajax({
        type: 'POST',
        cache: false,
        url: url,
        data: { categoryId: categoryId, queryString: queryString, __RequestVerificationToken: getAfToken() }
    })
    .done(function (result) {
        processFilterResult(result);
        filterPreFill();
    })
    .fail(function () {
        $('#product-list .grid').css('opacity', '1');
    })
    .always(function () {

    });

}

function loadFilterSearch(url, search, categoryId, queryString) {

    $.ajax({
        type: 'POST',
        cache: false,
        url: url,
        data: { q: search, cd: categoryId, queryString: queryString, __RequestVerificationToken: getAfToken() }
    })
    .done(function (result) {
        processFilterResult(result);
        filterPreFill();
    })
    .fail(function () {
        $('#product-list .grid').css('opacity', '1');
    })
    .always(function () {

    });

}

function applyCategoryFilter(filterBy) {

    if (filters.length <= 0) {
        $('#filter-by-category-active').hide();
    }
    else {
        var html = '';

        for (var i = 0; i < filters.length; i++) {
            var f = filters[i];

            if (f.filterBy == filterBy) {
                html += '<li data-filterby="' + f.filterBy + '" data-id="' + f.id + '" data-name="' + f.name + '" data-filter="' + f.filter + '"><i class="fa fa-times"></i> ' + f.name + '</li>';
            }
        }

        $('#filter-by-category-active').show();
        $('#filter-by-category-active ul').html(html);

        $('#filter-by-category-active li').off('click.filter.category').on('click.filter.category', function (e) {
            var $elem = $(this),
                elemItem = { filterBy: $elem.data('filterby'), id: $elem.data('id'), name: $elem.data('name'), filter: $elem.data('filter') };

            filters.removeObject(elemItem);
            $elem.remove();

            if ($('#filter-by-category-active li').length <= 0) {
                $('#filter-by-category-active').hide();
            }
        })
    }

    $('#filter-by-category')[0].value = -1;

}

function applyBrandFilter(filterBy) {

    if (filters.length <= 0) {
        $('#filter-by-brand-active').hide();
    }
    else {
        var html = '';

        for (var i = 0; i < filters.length; i++) {
            var f = filters[i];

            if (f.filterBy == filterBy) {
                html += '<li data-filterby="' + f.filterBy + '" data-id="' + f.id + '" data-name="' + f.name + '" data-filter="' + f.filter + '"><i class="fa fa-times"></i> ' + f.name + '</li>';
            }
        }

        $('#filter-by-brand-active').show();
        $('#filter-by-brand-active ul').html(html);

        $('#filter-by-brand-active li').off('click.filter.brand').on('click.filter.brand', function (e) {
            var $elem = $(this),
                elemItem = { filterBy: $elem.data('filterby'), id: $elem.data('id'), name: $elem.data('name'), filter: $elem.data('filter') };

            filters.removeObject(elemItem);
            $elem.remove();

            if ($('#filter-by-brand-active li').length <= 0) {
                $('#filter-by-brand-active').hide();
            }
        })
    }

    $('#filter-by-brand')[0].value = -1;

}

function applyAvailabilityFilter(checked) {
    $('#filter-by-availability')[0].checked = checked;
}

function processFilterResult(result) {

    $('#grid-filtering').html(result);

    if ($('#filter-by-category').length > 0) {

        $('#filter-by-category')[0].value = -1;

        $('#filter-by-category').change(function (e) {
            var $selectedItem = $(this).find(':selected');

            if ($selectedItem.val() == -1) {
                return;
            }

            var id = $selectedItem.data('id'),
                filterBy = $selectedItem.data('filterby'),
                filter = $selectedItem.data('filter'),
                name = $selectedItem.data('name');

            var item = { filterBy: filterBy, id: id, name: name, filter: filter };

            filters.pushIfNotExist(item, function (e) {
                return e.filter == item.filter;
            });

            applyCategoryFilter(filterBy);
        });

    }

    if ($('#filter-by-brand').length > 0) {

        $('#filter-by-brand')[0].value = -1;

        $('#filter-by-brand').change(function (e) {
            var $selectedItem = $(this).find(':selected');

            if ($selectedItem.val() == -1) {
                return;
            }

            var id = $selectedItem.data('id'),
                filterBy = $selectedItem.data('filterby'),
                filter = $selectedItem.data('filter'),
                name = $selectedItem.data('name');

            var item = { filterBy: filterBy, id: id, name: name, filter: filter };

            filters.pushIfNotExist(item, function (e) {
                return e.filter == item.filter;
            });

            applyBrandFilter(filterBy);
        });

    }

    $('#filter-by-availability').change(function (e) {
        var $selectedItem = $(this),
            filterBy = $selectedItem.data('filterby'),
            id = $selectedItem.data('id'),
            filter = $selectedItem.data('filter'),
            item = { filterBy: filterBy, id: id, filter: filter };

        if (this.checked) {
            filters.pushIfNotExist(item, function (e) {
                // availability = only one filter allowed
                return e.filter == item.filter;
            });
        }
        else {
            filters.removeObject(item);
        }
    });

    $('#filter-by-availability-store').change(function (e) {
        var $selectedItem = $(this).find(':selected'),
            filterBy = $selectedItem.data('filterby'),
            id = $selectedItem.data('id'),
            filter = $selectedItem.data('filter'),
            item = { filterBy: filterBy, id: id, filter: filter };

        if ($('#filter-by-availability').is(':checked')) {
            // trigger event to remove old item from filters
            $('#filter-by-availability').trigger('click');
        }

        $('#filter-by-availability').data('filterBy', filterBy).data('id', id).data('filter', filter);

        // trigger event to add new item with updated data-*-values
        $('#filter-by-availability').trigger('click');
    });

    $('#filter-submit').off('click.filter').on('click.filter', function (e) {
        e.preventDefault();

        submitFilterResult();

        return false;
    });

}

function submitFilterResult() {
    var filterUrl = filterBaseUrl;

    for (var i = 0; i < filters.length; i++) {
        var f = filters[i];
        filterUrl += "&f" + (i + 1) + "=" + f.filter;
    }

    window.location = filterUrl;
}
function isMobileViewport() {
    //return $(document).width() + getScrollbarWidth() < 768;
    return window.innerWidth < 768;
};

function isTabletViewport() {
    //return $(document).width() + getScrollbarWidth() < 1024;
    return window.innerWidth <= 1024;
};

function isMobileBrowser() {
    return typeof window.orientation !== 'undefined';
};

function getAfToken() {
    return $('input[name="__RequestVerificationToken"]').last().val();
};
var kornCommerce = kornCommerce || {};

kornCommerce.settings = kornCommerce.settings || {};

kornCommerce.init = function () {

};
;kornCommerce.accordion = kornCommerce.accordion || {};

kornCommerce.accordion.init = function () {
    $('.accordion .header').off('click.accordion').on('click.accordion', function (e) {
        var $this = $(this);

        // toggle class of accordion container
        $this.parent().toggleClass('active').promise().done(function () {
            // find and refresh possible owl carousels
            kornCommerce.carousel.refreshOwlCarousel($this.next().find('.owl-carousel'));
        });
    });
};
; kornCommerce.button = kornCommerce.button || {};

kornCommerce.button.reset = function () {

    // prevent bug where firefox keeps disabled state through page refreshed, despite the usage of autocomplete="off"
    try {
        window.onload = window.onpageshow = function () {
            $('button[type="submit"][autocomplete="off"][disabled]').removeAttr('disabled').find('.spinner-wrapper').remove();
        };
    } catch (e) {
        // nothing
    }

};

kornCommerce.button.startLoading = function ($elem) {

    $elem.attr('disabled', 'disabled').append('<div class="spinner-wrapper"><span class="spinner d-block"></span></div>');

    if ($elem.hasClass('btn-chevron-left')) {
        $elem.removeClass('btn-chevron-left').addClass('btn-chevron-left-loading');
    }

    if ($elem.hasClass('btn-chevron-right')) {
        $elem.removeClass('btn-chevron-right').addClass('btn-chevron-right-loading');
    }
};

kornCommerce.button.endLoading = function ($elem) {

    $elem.removeAttr('disabled').children().remove('.spinner-wrapper');

    if ($elem.hasClass('btn-chevron-left-loading')) {
        $elem.removeClass('btn-chevron-left-loading').addClass('btn-chevron-left');
    }

    if ($elem.hasClass('btn-chevron-right-loading')) {
        $elem.removeClass('btn-chevron-right-loading').addClass('btn-chevron-right');
    }
};

kornCommerce.button.forceDisable = function ($elem) {
    try {
        window.onload = window.onpageshow = function () {
            $elem.attr('disabled', 'disabled');
        };
    } catch (e) {
        // nothing
    }
};
; kornCommerce.carousel = kornCommerce.carousel || {};

kornCommerce.carousel.init = function ($elem, customOptions) {

    function applyEllipsis($elem) {
        $elem.find('.name span:last-child').ellipsis({
            lines: 2,             // force ellipsis after a certain number of lines. Default is 'auto'
            ellipClass: 'ellip',  // class used for ellipsis wrapper and to namespace ellip line
            responsive: false     // set to true if you want ellipsis to update on window resize. Default is false
        });
    };

    var options = {
        nav: true,
        navText: [
            '<i class="fa fa-fw fa-chevron-left"></i>',
            '<i class="fa fa-fw fa-chevron-right"></i>'
        ],
        lazyLoad: true,
        items: 5,
        smartSpeed: 200,
        responsive: {
            0: {
                items: 2,
            },
            680: {
                items: 3,
            },
            900: {
                items: 4,
            },
            1280: {
                items: 5,
            }
        },
        slideBy: 'page',
        onInitialized: function (event) {
            applyEllipsis($(event.target));
        },
        onResized: function (event) {
            applyEllipsis($(event.target));
        },
    };

    if (typeof (customOptions) !== 'undefined') {
        for (var attrname in customOptions) {
            options[attrname] = customOptions[attrname];
        }
    }

    //console.log(options);

    $elem.owlCarousel(options);
};

kornCommerce.carousel.initVideo = function ($elem) {

    var options = {
        nav: true,
        navText: [
            '<i class="fa fa-fw fa-chevron-left"></i>',
            '<i class="fa fa-fw fa-chevron-right"></i>'
        ],
        items: 3,
        margin: 10,
        video: true,
        lazyLoad: true,
        center: false,
        responsive: {
            0: {
                items: 1,
            },
            768: {
                items: 2,
            },
            1280: {
                items: 3,
            }
        },
    };

    $elem.owlCarousel(options);

};

kornCommerce.carousel.refreshOwlCarousel = function ($elems) {
    if ($elems !== undefined && $elems !== null && $elems.length > 0) {
        $elems.owlCarousel().trigger('refresh.owl.carousel');
    }
};
; kornCommerce.checkout = kornCommerce.checkout || {};

kornCommerce.checkout.init = function () {

    // show server-side validation errors
    $('.field-validation-error').siblings('input, select').addClass('invalid')

};

kornCommerce.checkout.initShipping = function (urlShippingTable, spinnerClass, errorText, chooseText) {

    function checkBillingRequired() {
        if ($('#cUseCustomBillingAddress:checked').length > 0) {
            $('#billing-address .b-required').each(function () {
                $(this).attr('required', 'required');
            });
            $('#billing-address').show();
        }
        else {
            $('#billing-address .b-required').each(function () {
                $(this).removeAttr('required');
            });
            $('#billing-address').hide();
        }
    }

    function getShippingTable(urlShippingTable, spinnerClass, errorText, chooseText) {

        var countryId = parseInt($('#ShippingCountry').find(':selected').val()),
            currentShippingTypeId = parseInt($('#CurrentShippingTypeId').val());

        if (typeof countryId === 'number' && (countryId % 1) === 0) {
            //$(spinnerClass).removeClass('hidden');
            $(spinnerClass).show();
            $('#shipping-table').empty();

            $.ajax({
                type: 'GET',
                cache: false,
                url: urlShippingTable,
                data: { countryId: countryId, currentShippingTypeId: currentShippingTypeId }
            })
            .done(function (result) {
                $('#shipping-table').html(result);
            })
            .fail(function () {
                $('#shipping-table').html(errorText);
            })
            .always(function () {
                //$(spinnerClass).addClass('hidden');
                $(spinnerClass).hide();
            });
        }
        else {
            $('#shipping-table').text(chooseText);
        }
    }

    // billing form init
    if ($('input[name="UseCustomBillingAddress"]').val() === 'true' || $('#billing-address span.field-validation-error').length > 0) {
        $('#cUseCustomBillingAddress').prop('checked', true);
    }
    else {
        $('#cUseCustomBillingAddress').prop('checked', false);
    }

    checkBillingRequired();

    // billing form events
    $('#use-custom-billing').off('click.checkout').on('click.checkout', function (e) {
        var $this = $(this),
            $chk = $this.find('input[type="checkbox"]'),
            checked = false;

        if ($chk.is(':checked')) {
            checked = false;
        }
        else {
            checked = true;
        }

        $chk.prop('checked', checked);
        $('input[name="UseCustomBillingAddress"]').val(checked.toString());

        checkBillingRequired();

        e.preventDefault();
        e.stopPropagation();
    });

    // load shipping table
    getShippingTable(urlShippingTable, spinnerClass, errorText, chooseText);

    $('#ShippingCountry').change(function () {
        getShippingTable(urlShippingTable, spinnerClass, errorText, chooseText);
    });

    // address picker
    $('.address-picker').change(function (e) {
        var sender = $(e.target);
        var option = sender.find(':selected');
        var prefix = sender.hasClass('shipping') ? 'Shipping' : 'Billing';

        // set data
        // trigger 'change' event for validation
        // trigger 'input' event for label activation
        $('#' + prefix + 'FirstName').val(option.data('firstname')).trigger('change').trigger('input');
        $('#' + prefix + 'LastName').val(option.data('lastname')).trigger('change').trigger('input');
        $('#' + prefix + 'Company').val(option.data('company')).trigger('change').trigger('input');
        $('#' + prefix + 'Street').val(option.data('street')).trigger('change').trigger('input');
        $('#' + prefix + 'ZipPostalCode').val(option.data('zippostalcode')).trigger('change').trigger('input');
        $('#' + prefix + 'City').val(option.data('city')).trigger('change').trigger('input');
        $('#' + prefix + 'Country').val(option.data('countryid')).trigger('change').trigger('input');
        $('#' + prefix + 'PhoneNumber').val(option.data('phone')).trigger('change').trigger('input');

        // de-select current dropdown
        $(this).blur();
    });

};

kornCommerce.checkout.initShippingTable = function () {

    $('#shipping-table .rb-wrapper').off('click.checkout').on('click.checkout', function (e) {
        var $this = $(this);

        $('#shipping-table .rb-wrapper').removeClass('active');
        $this.addClass('active');

        $this.find('input[type="radio"]').prop('checked', true);

        // determine shippingTypeId
        var selectedShippingTypeId = parseInt($this.data('shipping-type-id'));

        // set value to hidden field for post data
        $('#selectedShippingType').val(selectedShippingTypeId);

        // trigger select once
        $('#ddlStore option').each(function () {
            if (parseInt($(this).val()) === selectedShippingTypeId) {
                $('#ddlStore').trigger('change');
                return false;
            }
        });

        e.preventDefault();
        e.stopPropagation();
    });

    $('#ddlStore').off('change.checkout').on('change.checkout', function (e) {
        var $selectedOption = $(':selected', this),
            value = parseInt($selectedOption.val()),
            inputName = $selectedOption.data('shipping-type-id'),
            description = $selectedOption.data('description'),
            googleMapsUrl = $selectedOption.data('google-maps-url');

        if (value > 0 && googleMapsUrl.length > 0) {
            $('#store-description').show().html(description);
            $('#store-google-maps-url').show().find('a').attr('href', googleMapsUrl);
        }
        else {
            $('#store-description').hide().empty();
            $('#store-google-maps-url').hide().find('a').attr('href', '#');
        }

        $('#selectedShippingType').val(value);
    });

    if ($('#store-pickup-wrapper').hasClass('current')) {
        $('#store-pickup-wrapper').siblings('.rb-wrapper').trigger('click');
    }

};

kornCommerce.checkout.initPayment = function () {

    $('#payment-types .rb-wrapper').off('click.checkout').on('click.checkout', function (e) {

        var $this = $(this);

        if ($this.hasClass('disabled')) {
            return false;
        }

        if (!$this.hasClass('active')) {
            // activate underlying radio button
            $this.find('input[type="radio"]').prop('checked', true);

            // determine paymentTypeId
            var selectedPaymentTypeId = parseInt($this.data('payment-type-id'));

            // set value to hidden field for post data
            $('#selectedPaymentType').val(selectedPaymentTypeId);

            // set url to form action
            $('#form-checkout').attr('action', $this.data('payment-url'));
        }

        // handle "active" css class
        $('#payment-types .rb-wrapper').removeClass('active');
        $this.addClass('active');

    });

    // trigger click for current selected element (for browser refresh)
    $('.rb-wrapper[data-payment-type-id="' + $('input[name="rbPaymentType"]:checked').val() + '"]').trigger('click');

};

//kornCommerce.checkout.initVerify = function () {
//    $('#form-checkout').on('submit', function () {
//        // DON'T use $('#finish-order').on('click'), because Chrome will prevent form submission if the button is disabled
//        kornCommerce.button.startLoading($('#finish-order'));
//    });
//};
; kornCommerce.content = kornCommerce.content || {};

kornCommerce.content.initModal = function (modalId, modalAjaxContentId, fnCallback) {

    $(modalId).off('show.bs.modal.contentPopup').on('show.bs.modal.contentPopup', function (e) {

        var $this = $(this),
            link = $(e.relatedTarget),
            url = link.data('content'),
            $loadingContainer = $this.find('.alert');

        $loadingContainer.removeClass('hidden');

        $.ajax({
            type: 'GET',
            cache: false,
            url: url,
        })
        .done(function (result) {
            $(modalAjaxContentId).html(result);

            if (fnCallback !== undefined && fnCallback !== null && typeof (fnCallback) === 'function') {
                // execute custom callback
                fnCallback();
            }
        })
        .fail(function () {
            $(modalAjaxContentId).html('Fehler / Error');
        })
        .always(function () {
            $loadingContainer.addClass('hidden');
        });

    });

    $(modalId).off('hidden.bs.modal.contentPopup').on('hidden.bs.modal.contentPopup', function (e) {
        $(modalAjaxContentId).empty();
    });

};
; kornCommerce.cookieConsent = kornCommerce.cookieConsent || {};

kornCommerce.cookieConsent.init = function () {
    // click event for the "Accept all cookies" button
    $('.cconsent-button.accept').off('click.cconsent').on('click.cconsent', function () {
        $('#btn-cconsent-save-all').trigger('click.cconsent');
    });

    // click event for the "Deny all cookies" button
    $('.cconsent-button.deny').off('click.cconsent').on('click.cconsent', function () {
        saveCookieConsentSettings(true);
        $('#modal-cookie-consent').modal('hide');
        $('#cconsent-bar').remove();
    });

    // populate the current settings to modal
    $('#modal-cookie-consent').on('show.bs.modal', function () {
        // get cookie data
        var currentCookieValue = kornCommerce.functions.getCookie('cookieConsent');
        var cookieData = JSON.parse(currentCookieValue);

        // get customer choices
        if (cookieData.p === 1) {
            $('#cb-cookie-consent-preferences').prop('checked', true);
        }

        if (cookieData.m === 1) {
            $('#cb-cookie-consent-marketing').prop('checked', true);
        }

        if (cookieData.s === 1) {
            $('#cb-cookie-consent-statistics').prop('checked', true);
        }
    });

    // click events for save and save-all buttons
    $('#btn-cconsent-save-all').off('click.cconsent').on('click.cconsent', function () {
        $('#modal-cookie-consent').find('input[type="checkbox"]').prop('checked', true);
        saveCookieConsentSettings();
        $('#modal-cookie-consent').modal('hide');
        $('#cconsent-bar').remove();
    });

    $('#btn-cconsent-save-custom').off('click.cconsent').on('click.cconsent', function () {
        saveCookieConsentSettings();
        $('#modal-cookie-consent').modal('hide');
        $('#cconsent-bar').remove();
    });

    // update cookie with the selected values
    function saveCookieConsentSettings(denyAll = false) {

        var days = 90; // must be in sync with KornCommerce.Core.Configuration.CookieConfiguration

        // get cookie data
        var currentCookieValue = kornCommerce.functions.getCookie('cookieConsent');
        var cookieData = JSON.parse(currentCookieValue);

        // required cookies are always true
        cookieData.r = 1;

        // get customer choices
        if (!denyAll && $('#cb-cookie-consent-preferences').prop('checked')) {
            cookieData.p = 1;
        }
        else {
            cookieData.p = 0;

            // delete remnants
            removePreferencesCookies();
        }

        if (!denyAll && $('#cb-cookie-consent-marketing').prop('checked')) {
            cookieData.m = 1;

            // immediately trigger after consenting
            enableGoogleTagManager();
        }
        else {
            cookieData.m = 0;

            // delete remnants
            removeMarketingCookies();
        }

        if (!denyAll && $('#cb-cookie-consent-statistics').prop('checked')) {
            cookieData.s = 1;
        }
        else {
            cookieData.s = 0;

            // delete remnants
            removeStatisticsCookies();
        }

        // set cookie data
        var newCookieValue = JSON.stringify(cookieData);

        kornCommerce.functions.setCookie('cookieConsent', newCookieValue, days);
    }

    function enableGoogleTagManager() {
        if ($('.script-gtm').length === 0) {
            return;
        }

        $('.script-gtm').each(function (index) {
            var $this = $(this);

            $('head').append(''
                + '<script type="text/javascript">'
                + $this.html()
                + '</script>'
            );
        });
    }

    function removePreferencesCookies() {
        // currently not used
    }

    function removeMarketingCookies() {
        removeCookie('_dc_gtm_' + gaProperty); // gaProperty is a global variable, defined in MasterLayout
        removeCookie('_ga');
        removeCookie('_gat_' + gaProperty);
        removeCookie('_gcl_au');
        removeCookie('_gid');
    }

    function removeStatisticsCookies() {
        // currently not used
    }

    function removeCookie(name) {
        document.cookie = name + '=; path=/; domain=' + document.domain + '; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
    }
};

// check if an element exists in array using a comparer function
// comparer : function(currentElement)
Array.prototype.inArray = function (comparer) {
    for (var i = 0; i < this.length; i++) {
        if (comparer(this[i])) {
            return true;
        }
    }
    return false;
};

// adds an element to the array if it does not already exist using a comparer
// function
Array.prototype.pushIfNotExist = function (element, comparer) {
    if (!this.inArray(comparer)) {
        this.push(element);
    }
};

// find and remove a simple item from an array
Array.prototype.remove = function (element) {
    var i = this.indexOf(element);
    if (i !== -1) {
        this.splice(i, 1);
        return true;
    }
}

// find and remove a complex item from an array
// BUGGED ! wird aber noch von productList filter genutzt und funktioniert dort lustigerweise
Array.prototype.removeObject = function (element) {
    var exists = true,
        existsIndex = -1;

    for (var propertyName in element) {
        var index = -1;

        for (var i = 0, len = this.length; i < len; i++) {
            if (this[i][propertyName] === element[propertyName]) {
                index = i;
                break;
            }
        }

        existsIndex = index;
        exists &= index >= 0;
    }

    if (exists) {
        this.splice(existsIndex, 1);
    }
}

// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
if (!Array.prototype.filter) {
    Array.prototype.filter = function (fun/*, thisArg*/) {
        'use strict';

        if (this === void 0 || this === null) {
            throw new TypeError();
        }

        var t = Object(this);
        var len = t.length >>> 0;
        if (typeof fun !== 'function') {
            throw new TypeError();
        }

        var res = [];
        var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
        for (var i = 0; i < len; i++) {
            if (i in t) {
                var val = t[i];

                // NOTE: Technically this should Object.defineProperty at
                //       the next index, as push can be affected by
                //       properties on Object.prototype and Array.prototype.
                //       But that method's new, and collisions should be
                //       rare, so use the more-compatible alternative.
                if (fun.call(thisArg, val, i, t)) {
                    res.push(val);
                }
            }
        }

        return res;
    };
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
//// Production steps of ECMA-262, Edition 5, 15.4.4.18
//// Reference: http://es5.github.io/#x15.4.4.18
//if (!Array.prototype.forEach) {

//    Array.prototype.forEach = function (callback, thisArg) {

//        var T, k;

//        if (this == null) {
//            throw new TypeError(' this is null or not defined');
//        }

//        // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
//        var O = Object(this);

//        // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
//        // 3. Let len be ToUint32(lenValue).
//        var len = O.length >>> 0;

//        // 4. If IsCallable(callback) is false, throw a TypeError exception.
//        // See: http://es5.github.com/#x9.11
//        if (typeof callback !== "function") {
//            throw new TypeError(callback + ' is not a function');
//        }

//        // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
//        if (arguments.length > 1) {
//            T = thisArg;
//        }

//        // 6. Let k be 0
//        k = 0;

//        // 7. Repeat, while k < len
//        while (k < len) {

//            var kValue;

//            // a. Let Pk be ToString(k).
//            //   This is implicit for LHS operands of the in operator
//            // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
//            //   This step can be combined with c
//            // c. If kPresent is true, then
//            if (k in O) {

//                // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
//                kValue = O[k];

//                // ii. Call the Call internal method of callback with T as the this value and
//                // argument list containing kValue, k, and O.
//                callback.call(T, kValue, k, O);
//            }
//            // d. Increase k by 1.
//            k++;
//        }
//        // 8. return undefined
//    };
//}

// The trim() method removes whitespace from both ends of the string.
if (!String.prototype.trim) {
    (function () {
        // Make sure we trim BOM and NBSP
        var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
        String.prototype.trim = function () {
            return this.replace(rtrim, '');
        };
    })();
}

if (!String.prototype.removeWhitespace) {
    (function () {
        var trim = / /g;
        String.prototype.removeWhitespace = function () {
            return this.replace(trim, '');
        };
    })();
}

if (!String.prototype.isNumeric) {
    (function () {
        String.prototype.isNumeric = function () {
            return /^[0-9]+$/i.test(this.removeWhitespace());
        };
    })();
}

if (!String.prototype.isNullOrWhiteSpace) {
    (function () {
        String.prototype.isNullOrWhiteSpace = function () {
            return (!this || this.length === 0 || /^\s*$/.test(this))
        };
    })();
}
; kornCommerce.financing = kornCommerce.financing || {};

kornCommerce.financing.init = function (isInCart) {

    kornCommerce.content.initModal('#modal-financing', '#financing-container', initFinancingForm);

    function initFinancingForm() {

        // replace modal title
        var title = $('.financing-container-content').data('title');

        if (title != null && title.length > 0) {
            $('#modal-financing .modal-title').text(title);
        }

        // load stuff
        kornCommerce.global.buttons();
        kornCommerce.form.input();
        kornCommerce.form.inputValidation();
        kornCommerce.form.placeholder();

        // bind events
        $('#form-financing').submit(function (e) {
            e.preventDefault();

            $.ajax({
                url: $('#form-financing').attr('action'),
                type: 'POST',
                data: $('#form-financing').serialize()
            })
            .done(function (result) {
                $('#financing-container').html(result);

                // call self
                initFinancingForm();
            })
            .fail(function () {
                $('#financing-container').html('Fehler / Error');
            });
            //.always(function () {

            //});
        });

    };

};
; kornCommerce.form = kornCommerce.form || {};

kornCommerce.form.submit = function () {
    $('form').on('submit', function () {
        // DON'T use $('#finish-order').on('click'), because Chrome will prevent form submission if the button is disabled

        var $btn = $(this).find('button[type=submit]').not('.submit-ajax').not('.no-disable');

        if ($btn.length > 0 && $btn.hasClass('btn')) {
            kornCommerce.button.startLoading($btn);
        }
    });
};

kornCommerce.form.input = function () {

    // set css class on label for its movement
    var inputFields = $('.input-field input, .input-field textarea').not('input[type="file"]');

    // initial
    inputFields.each(function (index) {
        if ($(this).val().trim() !== '') {
            $(this).siblings('label').addClass('active');
        }
    });

    // on focus
    inputFields.off('focus.form').on('focus.form', function () {
        $(this).siblings('label').addClass('active');
    });

    // on blur
    inputFields.off('blur.form').on('blur.form', function () {
        if ($(this).val().trim() === '') {
            $(this).siblings('label').removeClass('active');
        }
    });

    // on input (browser autocomplete) + immediately unbind after one use
    inputFields.off('input.form').on('input.form', function () {
        if ($(this).val().trim() !== '') {
            $(this).siblings('label').addClass('active');
        }

        $(this).off('input.form');
    });


    // add asterisks to labels of required fields
    try {
        $('.input-field input:required').siblings('label').append(' *');
        $('.input-field select:required').parent().siblings('label').append(' *');
        $('.input-field textarea:required').siblings('label').append(' *');
    } catch (e) {
        // lte IE 9
        $('.input-field input[required="required"]').siblings('label').append(' *');
        $('.input-field select[required="required"]').parent().siblings('label').append(' *');
        $('.input-field textarea[required="required"]').siblings('label').append(' *');
    }

};

kornCommerce.form.inputValidation = function () {

    function validateField($elem) {

        var elem = $elem[0],
            inputType = $elem.attr('type'),
            $parentInputField = $elem.closest('.input-field'),
            $validationField = $('span[data-valmsg-for="' + $elem.attr('id') + '"]');

        if (inputType !== undefined) {
            inputType = inputType.toLowerCase();
        }

        var isValid = elem.checkValidity();

        // apply css class to input
        if ($elem.val().length > 0) {
            if (isValid) {
                $elem.addClass('valid');
                $elem.removeClass('invalid');
            }
            else {
                $elem.addClass('invalid');
                $elem.removeClass('valid');
            }
        }
        else {
            $elem.removeClass('valid');
            $elem.removeClass('invalid');
        }
    };

    function validatePasswordField($elem) {
        var $equalToOther = $($elem.data('val-equalto-other').replace('*.', '#'));

        if ($elem.val() !== $equalToOther.val()) {
            $elem.addClass('invalid');
            $elem.removeClass('valid');
        }
        else {
            $elem.addClass('valid');
            $elem.removeClass('invalid');
        }
    };

    $('.input-field input.validate, .input-field textarea.validate, .input-field select.validate').off('change.form').on('change.form', function () {
        try {
            validateField($(this));
        } catch (e) { }
    });

    $('.input-field input.validate-password').off('change.form.validatePw').on('change.form.validatePw', function () {
        try {
            validatePasswordField($(this));
        } catch (e) { }
    });

    // show server-side errors
    $('.field-validation-error.field-validation.hidden').removeClass('hidden');
    $('.input-validation-error').parent().next().removeClass('hidden');

};

kornCommerce.form.textarea = function () {

    function textareaAutoResize($textarea) {

        //// set font properties of hiddenDiv
        //var fontFamily = $textarea.css('font-family');
        //var fontSize = $textarea.css('font-size');
        //var lineHeight = $textarea.css('line-height');

        //if (fontSize) { hiddenDiv.css('font-size', fontSize); }
        //if (fontFamily) { hiddenDiv.css('font-family', fontFamily); }
        //if (lineHeight) { hiddenDiv.css('line-height', lineHeight); }

        //if ($textarea.attr('wrap') === "off") {
        //    hiddenDiv.css('overflow-wrap', "normal")
        //             .css('white-space', "pre");
        //}

        // write text in hiddenDiv
        hiddenDiv.text($textarea.val() + '\n');

        var content = hiddenDiv.html().replace(/\n/g, '<br>');

        hiddenDiv.html(content);

        // When textarea is hidden, width goes crazy.
        // Approximate with half of window size
        if ($textarea.is(':visible')) {
            hiddenDiv.css('width', $textarea.width());
        }
        else {
            hiddenDiv.css('width', $(window).width() / 2);
        }

        // calculate textarea height based on hiddenDiv
        var height = hiddenDiv.height() + parseInt($textarea.css('font-size'), 10);

        // set textarea height
        $textarea.css('height', height);
    }

    // Textarea Auto Resize
    var hiddenDiv = $('.hiddendiv').first();
    if (!hiddenDiv.length) {
        hiddenDiv = $('<div class="hiddendiv"></div>');
        $('body').append(hiddenDiv);
    }

    var text_area_selector = '.kc-input-container textarea';

    $(text_area_selector).each(function () {
        var $textarea = $(this);
        if ($textarea.val().length) {
            textareaAutoResize($textarea);
        }
    });

    $('body').off('keyup.form keydown.form autoresize.form').on('keyup.form keydown.form autoresize.form', text_area_selector, function () {
        textareaAutoResize($(this));
    });

};

kornCommerce.form.characterCounter = function () {

    $('textarea').off('keyup.form').on('keyup.form', function (e) {
        var $this = $(this),
            $counterElement = $this.siblings('.character-counter');

        if ($this.attr('length') === undefined) {
            //console.log('ABORT - no length attribute');
            return true;
        }

        var maxLength = $this.attr('length'),
            actualLength = $this.val().length,
            isValidLength = actualLength <= maxLength;

        $counterElement.html(actualLength + ' / ' + maxLength);

        var inputHasInvalidClass = $this.hasClass('invalid');

        if (isValidLength && inputHasInvalidClass) {
            $this.removeClass('invalid');
        }
        else if (!isValidLength && !inputHasInvalidClass) {
            $this.removeClass('valid');
            $this.addClass('invalid');
        }
    });

    $('textarea').trigger('keyup');

};

kornCommerce.form.placeholder = function () {

    // don't replace that with $('*[data-placeholder]'), because of both performance and css
    $('.d-placeholder').each(function () {
        var $this = $(this),
            placeholderText = $this.data('placeholder'),
            label = $this.siblings('label');

        if (!placeholderText || placeholderText.length === 0) {
            return;
        }

        //console.log(placeholderText, label);

        $(label).append('<small>(' + placeholderText + ')</small>');
    });

};

kornCommerce.form.imageUpload = function () {

    //console.log('init image upload');

    // check if browser supports file upload
    if (!(window.File && window.FileReader && window.FormData)) {
        // file upload is not supported

        $('#input-file-fail-notSupported').show();
        $('#image-upload-container').hide();

        //console.log('file upload not supported');

        return;
    }

    // reset all values because file inputs cannot be repopulated after a post due to browser security
    resetValues($('#image-upload-container #File'));

    $('input[type="file"]').off('change.fileUploadInput').on('change.fileUploadInput', function (e) {
        //console.log('input file changed');

        // reset error messages
        $('#input-file-fail-toBig').hide();
        $('#input-file-fail-format').hide();

        var $this = $(this),
            file = e.target.files[0],
            maxFileSize = parseInt($this.data('maxfilesize')),
            allowedFileTypes = $this.attr('accept');

        //console.log('file size:', file.size, typeof (file.size));
        //console.log('max size:', maxFileSize, typeof (maxFileSize));

        // validate file size
        if (file.size > maxFileSize) {
            $('#input-file-fail-toBig').show();
            //console.log('file too big');

            resetValues($this);

            return false;
        }

        // validate file type
        if (allowedFileTypes.indexOf(file.type) <= 0) {
            $('#input-file-fail-format').show();
            //console.log('file type not supported');

            resetValues($this);

            return false;
        }

        // call async function from non-async function
        //console.log('read file');

        readFileAsync(file).then(result => {
            $this.siblings('input[name="FilePath"]').first().val($this.val());
            $this.siblings('input[name="FileType"]').first().val(file.type);
            $this.siblings('input[name="FileData"]').first().val(result);
        });
    });

    function resetValues($fileInput) {
        //console.log('reset Values', $fileInput);

        $fileInput.val('');
        $fileInput.siblings('input[name="FilePath"]').first().val('');
        $fileInput.siblings('input[name="FileType"]').first().val('');
        $fileInput.siblings('input[name="FileData"]').first().val('');
    }

    async function readFileAsync(file) {
        return new Promise((resolve, reject) => {
            let reader = new FileReader();

            reader.onloadend = () => {
                resolve(reader.result);
            };

            reader.onerror = reject;

            reader.readAsDataURL(file);
        })
    }
};
; kornCommerce.frontpage = kornCommerce.frontpage || {};

kornCommerce.frontpage.init = function () {

    // top carousel
    $('#carousel').owlCarousel({
        loop: true,
        nav: false,
        lazyLoad: true,
        autoplay: true,
        autoplayHoverPause: true,
        alternateWidthCalculation: true,
        items: 1,
        margin: 1, /* necessary Bugfix to prevent 1px line on the left or right side */
        smartSpeed: 500,
    });

    // cross selling
    kornCommerce.carousel.init($('.cross-selling .owl-carousel'));

    // brands
    $('#brand .owl-carousel').owlCarousel({
        nav: true,
        navText: [
            '<i class="fa fa-chevron-left"></i>',
            '<i class="fa fa-chevron-right"></i>'
        ],
        lazyLoad: true,
        items: 8,
        margin: 1, /* necessary Bugfix to prevent 1px line on the left or right side */
        smartSpeed: 200,
        responsive: {
            0: {
                items: 2,
            },
            680: {
                items: 3,
            },
            900: {
                items: 4,
            },
            1024: {
                items: 6,
            },
            1280: {
                items: 8,
            }
        },
        slideBy: 'page',

        //navigation: true,
        //navigationText: [
        //    '<i class="fa fa-chevron-left"></i>',
        //    '<i class="fa fa-chevron-right"></i>'
        //],
        //lazyLoad: true,
        //scrollPerPage: true,

        //itemsCustom: [
        //    [0, 2],
        //    [319, 3],
        //    [479, 4],
        //    [767, 6],
        //    [1023, 8]
        //]
    });

};
;kornCommerce.functions = kornCommerce.functions || {};

kornCommerce.functions.hasParentClass = function (elem, classname) {
    if (elem === document) {
        return false;
    }
    if ($(elem).hasClass(classname)) {
        return true;
    }

    return elem.parentNode && kornCommerce.functions.hasParentClass(elem.parentNode, classname);
};

kornCommerce.functions.scrollTo = function ($elem, duration, additionalOffset) {
    if ($elem === undefined || $elem.length === 0) $elem = $('a[name="pagetop"]');
    if (duration == undefined) duration = 150;
    if (additionalOffset == undefined) additionalOffset = 0;
    verticalOffset = typeof (verticalOffset) != 'undefined' ? verticalOffset : 0;
    offset = $elem.offset();
    offsetTop = offset.top;
    $('html,body').animate({ scrollTop: offsetTop + additionalOffset }, duration, 'linear');
};

kornCommerce.functions.addUrlParameter = function (url, parameterName, parameterValue, atStart/*Add param before others*/) {
    replaceDuplicates = true;
    if (url.indexOf('#') > 0) {
        var cl = url.indexOf('#');
        urlhash = url.substring(url.indexOf('#'), url.length);
    } else {
        urlhash = '';
        cl = url.length;
    }
    sourceUrl = url.substring(0, cl);

    var urlParts = sourceUrl.split("?");
    var newQueryString = "";

    if (urlParts.length > 1) {
        var parameters = urlParts[1].split("&");
        for (var i = 0; (i < parameters.length) ; i++) {
            var parameterParts = parameters[i].split("=");
            if (!(replaceDuplicates && parameterParts[0] == parameterName)) {
                if (newQueryString == "") {
                    newQueryString = "?";
                }
                else {
                    newQueryString += "&";
                }
                newQueryString += parameterParts[0] + "=" + (parameterParts[1] ? parameterParts[1] : '');
            }
        }
    }
    if (newQueryString == "") {
        newQueryString = "?";
    }

    if (atStart) {
        newQueryString = '?' + parameterName + "=" + parameterValue + (newQueryString.length > 1 ? '&' + newQueryString.substring(1) : '');
    } else {
        if (newQueryString !== "" && newQueryString != '?') {
            newQueryString += "&";
        }
        newQueryString += parameterName + "=" + (parameterValue ? parameterValue : '');
    }

    return urlParts[0] + newQueryString + urlhash;
};

kornCommerce.functions.getToday = function () {
    var today = new Date(),
        dd = today.getDate(),
        mm = today.getMonth() + 1, //January is 0!
        yyyy = today.getFullYear();

    if (dd < 10) {
        dd = '0' + dd
    }

    if (mm < 10) {
        mm = '0' + mm
    }

    return dd + '.' + mm + '.' + yyyy;
};

kornCommerce.functions.getDateUtc = function(date, hoursToSubtract) {
    if (typeof (hoursToSubtract) !== 'number' || hoursToSubtract < 0) {
        hoursToSubtract = 0;
    }

    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours() - hoursToSubtract, date.getUTCMinutes(), date.getUTCSeconds());
};

kornCommerce.functions.getFileSize = function (number) {
    if (number < 1024) {
        return number + ' bytes';
    } else if (number >= 1024 && number < 1048576) {
        return (number / 1024).toFixed(2).replace(".", ",") + ' KB';
    } else if (number >= 1048576) {
        return (number / 1048576).toFixed(2).replace(".", ",") + ' MB';
    }
};



// https://javascript.info/cookie
// returns the cookie with the given name, or undefined if not found
kornCommerce.functions.getCookie = function (name) {
    let matches = document.cookie.match(new RegExp(
        "(?:^|; )" + name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1') + "=([^;]*)"
    ));
    return matches ? decodeURIComponent(matches[1]) : undefined;
};

kornCommerce.functions.setCookie = function (name, value, days) {

    var date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));

    var options = {
        path: '/',
        expires: date.toUTCString()
    };

    if (location.protocol === 'https:') {
        // if secure is set, SameSite is required
        options.secure = 'secure';
        options.sameSite = 'None';
    }

    //var updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
    var updatedCookie = name + "=" + value;

    for (let optionKey in options) {
        updatedCookie += "; " + optionKey;
        let optionValue = options[optionKey];
        if (optionValue !== true) {
            updatedCookie += "=" + optionValue;
        }
    }

    document.cookie = updatedCookie;
};

kornCommerce.functions.deleteCookie = function (name) {
    kornCommerce.functions.setCookie(name, "", {
        'max-age': -1
    })
};

kornCommerce.functions.escapeRegex = function (string) {
    return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); // $& means the whole matched string
};



// cached version of the $.getScript() function
jQuery.getCachedScript = function (url, options) {
    // Allow user to set any option except for dataType, cache, and url
    options = $.extend(options || {}, {
        dataType: 'script',
        cache: true,
        url: url
    });

    // Use $.ajax() since it is more flexible than $.getScript
    // Return the jqXHR object so we can chain callbacks
    return jQuery.ajax(options);

    // Usage
    // $.cachedScript('ajax/test.js').done(function (script, textStatus) {
    //     console.log(textStatus);
    // });
};

$.fn.oneClickSelect = function () {
    // single click selects entire node
    try {
        return $(this).on('click', function () {
            var range, selection;

            if (window.getSelection) {
                selection = window.getSelection();
                range = document.createRange();
                range.selectNodeContents(this);
                selection.removeAllRanges();
                selection.addRange(range);
            } else if (document.body.createTextRange) {
                range = document.body.createTextRange();
                range.moveToElementText(this);
                range.select();
            }
        });
    }
    catch (ex) {
        console.log('Error', ex);
    }
};


/* Überbleibsel vom MHK für einheitliche InfoCenter Content-Seiten */

function applyStandardOwlCarousel() {
    applyStandardOwlCarouselToElement($('.owl-carousel.standard'));
};

function applyStandardOwlCarouselToElement($elem, overrideOptions) {

    // MHK Fix START
    $elem.addClass('owl-theme');
    $elem.addClass('standard');
    // MHK Fix END

    var options = {
        nav: true,
        navText: [
            '<i class="fa fa-chevron-left"></i>',
            '<i class="fa fa-chevron-right"></i>'
        ],
        lazyLoad: true,
        items: 5,
        smartSpeed: 200,
        responsive: {
            0: {
                items: 2,
            },
            680: {
                items: 3,
            },
            900: {
                items: 4,
            },
            1280: {
                items: 5,
            }
        },
        slideBy: 'page',
    };

    options = $.extend({}, options, overrideOptions);

    $elem.owlCarousel(options);
};
; kornCommerce.global = kornCommerce.global || {};

// global variables
kornCommerce.global.culture;
kornCommerce.global.currencyFormatter;

kornCommerce.global.init = function (culture) {

    // set current culture
    if (typeof culture !== 'undefined' && culture.length > 0) {
        kornCommerce.global.culture = culture;
    }
    else {
        kornCommerce.global.culture = 'de-DE';
    }

    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
    // usage: kornCommerce.global.currencyFormatter.format(number)
    kornCommerce.global.currencyFormatter = new Intl.NumberFormat(kornCommerce.global.culture, {
        style: 'currency',
        currency: 'EUR',
        currencyDisplay: 'code'
    });

    // enable switching between languages
    kornCommerce.global.changeLanguage();

    // click toggles something
    kornCommerce.global.buttons();

    // events for customer account
    kornCommerce.global.account();

    // dropdown location changes, anchors
    kornCommerce.global.location();

    // for social stuff
    kornCommerce.global.share();

    // reset disabled submit buttons (firefox bug)
    kornCommerce.button.reset();

    // off canvas menu
    kornCommerce.navigation.init();

    // search
    kornCommerce.search.init();

    // forms
    kornCommerce.form.submit();

    // accordions
    kornCommerce.accordion.init();

    // modals
    kornCommerce.modal.init();

    // responsive image maps
    $('img[usemap]').rwdImageMaps();

    // register global ajax events
    kornCommerce.global.ajaxEvents();

    // cookie consent
    kornCommerce.cookieConsent.init();


    /* Google Analytics Opt-out */

    // disable tracking if the opt-out cookie exists.
    var disableStr = 'ga-disable-' + gaProperty;

    if (document.cookie.indexOf(disableStr + '=true') > -1) {
        window[disableStr] = true;
    }

    // set opt-out cookie
    $('#gaOptout').on('click', function () {
        document.cookie = disableStr + '=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
        window[disableStr] = true;

        alert('Google Analytics wurde deaktiviert / Google Analytics has been deactivated / Google Analytics a été désactivé');

        return false;
    });

    /* client side bot detection */
    if (google_remarketing_key != null && google_remarketing_key.length > 0) {
        function processLayout() {
            window.removeEventListener('mousemove', processLayout, false);
            window.removeEventListener('touchmove', processLayout, false);
            var f_image = new Image();
            f_image.src = '/content/images/google.gif?' + google_remarketing_key;
        }
        window.addEventListener('mousemove', processLayout, false);
        window.addEventListener('touchmove', processLayout, false);
    }
};

kornCommerce.global.changeLanguage = function () {
    $('a.change-language').on('click.global.changeLanguage', function (e) {
        var $this = $(this),
            $changeLanguageContainer = $this.next('.change-language-container');

        $changeLanguageContainer.toggleClass('hidden');

        e.preventDefault();
        e.stopPropagation();

        $('body').off('click.global.languageContainer').on('click.global.languageContainer', function (e) {
            if (!kornCommerce.functions.hasParentClass(e.target, 'change-language-container')) {
                $changeLanguageContainer.addClass('hidden');
                $('body').off('click.global.changeLanguage');
            }
        });
    });
};

kornCommerce.global.buttons = function () {

    // data-target is toggled if this element is clicked
    $('.click-toggle-target').off('click.global.toggle').on('click.global.toggle', function (e) {
        var $this = $(this),
            $target = $($this.data('toggle'));

        if (typeof $target === 'undefined' || $target.length <= 0) {
            return false;
        }

        $target.toggle();
    });

    // data-focus is focused if this element is clicked
    $('.click-focus-target').off('click.global.focus').on('click.global.focus', function (e) {
        var $this = $(this),
            $target = $($this.data('focus'));

        if (typeof $target === 'undefined' || $target.length <= 0) {
            return false;
        }

        $target.select();
    });

    $('.click-toggle-pw').off('click.global.togglePw').on('click.global.togglePw', function (e) {
        var $this = $(this),
            $target = $($this.data('target'));

        if (typeof $target === 'undefined' || $target.length <= 0) {
            return false;
        }

        if ($target.attr('type') === 'password') {
            $target.attr('type', 'text');
            $this.addClass('text-danger');
        }
        else if ($target.attr('type') === 'text') {
            $target.attr('type', 'password');
            $this.removeClass('text-danger');
        }
    });

};

kornCommerce.global.account = function () {

    $('.logoutForm a').off('click.global.logout').on('click.global.logout', function (e) {
        $(this).parent().submit();
        e.preventDefault();
    });

};

kornCommerce.global.highlightMenu = function (mode, url, openOnMobile) {

    var selector = '';

    if (mode === 'endsWith') {
        selector = '$';
    }
    else if (mode === 'startsWith') {
        selector = '^';
    }
    else if (mode === 'contains') {
        selector = '*';
    }
    // empty selector -> equals

    if (!url || url && url.length === 0) {
        url = window.location.pathname;
    }

    // highlight current page in menu
    var $target = $('.menu-standard a[href' + selector + '="' + url + '"]').last().parent();
    $target = $target.addClass('current');

    if (openOnMobile) {
        if ($target.find('ul').length > 0) {
            $('.content-menu-left.accordion').addClass('active');
        }
    }
};

kornCommerce.global.location = function () {
    $('.js-location').off('change.global').on('change.global', function (e) {
        // redirect
        window.location.href = $(this).find(':selected').data('location');
    });

    // all anchor tags that starts with hash but are not equal hash
    $('a[href^="#"][href!="#"]').off('click.global').on('click.global', function (e) {
        var $this = $(this),
            href = $this.attr('href'),
            openAccordion = $this.hasClass('open-accordion'),
            allowDefault = $this.hasClass('allow-default');

        var $target = $(href);

        if ($target.length === 0) {
            $target = $('a[name="' + href.replace('#', '') + '"]');
        }

        if ($target.length === 0) {
            return;
        }

        // scroll to container
        kornCommerce.functions.scrollTo($target, 250, -15);

        // open accordion
        if (openAccordion && $target.hasClass('accordion') && !$target.hasClass('active')) {
            $target.find('.header').trigger('click');
        }

        // prevent # in url
        if (!allowDefault) {
            e.preventDefault();
        }
    });
};

kornCommerce.global.share = function () {

    $('.korn-share a').off('click.share').on('click.share', function (e) {
        e.preventDefault();

        var url = $(this).attr('href');
        var windowName = '_blank';
        var windowSizeX = '600';
        var windowSizeY = '460';
        var windowSize = 'width=' + windowSizeX + ',height=' + windowSizeY;

        window.open(url, windowName, windowSize);
    });

};

kornCommerce.global.ajaxEvents = function () {

    //$(document).ajaxSend(function (event, request, settings) {
    //    console.log('Triggered ajaxSend handler.');
    //});

    $(document).ajaxStart(function (event) {
        //console.log('Triggered ajaxStart handler.');

        // show button loading indicator
        try {
            var $elem = $(event.target.activeElement);
            var isButton = $elem.hasClass('btn') && $elem.hasClass('submit-ajax');

            //console.log('elem: ', $elem);
            //console.log('isButton', isButton);

            if (isButton) {
                kornCommerce.button.startLoading($elem);
            }
        } catch (ex) {
            //console.log(ex);
        }
    });

    //$(document).ajaxStop(function () {
    //    console.log('Triggered ajaxStop handler.');
    //});

    $(document).ajaxComplete(function (event) {
        //console.log('Triggered ajaxComplete handler.');

        // remove button loading indicator
        try {
            var $elem = $(event.target.activeElement);
            var isButton = $elem.hasClass('btn') && !$elem.hasClass('submit-ajax-redirect');

            //console.log('$elem: ', $elem, 'isBtn: ', isButton);

            if (isButton) {
                kornCommerce.button.endLoading($elem);
            }
        } catch (ex) {
            //console.log(ex);
        }
    });

    //$(document).ajaxError(function (event, jqxhr, settings, thrownError) {
    //    console.log('Triggered ajaxError handler.');
    //});

    //$(document).ajaxSuccess(function (event, request, settings) {
    //    console.log('Triggered ajaxSuccess handler.');
    //});

};

kornCommerce.global.replace404Images = function ($elems, replaceWith) {
    $elems.on('error', function () {
        $(this).attr('src', replaceWith);
    });
};
; kornCommerce.google = kornCommerce.google || {};

// global variables
kornCommerce.google.dataLayer = kornCommerce.google.dataLayer || {};
kornCommerce.google.dataLayer.ecommerce = kornCommerce.google.dataLayer.ecommerce || {};
kornCommerce.google.dataLayer.ecommerce.items = kornCommerce.google.dataLayer.ecommerce.items || [];


// global functions
kornCommerce.google.viewItem = function () {
    try {
        if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
            return;
        }

        dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
        dataLayer.push({
            event: 'view_item',
            ecommerce: kornCommerce.google.dataLayer.ecommerce
        });

    } catch (e) { console.error('exception', e); }
};

kornCommerce.google.addToCart = function () {
    $('#add-to-cart').on('click.googleDataLayer', function () {
        try {
            if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
                return;
            }

            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'add_to_cart',
                ecommerce: kornCommerce.google.dataLayer.ecommerce
            });
        } catch (e) { console.error('exception', e); }
    });
};

kornCommerce.google.addEquipmentsToCart = function () {
    $('#add-equipments-to-cart').on('click.googleDataLayer', function () {
        try {
            var items = [];
            var successful = true;
            var totalValue = 0;

            // get every selected item and put them into the item array
            $('#product-equipment .table-row.active').each(function (index) {
                var $this = $(this);

                try {
                    var item = {
                        item_id: $this.data('model').toString().trim(),
                        item_name: $this.find('.product-equipment-name a').text().trim(),
                        affiliation: $('#product-equipment').data('affiliation').toString().trim(),
                        currency: $('#product-equipment').data('currency').toString().trim(),
                        item_brand: $this.data('brand').toString().trim(),
                        price: parseFloat(parseFloat($this.data('price').toString().trim().replace(',', '.')).toFixed(2)),
                        quantity: parseInt($this.find('.equipment-quantity').val())
                    };

                    totalValue += parseFloat(item.price).toFixed(2) * item.quantity;

                    items.push(item);
                } catch (e) {
                    console.error('exception', e);
                    successful = false;
                }
            });

            // if no error occured until here, send to google
            if (successful) {
                totalValue = parseFloat(parseFloat(totalValue).toFixed(2));

                dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
                dataLayer.push({
                    event: 'add_to_cart',
                    ecommerce: {
                        currency: kornCommerce.google.dataLayer.ecommerce.currency,
                        value: totalValue,
                        items: items
                    }
                });
            }
        } catch (e) { console.error('exception', e); }
    });
};

kornCommerce.google.addBundleToCart = function () {
    $('#add-to-cart').on('click.googleDataLayer', function () {
        try {
            if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
                return;
            }

            // get prices
            var totalValue = parseFloat($('#bt-summary-bundle-price').data('bundle-price'));
            var normalPrice = parseFloat($('#bt-summary-bundle-price-normal').data('bundle-price-normal'));
            var discount = parseFloat($('#bt-summary-bundle-price-discount').data('bundle-price-discount'));

            if (totalValue <= 0) {
                return;
            }

            // apply prices to item
            kornCommerce.google.dataLayer.ecommerce.items[0].price = normalPrice;
            kornCommerce.google.dataLayer.ecommerce.items[0].discount = discount;

            // send to google
            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'add_to_cart',
                ecommerce: {
                    currency: kornCommerce.google.dataLayer.ecommerce.currency,
                    value: totalValue,
                    items: kornCommerce.google.dataLayer.ecommerce.items
                }
            });
        } catch (e) { console.error('exception', e); }
    });
};

kornCommerce.google.viewCart = function () {
    try {
        if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
            return;
        }

        dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
        dataLayer.push({
            event: 'view_cart',
            ecommerce: kornCommerce.google.dataLayer.ecommerce
        });
    } catch (e) { console.error('exception', e); }
};

kornCommerce.google.removeFromCart = function () {
    $('#shopping-cart form.remove-item').on('submit.googleDataLayer', function () {
        try {
            if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
                return;
            }

            var $this = $(this),
                productId = $this.data('item-id');

            // get item from array based on item_id, return as array with one item
            var items = kornCommerce.google.dataLayer.ecommerce.items.filter(x => x.item_id.toString() == productId.toString()).map(x => x);
            var totalValue = kornCommerce.google.getTotalAmount(items);

            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'remove_from_cart',
                ecommerce: {
                    currency: kornCommerce.google.dataLayer.ecommerce.currency,
                    value: totalValue,
                    items: items
                }
            });
        } catch (e) { console.error('exception', e); }
    });
};

kornCommerce.google.beginCheckout = function () {
    $('#shopping-cart-index form.form-checkout-index').on('submit.googleDataLayer', function () {
        try {
            if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
                return;
            }

            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'begin_checkout',
                ecommerce: kornCommerce.google.dataLayer.ecommerce
            });
        } catch (e) { console.error('exception', e); }
    });
};

kornCommerce.google.addShippingInfo = function () {
    $('#form-checkout').on('submit.googleDataLayer', function () {
        try {
            if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
                return;
            }

            var shippingType = $('#shipping-table input:checked').data('shipping-tier').toLowerCase();

            if (shippingType) {
                kornCommerce.google.dataLayer.ecommerce.shipping_tier = shippingType;

                dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
                dataLayer.push({
                    event: 'add_shipping_info',
                    ecommerce: kornCommerce.google.dataLayer.ecommerce
                });
            }
        } catch (e) { console.error('exception', e); }
    });
};


kornCommerce.google.addPaymentInfo = function () {
    $('#form-checkout').on('submit.googleDataLayer', function () {
        try {
            if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
                return;
            }

            var paymentType = $('#payment-types input[type="radio"]:checked').first().parentsUntil('.rb-wrapper').parent().data('payment-type').toLowerCase();

            if (paymentType) {
                kornCommerce.google.dataLayer.ecommerce.payment_type = paymentType;

                dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
                dataLayer.push({
                    event: 'add_payment_info',
                    ecommerce: kornCommerce.google.dataLayer.ecommerce
                });
            }
        } catch (e) { console.error('exception', e); }
    });
};

kornCommerce.google.purchase = function () {
    try {
        if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
            return;
        }

        dataLayer.push({ ecommerce: null, dynamicRemarketing: null, userData: null });
        dataLayer.push({
            event: 'purchase',
            ecommerce: kornCommerce.google.dataLayer.ecommerce,
        });

        var userData = {
            email: kornCommerce.google.dataLayer.ecommerce.email //das wird wohl auch leer sein.
        }

        dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
        dataLayer.push({
            event: 'conversionData',
            userData: userData
        });

    } catch (e) { console.error('exception', e); }
};


// special functions
kornCommerce.google.expressCheckout = function (beginCheckout, shippingType, paymentType) {
    try {
        if (kornCommerce.google.dataLayer.ecommerce.items.length <= 0) {
            return;
        }

        if (beginCheckout) {
            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'begin_checkout',
                ecommerce: kornCommerce.google.dataLayer.ecommerce
            });
        }

        if (shippingType) {
            kornCommerce.google.dataLayer.ecommerce.shipping_tier = shippingType.toLowerCase();

            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'add_shipping_info',
                ecommerce: kornCommerce.google.dataLayer.ecommerce
            });

            kornCommerce.google.dataLayer.ecommerce.shipping_tier = null;
        }

        if (paymentType) {
            kornCommerce.google.dataLayer.ecommerce.payment_type = paymentType.toLowerCase();

            dataLayer.push({ ecommerce: null, dynamicRemarketing: null });
            dataLayer.push({
                event: 'add_payment_info',
                ecommerce: kornCommerce.google.dataLayer.ecommerce
            });

            kornCommerce.google.dataLayer.ecommerce.payment_type = null;
        }

    } catch (e) { console.error('exception', e); }
};


// helper functions
kornCommerce.google.getTotalAmount = function (itemArray) {
    return parseFloat(itemArray.map(item => ('discount' in item ? item.price - item.discount : item.price) * item.quantity).reduce((prev, next) => prev + next).toFixed(2));
};
; kornCommerce.infocenter = kornCommerce.infocenter || {};

kornCommerce.infocenter.initAjaxForm = function (formId, containerId, fnGetFormData, fnCallback) {

    // standard serialization
    function getFormData($form) {
        return $form.serialize();
    };

    // overwrite getFormData with custom function
    if (fnGetFormData !== undefined && fnGetFormData !== null && typeof (fnGetFormData) === 'function') {
        getFormData = fnGetFormData;
    };

    function init() {

        // bind stuff
        kornCommerce.global.buttons();
        kornCommerce.form.input();
        kornCommerce.form.inputValidation();
        kornCommerce.form.placeholder();
        kornCommerce.form.textarea();
        kornCommerce.form.characterCounter();

        // submit handling
        $(formId).submit(function (e) {
            e.preventDefault();

            var $this = $(this);
            var $submit = $this.find('button[type="submit"]');

            // disable submit button during POST
            $submit.addClass('disabled');

            $.ajax({
                url: $this.attr('action'),
                type: 'POST',
                data: getFormData($this)
            })
            .done(function (result) {
                // replace content with result
                $(containerId).html(result);

                if (fnCallback !== undefined && fnCallback !== null && typeof (fnCallback) === 'function') {
                    // execute custom callback instead of standard self-call
                    fnCallback();
                }
                else {
                    // call self to reapply events and shit
                    // necessary because the whole content was replaced
                    kornCommerce.infocenter.initAjaxForm(formId, containerId);
                }
            })
            .fail(function () {
                // ToDo: woanders platzieren... so würde das komplette Formular gekillt werden (evtl. mitsamt Eingaben)
                $(containerId).html('Fehler / Error');
            })
            .always(function () {
                // scroll to top
                kornCommerce.functions.scrollTo($(containerId), null, -15);
            });
        });

    };

    // initialize
    init();

};

kornCommerce.infocenter.initSpareParts = function () {

    // init form and call self after submit
    kornCommerce.infocenter.initAjaxForm('#form-spare-parts', '#spare-parts-container', null, kornCommerce.infocenter.initSpareParts);

    kornCommerce.form.imageUpload();
};

kornCommerce.infocenter.initNewsletter = function (formId) {

    //kornCommerce.global.buttons();
    kornCommerce.form.input();
    kornCommerce.form.inputValidation();
    kornCommerce.form.placeholder();
    //kornCommerce.form.textarea(),
    //kornCommerce.form.characterCounter();

    $('#newsletter-subscription-action').off('change.newsletter').on('change.newsletter', function () {
        var url = $(this).find(':selected').data('url');

        $(formId).attr('action', url);
    });

};

kornCommerce.infocenter.initShipping = function () {

    function showShippingInformation(elem) {

        var regex = /^\{[\w]{2}\}$/,
            shippingCost = elem.data('shippingcost'),
            freeshipping = elem.data('freeshipping'),
            shippingtime = elem.data('shippingtime'),
            paymenttypes = elem.data('paymenttypes'),
            duty = elem.data('duty'),
            weight = elem.data('weight'),
            information = elem.data('information');

        if (regex.test(shippingCost)) {
            shippingCost = $('#shipping-overview select option[value="' + shippingCost.replace('{', '').replace('}', '') + '"]').data('shippingcost');
        }

        if (regex.test(freeshipping)) {
            freeshipping = $('#shipping-overview select option[value="' + freeshipping.replace('{', '').replace('}', '') + '"]').data('freeshipping');
        }

        if (regex.test(shippingtime)) {
            shippingtime = $('#shipping-overview select option[value="' + shippingtime.replace('{', '').replace('}', '') + '"]').data('shippingtime');
        }

        if (regex.test(paymenttypes)) {
            paymenttypes = $('#shipping-overview select option[value="' + paymenttypes.replace('{', '').replace('}', '') + '"]').data('paymenttypes');
        }

        if (regex.test(duty)) {
            duty = $('#shipping-overview select option[value="' + duty.replace('{', '').replace('}', '') + '"]').data('duty');
        }

        if (regex.test(weight)) {
            weight = $('#shipping-overview select option[value="' + weight.replace('{', '').replace('}', '') + '"]').data('weight');
        }

        if (regex.test(information)) {
            information = $('#shipping-overview select option[value="' + information.replace('{', '').replace('}', '') + '"]').data('information');
        }

        $('#d-shippingcost').html(shippingCost);
        $('#d-freeshipping').html(freeshipping);
        $('#d-shippingtime').html(shippingtime);
        $('#d-paymenttypes').html(paymenttypes);
        $('#d-duty').html(duty);
        $('#d-weight').html(weight);
        $('#d-information').html(information);
    }

    $('#shipping-overview select').on('change', function () {
        showShippingInformation($(this).find(":selected"));
    });

    showShippingInformation($('#shipping-overview select').find(":selected"));

};

kornCommerce.infocenter.initRentingRequest = function () {

    // init form and call self after submit
    kornCommerce.infocenter.initAjaxForm('#form-renting-request', '#renting-request-container', null, kornCommerce.infocenter.initRentingRequest);
};

kornCommerce.infocenter.initCaseRequest = function () {

    // init form and call self after submit
    kornCommerce.infocenter.initAjaxForm('#form-case-request', '#case-request-container', null, kornCommerce.infocenter.initCaseRequest);

    kornCommerce.form.imageUpload();
};

kornCommerce.infocenter.initRepair = function () {

    // init form and call self after submit
    kornCommerce.infocenter.initAjaxForm('#form-repair', '#repair-container', null, kornCommerce.infocenter.initRepair);

    kornCommerce.form.imageUpload();
};
; kornCommerce.modal = kornCommerce.modal || {};

kornCommerce.modal.init = function () {
    // enable functionality for browser "back" button
    // closes modal instead of going back immediately

    $('.modal').on('show.bs.modal', function () {
        var $this = $(this);

        window.history.pushState(undefined, undefined, '#modal');

        window.addEventListener('popstate', (e) => $this.modal('hide'));
    });

    $('.modal').on('hidden.bs.modal', function () {
        if (window.location.hash === '#modal') {
            window.history.back();
        }

        window.removeEventListener('popstate', (e) => $this.modal('hide'));
    });
};
; kornCommerce.navigation = kornCommerce.navigation || {};

kornCommerce.navigation.init = function () {

    var offsideMenu1 = offside(document.getElementById('site-navigation'), {
        //debug: true,                                          // Boolean: If true, print errors in console
        buttonsSelector: '.btn-toggle-menu',                    // String: Menu toggle buttons selectors
        slidingSide: 'left',                                    // String: Off canvas menu on left or right
        //init: function () {},                                 // Function: After init callback
        beforeOpen: function () {                               // Function: Before open callback
            $('#site-overlay').off('click.offside').on('click.offside', window.offside.factory.closeOpenOffside);
        },
        //afterOpen: function () { },                           // Function: After open callback
        beforeClose: function () {                              // Function: Before close callback
            $('#site-overlay').off('click.offside');
        },
        //afterClose: function () { },                         // Function: After close callback
    });
};

$('#site-navigation .nav__level--1 > .nav__item > .nav__title').off('click.site-navigation').on('click.site-navigation', function (e) {
    var $this = $(this),
        $parent_li = $this.parent(),
        $parent_ul = $parent_li.parent(),
        $categoryId = $parent_li.data('cid'),
        language = $('#site-navigation').data('lang');

    function enableRootNavigation() {
        // remove active class from all li's and ul's in all levels besides the current one
        $('.nav__item').not($parent_li).removeClass('nav__item--active');
        $('.nav__level').not($parent_ul).removeClass('nav__level--active');

        // extra check if the menu was closed by clicking on the menu itself
        // otherwise the next click on any element on the site would be prevented
        if ($parent_li.hasClass('nav__item--active')) {
            $(document).off('click.navigation touchstart.navigation');
        }
        else {
            addClosingNavigationEvent();
        }

        // enable/disable class for the currently clicked li and its parent nav__level
        $parent_li.toggleClass('nav__item--active');
        $parent_ul.toggleClass('nav__level--active');

        // auto-activate next level if this is an alternate view
        if ($parent_li.hasClass('nav__item--active') && $this.next('div').hasClass('nav__level')) {
            $this.next('.nav__level').children('.nav__item').first().addClass('nav__item--active');
        }
        else {
            $this.next('.nav__level').children('.nav__item').first().removeClass('nav__item--active');
        }

        // make the normal content a bit transparent to enhance the visibility for the header menu
        if ($('#site-navigation .nav__item--active').length === 0) {
            $('#site-wrap > .semi-transparent').removeClass('semi-transparent');
        }
        else {
            /* MHK Special */
            $('#site-wrap > *').not('header').addClass('semi-transparent');
        }
    }

    function enableSubNavigation() {
        $('#site-navigation .nav__level--2 > .nav__item > a.nav__title').off('click.site-navigation').on('click.site-navigation', function (e) {
            var $this = $(this);
            var $parent_li = $this.parent(),
                $parent_ul = $parent_li.parent();

            if ($parent_li.hasClass('nav__item--with-children')) {
                // remove active class from all li's in current level
                $parent_ul.children().not($parent_li).removeClass('nav__item--active');

                // enable/disable class for the currently clicked li and its parent nav__level
                $parent_li.toggleClass('nav__item--active');
                $parent_ul.toggleClass('nav__level--active');

                // if there are sub-categories, prevent the browser from loading the url
                e.preventDefault();
            }
        });
    }

    function addClosingNavigationEvent() {
        // add event to close the menu whenever somewhere outside was clicked
        $(document).off('click.navigation touchstart.navigation').on('click.navigation touchstart.navigation', function (f) {
            // if anything else besides nav__level--1 is clicked
            if (!kornCommerce.functions.hasParentClass(f.target, 'nav__level--1')) {
                // remove every active class to close the entire menu
                $('.nav__item').removeClass('nav__item--active');
                $('.nav__level').removeClass('nav__level--active');

                // cleanup click event
                $(document).off('click.navigation touchstart.navigation');

                // when searchbar is clicked, abort here and leave the rest to search.js
                if (kornCommerce.functions.hasParentClass(f.target, 'search-input')) {
                    return;
                }

                // ensure all content is shown in normal opacity
                $('#site-wrap > .semi-transparent').removeClass('semi-transparent');

                // stop click from propagating
                f.preventDefault();
                f.stopPropagation();
            }
        });
    }

    function redirectToTarget() {
        $this.off('click.site-navigation');
        window.location = $this.attr('href');
    }

    if ($this.next('div.nav__level:not(.empty)').length === 0 && !$parent_li.hasClass('nav__item--active')) {
        $.ajax({
            url: '/' + language + '/category/subnavigation',
            type: 'GET',
            data: { 'selectedCategoryId': $categoryId }
        })
        .done(function (result) {
            if (!$.trim(result)) {
                // load the target site instead
                redirectToTarget();
            }
            else {
                // remove possible empty resultset
                $parent_li.find('div.nav__level').remove();

                // append result to DOM
                $parent_li.append(result);

                // add click functionality
                enableRootNavigation();
                enableSubNavigation();
            }
        })
        .fail(function () {
            // load the target site instead
            redirectToTarget();
        })
        .always(function () {
            // nothing
        })
    }
    else {
        enableRootNavigation();
    }

    e.preventDefault();
});
; kornCommerce.productDetail = kornCommerce.productDetail || {};

kornCommerce.productDetail.init = function (imageCount) {

    // abort if there is no image
    if (imageCount === 0) {
        return;
    }

    var options = {
        fullscreen: {
            enabled: true,
            //nativeFS: false
        },
        autoScaleSlider: true,
        autoScaleSliderHeight: 1,
        autoScaleSliderWidth: 1,
        autoHeight: false,
        arrowsNav: true,
        imageScaleMode: 'fit-if-smaller',
        keyboardNavEnabled: true,
        numImagesToPreload: 3,
        fadeinLoadedSlide: false,
        sliderDrag: true,
        usePreloader: false,
        slidesSpacing: 0,
        addActiveClass: true,
        kornCommerceProduct: true,
        navigateByClick: false
    };

    if (imageCount > 1) {
        options = $.extend({}, options, {
            controlNavigation: 'thumbnails',
            thumbs: {
                appendSpan: true,
                firstMargin: true,
                paddingBottom: 0
                //fitInViewport: false,
            }
        });
    }

    $('#product-detail_image-gallery').royalSlider(options);

    $('.slider-init').removeClass('slider-init');

    kornCommerce.productDetail.initSliderEvents();
    kornCommerce.productDetail.initQuantitySelector();
};

kornCommerce.productDetail.openAccordion = function (target) {
    // using this method (onlick on an anchor tag) instead of a script-side click function preserves the native smooth browser scrolling (at least in chromium)

    var $target = $(target),
        $accordion = $target.parentsUntil('.accordion').parent();

    if (!$accordion.hasClass('active')) {
        $accordion.find('.header').trigger('click');
    }
};

kornCommerce.productDetail.eecLabel = function () {
    $('#product-details .eec-label').off('click.eec-label').on('click.eec-label', function () {
        // https://dimsemenov.com/plugins/royal-slider/documentation/#api

        // get royalSlider instance
        var slider = $('#product-detail_image-gallery').data('royalSlider');

        // null checks
        if (slider != null && slider != undefined && typeof (slider) !== 'undefined') {
            if (slider.numSlides > 0) {
                // go to last entry
                slider.goTo(slider.numSlides - 1);
            }
        }
    });
};

kornCommerce.productDetail.priceProposal = function () {

    kornCommerce.content.initModal('#modal-price-proposal', '#price-proposal-container', initPriceProposalForm);

    function initPriceProposalForm() {

        kornCommerce.global.buttons();
        kornCommerce.form.input();
        kornCommerce.form.inputValidation();
        kornCommerce.form.placeholder();

        $('#form-price-proposal').submit(function (e) {
            e.preventDefault();

            $.ajax({
                url: $('#form-price-proposal').attr('action'),
                type: 'POST',
                data: $('#form-price-proposal').serialize()
            })
                .done(function (result) {
                    $('#price-proposal-container').html(result);

                    // call self
                    initPriceProposalForm();
                })
                .fail(function () {
                    $('#price-proposal-container').html('Fehler / Error');
                });
            //.always(function () {

            //});
        });

    };

};

kornCommerce.productDetail.renting = function () {

    kornCommerce.content.initModal('#modal-renting', '#renting-container', initRentingForm);

    function initRentingForm() {

        kornCommerce.global.buttons();
        kornCommerce.form.input();
        kornCommerce.form.inputValidation();
        kornCommerce.form.placeholder();
        kornCommerce.form.textarea();
        kornCommerce.form.characterCounter();

        $('#form-renting').submit(function (e) {
            e.preventDefault();

            $.ajax({
                url: $('#form-renting').attr('action'),
                type: 'POST',
                data: $('#form-renting').serialize()
            })
                .done(function (result) {
                    $('#renting-container').html(result);

                    // call self
                    initRentingForm();
                })
                .fail(function () {
                    $('#renting-container').html('Fehler / Error');
                });
            //.always(function () {

            //});
        });

    }
};

kornCommerce.productDetail.equipment = function () {

    // script for sticky footer

    // https://developers.google.com/web/updates/2017/09/sticky-headers
    // https://usefulangle.com/post/108/javascript-detecting-element-gets-fixed-in-css-position-sticky
    var observer = new IntersectionObserver(function (entries) {
        //console.log('stickeroni');
        // no intersection with screen
        if (entries[0].intersectionRatio === 0)
            document.querySelector('#product-equipment-footer').classList.add('sticky');
        // fully intersects with screen
        else if (entries[0].intersectionRatio === 1)
            document.querySelector('#product-equipment-footer').classList.remove('sticky');
    }, { threshold: [0, 1] });

    observer.observe(document.querySelector('.product-equipment--sticky_sentinel--bottom'));


    // increment/decrement value in the input field by 1 on click
    $('#product-equipment .product-equipment-quantity .btn').off('click.product-equipment').on('click.product-equipment', function () {
        updateEquipment($(this));
    });

    // select entire input on focus
    // clean up input after blur
    $('#product-equipment .product-equipment-quantity input')
        .on('focus', function () {
            $(this).select();
        }).on('blur', function () {
            updateEquipment($(this));
        });

    // recalculate price if product is added or removed
    $('#product-equipment .product-equipment-checkbox input').change(function () {
        updateEquipment($(this));
    });

    function updateEquipment($elem) {

        // null checks
        if ($elem === null || typeof $elem === 'undefined' || $elem.length === 0) {
            return;
        }

        // gather necessary elements
        var $row = $elem.parentsUntil('.table-row').parent(),
            $checkboxField = $row.find('.product-equipment-checkbox input'),
            $quantityField = $row.find('.product-equipment-quantity input[type="number"]'),
            $incrementButton = $row.find('.product-equipment-quantity .btn.increment'),
            $decrementButton = $row.find('.product-equipment-quantity .btn.decrement');

        // get quantity
        var quantity = isNaN(parseInt($quantityField.val())) ? 0 : parseInt($quantityField.val());

        // increment or decrement quantity if eligible
        if ($elem.hasClass('increment') && quantity < 10) {
            quantity++;
        }
        else if ($elem.hasClass('decrement') && quantity > 0) {
            quantity--;
        }

        // set quantity to 1 when checkbox is enabled or 0 when its disabled
        else if ($elem.attr('type') === 'checkbox') {
            quantity = $elem.prop('checked') ? 1 : 0;
        }

        // correct quantity if it is too low or too high
        quantity = quantity < 0 ? 0 : quantity;
        quantity = quantity > 10 ? 10 : quantity;

        // set quantity to input value
        $quantityField.val(quantity);

        // enable/disable checkbox based on quantity
        $checkboxField.prop('checked', quantity > 0);

        // activate/deactivate row
        $row.removeClass('active');

        if (quantity > 0) {
            $row.addClass('active');
        }

        // enable/disable increment/decrement buttons
        $incrementButton.removeClass('disabled');
        $decrementButton.removeClass('disabled');

        if (quantity === 0) {
            $decrementButton.addClass('disabled');
        }
        else if (quantity === 10) {
            $incrementButton.addClass('disabled');
        }

        // hide error field
        $('#product-equipment .error').addClass('hidden');

        // calculate price
        var $selectedFields = getSelectedFields(),
            totalAmount = 0.00;

        for (var i = 0; i < $selectedFields.length; i++) {
            var $field = $($selectedFields[i]),
                fieldQuantity = parseInt($field.val()),
                singlePrice = parseFloat($field.data('price').replace(',', '.')).toFixed(2);

            totalAmount += fieldQuantity * singlePrice;
        }

        // set formatted total value to field
        $('#product-equipment-total-price').text(kornCommerce.global.currencyFormatter.format(totalAmount));

        // determine if the shipping cost notice has to be changed
        var $equipmentShippingCostElement = $('#equipment-shipping-cost'),
            threshold = parseFloat($equipmentShippingCostElement.data('threshold')),
            thresholdTextHigher = $equipmentShippingCostElement.data('threshold-higher'),
            thresholdTextLower = $equipmentShippingCostElement.data('threshold-lower');

        if (totalAmount >= threshold) {
            $equipmentShippingCostElement.text(thresholdTextHigher);
        }
        else {
            $equipmentShippingCostElement.text(thresholdTextLower);
        }
    }

    function getSelectedFields() {
        // get all quantity fields of selected products
        return getSelectedRows().find('input[type="number"]');
    }

    function getSelectedRows() {
        // get all rows of selected products
        return $('#product-equipment input[type="checkbox"]:checked').parentsUntil('#product-equipment');
    }

    var $form = $('#form-add-product-equipment');

    $form.submit(function () {

        var selectedFields = getSelectedFields();

        if (typeof selectedFields === 'undefined' || selectedFields.length === 0) {
            $('#product-equipment .error').removeClass('hidden');
            kornCommerce.button.endLoading($form.find('.btn.cta'));

            return false;
        }

        for (var i = 0; i < selectedFields.length; i++) {
            var $field = $(selectedFields[i]),
                productId = $field.data('productid'),
                quantity = $field.val();

            // create form field for productId
            $('<input />')
                .attr('type', 'hidden')
                .attr('name', 'Items[' + i + '].ProductId')
                .attr('value', productId)
                .appendTo($form);

            // create form field for quantity
            $('<input />')
                .attr('type', 'hidden')
                .attr('name', 'Items[' + i + '].Quantity')
                .attr('value', quantity)
                .appendTo($form);
        }

        return true;
    });

    // trigger increment on main product on page load
    $('#product-equipment-main .product-equipment-quantity .btn.increment').trigger('click.product-equipment');
};

kornCommerce.productDetail.tierPrices = function () {
    var $tpContainer = $('#product-tier-price');

    // click on tier
    $tpContainer.find('li').on('click', function () {
        var $this = $(this),
            quantity = $this.data('quantity');

        $tpContainer.find('li').removeClass('selected');
        $this.addClass('selected');

        // write value to the input field (might have been changed in the validation earlier)
        $('#add-to-cart__container .add-to-cart__quantity--input').val(quantity).blur();
    });
};

kornCommerce.productDetail.initSoundSamples = function ($element) {
    $($element).on('click', function () {
        var $this = $(this),
            url = $this.data('url'),
            isPlaylist = $this.data('is-playlist').toLowerCase() === 'true',
            height = isPlaylist ? 465 : 166;

        $this.html('<iframe class="iframe" width="100%" height="' + height + '" scrolling="no" frameborder="no" src="' + url + '"></iframe>');
    });
};

kornCommerce.productDetail.lastVisited = function (addCurrent, cacheKey, maxEntries, maxLifetime) {

    // check whether localStorage exists
    if (!kornCommerce.webstorage.storageAvailable('localStorage')) {
        return;
    }

    var currentObjectVersion = 2;

    function getItemInfo() {
        var $product = $('#product'),
            item = {};

        if ($product === null) {
            return null;
        }

        item.Name = $product.find('h1').text().trim();
        item.Url = location.pathname;
        item.Culture = kornCommerce.global.culture;
        item.DateLastViewedUtc = kornCommerce.functions.getDateUtc(new Date());
        item.Version = currentObjectVersion;

        var $thumbs = $product.find('#product-detail_image-gallery .rsTmb');

        if ($thumbs.length > 0) {
            item.ImageUrl = $thumbs.first().attr('src');
        }
        else {
            item.ImageUrl = $('#product-image img').attr('src');
        }

        return item;
    }

    // set standard values if parameters are missing
    if (typeof (addCurrent) !== 'boolean') {
        addCurrent = false;
    }

    if (typeof (cacheKey) !== 'string' || cacheKey.length === 0) {
        cacheKey = 'lastVisited';
    }

    if (typeof (maxEntries) !== 'number' || maxEntries < 1) {
        maxEntries = 10;
    }

    if (typeof (maxLifetime) !== 'number' || maxLifetime < 1) {
        maxLifetime = 48;
    }

    // retrieve from localstorage and parse
    var itemsJson = kornCommerce.webstorage.getItem('localStorage', cacheKey);
    var items = new Array();

    if (itemsJson !== null) {
        items = JSON.parse(itemsJson);
    }

    // remove old or invalid entries
    var datePastUtc = kornCommerce.functions.getDateUtc(new Date(), maxLifetime);

    for (i = 0; i < items.length; i++) {
        var item = items[i],
            itemDate = Date.parse(item.DateLastViewedUtc);

        //console.log(itemDate, datePastUtc, itemDate < datePastUtc);

        if (itemDate < datePastUtc || item.Version !== currentObjectVersion || typeof (item.ImageUrl) === 'undefined' || item.Culture !== kornCommerce.global.culture) {
            items.splice(i, 1);
            i--;
        }
    }

    // add current product
    if (addCurrent) {
        var itemInfo = getItemInfo();

        if (itemInfo !== null) {

            for (i = 0; i < items.length; i++) {
                if (items[i].Url === itemInfo.Url) {
                    items.splice(i, 1);
                    i--;
                }
            }

            items.reverse();
            items.push(itemInfo);
            items.reverse();
        }
    }

    // shrink if item count exceeds maximum
    while (items.length > maxEntries) {
        items.pop();
    }

    kornCommerce.webstorage.setItem('localStorage', cacheKey, JSON.stringify(items));

    var $target = $('#carousel-last-visited');

    // append items
    $(items).each(function (index, data) {
        // don't show the first one, because its the same we are looking at right now (if addCurrent is true)
        // else, show all
        if ((addCurrent && index > 0) || !addCurrent) {
            $target.append('<div class="item-product"><a href="' + data.Url + '" title="' + data.Name + '"><img class="owl-lazy" data-src="' + data.ImageUrl + '" alt="' + data.Name + '"></a></div>');
        }
    });

    // show only if there are items, if addCurrent is true there must be more than one item
    if ((addCurrent && items.length > 1) || (!addCurrent && items.length > 0)) {
        // show container
        $('#last-visited-container').show();

        // init carousel
        kornCommerce.carousel.init($target, {
            items: 10,
            responsive: {
                0: {
                    items: 3
                },
                680: {
                    items: 5
                },
                900: {
                    items: 7
                },
                1280: {
                    items: 10
                }
            }
        });
    }
};

kornCommerce.productDetail.initImageGallery = function (items, index) {

    var gallery;
    var pswpElement = document.querySelectorAll('.pswp')[0];

    // items array example
    //var items = [
    //    {
    //        src: 'path to image',
    //        //msrc: 'path to small image placeholder',
    //        w: 600,
    //        h: 400,
    //        //html: '',
    //        title: 'fancy title',
    //    },
    //];

    // define options (if needed)
    var options = {
        // optionName: 'option value'
        // for example:
        index: index, // start at given slide

        // Size of top & bottom bars in pixels,
        // "bottom" parameter can be 'auto' (will calculate height of caption)
        // option applies only when mouse is used, 
        // or width of screen is more than 1200px
        // 
        // (Also refer to `parseVerticalMargin` event)
        barsSize: { top: 44, bottom: 'auto' },

        closeOnScroll: false,

        maxSpreadZoom: 2,

        // Adds class pswp__ui--idle to pswp__ui element when mouse isn't moving for 4000ms
        //timeToIdle: 4000,
        timeToIdle: 0,

        // Same as above, but this timer applies when mouse leaves the window
        //timeToIdleOutside: 1000,
        timeToIdleOutside: 0,

        // Delay until loading indicator is displayed
        loadingIndicatorDelay: 1000,

        // Function builds caption markup
        //addCaptionHTMLFn: function (item, captionEl, isFake) {
        //    // item      - slide object
        //    // captionEl - caption DOM element
        //    // isFake    - true when content is added to fake caption container
        //    //             (used to get size of next or previous caption)

        //    if (!item.title) {
        //        captionEl.children[0].innerHTML = '';
        //        return false;
        //    }
        //    captionEl.children[0].innerHTML = item.title;
        //    return true;
        //},

        // Buttons/elements
        closeEl: true,
        //captionEl: true,
        captionEl: false,
        fullscreenEl: true,
        zoomEl: true,
        //shareEl: true,
        shareEl: false,
        counterEl: true,
        arrowEl: true,
        preloaderEl: true,

        // Tap on sliding area should close gallery
        tapToClose: false,

        // Tap should toggle visibility of controls
        tapToToggleControls: true,

        // Mouse click on image should close the gallery,
        // only when image is smaller than size of the viewport
        //clickToCloseNonZoomable: true,
        clickToCloseNonZoomable: false,

        //loop: false,

        getDoubleTapZoom: function (isMouseClick, item) {

            // isMouseClick          - true if mouse, false if double-tap
            // item                  - slide object that is zoomed, usually current
            // item.initialZoomLevel - initial scale ratio of image
            //                         e.g. if viewport is 700px and image is 1400px,
            //                              initialZoomLevel will be 0.5

            //console.log('getDoubleTapZoom');

            if (isMouseClick) {
                //console.log('getDoubleTapZoom isMouseClick true');

                //if (currentZoomLevel == 0) {
                //    currentZoomLevel = 1;
                //}
                //else if (currentZoomLevel == 1) {
                //    currentZoomLevel = 2;
                //}
                //else {
                //    currentZoomLevel = 0;
                //}

                //console.log('zoomLevel', currentZoomLevel);

                //return currentZoomLevel;

                // is mouse click on image or zoom icon

                // zoom to original
                return 2;

                // e.g. for 1400px image:
                // 0.5 - zooms to 700px
                // 2   - zooms to 2800px

            } else {
                //console.log('getDoubleTapZoom isMouseClick false');

                // is double-tap

                // zoom to original if initial zoom is less than 0.7x,
                // otherwise to 1.5x, to make sure that double-tap gesture always zooms image
                return item.initialZoomLevel < 0.7 ? 1 : 1.5;
            }
        }

    };

    // Initializes and opens PhotoSwipe
    gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);

    // create variable that will store real size of viewport
    var realViewportWidth,
        realViewportHeight,
        useLargeImages = false,
        firstResize = true,
        imageSrcWillChange;

    // beforeResize event fires each time size of gallery viewport updates
    gallery.listen('beforeResize', function () {
        // gallery.viewportSize.x - width of PhotoSwipe viewport
        // gallery.viewportSize.y - height of PhotoSwipe viewport
        // window.devicePixelRatio - ratio between physical pixels and device independent pixels (Number)
        //                          1 (regular display), 2 (@2x, retina) ...

        // calculate real pixels when size changes
        realViewportWidth = gallery.viewportSize.x * window.devicePixelRatio;
        realViewportHeight = gallery.viewportSize.y * window.devicePixelRatio;

        // Code below is needed if you want image to switch dynamically on window.resize

        // Find out if current images need to be changed
        if (useLargeImages && realViewportWidth < 1000) {
            useLargeImages = false;
            imageSrcWillChange = true;
        } else if (!useLargeImages && realViewportWidth >= 1000) {
            useLargeImages = true;
            imageSrcWillChange = true;
        }

        if (useLargeImages && realViewportHeight < 500) {
            useLargeImages = false;
            imageSrcWillChange = true;
        } else if (!useLargeImages && realViewportHeight >= 500) {
            useLargeImages = true;
            imageSrcWillChange = true;
        }

        // Invalidate items only when source is changed and when it's not the first update
        if (imageSrcWillChange && !firstResize) {
            // invalidateCurrItems sets a flag on slides that are in DOM,
            // which will force update of content (image) on window.resize.
            gallery.invalidateCurrItems();
        }

        if (firstResize) {
            firstResize = false;
        }

        imageSrcWillChange = false;

    });


    // gettingData event fires each time PhotoSwipe retrieves image source & size
    gallery.listen('gettingData', function (index, item) {

        // Set image source & size based on real viewport width
        if (useLargeImages) {
            item.src = item.originalImage.src;
            item.w = item.originalImage.w;
            item.h = item.originalImage.h;
        } else {
            item.src = item.mediumImage.src;
            item.w = item.mediumImage.w;
            item.h = item.mediumImage.h;
        }

        // It doesn't really matter what will you do here, 
        // as long as item.src, item.w and item.h have valid values.
        // 
        // Just avoid http requests in this listener, as it fires quite often

    });

    gallery.init();
};

kornCommerce.productDetail.initSliderEvents = function () {
    var slider = $("#product-detail_image-gallery.royalSlider").data('royalSlider');

    //slider.ev.on('rsAfterSlideChange', function (event) {
    //    // triggers after slide change
    //    console.log('rsAfterSlideChange', event);
    //});

    //slider.ev.on('rsEnterFullscreen', function (event) {
    //    // enter fullscreen mode 
    //    console.log('rsEnterFullscreen', event);
    //});

    //slider.ev.on('rsExitFullscreen', function () {
    //    // exit fullscreen mode 
    //    console.log('rsExitFullscreen', event);
    //});

    slider.ev.on('rsSlideClick', function (event, originalEvent) {
        // originalEvent - the original jQuery click event. Parameter available since RoyalSlider v9.5.1
        // triggers when user clicks on slide
        // doesn't trigger after click and drag
        //console.log('rsSlideClick', event, originalEvent);

        var startIndex = event.currentTarget.currSlideId;
        var items = [];

        for (const slide of event.currentTarget.slides) {
            items.push({
                mediumImage: {
                    src: slide.image,
                    //w: slide.content[0].naturalWidth,
                    w: slide.iW,
                    //h: slide.content[0].naturalHeight
                    h: slide.iH
                },
                originalImage: {
                    src: slide.bigImage,
                    w: slide.iBW,
                    h: slide.iBH
                }
            });
        }

        //console.log('startIndex', startIndex, 'items', items);

        kornCommerce.productDetail.initImageGallery(items, startIndex);
    });
};

kornCommerce.productDetail.initQuantitySelector = function () {
    $('#add-to-cart__container select.add-to-cart__quantity--select').on('change.quantity', function () {
        var $this = $(this),
            selectedValue = $this.find(':selected').val();

        // remove non standard options, but keep the current selected (it might be a custom entry)
        $('#add-to-cart__container select.add-to-cart__quantity--select option:not(.orig)').filter(function () {
            return $(this).val() !== selectedValue;
        }).remove();

        // make sure the custom view is disabled
        $('#add-to-cart__container .add-to-cart__quantity').removeClass('custom');

        // do stuff based on selected value
        switch (selectedValue) {
            case "custom":
                // open custom view with input field so the customer can enter a different value
                $('#add-to-cart__container .add-to-cart__quantity').addClass('custom');

                // select the now visible input field and select all text inside
                $('#add-to-cart__container .add-to-cart__quantity--input').focus().select();
                break;
            default:
                // write the selected value to the hidden input field
                $('#add-to-cart__container .add-to-cart__quantity--input').val(selectedValue);

                // and to the visible label
                $('#add-to-cart__container .add-to-cart__quantity--label').text(selectedValue);

                // update tier price if available
                updateTierPrice(selectedValue);

                break;
        }
    });

    $('#add-to-cart__container .add-to-cart__quantity--input').on('keydown', function () {
        // prevent ENTER keypress from submitting the form
        // threat it instead like blur
        if (event.keyCode == 13) {
            event.preventDefault();
            $(this).blur();
            return false;
        }
    });

    $('#add-to-cart__container .add-to-cart__quantity--input').on('blur', function () {
        var $this = $(this),
            val = $this.val();

        // validate input
        try {
            // check if numeric
            if (!$.isNumeric(val)) {
                val = 1;
            }

            // check if int and not float
            if (Math.floor(val) != val) {
                val = 1;
            }

            // check if value is within range
            if (parseInt(val) <= 0) {
                val = 1;
            }
            else if (parseInt(val) >= 100) {
                val = 99;
            }
        } catch (e) {
            val = 1;
        }

        // append the value as another option to the select list if not already present
        if ($('#add-to-cart__container select.add-to-cart__quantity--select').find('option[value="' + val + '"]').length == 0) {
            $('#add-to-cart__container select.add-to-cart__quantity--select').append($('<option>').val(val).text(val));
        }

        // select the value and trigger change event
        $('#add-to-cart__container select.add-to-cart__quantity--select').val(val).change();
    });

    function updateTierPrice(selectedValue) {
        if ($('#product-tier-price li').length <= 0) {
            return;
        }

        // get all tiers as array
        var tiers = $('#product-tier-price li').map(function () {
            return $(this).data('quantity');
        }).get();

        // sort by number ascending and then reverse
        tiers.sort(function (a, b) {
            return a - b;
        }).reverse();

        // take the closest tier for the selected value
        var index = tiers.findIndex(function (number) { return number <= selectedValue });

        // update selected tier
        $('#product-tier-price li').removeClass('selected');
        $('#product-tier-price li[data-quantity="' + tiers[index] + '"]').addClass('selected');
    }
};
;kornCommerce.productFilter = kornCommerce.productFilter || {};

kornCommerce.productFilter.settings = kornCommerce.productFilter.settings || {};

kornCommerce.productFilter.init = function () {

    // external
    var activeFilters = this.settings.activeFilters,
        baseUrl = this.settings.baseUrl,
        baseUrlAjax = this.settings.baseUrlAjax,
        baseUrlPriceCount = this.settings.baseUrlPriceCount,
        currentCategoryId = this.settings.currentCategoryId,
        isSearch = this.settings.isSearch,
        search = this.settings.search;

    // internal
    var enableRealtime = true,
        expandedFilters = [],
        initialFilterCount = activeFilters.length,
        clientSupportsLocalStorage = false,
        allLabel = '';

    if (typeof (Storage) !== 'undefined') {
        clientSupportsLocalStorage = true;

        try {
            var lsItem = sessionStorage.getItem('expandedFilters');

            if (lsItem != null && lsItem.length > 0) {
                expandedFilters = JSON.parse(lsItem);
            }

        } catch (e) {
            clientSupportsLocalStorage = false;
            sessionStorage.clear();
        }

        if (clientSupportsLocalStorage && activeFilters.length == 0) {
            sessionStorage.clear();
            expandedFilters = [];
        }
    }

    //$('#toggle-realtime-updates').off('change.productFilter').on('change.productFilter', function () {
    //    var $this = $(this);

    //    if ($this.prop('checked')) {
    //        $('#attribute-filter').addClass('realtime');
    //    }
    //    else {
    //        $('#attribute-filter').removeClass('realtime');
    //    }
    //});

    //$('#toggle-realtime-updates').trigger('change');

    mobilizeAttributeFilter();
    initAttributeEvents();

    function initAttributeEvents() {

        //console.log('initAttributeEvents');

        // preset before events are bound
        presetFilter();

        //console.log('attribute-sliders', $('.attribute-sliders'));
        //console.log('standard-sliders', $('.standard-sliders'));

        // set buttons
        $('.clear-filter').off('click.productFilter').on('click.productFilter', function () {
            if (activeFilters.length > 0) {
                //console.log('clear filter');
                activeFilters = [];
                //console.log('activeFilters', activeFilters);
                if (clientSupportsLocalStorage) {
                    sessionStorage.clear();
                }
                callAttributeUrl(false);
            }
        });

        // set sliders
        $('.attribute-sliders').each(function (i) {
            var $this = $(this),
                hide = $this.data('hide'),
                start = [$this.data('start-min'), $this.data('start-max')],
                rangeString = $this.data('range'),
                range = JSON.parse(rangeString.replace(/'/g, '"'));

            if (hide) {
                $this.parent().parent().hide();
                return true;
            }

            createAttributeSlider($this, start, range);
        });

        $('.standard-sliders').each(function (i) {
            var $this = $(this),
                startMin = parseInt($this.data('start-min')),
                startMax = parseInt($this.data('start-max')),
                min = parseInt($this.data('min')),
                max = parseInt($this.data('max'));

            createStandardSlider($this, startMin, startMax, min, max);
        });

        // set checkboxes
        $('input.filter-by[type="checkbox"]').off('change.productFilter').on('change.productFilter', function (e) {
            var $this = $(this);
            var filter = $this.data('filter').toString();
            //var filterCount = (baseUrl.match(/f\d=/g) || []).length;
            var isChecked = $this.is(':checked');

            //console.log('filter', filter);

            if ($.inArray(filter, activeFilters) >= 0) {
                //console.log('ist vorhanden');

                if (!isChecked) {
                    //console.log('remove from url');
                    activeFilters.remove(filter);
                }
            }
            else {
                //console.log('nicht vorhanden');

                if (isChecked) {
                    //console.log('add to url');
                    activeFilters.push(filter);
                }
            }

            if (clientSupportsLocalStorage) {
                if (isChecked) {
                    addFilterToSessionStorage($this);
                }
                //else {
                //    console.log('remove 3');
                //    removeFilterFromSessionStorage($this);
                //}
            }

            //console.log('activeFilters: ', activeFilters);

            callAttributeUrl();
        });

        // set availability checkbox
        $('#store-availability').off('change.productFilter').on('change.productFilter', function (e) {
            //console.log('change checkbox');

            var $this = $(this);
            var isChecked = $this.prop('checked');

            //console.log('isChecked', isChecked);

            var filter = '';
            var oldFilter = $this.data('old-filter');
            var checkedStore = $('#store-list :checked');

            if (oldFilter != '') {
                //console.log('remove old filter');
                activeFilters.remove(oldFilter);
            }

            if (isChecked) {
                if (checkedStore.length == 0) {
                    $('#store--1').prop('checked', true);

                    checkedStore = $('#store--1');
                }

                filter = checkedStore.data('filter').toString();

                $this.data('old-filter', filter);
            }
            else {
                filter = oldFilter;
                $('#store-list .filter-by.radio-list').removeAttr('checked');
            }

            if (clientSupportsLocalStorage) {
                if (isChecked) {
                    addFilterToSessionStorage($this);
                }
                else {
                    removeFilterFromSessionStorage($this);
                }
            }

            if ($.inArray(filter, activeFilters) >= 0) {
                //console.log('ist vorhanden');

                if (!isChecked) {
                    //console.log('remove from url');
                    activeFilters.remove(filter);
                }
            }
            else {
                //console.log('nicht vorhanden');

                if (isChecked) {
                    //console.log('add to url');
                    activeFilters.push(filter);
                }
            }

            //console.log('activeFilters: ', activeFilters);

            callAttributeUrl();
        });

        // set store radio buttons
        $('#store-list .filter-by.radio-list').off('change.productFilter').on('change.productFilter', function (e) {
            //console.log('change radio');

            if ($('#store-availability').prop('checked')) {
                $('#store-availability').trigger('change');
            }
            else {
                $('#store-availability').trigger('click');
            }
        });

        // set buttons
        $('.attribute-btn').off('click.productFilter').on('click.productFilter', function () {

            if (clientSupportsLocalStorage) {
                addFilterToSessionStorage($(this));
            }

            callAttributeUrl();
        });

        // set input filter
        $('#brand-search-filter input').searchFilter({ targetSelector: '.filter-by-brand label', hideParent: true, charCount: 1 });

        // set mobile ajax loader
        $('#load-attribute-ajax').off('click.productFilter').on('click.productFilter', function () {
            if (activeFilters.length > 0 || initialFilterCount > 0) {
                callAttributeUrl(true);
            }
            else {
                $('.mfp-close').trigger('click');
            }
        });
    };

    function addFilterToSessionStorage($elem) {
        if (clientSupportsLocalStorage) {
            var parentId = $elem.closest('.attribute-container').find('input.toggle').attr('id');

            if ($.inArray(parentId, expandedFilters) < 0) {
                expandedFilters.push(parentId);
            }

            sessionStorage.setItem('expandedFilters', JSON.stringify(expandedFilters));
        }
    };

    function removeFilterFromSessionStorage($elem) {
        if (clientSupportsLocalStorage) {
            var parentId = $elem.closest('.attribute-container').find('input.toggle').attr('id'),
                index = $.inArray(parentId, expandedFilters);

            if (index >= 0) {
                expandedFilters.splice(index, 1);
            }

            sessionStorage.setItem('expandedFilters', JSON.stringify(expandedFilters));
        }
    };

    function createStandardSlider($elem, startMin, startMax, min, max) {
        var slider = $elem[0];

        noUiSlider.create(slider, {
            start: [startMin, startMax],
            range: {
                'min': [min],
                'max': [max]
            },
            connect: true
        });

        sliderAppendBottomTooltip(slider, document.getElementById('price-slider-value-lower'), document.getElementById('price-slider-value-upper'));
        sliderAppendCustomConnector(slider);
        sliderSetChangeEvent(slider, function () {

            var url = baseUrlPriceCount;

            for (var i = 0; i < activeFilters.length; i++) {
                var subFilter = activeFilters[i];

                url = kornCommerce.functions.addUrlParameter(url, 'f' + (i + 1), subFilter, false)
            }

            //console.log(url);

            $('#price-slider-value-count').text('(...)');

            if (isSearch) {
                url = kornCommerce.functions.addUrlParameter(url, 'search', search, false);
                //console.log('is search 1', url);
            }

            $.ajax({
                type: 'GET',
                cache: true,
                url: url,
                data: { categoryId: currentCategoryId }
            })
            .done(function (result) {
                //console.log('AJAX done', result);

                $('#price-slider-value-count').text('(' + result + ')');
            })
            .fail(function () {
                alert("Es ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut / An error occured, please try again later");
                //console.log('AJAX fail');
            })
            .always(function () {
                //console.log('AJAX always');
            });

        });
    };

    function createAttributeSlider($elem, start, range) {
        var slider = $elem[0];

        noUiSlider.create(slider, {
            range: range,
            start: start,
            snap: true,
            connect: true,
            pips: {
                mode: 'positions',
                values: [0, 25, 50, 75, 100],
                density: 4,
                stepped: true
            }
        });

        sliderAppendTopTooltip(slider);
        sliderAppendCustomConnector(slider);
        sliderSetChangeEvent(slider);
    };

    function sliderAppendTopTooltip(slider) {
        // append tooltips
        var tipHandles = slider.getElementsByClassName('noUi-handle'),
            tooltips = [];

        // Add divs to the slider handles.
        for (var i = 0; i < tipHandles.length; i++) {
            tooltips[i] = document.createElement('div');
            tipHandles[i].appendChild(tooltips[i]);
            // Add a class for styling
            tooltips[i].className += 'tooltip';
            // Add additional markup
            tooltips[i].innerHTML = '<span class="nowrap"></span>';
            // Replace the tooltip reference with the span we just added
            tooltips[i] = tooltips[i].getElementsByTagName('span')[0];
        }

        // When the slider changes, write the value to the tooltips.
        // kein .off() hier setzen
        slider.noUiSlider.on('update.productFilter', function (values, handle) {
            tooltips[handle].innerHTML = parseInt(values[handle]);
        });
    };

    function sliderAppendBottomTooltip(slider, leftSpan, rightSpan) {
        var snapValues = [
            leftSpan,
            rightSpan
        ];

        // kein .off() hier setzen
        slider.noUiSlider.on('update.productFilter', function (values, handle) {
            snapValues[handle].innerHTML = parseInt(values[handle]);
        });
    };

    function sliderAppendCustomConnector(slider) {
        // append connector
        var connectBar = document.createElement('div'),
            connectBase = slider.getElementsByClassName('noUi-base')[0],
            connectHandles = slider.getElementsByClassName('noUi-origin');

        // Give the bar a class for styling and add it to the slider.
        connectBar.className += 'connect';
        connectBase.appendChild(connectBar);

        // kein .off() hier setzen
        slider.noUiSlider.on('update.productFilter', function (values, handle) {

            // Pick left for the first handle, right for the second.
            var side = handle ? 'right' : 'left',
            // Get the handle position and trim the '%' sign.
                offset = (connectHandles[handle].style.left).slice(0, -1);

            // Right offset is 100% - left offset
            if (handle === 1) {
                offset = 100 - offset;
            }

            connectBar.style[side] = offset + '%';
        });
    };

    function sliderSetChangeEvent(slider, callback) {
        // event after value has been changed
        // kein .off() hier setzen
        slider.noUiSlider.on('change.productFilter', function () {
            var $slider = $(slider),
                filter = $slider.data('filter').toString(),
                dataMin = parseInt($slider.data('min')),
                dataMax = parseInt($slider.data('max')),
                startMin = parseInt($slider.data('start-min')),
                startMax = parseInt($slider.data('start-max')),
                values = slider.noUiSlider.get(),
                minValue = parseInt(values[0]),
                maxValue = parseInt(values[1]);

            // get old filter from data api and remove from array
            var filterOld = $slider.data('filter-old');

            //console.log('filter-old: ', filterOld);

            // prepare filter
            filter = filter.replace('{min}', minValue).replace('{max}', maxValue);
            //console.log('filter: ', filter);

            if (filterOld == null || filterOld == '') {
                filterOld = filter;
            }

            // add new filter to data api
            $slider.data('filter-old', filter);

            var index = $.inArray(filterOld, activeFilters);

            if (index >= 0) {
                // if attribute is present, remove
                activeFilters.splice(index, 1);
            }

            //console.log('dataMin', dataMin);
            //console.log('dataMax', dataMax);
            //console.log('startMin', startMin);
            //console.log('startMax', startMax);
            //console.log('minValue', minValue);
            //console.log('maxValue', maxValue);

            if (minValue > dataMin || maxValue < dataMax) {
                activeFilters.push(filter);
            }

            // handle apply-button
            if (minValue != startMin || maxValue != startMax) {
                $slider.nextUntil(null, '.attribute-btn').show();
                if (clientSupportsLocalStorage) {
                    //console.log('slider add', $slider);
                    addFilterToSessionStorage($slider);
                }
            }
            else {
                $slider.nextUntil(null, '.attribute-btn').hide();
                if (clientSupportsLocalStorage) {
                    //console.log('slider remove', $slider);
                    removeFilterFromSessionStorage($slider);
                }
            }

            //console.log('activeFilters: ', activeFilters);

            if (callback != undefined) {
                callback();
            }

            //if (filter != filterOld) {
            //    callAttributeUrl();
            //}
            //else {
            //    console.log('same filter');
            //}

            //callAttributeUrl();
        });
    };


    function mobilizeAttributeFilter() {

        $('#open-kc-attributes a').magnificPopup({
            type: 'inline',
            //overflowY: 'hidden',
            midClick: true,

            // instad of modal: true - because with active modal option, the close button disappears
            closeOnContentClick: false,
            closeOnBgClick: false,
            enableEscapeKey: false,

            fixedContentPos: true, // prevent viewport overscrolling
            removalDelay: 500, //delay removal by X to allow out-animation
            callbacks: {
                beforeOpen: function () {
                    this.st.mainClass = this.st.el.attr('data-effect');
                },
                open: function () {
                    //console.log('Popup is opened');

                    enableRealtime = false;
                    //console.log('disable realtime');

                    //var $this = $(this),
                    //    $this0 = $this[0],
                    //    enableFullscreen = false,
                    //    $popup = $this0.content;

                    //if ($popup.hasClass('is-fullscreen')) {
                    //    $this0.container.addClass('fullscreen-modal');
                    //    enableFullscreen = true;
                    //}

                    //if (!enableFullscreen) {
                    //    // calculate height and fire once
                    //    $(window).off('resize.modal.productFilter').on('resize.modal.productFilter', function () {
                    //        if (isMobileViewport()) {
                    //            $('.popup-scroll').css('height', '');
                    //        }
                    //        else {
                    //            var maxHeight = window.innerHeight - ($popup.outerHeight(true) - $popup.find('.popup-scroll').height());
                    //            $('.popup-scroll').css('height', maxHeight);
                    //        }
                    //    });

                    //    $(window).trigger('resize.modal');

                    //    // switch normal and responsive theme
                    //    $(window).off('resize.responsiveAttribute.productFilter').on('resize.responsiveAttribute.productFilter', function () {
                    //        //console.log('resize.responsiveAttribute', enableFullscreen);
                    //        if (isMobileViewport()) {
                    //            if (!enableFullscreen) {
                    //                console.log('enable');
                    //                $this0.container.addClass('fullscreen-modal');
                    //                enableFullscreen = true;
                    //            }
                    //        }
                    //        else if (enableFullscreen) {
                    //            console.log('disable');
                    //            $this0.container.removeClass('fullscreen-modal');
                    //            enableFullscreen = false;
                    //        }
                    //    });
                    //}

                    //$(window).trigger('resize.responsiveAttribute');

                    var headerHtml = $('#attribute-filter-header').html();
                    var container = $('#attribute-filter-body > div').detach();

                    $('#kc-attributes .kc-modal-header').html(headerHtml);
                    $('#kc-attributes .kc-modal-body').empty().append(container);

                    allLabel = $('#attribute-filter-product-count').text();

                    // product count
                    countProducts();
                },
                close: function () {
                    //console.log('Popup is closed');

                    enableRealtime = true;
                    //console.log('re-enable realtime');

                    var container = $('#kc-attributes .kc-modal-body > div').detach();

                    $('#attribute-filter-body').append(container);
                }
            },
        });

    };

    function presetFilter() {

        //console.log('presetFilter');

        //// expand brand if no filter is set
        //if (activeFilters.length == 0) {
        //    $('#brand-filter > input').prop('checked', true);
        //}

        // reset checkboxes
        //console.log('reset checkboxes');
        //$('input.toggle').prop('checked', false);
        $('input.filter-by[type="checkbox"]').prop('checked', false);

        // clear availability buttons
        $('#store-availability').prop('checked', false);
        $('#store-list .filter-by.radio-list').removeAttr('checked');

        //console.log('prepare filter, activeFilters', activeFilters);

        for (var i = 0; i < activeFilters.length; i++) {
            var filter = activeFilters[i];

            // Attribut
            if (filter.indexOf('1$') >= 0) {
                presetFilterAttribute(filter);
            }

                // Brand
            else if (filter.indexOf('2$') >= 0) {
                // gleiche handhabung
                presetFilterAttribute(filter);
            }

                // PriceRange
                // aktuell nicht notwendig
                //else if (filter.indexOf('3$') >= 0) {
                //    presetFilterPrice(filter);
                //}

                // Availability
            else if (filter.indexOf('4$') >= 0) {
                // gleiche handhabung
                presetFilterAttribute(filter);

                $('#store-availability').prop('checked', true);
            }

            else {
                //console.log('skip presetFilter for:', filter);
                continue;
            }
        }

        if (clientSupportsLocalStorage && expandedFilters != null) {
            //console.log('preset via sessionStorage');

            //console.log('expandedFilters', expandedFilters);

            for (var i = 0; i < expandedFilters.length; i++) {
                var toggleId = '#' + expandedFilters[i];
                //console.log(toggleId);
                $(toggleId).prop('checked', true);
                $(toggleId).off('change.productFilter').on('change.productFilter', function () {
                    //console.log('remove #' + $(this).attr('id') + ' from storage');
                    removeFilterFromSessionStorage($(this));
                    $(this).off('change');
                });
            }
        }

        //$('.attribute-sliders[data-expand="1"]').parent().prev().prev().prop('checked', true);

    };

    function presetFilterAttribute(filter) {
        //var attributeId = filter.split('$')[1].split(':')[0].trim();

        // expand attribute container
        //$('#toggle-attribute-' + attributeId).prop('checked', true);

        if (filter.indexOf('::') >= 0) {
            return;
        }

        //console.log('filter: ', filter);

        // activate attribute value checkbox
        $('.filter-by[data-filter="' + filter + '"]').prop('checked', true);
    };

    function countProducts() {
        if (activeFilters.length == 0) {
            $('#attribute-filter-product-count').text(allLabel);
        }
        else {
            var productCount = 0;

            $('#brand-filter label[data-product-count]').each(function () {
                productCount += parseInt($(this).data('product-count'));
            });

            $('#attribute-filter-product-count').text(productCount);
        }
    };

    function callAttributeUrl(forceLoad) {
        var url = baseUrl;

        if (forceLoad == null) {
            forceLoad = false;
        }

        if (!(forceLoad || enableRealtime)) {
            url = baseUrlAjax;
        }

        for (var i = 0; i < activeFilters.length; i++) {
            var subFilter = activeFilters[i];

            url = kornCommerce.functions.addUrlParameter(url, 'f' + (i + 1), subFilter, false)
        }

        //console.log('new url: ', url);

        if (forceLoad || enableRealtime) {
            location.href = url;
        }
        else {
            getFilterAjax(url);
        }
    };

    function getFilterAjax(url) {
        toggleAjaxFilterLoadingOverlay(true);

        var scrollMarginTop = $('.kc-modal-body').scrollTop();

        $('.kc-modal-body').scrollTop(0);

        if (isSearch) {
            url = kornCommerce.functions.addUrlParameter(url, 'search', search, false);
            //console.log('is search 2', url);
        }

        $.ajax({
            type: 'GET',
            cache: true,
            url: url,
            data: { categoryId: currentCategoryId }
        })
        .done(function (result) {
            //console.log('AJAX done');

            // replace everything
            $('#kc-attributes .kc-modal-body > div').html(result);

            // rebind events
            initAttributeEvents();

            // scroll back to previous position
            $('.kc-modal-body').scrollTop(scrollMarginTop);

            // product count
            countProducts();
        })
        .fail(function () {
            alert("Es ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut / An error occured, please try again later");
            //console.log('AJAX fail');
        })
        .always(function () {
            //console.log('AJAX always');

            toggleAjaxFilterLoadingOverlay(false);
        });
    };

    function toggleAjaxFilterLoadingOverlay(show) {
        if (show) {
            $('#attribute-filter-content').parent().addClass('attribute-loading');
            $('.kc-modal-body').removeClass('scroll-y');
        }
        else {
            $('#attribute-filter-content').parent().removeClass('attribute-loading');
            $('.kc-modal-body').addClass('scroll-y');
        }
    };

    //$('#open-kc-attributes a').trigger('click');

};
; kornCommerce.productReviews = kornCommerce.productReviews || {};

kornCommerce.productReviews.init = function (imageCount) {
    let list = document.querySelectorAll('#product-reviews p');

    list.forEach(item => {
        item.classList[item.scrollHeight > item.offsetHeight ? 'add' : 'remove']('truncated');
    });
};
; kornCommerce.search = kornCommerce.search || {};

kornCommerce.search.init = function () {

    var lastSearchValue = '',
        searchQueue = [],
        isSearching = false,
        isSearchingAborted = false,
        quickSearchUrl = $('input[name="QuickSearchUrl"]').val();

    var $modalSearch = $('#modal-search'),

        // inputs
        $searchInputs = $('#standard-search-input, #modal-search-input'),
        $standardSearchInput = $('#standard-search-input'),
        $modalSearchInput = $('#modal-search-input'),
        $searchInputOrigin,

        // result containers
        $searchResultContainers = $('#standard-search-result-container, #modal-search-result-container'),
        $standardSearchResultContainer = $('#standard-search-result-container'),
        $modalSearchResultContainer = $('#modal-search-result-container'),
        $targetSearchResultContainer,

        // result lists
        $searchResultLists = $('#standard-search-results, #modal-search-results'),
        $standardSearchResultList = $('#standard-search-results'),
        $modalSearchResultList = $('#modal-search-results'),
        $targetSearchResultList;

    // event when the standard searchbar is clicked/focused
    $standardSearchInput.off('focus.search').on('focus.search', function () {
        var $this = $(this);

        //console.log('focus', $this.val().length);

        isSearchingAborted = false;

        // add event to close the search results whenever somewhere outside was clicked
        $(document).off('click.search touchstart.search').on('click.search touchstart.search', function (e) {
            //console.log('click.search');

            if (!kornCommerce.functions.hasParentClass(e.target, 'search-wrapper')) {
                //console.log('clicked outside search-wrapper');

                // force remove click event
                $(document).off('click.search touchstart.search');

                if (isSearching) {
                    resetSearch();

                    // stop click from propagating
                    //console.log('stop click propagation');
                    e.preventDefault();
                    e.stopPropagation();

                    return;
                }

                // show/hide the results list
                if ($standardSearchResultList.find('li').length > 0 && $standardSearchResultList.find('li.selected').length === 0) {
                    //console.log('search results present, blur container');

                    if ($this.attr('id') === 'standard-search-input') {
                        $standardSearchResultContainer.hide();
                    }
                    else {
                        $modalSearchResultContainer.hide();
                    }
                }

                // when navbar is clicked, abort here and leave the rest to navbar.js
                if (kornCommerce.functions.hasParentClass(e.target, 'nav__level--1')) {
                    return;
                }

                // make searchbar stand out more by adding transparency to other elements
                $('#site-wrap > .semi-transparent').removeClass('semi-transparent');

                if ($this.val().length < 2) {
                    return;
                }

                // stop click from propagating
                //console.log('stop click propagation');
                e.preventDefault();
                e.stopPropagation();
            }
        });

        if ($this.val().length < 2) {
            resetSearch();

            return;
        }

        $('#site-wrap > *').not('header').addClass('semi-transparent');

        if ($standardSearchResultList.find('li').length > 0) {
            //console.log('search results present, show container');

            if ($this.attr('id') === 'standard-search-input') {
                $standardSearchResultContainer.show();
            }
            else {
                $modalSearchResultContainer.show();
            }
        }

        // trigger search
        $standardSearchInput.trigger('keyup.search');
    });

    // keyboard navigation
    $searchInputs.off('keydown.search').on('keydown.search', function (e) {
        var $this = $(this),
            code = e.keyCode || e.which,
            $listItems = $targetSearchResultList != null ? $targetSearchResultList.find('li') : null,
            $selectedlistItem = $targetSearchResultList != null ? $targetSearchResultList.find('li.selected') : null,
            $prevItem,
            $nextItem;

        switch (code) {

            // enter
            case 13:
            case 10:
                //console.log('key: enter');

                // if input is empty, prevent form submit
                if ($this.val().trim() === '') {
                    return false;
                }

                if ($listItems == null) {
                    return true;
                }

                if ($selectedlistItem != null && $selectedlistItem.length > 0) {
                    var selectedValue = $selectedlistItem.text().trim();

                    if ($selectedlistItem.hasClass('no-result')) {
                        // prevent form submit
                        return false;
                    }

                    if (!$selectedlistItem.hasClass('show-all')) {
                        // put the selected value in the input box
                        //$this.val(selectedValue);

                        // set isSearching true to prevent another quicksearch while loading
                        isSearching = true;

                        // load target url
                        $selectedlistItem.children('a')[0].click();

                        // prevent form submit
                        return false;
                    }

                    // otherwise just let the normal form submit happen
                }

                // let form submit happen
                return true;
                break;

            // esc
            case 27:
                //console.log('key: esc');

                // deselect current item and close the search
                if ($selectedlistItem != null && $selectedlistItem.length != 0) {
                    //console.log('esc -> deselect and hide');

                    // deselect
                    $selectedlistItem.removeClass('selected');
                }

                if ($searchResultContainers.is(':visible')) {
                    // hide result container
                    $searchResultContainers.hide();

                    // prevent default (modal close, clear input)
                    return false;
                }

                //console.log('esc -> default');

                // clean input field
                $this.val('');

                // let default happen
                return true;
                break;

            // arrow up
            case 38:
                //console.log('key: arrow up');

                if ($listItems == null || $selectedlistItem == null) {
                    return true;
                }

                if ($selectedlistItem.length === 0) {
                    $selectedlistItem = $prevItem = $listItems.last();
                }
                else {
                    if ($selectedlistItem.index() == $listItems.first().index()) {
                        $prevItem = null;
                    }
                    else {
                        $prevItem = $selectedlistItem.prev();
                    }
                }

                $listItems.removeClass('selected');

                if ($prevItem !== null) {
                    $prevItem.addClass('selected');
                }

                return false;
                break;

            // arrow down
            case 40:
                //console.log('key: arrow down');

                if ($listItems == null || $selectedlistItem == null) {
                    return true;
                }

                if ($selectedlistItem.length === 0) {
                    $selectedlistItem = $nextItem = $listItems.first();
                }
                else {
                    if ($selectedlistItem.index() == $listItems.last().index()) {
                        $nextItem = null;
                    }
                    else {
                        $nextItem = $selectedlistItem.next();
                    }
                }

                $listItems.removeClass('selected');

                if ($nextItem !== null) {
                    $nextItem.addClass('selected');
                }

                return false;
                break;

            //case 37: // arrow left
            //case 39: // arrow right

            default:
                break;
        }
    });

    // determine when to trigger the search
    $searchInputs.off('keyup.search').on('keyup.search', function (e) {
        var $this = $(this),
            currentSearchValue = $this.val().trim().toLowerCase();

        if (currentSearchValue.length < 2) {
            // abort when search is too short
            //console.log('search length too short');

            // reset the search to original
            resetSearch();

            return;
        }

        if (lastSearchValue === currentSearchValue) {
            // abort when search didn't change
            //console.log('search equals lastSearchValue');

            return;
        }

        // current state of search-input is eligible
        isSearchingAborted = false;

        if (isSearching) {
            // if a search is already in progress, put new search value in queue on position 0 and abort
            //console.log('already searching');
            searchQueue.unshift(currentSearchValue);

            return;
        }

        // handle cleanup of previous searches, loading animations, etc. before the actual search starts
        prepareSearch($this);

        // start search, results will be processed in function 'searchCallbackDone'
        startSearch(currentSearchValue);
    });

    $modalSearch.off('shown.bs.modal.search').on('shown.bs.modal.search', function (e) {
        // set focus on input element when modal is opened
        $modalSearchInput.focus();

        // code for switching between mobile and desktop view
        // if a search was executed in desktop and modal is opened
        // trigger search if the input is not empty
        if ($modalSearchInput.val() != null && $modalSearchInput.val().length >= 2) {
            lastSearchValue = '';
            $modalSearchInput.trigger('keyup.search');
        }
    });

    $modalSearch.off('hidden.bs.modal.search').on('hidden.bs.modal.search', function () {
        // code for switching between mobile and desktop view
        // if a search was executed in mobile and modal is closed
        // reset the last search value, so the search will be executed if desktop/standard input is clicked
        lastSearchValue = '';
    });

    function resetSearch() {
        //console.log('resetSearch');

        // clear queue
        //searchQueue = [];

        // abort any queued search
        isSearchingAborted = true;

        //// remove click event
        //if ($targetSearchResultContainer != null && $targetSearchResultContainer.is(':visible')) {
        //    $(document).off('click.search touchstart.search');
        //}

        // hide result containers
        if ($searchResultContainers != null) {
            $searchResultContainers.hide();
        }

        // clear all result lists
        if ($searchResultLists != null) {
            $searchResultLists.empty();
        }

        //// hide loading animations
        //if ($targetSearchResultContainer != null) {
        //    $targetSearchResultContainer.find('.search-loading').hide();
        //}

        //// hide previous error messages if present
        //if ($targetSearchResultContainer != null) {
        //    $targetSearchResultContainer.find('.search-error').hide();
        //}

        // remove transparency
        $('#site-wrap > .semi-transparent').removeClass('semi-transparent');
    }

    function prepareSearch($input) {
        //console.log('prepareSearch');

        // set used input field as the search origin
        $searchInputOrigin = $input;

        if (isSearchingAborted) {
            return;
        }

        // determine the correct result list, based on the input the search originated from
        if ($searchInputOrigin.attr('id') === 'standard-search-input') {
            $targetSearchResultList = $standardSearchResultList;
            $targetSearchResultContainer = $standardSearchResultContainer;

            // set input value to the other input to keep them in sync
            $modalSearchInput.val($searchInputOrigin.val());

            if (!isSearchingAborted) {
                // add transparency to other page elements
                $('#site-wrap > *').not('header').addClass('semi-transparent');
            }
        }
        else {
            $targetSearchResultList = $modalSearchResultList;
            $targetSearchResultContainer = $modalSearchResultContainer;

            // set input value to the other input to keep them in sync
            $standardSearchInput.val($searchInputOrigin.val());
        }

        //// abort here to let the variables be set with the most recent values
        //if (isSearchingAborted) {
        //    return;
        //}

        // clear all result lists
        $searchResultLists.empty();

        // hide previous error messages if present
        $targetSearchResultContainer.find('.search-error').hide();

        // show result container and loading animation while search is ongoing
        $targetSearchResultContainer.show();

        // show loading animation
        $targetSearchResultContainer.find('.search-loading').show();
    }

    function startSearch(value) {
        //console.log('startSearch', value);
        isSearching = true;
        lastSearchValue = value;

        $.ajax({
            type: 'POST',
            cache: false,
            url: quickSearchUrl,
            data: { search: value }
        })
        .done(function (result) {
            searchCallbackDone(result);
        })
        .fail(function () {
            searchCallbackFail();
        })
        .always(function () {
            isSearching = false;
            searchCallbackAlways();
        });
    };

    function searchCallbackDone(result) {
        //console.log('done');

        // apply result to target result list
        $targetSearchResultList.html(result);

        // get all eligible list items
        var $searchResultList = $targetSearchResultList.find('li:not(.show-all)');

        // apply some hover effects
        addMouseOverEffects($searchResultList);

        // highlight searchword within results
        highlightSearchWords($searchResultList);

        // check if search is still valid, otherwise drop the results
        if (isSearchingAborted) {
            //console.log('aborted, dont show results');
            return;
        }

        // make sure the right result container is shown
        $searchResultContainers.hide();

        $targetSearchResultContainer.show();
    };

    function searchCallbackFail() {
        //console.error('fail');

        // clear all result lists
        $searchResultLists.empty();

        // show error message
        $targetSearchResultContainer.find('.search-error').show();
    };

    function searchCallbackAlways() {
        //console.log('always');

        $targetSearchResultContainer.find('.search-loading').first().hide();

        // if search queue has entries, perform the last entered text as search again (position 0) and clear the queue
        // this prevents spamming the endpoint while the current search is still processing
        if (searchQueue.length > 0 && searchQueue[0] != lastSearchValue) {
            //console.log('search again for most recent queue entry', searchQueue[0]);

            // update search and clear array
            var queuedSearchValue = searchQueue[0];
            searchQueue = [];

            // perform another search, cleanup before that
            prepareSearch($searchInputOrigin);
            startSearch(queuedSearchValue);
        }
    };

    function addMouseOverEffects($searchResultList) {
        $searchResultList.off('mouseover.search').on('mouseover.search', function (e) {
            $searchResultList.removeClass('selected');
            $(this).addClass('selected');
        });

        $searchResultList.off('mouseout.search').on('mouseout.search', function (e) {
            $(this).removeClass('selected');
        });
    };

    function highlightSearchWords($searchResultList) {
        $searchResultList.each(function (i) {
            var $searchResultItem = $(this).find('a'),
                searchResultText = $searchResultItem.text(),

                // replace multiple spaces with a single one, split on them and trim every entry again
                searchArray = lastSearchValue.replace(/ +(?= )/, '').split(' ').map(function (item) {
                    return item.trim();
                });

            // sort array by length
            searchArray.sort(function (a, b) {
                // ASC  -> a.length - b.length
                // DESC -> b.length - a.length
                return b.length - a.length;
            });

            var replacedResultText = searchResultText;

            for (var j = 0; j < searchArray.length; j++) {
                var partialSearch = searchArray[j].trim();
                var posStart = searchResultText.toLowerCase().indexOf(partialSearch, 0),
                    posEnd = posStart + partialSearch.length;

                if (partialSearch.length <= 1 && /[<>/\\]/.test(partialSearch)) {
                    continue;
                }

                if (posStart !== -1) {

                    // find hit
                    var hit = searchResultText.substring(posStart, posEnd);

                    // remove the hit
                    searchResultText = searchResultText.replace(hit, '');

                    if (hit.isNullOrWhiteSpace()) {
                        continue;
                    }

                    // setup regex
                    var rex = new RegExp('(' + kornCommerce.functions.escapeRegex(hit) + ')(?!>)', 'gi'); // 'g' global, 'i' case insensitive

                    // replace hit with <b>'s
                    replacedResultText = replacedResultText.replace(rex, '<b>$1</b>');
                }
            }

            $searchResultItem.html('<span>' + replacedResultText + '</span>');
        });
    };
};
; kornCommerce.shoppingcart = kornCommerce.shoppingcart || {};

kornCommerce.shoppingcart.init = function () {

    if ($('#shopping-cart').length <= 0) {
        return;
    }

    // quantity buttons click
    $('#shopping-cart .shopping-cart-item__quantity button:not(.disabled)').off('click.shoppingcart').on('click.shoppingcart', function (e) {
        var $this = $(this),
            productId = parseInt($this.data('product-id')),
            quantity = parseInt($this.data('quantity'));

        $('#quantity_' + productId).val(quantity);
    });

    // quantity input change
    $('#shopping-cart .shopping-cart-item__quantity input').off('change.shoppingcart').on('change.shoppingcart', function () {
        var $this = $(this),
            reg = /^\d+$/,
            val = $this.val(),
            oldQuantity = parseInt($this.data('old-quantity')),
            min = parseInt($this.data('min')),
            max = parseInt($this.data('max'));

        // validate input
        if (!val.match(reg)) {
            $this.val(oldQuantity);
            return false;
        }

        val = parseInt(val);

        if (val < min) {
            val = min;
            $this.val(min);
        }

        if (val > max) {
            val = max;
            $this.val(max);
        }

        if (oldQuantity !== val) {
            $this.parent('form').submit();
        }
    });

    // coupon button click
    var couponIsSent = false;

    $('#form-send-coupon').off('submit').on('submit', function (e) {
        var $this = $(this),
            $button = $this.find('button[type="submit"]');

        $('#coupon-validation').hide().text('');

        if (!couponIsSent) {
            couponIsSent = true;

            $.ajax({
                type: 'POST',
                cache: false,
                url: $this.attr('action'),
                data: { couponCode: $('#input-coupon').val() },
                success: function (result) {
                    if (result === 'OK') {
                        window.location = location.pathname;
                    }
                    else {
                        $('#coupon-validation').show().text(result);

                        // reenable button manually
                        kornCommerce.button.endLoading($button);

                        couponIsSent = false;
                    }
                },
                error: function () {
                    $('#coupon-validation').show().text('Error');

                    // reenable button manually
                    kornCommerce.button.endLoading($button);

                    couponIsSent = false;
                }
            });
        }

        e.preventDefault();
        return false;
    });
};

kornCommerce.shoppingcart.initCartSummary = function () {
    //var cartItemCount = kornCommerce.webstorage.getItem('localStorage', 'shoppingCartItemAmount'); // getCookie('kc.CartAmount');

    //if (cartItemCount && parseInt(cartItemCount) > 0) {
    //    $('#btn-toggle-cart').append('<span class="tag tag-pill tag-default">' + cartItemCount + '</span>');
    //}

    $.ajax({
        url: '/de/warenkorb/summary',
        type: 'GET',
        cache: false
    })
    .done(function (result) {
        try {
            var amount = parseInt(result);

            if (amount >= 0) {
                $('#btn-toggle-cart .tag-pill').text(amount);
            }
        } catch (ex) {
            console.log('Exception: ' + ex);
        }
    });
};

//kornCommerce.shoppingcart.updateCartSummary = function (count) {
//    kornCommerce.webstorage.setItem('localStorage', 'shoppingCartItemAmount', count);
//};

//kornCommerce.shoppingcart.resetCartSummary = function () {
//    kornCommerce.webstorage.removeItem('localStorage', 'shoppingCartItemAmount');
//};

//function getCookie(name) {
//    var value = "; " + document.cookie;
//    var parts = value.split("; " + name + "=");
//    if (parts.length == 2) return parts.pop().split(";").shift();
//}
; kornCommerce.webstorage = kornCommerce.webstorage || {};

kornCommerce.webstorage.storageAvailable = function (type) {
    try {
        var storage = window[type],
			x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);

        return true;
    }
    catch (e) {
        return false;
    }
};

kornCommerce.webstorage.setItem = function (storageType, key, value) {
    try {
        if (kornCommerce.webstorage.storageAvailable(storageType)) {
            var storage = window[storageType];
            storage.setItem(key, value)
        }
    } catch (e) { }
};

kornCommerce.webstorage.getItem = function (storageType, key) {
    try {
        if (kornCommerce.webstorage.storageAvailable(storageType)) {
            var storage = window[storageType];
            return storage.getItem(key);
        }
    } catch (e) { }
};

kornCommerce.webstorage.removeItem = function (storageType, key) {
    try {
        if (kornCommerce.webstorage.storageAvailable(storageType)) {
            var storage = window[storageType];
            storage.removeItem(key);
        }
    } catch (e) { }
};

kornCommerce.webstorage.clear = function (storageType) {
    try {
        if (kornCommerce.webstorage.storageAvailable(storageType)) {
            var storage = window[storageType];
            storage.clear();
        }
    } catch (e) { }
};
; kornCommerce.plugins = kornCommerce.plugins || {};

kornCommerce.plugins.easyCredit = kornCommerce.plugins.easyCredit || {};

kornCommerce.plugins.easyCredit.initInstallmentPlans = function () {
    //console.log('initInstallmentPlans');

    function ecChange() {
        var $this = $(':selected', '#easycredit-rateSelect');

        $('#easycredit-totalinterest').html($this.data('totalinterest'));
        $('#easycredit-totalvalue').html($this.data('totalvalue'));
        $('#easycredit-installment').html($this.data('installment'));
        $('#easycredit-lastinstallment').html($this.data('lastinstallment'));
        $('#easycredit-nominalinterestrate').html($this.data('nominalinterestrate'));
        $('#easycredit-effectiveinterestrate').html($this.data('effectiveinterestrate'));

        $('#easycredit-chosenRate').val($this.val());
    };

    $('#easycredit-rateSelect').val($('#easycredit-chosenRate').val());

    $('#easycredit-rateSelect').on('change', function (e) {
        ecChange();
    });

    if (parseInt($('#easycredit-chosenRate').val()) === 0) {
        $('#easycredit-rateSelect > option').last().prop('selected', true);
    }

    ecChange();
};

kornCommerce.plugins.easyCredit.initPayment = function () {
    //console.log('easyCredit initPayment');

    //$('#easycredit-accept').on('change', function () {
    //    $('#PaymentConditionsAccepted').val($(this).is(':checked'));
    //});
};

kornCommerce.plugins.easyCredit.initHirePurchaseStart = function () {
    //console.log('initHirePurchase');

    var redirectTo = $('#easycredit-hirepurchase-start a').first().attr('href');

    //console.log('redirectTo: ', redirectTo);

    // redirect to easycredit payment page
    // use location.replace instead of location.href so the user won't be stuck in an endless loop when using the back button
    setTimeout(redirectToEasyCredit, 2500);

    function redirectToEasyCredit() {
        window.location.replace(redirectTo);
    }
};

//kornCommerce.plugins.easyCredit.initHirePurchaseEnd = function () {
//    //console.log('initHirePurchaseEnd');

//};
; kornCommerce.plugins = kornCommerce.plugins || {};

kornCommerce.plugins.paypalExpress = kornCommerce.plugins.paypalExpress || {};

kornCommerce.plugins.paypalExpress.init = function (shoppingCartAmount, clientId, clientToken, productId) {

    //function releaseLockedButtons() {
    //    kornCommerce.button.endLoading($('#btn-paypal-checkout'));
    //    //paypalButton.removeAttribute('disabled');

    //    $('#express-checkout-container button, #shopping-cart-index .form-checkout-index button').removeAttr('disabled');
    //};

    function stop() {
        // stop loading indicator
        kornCommerce.button.endLoading($('#btn-paypal-checkout'));

        // make sure the button is disabled
        $('#btn-paypal-checkout').attr('disabled', 'disabled');

        // re-enable other checkout buttons
        $('#express-checkout-container button, #shopping-cart-index .form-checkout-index button').not('#btn-paypal-checkout').removeAttr('disabled');
    }

    function showError(errorText) {
        // show message and scroll to that container
        $('#express-checkout-container').next().text(errorText).show();
        kornCommerce.functions.scrollTo($('#express-checkout-container'), 250, -15);
    };

    function hideError() {
        $('#express-checkout-container').next().hide().text('');
    };

    if (clientToken === '') {
        kornCommerce.plugins.paypalExpress.fail();
        return;
    }

    shoppingCartAmount = shoppingCartAmount.replace(",", ".");
    var parsedAmount = parseFloat(shoppingCartAmount);
    var amount = parsedAmount.toFixed(2);
    var isSuccessful = false;

    if (typeof braintree === 'undefined' || amount <= 0) {
        kornCommerce.plugins.paypalExpress.fail();
    }
    else {
        //console.log('initBraintree');

        // show loading indicator
        kornCommerce.button.startLoading($('#btn-paypal-checkout'));

        // init braintree
        braintree.client.create({
            authorization: clientToken
        }, function (clientErr, clientInstance) {

            // Create PayPal component
            braintree.paypalCheckout.create({
                client: clientInstance
            }, function (paypalCheckoutErr, paypalCheckoutInstance) {
                //console.log('paypalCheckout created');

                if (typeof paypalCheckoutInstance === 'undefined' || paypalCheckoutErr) {
                    showError('An error occured');
                    return;
                }

                hideError();

                // init Paypal SDK
                paypalCheckoutInstance.loadPayPalSDK({
                    'client-id': clientId,
                    intent: 'authorize',
                    currency: 'EUR',
                    commit: false,
                    vault: false,
                }, function () {
                    //console.log('paypal.Buttons');

                    // example for a second button
                    //paypal.Buttons({
                    //    fundingSource: paypal.FUNDING.SEPA,
                    //    style: {
                    //        layout: 'vertical',
                    //        color: 'silver',
                    //        shape: 'rect',
                    //    },
                    //}).render('#PaypalButton');

                    // https://developer.paypal.com/docs/checkout/integration-features/standalone-buttons/
                    // https://developer.paypal.com/docs/checkout/#try-the-buttons
                    paypal.Buttons({
                        fundingSource: paypal.FUNDING.PAYPAL,
                        // https://developer.paypal.com/docs/checkout/integration-features/customize-button/
                        style: {
                            layout: 'vertical',
                            color: 'white',
                            shape: 'rect',
                            label: 'checkout',
                            height: 48,
                            tagline: false
                        },

                        createOrder: function () {
                            // Button is clicked, overlay is loading
                            //console.log('createOrder');

                            // disable checkout buttons
                            $('#express-checkout-container button, #shopping-cart-index .form-checkout-index button').attr('disabled', 'disabled');

                            return paypalCheckoutInstance.createPayment({
                                // Include your PayPal options here. For available options, see
                                // http://braintree.github.io/braintree-web/current/PayPalCheckout.html#createPayment
                                flow: 'checkout',
                                intent: 'authorize',
                                amount: amount,
                                currency: 'EUR',
                                displayName: 'Musikhaus Korn',
                                locale: 'de_DE',
                                enableShippingAddress: true,
                                shippingAddressEditable: true,
                            });
                        },

                        onApprove: function (data, actions) {
                            //console.log('onApprove');

                            // hide the rendered button from Paypal, instead show our custom one
                            $('#PaypalButton').hide();
                            $('#btn-paypal-checkout').attr('disabled', 'disabled').show();

                            return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) {
                                // hide previous errors
                                hideError();

                                // add productId to POST data if available
                                payload.productId = productId;

                                // Submit 'payload.nonce' to your server
                                var postData = JSON.stringify(payload);

                                //console.log('postData', postData);

                                // post to server
                                $.ajax({
                                    type: 'POST',
                                    cache: false,
                                    url: '/de/paypalexpress/startexpresspayment',
                                    data: postData,
                                    contentType: 'application/json; charset=utf-8',
                                })
                                .done(function (result) {
                                    //console.log('done', result);

                                    if (result.toString().indexOf('success:') === 0) {
                                        isSuccessful = true;

                                        // inform google data layer
                                        // trigger begin_checkout, add_shipping_info and add_payment_info
                                        kornCommerce.google.expressCheckout(true, 'Standard', 'Paypal Express');

                                        // redirect
                                        window.location = result.toString().split('success:')[1];
                                    }
                                    else {
                                        showError(result.replace('error:', ''));
                                        stop();
                                    }
                                })
                                .fail(function () {
                                    //console.log('fail');

                                    showError('An error occured');
                                    stop();
                                })
                                .then(function () {
                                    //console.log('then');
                                });
                            });
                        },

                        onCancel: function (data) {
                            //console.log('PayPal payment cancelled', JSON.stringify(data, 0, 2));

                            // reenable all checkout buttons
                            $('#express-checkout-container button, #shopping-cart-index .form-checkout-index button').removeAttr('disabled');
                        },

                        onError: function (err) {
                            //console.error('PayPal error', err);

                            // Handle tokenization errors or premature flow closure
                            switch (err.code) {
                                case 'PAYPAL_POPUP_CLOSED':
                                    // not an error
                                    break;
                                case 'PAYPAL_ACCOUNT_TOKENIZATION_FAILED':
                                    //console.log('PayPal tokenization failed. See details: ' + err.details);
                                    break;
                                case 'PAYPAL_FLOW_FAILED':
                                    //console.log('Unable to initialize PayPal flow. Are your options correct? ' + err.details);
                                    showError('Error');
                                    break;
                                default:
                                    break;
                            }

                            showError('Error');
                        }
                    })
                    .render('#PaypalButton')
                    .then(function () {
                        // The PayPal button will be rendered in an html element with the given ID.
                        // This function will be called when the PayPal button is set up and ready to be used.
                        //console.log('render');
                        $('#btn-paypal-checkout').hide();
                        $('#PaypalButton').show();
                    });
                });
            });
        });
    }
};

kornCommerce.plugins.paypalExpress.fail = function () {
    $('#btn-paypal-checkout').attr('disabled', 'disabled');
};;
