/* Minification failed. Returning unminified contents.
(2490,62-63): run-time error JS1195: Expected expression: >
(2490,91-92): run-time error JS1004: Expected ';': )
(2507,14-15): run-time error JS1100: Expected ',': )
(2508,9-10): run-time error JS1002: Syntax error: }
(2510,46-47): run-time error JS1195: Expected expression: )
(2510,48-49): run-time error JS1004: Expected ';': {
(2534,10-11): run-time error JS1195: Expected expression: ,
(2536,55-56): run-time error JS1004: Expected ';': {
(2571,10-11): run-time error JS1195: Expected expression: ,
(2573,65-66): run-time error JS1004: Expected ';': {
(2607,5-6): run-time error JS1002: Syntax error: }
(2610,35-36): run-time error JS1195: Expected expression: )
(2610,37-38): run-time error JS1004: Expected ';': {
(2654,2-3): run-time error JS1195: Expected expression: )
(2656,12-13): run-time error JS1195: Expected expression: )
(2656,14-15): run-time error JS1004: Expected ';': {
(2658,2-3): run-time error JS1195: Expected expression: )
(2620,2,2653,3): run-time error JS1018: 'return' statement outside of function: return {
        Init: function () {
			this.Bindings();
		},
        Bindings: function () {
            $(document).on("change", selectors.fileInput, function () {
                var $this = $(this);
                if (!$this.attr("id")) {
                    return;
                }

                // Update label to include file name
                var filePath = $this.val();
                var fileName = filePath ? filePath.substring(filePath.lastIndexOf("\\") + 1) : "";

                var fieldLabel = $("label[for='" + $this.attr("id") + "']");
                
                if (!fieldLabel.attr(attributes.fileUploadLabel)) {
                    fieldLabel.attr(attributes.fileUploadLabel, fieldLabel.text());
                }

                fieldLabel.text(fileName.length > 18 ? fileName.substring(0 , 15) + "..." : fileName || fieldLabel.attr(attributes.fileUploadLabel));

                if (filePath) {
                    var requiredWrapper = $this.closest('.e-field__wrapper--required');

                    if (requiredWrapper.length) {
                        requiredWrapper.removeClass('e-field__wrapper--error');
                        requiredWrapper.next('.field-validation-error').hide();
                    }
                }
            });
        } 
	}
(2577,73-79): run-time error JS1018: 'return' statement outside of function: return
(2576,44-50): run-time error JS1018: 'return' statement outside of function: return
(2539,72-78): run-time error JS1018: 'return' statement outside of function: return
(2515,79-85): run-time error JS1018: 'return' statement outside of function: return
 */
/**
 * @dependencies : Jquery
 */
var Helpers = (function() {
	return {
		/**
		 * @param {function} func 		[function to execute]
		 * @param {int} wait 			[Milliseconds to wait between excecutions]
		 * @param {bool} immediate		[Run the function immediately]
		 * @return {function}
		 */
		Debounce: function(func, wait, immediate) {
			var timeout;

			return function() {
				var context = this, args = arguments;
				var later = function() {
					timeout = null;
					if (!immediate) func.apply(context, args);
				};
				var callNow = immediate && !timeout;
				clearTimeout(timeout);
				timeout = setTimeout(later, wait);
				if (callNow) func.apply(context, args);
			};
		},
		QueryString: (function (params) {
			if (params === '')
				return {};

			var returnParams = {};
			for (var i = 0; i < params.length; ++i)
			{
				var group = params[i].split('=');
				if (group.length != 2) continue;

				returnParams[group[0]] = decodeURIComponent(group[1].replace(/\+/g, " "));
			}
			return returnParams;
		})(window.location.search.substr(1).split('&'))
	}
})();;
var ReLazeImages = (function (){
	// Polyfill for checking if an element matches a selector.
	if (!Element.prototype.matches) {
		Element.prototype.matches = 
		Element.prototype.matchesSelector || 
		Element.prototype.mozMatchesSelector ||
		Element.prototype.msMatchesSelector || 
		Element.prototype.oMatchesSelector || 
		Element.prototype.webkitMatchesSelector ||
		function(s) {
		var matches = (this.document || this.ownerDocument).querySelectorAll(s),
		    i = matches.length;
		while (--i >= 0 && matches.item(i) !== this) {}
		return i > -1;            
		};
	}
	var $q = function ( query, res ) {
		if( document.querySelectorAll ) {
			res = document.querySelectorAll( query );
		} else {
			var documentObj = document,
				stylesheet = documentObj.stylesheets[0] || documentObj.createStyleSheet();

			stylesheet.addRule( query, 'f:b' );
			for ( var elements = documentObj.all, count = 0, ruleArray = [], elLength = elements.length; count < elLength; count++ ) {
				elements[count].currentStyle.f && ruleArray.push(elements[count]); 
			}

			stylesheet.removeRule(0);
			res = ruleArray;
		}
		return res;
	},
	addEventListener = function ( evt, fn ) {
		window.addEventListener
			? this.addEventListener( evt, fn, false )
			: ( window.attachEvent )
				? this.attachEvent( 'on' + evt, fn )
				: this['on' + evt] = fn;
	},
	debounce = function(func, wait, immediate) {
		var timeout;

		return function() {
			var context = this, args = arguments;
			var later = function() {
				timeout = null;
				if (!immediate) func.apply(context, args);
			};
			var callNow = immediate && !timeout;
			clearTimeout(timeout);
			timeout = setTimeout(later, wait);
			if (callNow) func.apply(context, args);
		};
	},
	removeClass = function(el, cssClass) {
		el.className = el.className.replace(new RegExp(" ?\\b"+cssClass+"\\b"),'');
	}
	addClass = function(el, cssClass) {
		var classes = el.className.split(' '),
			hasClass = false;
		for(var x = 0; x < classes.length; x++) {
			if(classes[x] === cssClass) hasClass = true;
		}
		if(!hasClass){ el.className += ' ' + cssClass; }
	},
	_has = function ( obj, key ) {
		return Object.prototype.hasOwnProperty.call(obj, key);
	},
	empty = function (val) {
		return (typeof(val) === 'undefined' || val === null || val === '');
	},
	breakpoints =  {
		mobile : 0,
		tablet : 768,
		desktop : 1280
	};
	return {
		Init: function ( query ) {
			if ( !query.length ) return;

			var images = $q(query),
				imageArray = [];

			if( !images.length ) return;

			// Array.prototype.slice.call is not callable under IE8 
			for (var i = 0; i < images.length; i++) {
				imageArray.push(images[i]);
			};

			var processImages = function ( allElements ) {
				allElements = (!empty(allElements) && allElements === true);

				var imagesToProcess = allElements ? images : imageArray;

				ReLazeImages.PrepImages( imagesToProcess );

				for ( var i = imagesToProcess.length - 1; i >= 0; i-- ) {
					if ((ReLazeImages.ElementInViewport(imagesToProcess[i]) || allElements) && imagesToProcess[i].hasAttribute('data-src')) {
						ReLazeImages.LoadImage(imagesToProcess[i], function () {
							!!imagesToProcess.splice ? imagesToProcess.splice(i, 1) : null;
						});
					}
				}
			};

			processImages();

			addEventListener('scroll', debounce(function(){
				processImages();
			}, 100));
			addEventListener('touchmove', debounce(function(){
				processImages();
			}, 100));
			addEventListener('resize', debounce(function(){
				processImages( true );
			}, 10));
		},
		PrepImages: function ( images ) {
			if ( !images.length ) return;

			for ( var x = 0; x < images.length; x++ ) {
				var image = images[x];
					imageToUse = this.UseWhichImage( image ),
					dimensions = this.GetImageDimensionsFromPath( imageToUse );

				if(empty(imageToUse) || empty(dimensions))
					continue;

				image.setAttribute('data-src', imageToUse);

				image.style.width = '100%';

				var clientWidth = image.clientWidth,
					parentWidth = parseFloat(window.getComputedStyle(image).width),
					widthToUse = dimensions.width;

				image.style.width = '';
				if(dimensions.width > parentWidth) {
					widthToUse = parentWidth;
				}

				image.style.width = widthToUse + 'px';
				image.style.height = (widthToUse * dimensions.aspectRatio) + 'px';
				
			}
		},
		GetImageDimensionsFromPath: function ( path ) {
			if ( empty(path) ) return null;

			var width = /width=(\d*)/g.exec(path),
				height = /height=(\d*)/g.exec(path);

			width = !empty(width) && !empty(width[1]) && !isNaN(parseInt(width[1])) ? parseInt(width[1]) : 0;
			height = !empty(height) && !empty(height[1]) && !isNaN(parseInt(height[1])) ? parseInt(height[1]) : 0;

			var aspectRatio = 1;
			if(width !== 0 && height !== 0)
				aspectRatio = height / width;

			return {
				width: width,
				height: height,
				aspectRatio: aspectRatio
			};
		},
		ResetImageStyles: function ( image , resetBackground ) {
			if(!empty(resetBackground) && resetBackground === true) {
				image.style.backgroundColor = '';	
			}
			image.style.width = '';
			image.style.height = '';
		},
		UseWhichImage: function ( el ) {
			var viewportSize = parseFloat(window.getComputedStyle(document.body).width),
				src = el.getAttribute('data-src'),
				desktopSrc = el.getAttribute('data-src-desktop'),
				tabletSrc = el.getAttribute('data-src-tablet'),
				mobileSrc = el.getAttribute('data-src-mobile');

			if( viewportSize < breakpoints.tablet && !empty(mobileSrc) )
				return mobileSrc;
			else if ( viewportSize < breakpoints.desktop && !empty(tabletSrc) )
				return tabletSrc;
			else if ( viewportSize >= breakpoints.desktop && !empty(desktopSrc) )
				return desktopSrc;

			return src;
		},
		LoadImage: function ( el, callback ) {
			removeClass(el, 'js-image-loaded');
			var img = new Image(),
				src = el.getAttribute('data-src');

			img.onload = function() {
				if(!el.matches("img")) {
					el.style.backgroundImage = 'url('+src+')';
				} else {
					el.style.height = '';
					el.style.width = '';
					if ( !! el.parent ) {
						el.parent.replaceChild(img, el);
					} else {
						el.src = src;
					}

					addClass(el, 'js-image-loaded');
				}

				if(typeof(callback) !== 'undefined') { callback(); }

				ReLazeImages.ResetImageStyles( el, true );
				el.removeAttribute('data-src');
			}
			img.src = src;

		},
		ElementInViewport: function ( el ) {
			var rect = el.getBoundingClientRect();

			return (
				rect.top >= 0
				&& rect.left >= 0
				&& rect.top <= (window.innerHeight || document.documentElement.clientHeight)
			)
		}
	}
})();
ReLazeImages.Init( '[data-lazy]' );;

$(function(){
	Videos.Init();
});

var Videos = (function(){
	return {
		Init: function() {
			this.VideoModalsSingle();
		},
		VideoModalsSingle: function() {
			var videos = $('[data-video-popup]');
			if(!videos.length) return;

			videos.each(function(){
				var video = $(this),
					trigger = video.find("[data-video-thumb]").first(),
					iframe = video.find("[data-video-frame]").first();

				if(!trigger.length || !iframe.length) return; // Iframe and trigger el required. Skip iteration.

				var newIframe = $('<iframe class="s-popupvideo__iframe" />');

				newIframe.attr('src', iframe.attr('src') + (iframe.attr('src').indexOf('?') > -1 ? '&':'?') + 'autoplay=1');

				trigger.magnificPopup({
					items: {
						src: '	<div class="s-modal">\
									<div class="s-modal__inner__content">\
										<div class="s-popupvideo">\
											<div class="s-popupvideo__inner">\
												'+newIframe[0].outerHTML+'\
											</div>\
										</div>\
									</div>\
								</div>\
						',
						type: 'inline'
					},
					callbacks: {
						open: function() {
							var modal = this.content;
							if(!modal.length) return;

							var videoWrapper = modal.find('.s-popupvideo').first();

							setTimeout(function(){
								videoWrapper.addClass('s-popupvideo--loaded');
							}, 600);
						}
					},
					closeMarkup: '<button class="s-modal__close mfp-close">Close <span class="s-modal__close__icon">&times;</span></button>'
				})
			});
		},
		MaintainAspectRatio: function(element) {
            var allElements = $(element),
                fluidEl = allElements.parent(); // The element that is fluid width

            // Figure out and save aspect ratio for each element
            allElements.each(function() {
              $(this)
                .data("aspectRatio", this.height / this.width)
                // and remove the hard coded width/height
                .removeAttr("height")
                .removeAttr("width");
            });

            // When the window is resized
            $(window).resize(function() {
              var newWidth = fluidEl.width();

              // Resize all elements according to their own aspect ratio
              allElements.each(function() {
                var el = $(this);
                el
                  .width(newWidth)
                  .height(newWidth * el.data("aspectRatio"));
              });

            // Kick off one resize to fix all elements on page load
            }).resize();
        }

	}
})();;

var MediaQueries = (function() {

    // User Agent
    var navU = navigator.userAgent;

    return {

        // Checks if we were at a breakpoint before resize, then checks what breakpoint we're at after resize
        // See scripts.js for initialisation.
        WasIs: function(options){

            var settings = $.extend({
                    wasMinWidth: null,
                    isMinWidth: null,
                    wasMaxWidth: null,
                    isMaxWidth: null,
                    ifTrueDo: null,
                    ifFalseDo: null
                }, options );

            var previousWidth = undefined,
                currentWidth = $(window).innerWidth(),

                // was/isMin/MaxWidth get set to true or false
                wasMinWidth = null,
                isMinWidth = null,
                wasMaxWidth = null,
                isMaxWidth = null,

                // propertiesToCheck gets given was/isMin/MaxWidth properties that were defined, and their values
                propertiesToCheck = {};

            $(window).smartresize(function() {

                // Check if the wasMin/MaxWidth properties are true

                // was: MinWidth
                if (settings.wasMinWidth !== null && settings.wasMinWidth !== undefined) {
                    wasMinWidth = previousWidth > parseInt(settings.wasMinWidth);
                    propertiesToCheck.wasMinWidth = wasMinWidth;
                }

                // was: MaxWidth
                if (settings.wasMaxWidth !== null && settings.wasMaxWidth !== undefined) {
                    wasMaxWidth = previousWidth < parseInt(settings.wasMaxWidth);
                    propertiesToCheck.wasMaxWidth = wasMaxWidth;
                }

                // Set the current width before we detect if the isMin/MaxWidth properties are true
                currentWidth = $(window).innerWidth();

                // is: MinWidth
                if (settings.isMinWidth !== null && settings.isMinWidth !== undefined) {
                    isMinWidth = currentWidth > parseInt(settings.isMinWidth);
                    propertiesToCheck.isMinWidth = isMinWidth;
                }

                // is: MaxWidth
                if (settings.isMaxWidth !== null && settings.isMaxWidth !== undefined) {
                    isMaxWidth = currentWidth < parseInt(settings.isMaxWidth);
                    propertiesToCheck.isMaxWidth = isMaxWidth;
                }

                // Number of properties & number of true values get counted
                var propertiesToCheckCount = 0,
                    propertiesToCheckTrueCount = 0

                for (property in propertiesToCheck) {
                    propertiesToCheckCount++;
                    if (propertiesToCheck[property] === true) propertiesToCheckTrueCount++;
                }

                // If there are as many true values as there are properties, we run the ifTrueDo function
                if (propertiesToCheckCount === propertiesToCheckTrueCount) {
                    if (settings.ifTrueDo !== null
                        && settings.ifTrueDo !== undefined
                        && typeof(settings.ifTrueDo) === "function") {
                        settings.ifTrueDo.call(this);
                    }
                }
                // Otherwise we run the ifFalseDo function
                else {
                    if (settings.ifFalseDo !== null
                        && settings.ifFalseDo !== undefined
                        && typeof(settings.ifFalseDo) === "function") {
                        settings.ifFalseDo.call(this);
                    }
                }

                // Set the previousWidth property when we're done resizing
                previousWidth = $(window).innerWidth();

            }).resize();

        },

        IsTouch: function() { 
            if (Modernizr.mq != undefined) {
                return Modernizr.touchevents;
            }
            else { return "\"Media Queries\" is not an included detect in your Modernizr build."; }
        },

        IsAndroidMobile: function() {
            return navU.indexOf('Android') > -1 && navU.indexOf('Mozilla/5.0') > -1 && navU.indexOf('AppleWebKit') > -1;
        },

        IsAndroidNativeBrowser: function() {
            var regExAppleWebKit = new RegExp(/AppleWebKit\/([\d.]+)/),
                resultAppleWebKitRegEx = regExAppleWebKit.exec(navU),
                appleWebKitVersion = (resultAppleWebKitRegEx === null ? null : parseFloat(regExAppleWebKit.exec(navU)[1]));

            return this.IsAndroidMobile() && appleWebKitVersion !== null && appleWebKitVersion < 537;
        },

        MinWidth: function(minWidthValue) {
            if (Modernizr.mq != undefined) {
                if (Modernizr.mq('only screen and (min-width: ' + minWidthValue + ')')) return true;
                else return false;
            }
            else { return "\"Media Queries\" is not an included detect in your Modernizr build."; }
        },

        MaxWidth: function(maxWidthValue) {
            if (Modernizr.mq != undefined) {
                if (Modernizr.mq('only screen and (max-width: ' + maxWidthValue + ')')) return true; 
                else return false;
            }
            else { return "\"Media Queries\" is not an included detect in your Modernizr build."; }
        },

        DeviceOrientation: function() {
            if (Modernizr.mq != undefined) {
                if (Modernizr.mq('only screen and (orientation:portrait)')) return "portrait";
                else if (Modernizr.mq('only screen and (orientation:landscape)')) return "landscape";
                else return null;
            }
            else { return "\"Media Queries\" is not an included detect in your Modernizr build."; }
        },

        DetectFirefox: function() {
            Modernizr.addTest('firefox', function () {
                return !!navigator.userAgent.match(/firefox/i);
            });
        },

        // Adds user agent (lets us detect IE10 and style through CSS)
        AddUserAgentAsClass: function() {
            var doc = document.documentElement;
            doc.setAttribute('data-useragent', navigator.userAgent);  
        },

        //  Adds support for the indexOf() method
        //  Running immediately because we tend to use indexOf regularly.
        AddIndexOfSupport: (function() {
            if (!Array.prototype.indexOf) {
                Array.prototype.indexOf = function(obj, start) {
                     for (var i = (start || 0), j = this.length; i < j; i++) {
                         if (this[i] === obj) { return i; }
                     }
                     return -1;
                }
            }
        })()

    }

})();
;
$(function(){
	ProjectFunctions.Init();
	MainNavigation.Init();
	RangeSliders.Init();
	FAQs.Init();
	Testimonials.Init();
	Tabs.Init();
	Collapsibles.Init();
	Products.Init();
	Forms.Init();
    Promos.Init();
    ValidatePromoRequestQuote.Init();

	ShoppingCart.Init();

	ResponsiveTables.Init();

	LiveChatExpanders.Init();

	MoreContentBtn.Init();

	//StyledSelects.Init('[data-styled-select]');

    svg4everybody();
});

var Utils = (function(){
	return {
		ImagesLoaded: function(el, func){
			var imgs = el.find('img'),
				count = imgs.length;

			return function() {
				var context = this, args = arguments;
				if(count) {
					imgs.load(function() {
						count--;
						if(!count) {
							func.apply(context, args);
						}
					}).filter(function() { return this.complete; }).load();
				} else {
					func.apply(context, args);
				}
			};

		},
		EqualHeightGroup : function (group)
		{
			group = $(group);

			tallest = 0;
			group.each(function() {
				thisHeight = $(this).height();
				if(thisHeight > tallest) {
					tallest = thisHeight;
				}
			});
			group.height(tallest);
		},
		EqualHeightGroupMinMax: function(group, minWidth, maxWidth) {
			group = $(group);

			$(window).on('resize', Helpers.Debounce(function() {
				var windowWidth = window.innerWidth;
				if (windowWidth >= minWidth && windowWidth < maxWidth) {
					group.css('height', '');
					Utils.EqualHeightGroup(group);
				} else {
					group.css('height', '');
				}
			}, 100)).resize();
		}
	}
})();

var Forms = (function(){
	return {
		Init: function() {
			this.ToggleSections();
		},
		ToggleSections: function() {
			var toggleTriggers = $('[data-toggle-target]');
			if(!toggleTriggers.length) return;
			toggleTriggers.on('change', function(){

				var trigger = $(this),
					target = $('[data-toggle-section="'+trigger.attr('data-toggle-target')+'"]'),
					requiredValue = trigger.attr('data-toggle-value-requirement');

				if(!target.length || typeof(requiredValue) === undefined) return;

				if(trigger.val() === requiredValue) {
					target.removeClass('e-hidden');
				} else {
					target.addClass('e-hidden');
				}
			});
		}
	}
})();

var ProjectFunctions = (function(){
	return {
		Init: function() {
			this.BannerSlider('.s-banners', '.s-banners__item');
            this.StandardModals('data-modal-target', 'data-modal-id');
            this.alternativeFitments();
            this.resetBindings();
			this.GenericSlideshows('data-slideshow', 'data-slideshow-item');
            this.CountOnCooperSlideshow();
            this.QuoteFormSubmit('#RequestQuoteForm', '#RequestQuoteFormSubmit');

			Utils.EqualHeightGroup('.h-navigation__article__title');
			Utils.EqualHeightGroup('.h-navigation__article__content');
			Utils.EqualHeightGroupMinMax('.e-promo-panel__title', 768, 1279);
			Utils.EqualHeightGroupMinMax('.e-promo-panel__text', 768, 1279);

			$(document).on("change", "select[data-id='select-site-country']", function (e) {
			    ProjectFunctions.ToggleSiteCountry(e.target);
			});

			// Setup Contour instances
			var contourInstances = $(Object.keys(window)).filter(function(_, key) {
				return key.indexOf('Contour') === 0;
			}).each(function(_, instanceName) {
				if (window.hasOwnProperty(instanceName)) {
					window[instanceName].Init();
				}
			});
        },
        resetBindings: function () {
            ProjectFunctions.alternativeFitments();
            RangeSliders.Init();
        },
        QuoteFormSubmit: function (form, button) {
            var form = $(form),
                button = $(button);
            form.submit(function (e) {
                if ($(this).valid()) {
                    button.prop('disabled', true);
                    button.css({
                        "background-color": "#edf0f2",
                        "border-color"    : "#edf0f2",
                        "color"           : "#1f1f1f"
                    });
                    button.children('span').html('processing<svg class="icon icon-loading-process"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Custom/UI/Content/svg/symbol-defs.svg#icon-loading-process"></use></svg>');
                    button.children('span').css('padding-right', "20px");
                    button.find('.icon-loading-process').show();
                }
            });
        },
		ToggleSiteCountry: function(selector) {		    
		    window.location.href = $(selector).val();
		},
		BannerSlider: function(selector, slideSelector) {
			var $banners = $(selector),
				actions = selector.replace('.','') + '__actions';
			if (!$banners.length) return;

			$banners.each(function(){
				var $banner = $(this);
				$banner.on('init', function( event, slick, direction ) {

					var $dots = slick.$dots;
					if(!$dots || !$dots.length) return;

					var icons = '\
						<svg class="icon icon-Pagination_Pause">\
							<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Custom/UI/Content/svg/symbol-defs.svg#icon-Pagination_Pause"></use>\
						</svg>\
						<svg class="icon icon-Pagination_Play">\
							<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Custom/UI/Content/svg/symbol-defs.svg#icon-Pagination_Play"></use>\
						</svg>\
					';

					var play = $('<button class="s-banners-toggle" aria-label="Play or pause slider">'+icons+'</button>');
					play.on('click', function(){
						var btn = $(this);
						if(!btn.is('.s-banners-toggle--pasued')) {
							slick.slickPause();
							btn.addClass('s-banners-toggle--pasued');
						} else {
							slick.slickPlay();
							btn.removeClass('s-banners-toggle--pasued');
						}
					});


					$dots.wrap('<div class="s-banners-dots" />')
						.parent()
						.prepend(play);

					play.wrap('<div class="'+actions+'" />');
				});

				$banner.slick({
					dots: true,
					dotsClass: actions,
					arrows: false,
					autoplay: true,
					slide: slideSelector,
					infinite: true,
					speed: 1500,
					autoplaySpeed: 4000,
					fade: true
				});
			});
		},
		StandardModals: function (triggerDataAttribute, modalDataAttribute) {
			var $triggers = $('['+triggerDataAttribute+']');

			if(!$triggers.length) return; // No triggers. Stop function.

			$triggers.each(function(){
				var $trigger = $(this),
					$modalContent = $('['+modalDataAttribute+'="'+$trigger.attr(triggerDataAttribute)+'"]');

				if(!$modalContent.length) return; // Cannot find modal content. Skip iteration.

				$trigger.magnificPopup({
					items: {
						type: 'inline',
						src: $modalContent
					},
					callbacks: {
					    open: function() {
					        // For any iframes on the comparison modals (ie youtube videos), set up the auto resize
					        var content = $(this.content);

					        if (content.find(".s-modal__video--comparison").length > 0) {
					        	setTimeout(function(){
									Videos.MaintainAspectRatio(content.find(".s-modal__video--comparison"));
								}, 500);
					        }
					    }
					},
					closeMarkup: '<button class="s-modal__close mfp-close">Close <span class="s-modal__close__icon">&times;</span></button>'
				});
			});
        },
        alternativeFitments: function (content, selectButton) {
            var trigger = $('[data-js-alternative-fitments-link]'),
                content = $('[data-js-alternative-fitments-content]'),
                selectBtn = $('[data-js-alternative-fitment-select]');
            trigger.magnificPopup({
                items: {
                    src: content,
                    type: 'inline'
                },
                midClick: true // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.
            });

            selectBtn.click(function () {
                $('.mfp-close').click();
            });
        },
		CountOnCooperSlideshow: function() {
			// Set up the Testimonials slider on Count on Coopers pages
			$(".s-testimonials-slideshow").slick({
				dots: false,
				arrows: true,
				autoplay: true,

				infinite: true,
				autoplaySpeed: 5000,
				prevArrow: "<a href='#' aria-label='Previous' class='s-testimonials-slideshow__arrow s-testimonials-slideshow__arrow--left'><svg class='icon icon-arrow_left'><use xlink:href='/Custom/UI/Content/svg/symbol-defs.svg#icon-arrow_left'></use></svg></div>",
				nextArrow: "<a href='#' aria-label='Next' class='s-testimonials-slideshow__arrow s-testimonials-slideshow__arrow--right'><svg class='icon icon-arrow_right'><use xlink:href='/Custom/UI/Content/svg/symbol-defs.svg#icon-arrow_right'></use></svg></div>"
			})
		},
		// This replaces jQuery's slideUp method.
        // Uses ".visually-hidden" class to hide
        // elements instead of display:none; so
        // they're stil visible to screen readers.
        SlideUp: function(selector, speed) {
            var speed = typeof speed === "undefined" ? "fast" : speed;
            selector.slideUp(speed, function() {
                selector.addClass("visually-hidden")
                        .attr("aria-hidden","true")
                        .slideDown(0);
            });
        },

        // This replaces jQuery's slideDown method.
        // Uses ".visually-hidden" class to hide
        // elements instead of display:none; so
        // they're stil visible to screen readers.
        SlideDown: function(selector, speed) {
            var speed = typeof speed === "undefined" ? "fast" : speed;
            selector.slideUp(0, function() {
                selector.removeClass("visually-hidden")
                        .removeAttr("aria-hidden")
                        .slideDown(speed);
            });
        },
        GenericSlideshows: function(slideshowDataAttr, slideDataAttr) {
        	var slideshows = $('['+slideshowDataAttr+']');
        	if(!slideshows.length) return; // Not slideshows. Stop function.
        	// add .mfp-iframe to the slide element if it is a youtube video.

        	slideshows.each(function(){
        		var slideshow = $(this),
        			markup = '<div class="s-modal">\
								<div class="s-modal__inner__content">\
									%content%\
								</div>\
								<div class="mfp-close"></div>\
							</div>';

        		slideshow.magnificPopup({
        			delegate: '['+slideDataAttr+']',
        			type: 'image',
        			gallery: {
        				enabled: true,
        				arrowMarkup: 	'<button type="button" class="s-modal__arrow s-modal__arrow--%dir% mfp-arrow mfp-arrow-%dir%" aria-label="Navigate %dir%">\
											<svg class="icon icon-arrow_%dir% s-modal__arrow__svg">\
												<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Custom/UI/Content/svg/symbol-defs.svg#icon-arrow_%dir%"></use>\
											</svg>\
        								</button>'
        			},
        			image: {
        				markup: markup.replace('%content%', '<div class="mfp-img"></div>')
        			},
        			iframe: {
        				markup: markup.replace('%content%', '<div class="s-popupvideo s-popupvideo--loaded"><div class="s-popupvideo__inner"><iframe class="s-popupvideo__iframe mfp-iframe" frameborder="0" allowfullscreen></iframe></div></div>')
        			},
        			closeMarkup: '<button class="s-modal__close mfp-close">Close <span class="s-modal__close__icon">&times;</span></button>'
        		});
        	});

        }
	}
})();

var Collapsibles = (function(){
	var collapsibleOpenClass = "active",
		collasibleTriggerSelector = '[data-collapsible-trigger]',
		collapsibleSectionSelector = '[data-collapsible-section]',
		collapsibleParentSelector = '[data-collapsible-parent]';

	return {
		Init: function() {
			this.Bindings(true, true);
		},
		Bindings: function(bindWindowEvents, animate) {
			bindWindowEvents = (typeof(bindWindowEvents) !== 'undefined' && bindWindowEvents === true);
			animate = (typeof(animate) !== 'undefined' && animate === true);
			var triggers = $(collasibleTriggerSelector);
			if(!triggers.length) return; // No Collapsibles on this page. Stop function.

			triggers.off('click').on('click', function(e){
				e.preventDefault();
				var trigger = $(this);
				Collapsibles.Toggle(trigger, collapsibleSectionSelector, collapsibleParentSelector);
			});

			if(bindWindowEvents) {
				var windowWidth = parseInt($(window).innerWidth());
				$(window).on('resize', Helpers.Debounce(function(){

					// Only run when the window is resized horizontally.
					var newWindowWidth = parseInt($(window).innerWidth());
					if(windowWidth !== newWindowWidth) {
						Collapsibles.ResetHeight($(collapsibleSectionSelector));
						windowWidth = newWindowWidth;
					}

				},100));
			}

			Collapsibles.ResetHeight($(collapsibleSectionSelector), animate);

		},
		ResetHeight: function(el, animate) {
			animate = (typeof(animate) !== 'undefined' && animate === true);
			el.filter("."+collapsibleOpenClass).each(function() {
				var elSingle = $(this);
				Utils.ImagesLoaded(elSingle, function(){
					elSingle.css({
						'max-height' : 'inherit',
						'transition' : 'none'
					});
					var height = elSingle.css('height');

					if(animate){
						elSingle.css('max-height', 0);
					}
					setTimeout(function(){
						elSingle.css({
							'max-height': height,
							'opacity' : '1'
						});
						if(animate){
							elSingle.css('transition', '');
						}
					}, 0);
				}());
			});
		},
		Open: function(el) {
			var parentEl = el.closest(collapsibleParentSelector),
				section = parentEl.find(collapsibleSectionSelector).first();

			if(!parentEl.length || !section.length) return; // Cannot find the section | parent.

			el.addClass(collapsibleOpenClass);

			var textNode = el[0].childNodes[0];
			// Text replacement to toggle between 'Open' and 'Close', or 'View More' and 'View Less'
			textNode.nodeValue = textNode.nodeValue.trim().replace(/open/gi, 'Close');
			textNode.nodeValue = textNode.nodeValue.trim().replace(/more/gi, 'less');

			section.addClass(collapsibleOpenClass);

			Collapsibles.ResetHeight(section, true);
		},
		Close: function(el) {
			var parentEl = el.closest(collapsibleParentSelector),
				section = parentEl.find(collapsibleSectionSelector).first();

			if(!parentEl.length || !section.length) return; // Cannot find the section | parent.

			el.removeClass(collapsibleOpenClass);

			var textNode = el[0].childNodes[0];
			// Text replacement to toggle between 'Open' and 'Close', or 'View More' and 'View Less'
			textNode.nodeValue = textNode.nodeValue.trim().replace(/close/gi, 'Open');
			textNode.nodeValue = textNode.nodeValue.trim().replace(/less/gi, 'more');

			section.removeClass(collapsibleOpenClass);
			section.css({'max-height' : 0, 'opacity' : '0', 'transition' : ''});
		},
		Toggle: function(el) {
			if(el.hasClass(collapsibleOpenClass)){
				this.Close(el);
			} else {
				this.Open(el);
			}
		}
	}
})();

var Tabs = (function(){
	var activeTabClass = "active";
	return {
		Init: function() {
			this.Bindings('data-tab-target', 'data-tab-id');
		},
		Bindings: function(triggerDataAttr, tabDataAttr) {
			var triggers = $('['+triggerDataAttr+']'),
				triggerParents = triggers.parents(),
				tabs = $('['+tabDataAttr+']');

			if(!triggers.length || !tabs.length) return; // No triggers. Stop function.

			triggers.on('click', function(e){
				e.preventDefault();
				var trigger = $(this),
					triggerParent = trigger.parent(),
					targetTab = $('['+tabDataAttr+'="'+trigger.attr(triggerDataAttr)+'"]');

				if(targetTab.length) {
					tabs.removeClass(activeTabClass);
					triggerParents.removeClass(activeTabClass);

					targetTab.addClass(activeTabClass);
					triggerParent.addClass(activeTabClass);
				}
			});
		}
	}
})();

var MainNavigation = (function(){
	return {
		Init: function() {
			var _headerWrapper = $(".h-wrapper");
			var _deviceNavigationWrapper = $(".h-navigation__device", _headerWrapper);
			var _deviceNavigationInner = $(".h-navigation__wrapper", _deviceNavigationWrapper);
			var _navCloseButton = $(".h-navigation__device__close");
			var _timeoutId = undefined;

			// Set up the binds
			// Device navigation open / close
			$(".h-navigation-toggle").on("click", function(e) {
				e.preventDefault();

				// Prevent the timeout from firing if it's in progress
				_deviceNavigationWrapper.removeClass("h-navigation__device--hidden");
				window.clearTimeout(_timeoutId);
				_timeoutId = undefined;

				// Now open it
				_timeoutId = window.setTimeout(function() {
					_headerWrapper.addClass("is-open");
				}, 10);
			})
			_navCloseButton.on("click", function(e) {
				e.preventDefault();

				// Close it
				_headerWrapper.removeClass("is-open");

				_deviceNavigationWrapper.attr("aria-hidden", "true");
				_deviceNavigationWrapper.attr("tabindex", "-1");

				// Set a timeout to hide the navigation from view once it finishes sliding out
				_timeoutId = window.setTimeout(function() {
					_deviceNavigationWrapper.addClass("h-navigation__device--hidden");
				}, 500);

			});

			// Expand toggles
			$(".h-navigation__item__expand").on("click", function(e) {
				e.preventDefault();

				var _this = $(this);
				var navItemWrapper = _this.closest(".h-navigation__item");
				var subNavWrapper = $(".h-navigation__sub-list__wrapper", navItemWrapper)

				navItemWrapper.addClass("is-expanded");
				_deviceNavigationWrapper.attr("aria-hidden", "false");
				_deviceNavigationWrapper.attr("tabindex", "0");
			})

			// Back buttons for tablet / mobile
			$(".h-navigation__sub-list__heading__link").on("click", function(e) {
				e.preventDefault();

				var navItemWrapper = $(this).closest(".h-navigation__item");
				var subNavWrapper = $(".h-navigation__sub-list__wrapper", navItemWrapper)

				navItemWrapper.removeClass("is-expanded");
			})

			// Disable page change actions for desktop navigation on tablet/mobile
			// Useful for "Our Range" item which stays visible on tablet
			$('.h-navigation__desktop .h-navigation__link').on('click', function(e) {
				if (MediaQueries.MaxWidth("1279px")) {
					e.preventDefault();
				}
			});

			// When a click is detected outside the menu, close the menu
			$(document).on("click", function(e) {

				if (_deviceNavigationInner.is(":visible"))
				{
					var $target = $(e.target);

					if ($target.closest(".h-navigation-toggle").length === 0 && $target.closest(".h-navigation__device").length === 0) {
						$(".h-navigation__device__close").trigger("click");
					}
				}
			});

			// Scrolling functionality
			var lastScrollPos = $(window).scrollTop();
			$(document).on('scroll', Helpers.Debounce(function() {
				if (!_headerWrapper.hasClass('is-open') && !_headerWrapper.is(':hover')) {
					var currentScrollPos = $(window).scrollTop();

					// Toggles class depending on: user has scrolled down && user has scrolled past header height
					_headerWrapper.toggleClass('is-hidden', (currentScrollPos > lastScrollPos && currentScrollPos > _headerWrapper.height()));

					// Set last scroll position
					lastScrollPos = currentScrollPos;
				}
			}, 50));
		}
	}
})();

// var StyledSelects = (function() {
// 	var classes = {
// 		selectNormalState : 's-styled-select',
// 		selectActiveState : 's-styled-select--active',
// 		selectDisplayedOption: 's-styled-select__current',
// 		selectDropdown : 's-styled-select__drop',
// 		selectOption : 's-styled-select__option',
// 		selectOptionSelected: 's-styled-select__option--selected',
// 		hideClass: 'visually-hidden' // Class not to copy to the new select box
// 	},
// 	boxTemplate = '\
// 		<div class="{{selectNormalState}}">\
// 			<span class="{{selectDisplayedOption}}">{{currentSelectedItemText}}</span>\
// 			<div class="{{selectDropdown}}">\
// 				{{dropDownItems}}\
// 			</div>\
// 		</div>\
// 	',
// 	itemTemplate = '\
// 		<span class="{{selectOption}}" data-option-val="{{selectOptionValue}}">{{selectOptionText}}</span>\
// 	';
// 	return {
// 		Init: function(selector) {
// 			var selects = $(selector).filter(function() { return $(this).is('select')});

// 			if(!selects.length) return;

// 			this.GenerateBoxes(selects);
// 		},
// 		GenerateBoxes: function(selectBoxes) {
// 			selectBoxes.each(function() {
// 				var select = $(this),
// 					options = select.find('option'),
// 					selectedOption = options.filter(function(){ return $(this).is(':selected') }),
// 					selectClasses = select.attr('class'),

// 					optionArray = [];

// 				options.each(function(){
// 					var option = $(this),
// 						value = option.attr('value'),
// 						text = option.text();
					
// 					optionHtml = itemTemplate
// 						.replace('{{selectOption}}', classes.selectOption + (option.is(selectedOption) ? ' '+classes.selectOptionSelected : ''))
// 						.replace('{{selectOptionValue}}', typeof(value) !== 'undefined' ? value : '')
// 						.replace('{{selectOptionText}}', typeof(text) !== 'undefined' ? text : '');
					
// 					optionArray.push({
// 						selected: option.is(selectedOption),
// 						text: typeof(text) !== 'undefined' ? text : '',
// 						value: typeof(value) !== 'undefined' ? value : '',
// 						html: optionHtml
// 					});
// 				});

// 				if(!optionArray.length) return;

// 				var selectedItem = optionArray.sort(function(item){ return item.selected; })[0];
// 				var selectHtml = boxTemplate
// 					.replace('{{selectNormalState}}', selectClasses + ' ' + classes.selectNormalState)
// 					.replace('{{selectDisplayedOption}}', classes.selectDisplayedOption)
// 					.replace('{{currentSelectedItemText}}', selectedItem.text)
// 					.replace('{{selectDropdown}}', classes.selectDropdown)
// 					.replace('{{dropDownItems}}', function(){
// 						var returnItems = '';
// 						for(var x = 0; x < optionArray.length; x++) { returnItems += optionArray[x].html; }
// 						return returnItems;
// 					});
// 				select.addClass(classes.hideClass);
// 				$(selectHtml).insertAfter(select);
// 			});
// 			this.Bindings();
// 		},
// 		Bindings: function() {
// 			var styledSelects = $('.' + classes.selectNormalState);
// 			if(!styledSelects.length) return;

// 			styledSelects.removeClass(classes.hideClass);

// 			$(document).on('click', '.'+classes.selectNormalState, function(e){
// 				var clickTarget = $(e.target),
// 					styledSelect = clickTarget.closest('.'+classes.selectNormalState),
// 					styledOptions = styledSelect.find('.'+classes.selectOption),
// 					select = styledSelect.prev();

// 				if(!select.length || !select.is('select')) return;

// 				if(clickTarget.is('.'+classes.selectOption)) {
// 					styledOptions.removeClass(classes.selectOptionSelected);
// 					clickTarget.addClass(classes.selectOptionSelected);

// 					var value = clickTarget.attr('data-option-val'),
// 						text = clickTarget.text();
					
// 					select.val(value);
// 					styledSelect.find('.'+classes.selectDisplayedOption).first().html(text);
// 					styledSelect.removeClass(classes.selectActiveState);
// 				} else {
// 					styledSelect.toggleClass(classes.selectActiveState)
// 				}
// 			});
// 		}
// 	}
// })();

var FAQs = (function() {
	return {
		Init: function() {
			var accordionTriggers = $("[data-accordion-trigger]");

			accordionTriggers.on("click", function(e) {
				e.preventDefault();

				// This accordion..
				var accordion = $(this).closest("[data-accordion]");

				// This accordion item..
				var thisAccordionItem = $(this).closest("[data-accordion-item]");

				var accordionItems = $("[data-accordion-item]", accordion)

				// Find ones that are open within this accordion
				var openAccordionItems = accordionItems.not(thisAccordionItem).filter(".is-open");

				// Close them if there are any
				if (openAccordionItems.length) {
					ProjectFunctions.SlideUp($("[data-accordion-content]", openAccordionItems));
					openAccordionItems.removeClass("is-open");
				}
				// Now expand the current one (if it isn't already)
				if (!thisAccordionItem.hasClass("is-open"))
				{
					thisAccordionItem.addClass("is-open");
					ProjectFunctions.SlideDown($("[data-accordion-content]", thisAccordionItem));
				}
			});

			// Accordion close button
			var accordionCloseTriggers = $("[data-accordion-close]");

			accordionCloseTriggers.on("click", function(e) {
				e.preventDefault();

				// This accordion item..
				var thisAccordionItem = $(this).closest("[data-accordion-item]");
				ProjectFunctions.SlideUp($("[data-accordion-content]", thisAccordionItem));
				thisAccordionItem.removeClass("is-open");

			});

			// Set up the category switching
			var faqItemGroups = $("[data-faq-group]");
			var faqCategories = $("[data-faq-category]");
			var faqCategoryTriggers = $("[data-faq-category-trigger]", faqCategories);
			faqCategoryTriggers.on("click", function(e) {
				e.preventDefault();
				faqCategories.removeClass("is-current");
				$(this).closest("[data-faq-category]").addClass("is-current");

				// fade out the currently visible group and show the relevant one
				var faqGroupToShow = faqItemGroups.filter("[data-faq-group=" + $(this).data("id") + "]");
				var faqGroupToHide = faqItemGroups.filter(":not(.visually-hidden)");

				// Now find the FAQ group that should be displayed
				if (faqGroupToHide[0] != faqGroupToShow[0]) {
					faqGroupToHide.fadeOut(300, function() {
						$(this).addClass("visually-hidden").show();

						faqGroupToShow.hide().removeClass("visually-hidden").fadeIn(300);

					})

				}

			});

		}
	}
})();

var RangeSliders = (function() {
	return {
		Init: function() {
			$('.s-tyre-filter__range-input').each(function() {
                var thisSlider = $(this);
                thisSlider.rangeslider({
					polyfill: false,
					onInit: function() {
						RangeSliders.UpdateRangeDisplay(this.value);
					},
					onSlide: function(position, value) {
						//makeRangeSliderActive(this.$element, value);
					}
				}).on('input', function() {
					RangeSliders.UpdateRangeDisplay(this.value);
				});
			});

			// Code currently not being used, originally the animation was done in CSS but this was proving
			// to be time consuming
			//
			// Set max heights of all products to current heights
			// var products = $('.s-product-list__box');
			// $(window).on('resize', function(){
			// 	var hiddenProducts = products.filter('.is-hidden');
			// 	hiddenProducts.removeClass('is-hidden');
			// 	products.each(function(index) {
			// 		var product = $(this);
			// 		Utils.ImagesLoaded(product, function(){
			// 			product.css('max-height', 'auto');
			// 			product.css('max-height', product.css('height'));
			// 		})();
			// 	}).promise().done(function(){ hiddenProducts.addClass('is-hidden'); });
			// }).resize();
		},
		UpdateRangeDisplay: function(rangeVal) {
			// Check if value is N/A
			if (parseInt(rangeVal) !== 0) {
				var products = $('.s-product-list__box');

				// Discover and reset product error
				var productError = $('.s-product-list-error');
				productError.addClass('is-visible');

				$('.s-product-list__box').each(function() {
					var product = $(this);
					// Check if the tyre should be visible at this rating and toggle its class
					// !product.data('terrain-rating')['terrainRating' + rangeVal] ? product.addClass('is-hidden') : product.removeClass('is-hidden');
					if (!product.data('terrain-rating')['terrainRating' + rangeVal]) {
						product.slideUp();
					} else {
						// At least one product is visible, don't display an error
						$('.s-product-list-error').removeClass('is-visible');
						product.slideDown();
					}
				});
			} else {
				// No selection was made, display all the tyres
				$('.s-product-list__box').slideDown();
			}
		}
	}
})();

var Testimonials = (function () {
        var sideBarTestimonials = $('[data-testimonial]'),
	        filterDropDown = $('[data-testimonial-filter]').first(),
	        currentPageShowing = 1,
	        filterApplied = "all",
	        itemsToShowPerPage = 3;

        return {
            Init: function () {
            	if(!sideBarTestimonials.length) return; // No testimonials. Stop function.

                // Add class "current" to first testimonial in sidebar
                sideBarTestimonials.first().addClass('current');

                // Get the filter from the querystring and set the selected item in the dropdown
                filterApplied = Helpers.QueryString["filter"] != null ? Helpers.QueryString["filter"] : filterApplied;

                // If the filter is invalid (eg typed it manually and doesn't exist in the drop down), change it to all
                if (!filterDropDown.find('option[value=' + filterApplied + ']').length)
                    filterApplied = "all";

                Testimonials.SetLinks();

                // Add class "active" to first select box option (changes later)
                //filterDropDown.find('option').first().addClass('active');

                Testimonials.ShowItems();

                // When a option is selected in the select menu:
                filterDropDown.change(function () {
                    //Remove any existing "active" classes and give one to the selected option
                    var dropDown = $(this),
                    	selectedValue = dropDown.val();

                    filterApplied = selectedValue;
                    // Reset the page counter, update the links for each testimonial and show the relevant items
                    currentPageShowing = 1;
                    Testimonials.SetLinks();
                    Testimonials.ShowItems();
                });

                // Bind the next/prev buttons
                $('[data-testimonial-next]').on('click', function (e) {
                    e.preventDefault();
                    Testimonials.Next();
                });
                $('[data-testimonial-prev]').on('click', function (e) {
                    e.preventDefault();
                    Testimonials.Prev();
                });
            },
            ShowItems: function () {
                var itemsToShow = filterApplied == 'all' ? sideBarTestimonials : sideBarTestimonials.filter('[data-product="' + filterApplied + '"]'),
                	totalPagesForItems = itemsToShow.length / itemsToShowPerPage,
                	nextButton = $('[data-testimonial-next]'),
                	prevButton = $('[data-testimonial-prev]');

                if (itemsToShow.length > 0)
                {
                    // Don't change the display if we are trying to show more than the last page of items (ie if 'next' has been clicked & there aren't actually any more)
                    if (currentPageShowing > Math.ceil(totalPagesForItems))
                        currentPageShowing = Math.ceil(totalPagesForItems);
                    else {
                        // Hide all testimonials, then show the relevant items
                        if (itemsToShow.length > 3){
							nextButton.removeAttr('disabled');
							prevButton.removeAttr('disabled');

                            if (currentPageShowing == 1){
                                prevButton.attr('disabled', true);
                            } else if (currentPageShowing > 1){
                                prevButton.removeAttr('disabled');
                            }

                            if (currentPageShowing == Math.ceil(totalPagesForItems)){
                                nextButton.attr('disabled', true);
                            } else if (currentPageShowing < Math.ceil(totalPagesForItems)){
                            	nextButton.removeAttr('disabled');
                            }
                        }
                        sideBarTestimonials.fadeOut(500);
                        itemsToShow.slice((currentPageShowing - 1) * itemsToShowPerPage, currentPageShowing * itemsToShowPerPage).delay(500).fadeIn();
                    }

                    if (itemsToShow.length <= 3){
	                    nextButton.attr('disabled', true);
	                    prevButton.attr('disabled', true);
                    }
                }
                else
                {
                    // No items, show a message
                    sideBarTestimonials.fadeOut(500);
                    nextButton.attr('disabled', true);
	                prevButton.attr('disabled', true);

                    $('.s-testimonial-sidebar__copy').first().fadeIn(500);
                }
            },
            // Next 'page'
            Next: function () {
                currentPageShowing++;
                Testimonials.ShowItems();
            },
            // Previous 'page'
            Prev: function () {
                if (currentPageShowing > 1) {
                    currentPageShowing--;
                    Testimonials.ShowItems();
                }
            },
            // When a testimonial is selected from the sidebar, update the links in the sidebar so the filtered state remains
            SetLinks: function () {
                sideBarTestimonials.find('a').each(function () {
                    var baseurl = $(this).attr('href').indexOf("?") == -1
                        ? $(this).attr('href')
                        : $(this).attr('href').substring(0, $(this).attr('href').indexOf("?"));
                    $(this).attr('href', baseurl + "?filter=" + filterApplied);
                });
            }
        }
    }());

var Products = (function() {
	var activeInfoPanelClass = "active",
		boxButtonTriggerSelector = "[data-product-feature-trigger]",
		figureFeatureSelector = "[data-product-figure-feature]",
		readMoreTriggerSelector = "[data-product-readmore-trigger]",
		closeTriggerSelector = "[data-product-feature-close]",
		boxThreshold = 989; // Maximum width, before clicking the circle on the product figure scrolls to the element, rather than showing the little info box.

	return {
		Init: function() {
			this.Bindings();
			this.TableToggleSections('[data-productinfo-toggle]', '[data-productinfo-toggle-parent]');

			$(window).on('load', function() {
                var id = window.location.hash;

                if(typeof id === 'undefined' || id == '')
                    return;

                var element = $(id);
                if(!element.length)
                    return;

				// If it is the ProductTestimonials div.. open that panel
				if (id === "#ProductTestimonials") {
					element.find("[data-collapsible-trigger]").trigger("click");
				}
            });

		},
		Bindings: function() {
			var readMoreTriggers = $(readMoreTriggerSelector),
				boxButtonTriggers = $(boxButtonTriggerSelector),
				allFeatures = $(figureFeatureSelector);

			if(readMoreTriggers.length) {
				readMoreTriggers.on('click touchstart', function(e) {
					e.preventDefault();
					var trigger = $(this),
						targetEl = $(trigger.attr('href'));
					Products.ScrollToInfoEl(targetEl);
				});
			}

			if(boxButtonTriggers.length) {
				boxButtonTriggers.on('click touchstart', function(e) {
					e.preventDefault();
					var trigger = $(this),
						feature = trigger.closest(figureFeatureSelector),
						readMoreTrigger = feature.find(readMoreTriggerSelector).first();

					if(!feature.length || !readMoreTrigger.length) return;

					var winWidth = window.innerWidth; // Returns the actual width of the window, with or without scrollbars and lines up with media queries.
					if(winWidth > boxThreshold) {
						readMoreTrigger.click(); // Scroll to the appropirate element.
					} else {
						allFeatures.removeClass(activeInfoPanelClass);
						feature.addClass(activeInfoPanelClass);
					}
				});

				$(document).on('click touchstart', function(e){
					var clickedEl = $(e.target),
						parentFeature = clickedEl.closest(figureFeatureSelector);

					if((clickedEl.is(figureFeatureSelector) || parentFeature.length) && !clickedEl.is(closeTriggerSelector)) return;
					allFeatures.removeClass(activeInfoPanelClass);
				});
			}
		},
		TableToggleSections: function(triggerSelector, parentSelector) {
			var triggers = $(triggerSelector),
				activeClass = "active-table";

			if(!triggers.length) return;

			triggers.on('click', function(e){
				e.preventDefault();
				var trigger = $(this),
					section = trigger.closest(parentSelector);

				if(!section.length) return;

				if(section.hasClass(activeClass)){
					section.removeClass(activeClass);
					trigger.text(trigger.text().replace("Less", "More"));
				} else {
					section.addClass(activeClass);
					trigger.text(trigger.text().replace("More", "Less"));
				}
				Collapsibles.Bindings();
			});
		},
		ScrollToInfoEl: function(el) {
			var element = $(el);
			if(!el.length) return;

			$('html, body').animate( {scrollTop: element.offset().top}, 1000);
		}
	}
})();

var ShoppingCart = (function() {
	return {
		Init: function() {
			$(".s-retailer-select").on("click", function(e) {
				e.preventDefault();
			})
		}
	}
})();

var ResponsiveTables = (function() {
	return {
		Init: function() {
			// Wraps editable text layout tables so they can scroll horizontally as needed
			$('.editable-text .LayoutTable').wrap('<div class="editable-text__table-wrapper" />');

			var responsiveTables = $('.editable-text .ResponsiveTable');
			responsiveTables.each(function() {
				var table = $(this);
				var tableRows = table.find('tr');

				// Find headers
				var colHeaders = table.find('th[scope="col"]');

				tableRows.each(function() {
					var row = $(this);

					// Column headers
					var rowData = row.children();
					for (var i = 0; i < rowData.length; i++) {
						// This ensures tables have correct headers applied even if the table is not simple
						if ($(rowData[i]).is('td')) {
							rowData[i].setAttribute('data-title', $(colHeaders[i]).text());
							$(rowData[i]).wrapInner('<span class="table-cell-content" />')
						}
					}

					// Row header
					var rowHeader = row.find('th[scope="row"]').first();
					if (rowHeader.length) {
						// For some reason, row.data() does not work here
						row[0].setAttribute('data-title', rowHeader.text());
						row.addClass('has-header');
					}
				});
			});
		}
	}
})();

var LiveChatExpanders = (function() {
	return {
		Init: function() {
			// Onclicks for livechat openers
			$('[data-livechat-trigger], .js-open-live-chat').on('click', function(e) {
				e.preventDefault();

                try {
                    if (!!window.olark) {
                        window.olark("api.box.expand");
                    } else {
                        var fixedChat = $('[data-fixed-chat]');
                        if (fixedChat.length) {
                            fixedChat.click();
                        }
                    }
				} catch (ex) {
					log({
						origin: "data-livechat-trigger.onclick",
						message: "Exception on trying to invoke third-party 'olark' component.",
						exception: ex
					});
				}
			});
		}
	}
})();

var Promos = (function() {
	var selectors = {
		promos: '[data-js-promos]',
		wrapper: '.row'
	};
	var classes = {
		sticky: 'e-promos--sticky',
		bottom: 'e-promos--bottom'
	};

	var promos = [];
	// If .h-wrapper cannot be found, this would be null => Offset defaults to 15
	var scrollOffset = $('.h-wrapper').first().outerHeight() + 15;

	return {
		Init: function() {
			var promosWrappers = $(selectors.promos);

			if (promosWrappers.length && promosWrappers.children().length) {
				promosWrappers.each(function() {
					var promoWrapper = $(this);
					promos.push({ wrapper: promoWrapper, defaultPosition: promoWrapper.offset().top });
				});

				this.Bindings();
			}
		},
		Bindings: function() {
			$(document).on('scroll', Helpers.Debounce(function() {
				$(promos).each(function() {
					var promo = this,
						promoWrapper = this.wrapper,
						promoWrapperOffsetBottom = promoWrapper.outerHeight() + scrollOffset,
						parent = promoWrapper.parent(),
						parentInnerWidth = parent[0].getBoundingClientRect().width - parseInt(parent.css('padding-left')) - parseInt(parent.css('padding-right')),
						closestWrapper = promoWrapper.closest(selectors.wrapper),
						closestWrapperOffsetBottom = closestWrapper.offset().top + closestWrapper.outerHeight(),
						currentScrollPos = $(window).scrollTop();

					if (currentScrollPos >= (promo.defaultPosition - scrollOffset) && (promoWrapperOffsetBottom + currentScrollPos) < closestWrapperOffsetBottom) {
						// Go sticky
						promoWrapper.css({ width: parentInnerWidth, top: '' });
						promoWrapper.addClass(classes.sticky).removeClass(classes.bottom);

						parent.css({ paddingBottom: promoWrapper.outerHeight() });
					} else if (promoWrapper.hasClass(classes.sticky)) {
						// Stick to bottom or unstick completely
						if ((promoWrapperOffsetBottom + currentScrollPos) >= closestWrapperOffsetBottom) {
							var offsetParent = promoWrapper.offsetParent(),
								offsetParentOffsetBottom = offsetParent.offset().top + offsetParent.outerHeight(),
								position = closestWrapper.outerHeight() - promoWrapper.outerHeight();
							
							promoWrapper.css('top', position);
							promoWrapper.addClass(classes.bottom).removeClass(classes.sticky);
						} else {
							promoWrapper.css({ width: '', top: '' });
							promoWrapper.removeClass(classes.sticky).removeClass(classes.bottom);
						}
					}
				});
			}, 10));
		}
	}
})();

var ValidatePromoRequestQuote = (function () {

    var validateBtn = $('#validatePromoCodeBtn');
    var removeBtn = $('#removePromoCodeRequestQuoteBtn');
    var promoCodeTextBox = $('.promocode-value');
    var promoCodeMessageDiv = $('#promoCodeDiv');

    return {
        Init: function () {
            this.Bindings();
            removeBtn.hide();
        },
        Bindings: function () {


            if (promoCodeMessageDiv.length > 0) {
                promoCodeMessageDiv.hide();
                promoCodeMessageDiv.empty();
            }

            validateBtn.click(function () {
                
                if (promoCodeTextBox.val().length > 0) {
                    var promoCode = promoCodeTextBox.val();
                    try {
                        $.ajax({
                            url: "/api/applyPromoCodeVoucher",
                            data: JSON.stringify({ promoCode : promoCode }),
                            type: "POST",
                            dataType: "json",
                            contentType: "application/json",
                            success: function (response) {
                                var responseData = response.Data;
                                var payload = {
                                    state: "AJAX-SUCCESS",
                                    ajaxStatus: "Success",
                                    response: response,
                                    data: responseData
								};
								
                                if (!response.Success) {
                                    promoCodeMessageDiv.empty();
                                    promoCodeMessageDiv.append("<span class=\"field-validation-error\">Invalid promo code</span>");
                                    promoCodeMessageDiv.show();
                                    return;
								}
								
                                promoCodeMessageDiv.hide();
                                promoCodeMessageDiv.empty();

                                var promo = response.Data.Voucher;
                                var msg = "";
                                switch (promo.DiscountTypeName) {

                                    case "AmountPerItem":
                                        msg = '$' + promo.AmountPerItem + ' off per tyre';
                                        break;

                                    case "AmountOffTotal":
                                        msg = '$' + promo.AmountOffTotal + ' off of final order';
                                        break;

                                    case "PercentageOffTotal":
                                        msg = promo.PercentageOffTotal + '%' + ' off of final order';
                                        break;
                                
                                    default:
                                        msg = "Discount code applied";
                                        break;
                                }
                                promoCodeMessageDiv.append("<p class=\"e-content-box-grey s-form-promo__success\"><strong>Promo:</strong> " + msg + "</p>");
                                promoCodeMessageDiv.show();
                                validateBtn.hide();
                                removeBtn.show();
                            },
                            error: function (xhr, textStatus, error) {
                                var payload = {
                                    state: "AJAX-ERROR",
                                    ajaxStatus: "Error",
                                    ajaxError: {
                                        xhr: xhr, textStatus: textStatus, error: error
                                    }
                                };
                            }
                        });
                    } catch (ex) {
                        var payload = {
                            state: "ERROR",
                            ajaxStatus: "Error",
                            ajaxError: {
                                exception: ex
                            }
                        };
                    }
                }
            });

            removeBtn.click(function () {
                promoCodeTextBox.val('');
                promoCodeMessageDiv.hide();
                promoCodeMessageDiv.empty();
                removeBtn.hide();
                validateBtn.show();
            });
        }
    }
})();

var MoreContentBtn = (function() {
	return {
		Init: function() {
			$('[data-js-more-content]').on('click', function(e) {
				var allScrollPositions = $('.e-body-content__wrapper, .e-content-row, .s-product-list__box, .e-subpage-panel__section, .editable-text__table-wrapper, .w-video-text, .w-videos, .s-testimonial__content, .s-blog-list__item, .editable-text h2, .editable-text h3, .s-feeds').map(function() {
					return $(this).offset().top;
				}).toArray();

				allScrollPositions.push($(document).height());

				var nextScrollPosition = $.grep(allScrollPositions, function(position) {
					return parseInt(position) > $(window).scrollTop();
				})[0];

				if (typeof nextScrollPosition !== 'undefined') {
					$('html, body').animate({ scrollTop: nextScrollPosition }, 1000);
				}
			});

			$(document).on('scroll', Helpers.Debounce(function() {
				if ($(window).scrollTop() + $(window).height() >= $(document).height() - $('.f-wrapper').first().height()) {
					$('[data-js-more-content]').addClass('s-more-content__btn--hidden');
				} else {
					$('[data-js-more-content]').removeClass('s-more-content__btn--hidden');
				}
			}, 50));
		}
	}
})();;
$(function(){
    TyreFinder.Init();
    TyreFinder.GeneralBindings();
    TyreFinder.InitPostcode();
});

var TyreFinder = (function(){
	return {
	    Init: function () {
	        this.SetFocus();
		    this.Tabs();
		    this.ByVehicle();
		    this.BySize();
		    this.TyreComparison();
		    this.RequestQuote();
		},
	    GeneralBindings: function () {
	        $(document).on('keydown', '.tyrefinder-vehicle-input', function (e) {
	            var input = $(this),
	                wrapper = input.closest('[data-tyrefinder]'),
                    allInputs = wrapper.find('.tyrefinder-vehicle-input');
	            if (event.shiftKey && e.which === 9) {
	                return; // Shift tab, don't do anything.
	            } else if (e.which === 9 || e.which === 13) {
	                wrapper.removeAttr('data-keyboard-in-use');
	                if(!allInputs.last().is(input)) {
	                    input.change();
	                }
	            } else {
	                wrapper.attr('data-keyboard-in-use', '');
	            }
	        }).on('change', '.tyrefinder-vehicle-input', function (e) {
		        var input = $(this),
		            wrapper = input.closest('[data-tyrefinder]'),
                    allInputs = wrapper.find('.tyrefinder-vehicle-input');

		        $('[data-tyrefinder-active]').removeAttr('data-tyrefinder-active');
		        wrapper.attr('data-tyrefinder-active', allInputs.index(input));
		    });
	    },
	    SetFocus: function() {
	        var wrapper = $('[data-tyrefinder-active]').first();                
	        if (!wrapper.length) return;

	        var allInputs = wrapper.find('.tyrefinder-vehicle-input'),
                lastEnteredItemIndex = wrapper.attr('data-tyrefinder-active');

	        if (isNaN(parseInt(lastEnteredItemIndex))) return;

	        var inputToFocus = allInputs.eq(parseInt(lastEnteredItemIndex) + 1);
	        if (!inputToFocus.length) return;

	        inputToFocus.focus();
	    },
		InitPostcode: function () {
		    this.PostcodeFinder();
		},

		Tabs: function() {
			var options = $('[data-tyrefinder-option]'),
				tabs = $('[data-tyrefinder-tab]');

			if(!options.length || !tabs.length) return;

			options.off('change').on('change', function(){
				var radio = $(this);
				if(!radio.is(':checked')) return;

				tabs.hide();

				var tabToShow = $('[data-tyrefinder-tab="'+radio.data('tyrefinder-option')+'"]').first();
				if(!tabToShow.length) return;

				tabToShow.show();
			});
		},

	    ByVehicle: function() {
	        if ($('.tyrefinder-vehicle-wrapper').length == 0) {
	            return;
	        }

	        if ($("#hidden-quote-vehicle").length != 0 && $('#vehicle-selector').length != 0) {
	            quoteControl();
	        }

	        $('.tyrefinder-vehicle-search-type').val('');

	        $('.tyrefinder-vehicle-input').off('change').on('change', function (e) {
	            var input = $(this),
                    wrapper = input.closest('[data-tyrefinder]');

	            if (wrapper.is('[data-keyboard-in-use]')) {
	                return;
	            }

	            var form = $(this).parents('form:first');
	            form.submit();
	        });

	        $('.tyrefinder-vehicle-submit').off('click').on('click', function () {
	            var form = $(this).parents('form:first');
	            form.find('.tyrefinder-vehicle-search-type').val('FindVehicle');
	        });

	        $('.tyrefinder-vehicle-reset').off('click').on('click', function () {
	            var form = $(this).parents('form:first');
	            $('.tyrefinder-vehicle-input').val('');
	            form.submit();
	        });

	        function quoteControl() {
	            var quoteSearch = $("#hidden-quote-vehicle").find('.tyrefinder-vehicle-wrapper');

	            var vehicleManufacturerddl = quoteSearch.find('.tyrefinder-vehicle-manufacturer');
	            var quoteManufacturerddl = $('#ddlManufacturer');
	            quoteManufacturerddl.html(vehicleManufacturerddl.html());

	            quoteManufacturerddl.off('change').on('change', function () {
	                vehicleManufacturerddl.val($(this).val());
	                vehicleManufacturerddl.trigger('change');
	            });

	            var vehicleYearddl = quoteSearch.find('.tyrefinder-vehicle-year');
	            var quoteYearddl = $('#ddlYear');
	            quoteYearddl.html(vehicleYearddl.html());

	            quoteYearddl.off('change').on('change', function () {
	                vehicleYearddl.val($(this).val());
	                vehicleYearddl.trigger('change');
	            });

	            var vehicleModelddl = quoteSearch.find('.tyrefinder-vehicle-model');
	            var quoteModelddl = $('#ddlModel');
	            quoteModelddl.html(vehicleModelddl.html());

	            if (vehicleModelddl.is(':disabled')) {
	                quoteModelddl.prop('disabled', true);
	            } else {
	                quoteModelddl.prop('disabled', false);
	            }

	            quoteModelddl.off('change').on('change', function () {
	                vehicleModelddl.val($(this).val());
	                vehicleModelddl.trigger('change');
	            });

	            var vehicleSeriesddl = quoteSearch.find('.tyrefinder-vehicle-series');
	            var quoteSeriesddl = $('#ddlSeries');
	            quoteSeriesddl.html(vehicleSeriesddl.html());

	            if (vehicleSeriesddl.is(':disabled')) {
	                quoteSeriesddl.prop('disabled', true);
	            } else {
	                quoteSeriesddl.prop('disabled', false);
	            }

	            quoteSeriesddl.off('change').on('change', function () {
	                vehicleSeriesddl.val($(this).val());
	                vehicleSeriesddl.trigger('change');
	            });
	        }
	    },
	    BySize: function () {
	        if ($('.tyrefinder-size-wrapper').length == 0) {
	            return;
	        }

	        $('.tyrefinder-size-reset').off('change').on('click', function () {
	            $('.tyrefinder-size-input').val('');
	        });
	    },
	    TyreComparison: function () {
	        if ($('[data-product-compare-button]').length == 0 || $('[data-product-compare-checkbox]').length == 0) {
	            return;
	        }

	        setupComparisonUrl();

	        $('[data-product-compare-checkbox]').off('change').on('click', function (e) {
	            if ($('[data-product-compare-checkbox]:checked').length > 3) {
	                e.preventDefault();
	                return;
	            }
	            setupComparisonUrl();
	        });

	        $('.reset-comparison-options').off('click').on('click', function (e) {
	            e.preventDefault();
	            $('[data-product-compare-checkbox]').each(function () {
	                if ($(this).is(':checked')) {
	                    $(this).trigger('click');
	                }
	            });
	        });

	        function setupComparisonUrl () {
                var comparisonUrl = $('[data-product-compare-url]').val() + "/";
	            var maxCompareAmount = 3;
	            var currentCount = 0;
	            $('[data-product-compare-checkbox]').each(function () {
	                if (currentCount >= maxCompareAmount) {
	                    return;
	                }
	                var compareCheckbox = $(this);
	                if (compareCheckbox.is(':checked')) {
	                    comparisonUrl += compareCheckbox.val() + "/";
	                    currentCount++;
	                }
	            });
	            $("[data-product-compare-button]").attr("href", comparisonUrl);
	        }
	    },
	    RequestQuote: function() {
			$('#show-all-tyres').off('click').on('click', function (e) {
				e.preventDefault();

				// Toggle link styles
				$('.s-size-chart__display__link').removeClass('is-active');
				$(this).addClass('is-active');

				$('.tyre-found').hide();
				$('.tyres-all-found').show();
				Collapsibles.Bindings(false, false);
			});

			$('#show-found-tyres').off('click').on('click', function (e) {
				e.preventDefault();

				$('.s-size-chart__display__link').removeClass('is-active');
				$(this).addClass('is-active');


				$('.tyres-all-found').hide();
				$('.tyre-found').show();
				Collapsibles.Bindings(false, false);
			});

	        if ($('.tyres-all-found').length == 0 || $('.tyre-found').length == 0) {
	            return;
	        }
	    },
        PostcodeFinder: function() {
            var suburbSelectorField = $('.autocomplete-text-selector-wrapper input');
            if (suburbSelectorField.length) {
                var suburbData = new Bloodhound({
                    initialize: false,
                    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
                    queryTokenizer: Bloodhound.tokenizers.obj.whitespace,
                    identify: function (obj) { return obj.ID; },
                    remote: {
                        cache: false,
                        url: '/api/GetSuburbs',
                        prepare: function (query, settings) {
                            var queryString = query;
                            settings.type = "POST";
                            settings.beforeSend = function (jqXhr, settings) {
                                settings.data = JSON.stringify({ startsWith: queryString });
                            };
                            settings.contentType = "application/json; charset=utf-8";
                            return settings;
                        },
                        transform: function (response) {
                            return response.Data.Suburbs;
                        }
                    }
                });

                suburbSelectorField.typeahead({
                    minLength: 2
                },
                {
                    name: 'suburb-data',
                    source: suburbData
                });

                var suburbs = suburbData.initialize();

                suburbs
                    .done(function () {

                        var hiddenSuburbSelectorField = $('.autocomplete-text-selector-wrapper input')[0]; // gets tt-hint (duplicate input)
                        if ((typeof hiddenSuburbSelectorField !== "undefined")) {
                            hiddenSuburbSelectorField.removeAttribute("data-val")
                        }
                    })
                    .fail(function () {
                        if (console && console.log) {
                            console.log('err, something went wrong :(');
                        }
                    });
            }
        }
	}
})();
;
$(function(){
	TyreComparison.Init();
});

var TyreComparison = (function(){
	return {
		Init: function() {
		    // When a tyre is selected to compare, toggle the visibility of the 'comparison' bar at the bottom of the browser
		    var comparisonBarElement = $("[data-product-compare-bar]");
		    var comparisonCheckboxes = $("[data-product-compare-checkbox]");
		    var comparisonButton = $("[data-product-compare-button]");
		    var comparisonInstruction = $(".s-product-compare-bar__instruction");
		    var comparisonResetButton = $(".s-product-compare-bar__reset");

		    checkboxesTicked();

		    comparisonCheckboxes.on("change", function() {
		    	checkboxesTicked();
		    });

		    // Check the button class on click before allowing the link to function
		    comparisonButton.on("click", function(e) {
		    	if ($(this).hasClass("btn--disabled"))
		    		e.preventDefault();
		    });

		    comparisonResetButton.on("click", function(e) {
		    	e.preventDefault();
		    	comparisonCheckboxes.prop("checked", false);
		    });

		    function checkboxesTicked() {
		    	// check how many of the checkboxes are ticked
		    	var comparisonCheckboxesChecked = comparisonCheckboxes.filter(":checked").length;
		    	if (comparisonCheckboxesChecked > 0) {
		    		comparisonBarElement.addClass("s-product-compare-bar--visible");
                    comparisonBarElement.removeClass("s-product-compare-bar--hidden");
                    
                    if (comparisonCheckboxesChecked > 1) {
                    	comparisonButton.removeClass("btn--disabled");
                    	// Hide the message from view
                    	comparisonInstruction.css("opacity", 0);
                    }
                    else {
                    	comparisonButton.addClass("btn--disabled");
                    	comparisonInstruction.css("opacity", 1);
                    }
		    	}
		    	else {
                    comparisonBarElement.removeClass("s-product-compare-bar--visible");
		    		setTimeout(function () {
	                    comparisonBarElement.addClass("s-product-compare-bar--hidden");
	                }, 300);
		    	}
		    }
		}

	}
})();;
$(function () {
	GTM.Init();
});

// Anonymous Function 
GTM = (function () {

	StepNo = 0 // Defined in checkout views
	StepName = '' // Defined in checkout views
	chekoutOptionBtn = $('#chekoutOptionBtn');

	return {
		Init: function () {
		    //--
		   if (chekoutOptionBtn.length) {
               
		       chekoutOptionBtn.on('click', function (event, StepNo, StepName) {
		           GTM.FireCheckoutOption(StepNo, StepName);
		        });
		    }
		},
		ProductClick: function (name, id, brand, category) {
			
            /*
            * Measure a view of product details. sent via click event
            */
			window.dataLayer = window.dataLayer || [];
            dataLayer.push({
                'event': 'productClick',
                'ecommerce': {
                    'click': {
                        'actionField': { 'list': 'Our Range' },
                        'products': [{
                            'name': name,                      
                            'id': id,
                            'price': '0.00',
                            'brand': brand,
                            'category': category
                        }]
                    }
                }
            });
		},
		ProductDetails: function (name, id, brand, category) {
			
			/* 
             * Measure a view of product details. This example assumes the detail view occurs on pageload,
			 *  and also tracks a standard pageview of the details page.
			 */
			window.dataLayer = window.dataLayer || [];
			dataLayer.push({
				'ecommerce': {
					'detail': {
						'actionField': {'list': 'Our Range'},    
						'products': [{
							'name': name,
							'id': id,
							'price': '0.00',
							'brand': brand,
							'category': category
						}]
					}
				}
			});
		},
		FireCheckoutOption: function (StepNo, StepName) {
		   
		    /*
             * Meause Checkout options
             */
		    window.dataLayer = window.dataLayer || [];
		    //dataLayer.push({
		    //	'event': 'checkoutOption',
		    //	'ecommerce': {
		    //		'checkout_option': {
		    //		    'actionField': { 'step': StepNo, 'option': StepName }
		    //		}
		    //	}
		    //});
		    // implemented as per below instead of what Google Doc explains (above)
            // the above call does not end up in the checkout behaviour in GA
		    dataLayer.push({
		        'event': 'checkout',
		        'ecommerce': {
		            'checkout': {
		                'actionField': { 'step': StepNo }
		            }
		        }
		    });
		},
		CheckOutStep: function (StepNo, StepName) {
            
		if (StepNo != 0) {
				
		    if (chekoutOptionBtn.length) {
		        chekoutOptionBtn.trigger('click', [StepNo, StepName]);
		    }
		}
		},
		Purchase: function (orderId, taxAmount, totalAmount, name, id, brand, category, qty) {
			
			/* 
             * Measure purchase - Enhanced
             */
			window.dataLayer = window.dataLayer || [];
			dataLayer.push({
			    'event': 'transaction',
				'ecommerce': {
					'purchase': {
						'actionField': {
							'id': orderId,                         
							'affiliation': 'Online Purchase',
							'revenue': totalAmount,                     // Total transaction value (incl. tax and shipping)
							'tax': taxAmount,
							'shipping': '0.00'
						},
						'products': [{
						    'id': id,
						    'name': name,
							'price': (totalAmount / qty),
							'brand': brand,
							'category': brand,
							'quantity': qty
						}]
					}
				}
		    });
        }
	};
})();;
/**
 * Allows states to be auto selected based on postcode entry
 * 
 * @return {object}
 */
var PostcodeStatePrefill = (function () {

    var selectors = {
        postCodeEntry: '[data-js-state-prefill-postcode]',
        postCodeErrorMessage: '[data-js-state-prefill-postcode-error-message]',
        postCodeError: '[data-js-state-prefill-postcode-error]'
    };
    var dataAttr = {
        postCodeKey: "data-js-state-prefill-postcode",
        stateKey: "data-js-state-prefill",
        suburbKey: "data-js-suburb-prefill",
    };

	/**
	 * @description Sets up the events when a postcode value is entered
	 * @returns void
	 */
    function BindChangeEvents() {
        var postCodeFields = $(selectors.postCodeEntry);
        postCodeFields.off("keyup.postcodeStatePrefill").on("keyup.postcodeStatePrefill", function (e) {
            var postCodeField = $(this);
            var postcode = postCodeField.val();

            // If the postcode is not a valid australian postcode then don't do the lookup
            if (postcode.length < 4 || postcode.length > 4)
                return;

            // Get the state & suburb based on the matching key for the postcode field
            var fieldKey = postCodeField.attr(dataAttr.postCodeKey);
            var stateField = $("[" + dataAttr.stateKey + "='" + fieldKey + "']");
            var suburbField = $("[" + dataAttr.suburbKey + "='" + fieldKey + "']");

            $(selectors.postCodeError).hide();

            // Get the state based on postcode
            $.getJSON('/umbraco/surface/requestquote/getstate',
                { postcode: postcode },
                function(response) {
                    if (response && response.State) {
                        stateField.val(response.State);
                    } else {
                        if (postcode.length === 4)
                        {
                            $(selectors.postCodeErrorMessage).text("Must be a valid postcode");
                            $(selectors.postCodeError).show();
                        }
                }
                });

            // Get the suburbs based on postcode
            $.getJSON('/umbraco/surface/requestquote/getsuburbs',
                { postcode: postcode },
                function (response) {
                    if (response && response.Suburbs) {
                        suburbField.empty();
                        $.each(response.Suburbs, function (index, value) {
                            suburbField.append("<option value=\"" + value + "\">" + value + "</option>");
                        });
                        
                        
                    } else {
                        if (postcode.length === 4) {
                            $(selectors.postCodeErrorMessage).text("Must be a valid postcode");
                            $(selectors.postCodeError).show();
                        }
                    }
                });
        });
    }

    return {
		/**
		 * @description Initialises the JS functionality on the page
		 * @returns void
		 */
        Init: function () {
            if ($(selectors.postCodeEntry).length > 0) {
                BindChangeEvents();
            }

            $(selectors.postCodeEntry).focus(function () {
                $(selectors.postCodeEntry).removeAttr("readonly");
            });

            $(selectors.postCodeEntry).on("touchend", function () {
                $(selectors.postCodeEntry).removeAttr("readonly");
                $(selectors.postCodeEntry).focus();
            });
        }
    }
})();

$(function () {
    PostcodeStatePrefill.Init();
});;
$(function () {
    Warranty.Init();
});

var Warranty = (function () {
  
    return {
        Init: function () {
            this.SetupModelPatternOptions();
            this.LoadVehicleModelsAndYears();
        },
        
        SetupModelPatternOptions : function () {

            var aTyreSizes = [];
            var tyreModelPatternWrapper = $("[data-tyre-model-pattern]").first();
            var tyreSizeWrapper = $("[data-tyre-size]").first();

            if (tyreModelPatternWrapper.length === 0 && tyreSizeWrapper.length === 0) return;

            var ddltyreModelPattern = tyreModelPatternWrapper.find("select");
            var ddlTyreSize = tyreSizeWrapper.find("select");

            ddlTyreSize.find("option").each(function () {
                if (this.value !== "") {
                    // store all values
                    aTyreSizes.push(
                        {
                            'modelId': this.value.split("|")[0]
                            , 'sku': this.value.split("|")[1]
                            , 'name': this.text
                        });

                    if (ddltyreModelPattern.val() === "") {
                        //remove item
                        this.remove();
                        ddlTyreSize.prop("disabled", true);
                    } else {
                        var modelPatternId = ddltyreModelPattern.val();
                        if (aTyreSizes.length > 0 && aTyreSizes[aTyreSizes.length - 1].modelId !==  modelPatternId) {
                            //remove item except selected model pattern ones
                            this.remove();
                        }
                    }
                }
            });
          
            ddltyreModelPattern.on("change", function () {
                var $input = $(this)
                var selectedModel = $input.val();

                var filteredTyreSizes = aTyreSizes.filter(x => x.modelId === selectedModel);
                ddlTyreSize.empty();
                ddlTyreSize.prop("disabled", false);

                ddlTyreSize.append(
                    $("<option></option>").html("Select tyre model/pattern")
                );
                if (selectedModel.length === 0) {
                    ddlTyreSize.prop("disabled", true);
                }

                $.each(filteredTyreSizes, function (i, item) {
                    // populate Size dropdown
                    ddlTyreSize.append(
                        $("<option></option>").val(item.modelId+"|"+item.sku).html(item.name)
                    );
                });
            });
        },

        LoadVehicleModelsAndYears: function () {

            var manufacturerWrapper = $("[data-vehicle-manufacturer]").first();
            var yearWrapper = $("[data-vehicle-year]").first();
            
            if (manufacturerWrapper.length === 0 && yearWrapper.length === 0) return;

            var ddlManufacturer = manufacturerWrapper.find("select");
            var ddlYear = yearWrapper.find("select");

            ddlManufacturer.on("change", function () {
                var $input = $(this);
                var selectedMake = $input.val();

                Warranty.GetManufacturerYears(selectedMake);
            });

            ddlYear.on("change", function () {
                var $input = $(this);
                var selectedYear = $input.val();
                var selectedMake = ddlManufacturer.val();
                
                Warranty.GetVehicleModels(selectedMake, selectedYear);
            });
        },

        GetManufacturerYears: function (selectedMake) {

            var yearWrapper = $("[data-vehicle-year]").first();
            if (yearWrapper.length === 0 && selectedMake.length === 0) return;

            var ddlYear = yearWrapper.find("select");

            $.ajax({
                type: "POST",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                traditional: true,
                url: "/api/GetVehicleManufacturerYears",
                data: JSON.stringify({ makeId: selectedMake }),
                success: function (data) {
                    ddlYear.empty();
                    ddlYear.append(
                        $("<option></option>").val("").html("Year")
                    );
                    if (data.Data.Years.length > 0) {
                        $.each(data.Data.Years, function (i, item) {
                            // populate years dropdown
                            ddlYear.append(
                                $("<option></option>").val(item.Value).html(item.Text)
                            );
                        });

                        Warranty.GetVehicleModels(selectedMake, data.Data.Years[0].Value);
                    }
                },
                error: function (data, textStatus, jqXHR) {
                    alert("Error communicating with server");
                }
            });

        },

        GetVehicleModels: function (selectedMake, selectedYear) {

            var modelWrapper = $("[data-vehicle-model]").first();
            if (modelWrapper.length === 0) return;
            if (selectedMake.length === 0 || selectedYear.length === 0) return;
            
            var ddlModel = modelWrapper.find("select");

            $.ajax({
                type: "POST",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                traditional: true,
                url: "/api/GetVehicleModels",
                data: JSON.stringify({ make: selectedMake, year: selectedYear }),
                success: function (data) {
                    ddlModel.empty();
                    ddlModel.append(
                        $("<option></option>").val("").html("Model")
                    );
                    if (data.Data.Models.length > 0) {
                        $.each(data.Data.Models, function (i, item) {
                            // populate models dropdown
                            ddlModel.append(
                                $("<option></option>").val(item.Value).html(item.Text)
                            );
                        });
                    }
                },
                error: function (data, textStatus, jqXHR) {
                    alert("Error communicating with server");
                }
            });
        }
    }
}) ();;

Components.FileUpload = (function() {
	var selectors = {
        fileInput: 'input[type=file]',
        fileUploadLabel: '[data-js-fileupload-label]'
    };
    var attributes = {
        fileUploadLabel: 'data-js-fileupload-label'
    };
	
	// Public methods
	return {
        Init: function () {
			this.Bindings();
		},
        Bindings: function () {
            $(document).on("change", selectors.fileInput, function () {
                var $this = $(this);
                if (!$this.attr("id")) {
                    return;
                }

                // Update label to include file name
                var filePath = $this.val();
                var fileName = filePath ? filePath.substring(filePath.lastIndexOf("\\") + 1) : "";

                var fieldLabel = $("label[for='" + $this.attr("id") + "']");
                
                if (!fieldLabel.attr(attributes.fileUploadLabel)) {
                    fieldLabel.attr(attributes.fileUploadLabel, fieldLabel.text());
                }

                fieldLabel.text(fileName.length > 18 ? fileName.substring(0 , 15) + "..." : fileName || fieldLabel.attr(attributes.fileUploadLabel));

                if (filePath) {
                    var requiredWrapper = $this.closest('.e-field__wrapper--required');

                    if (requiredWrapper.length) {
                        requiredWrapper.removeClass('e-field__wrapper--error');
                        requiredWrapper.next('.field-validation-error').hide();
                    }
                }
            });
        } 
	}
})();

$(function() {
    Components.FileUpload.Init();
});
;
/**
 * @param {function} $
 * @return {object}
 */

var FormModule = (function($) {
	

	// Public methods
	return {
		/**
		 * Initial setup for Forms
		 * 
		 */
		Init: function() {
		
            this.Datepickers.Init();
            this.DateValidationFormat();

            $('.search-dropdown').each(function(_, dropdown) {
				var $dropdown = $(dropdown);
				var $firstOption = $dropdown.find('option').first();

				// Ensure placeholder first options do not contain text
				if ($firstOption.val() === '') {
					$firstOption.text('');
				}

				// Initialise chosen
                $dropdown.chosen({
                    no_results_text: "Retailer not found! <button type=\"button\" class=\"no-retailer-btn\">Can't find my retailer</button>"
                });

                $('.search-dropdown').on('chosen:no_results', function (evt, params) {
                    if (typeof (params.chosen.options["no_results_text"]) !== 'undefined') {
                        $('.search-dropdown').val(99999);
                    }

                    $('.no-retailer-btn').on('click', function () {
                        $('.search-dropdown').trigger('chosen:updated');
                    });
                });                
            });
        },

        DateValidationFormat: function () {
            // Update jquery date validation to validate australian date format
            $.validator.methods.date = function (value, element) {
                var replacedValue = value.replace(/-/g, '/');
                var parts = replacedValue.split("/");
                if (parts.length === 3) {
                    if (element.type === "date") {
                        replacedValue = (parts[2].length < 2 ? "0" : "") + parts[2] + "/" +
                            (parts[1].length < 2 ? "0" : "") + parts[1] + "/" +
                            (parts[0].length === 2 ? "20" : "") + parts[0];
                    } else {
                        replacedValue = (parts[0].length < 2 ? "0" : "") + parts[0] + "/" +
                            (parts[1].length < 2 ? "0" : "") + parts[1] + "/" +
                            (parts[2].length === 2 ? "20" : "") + parts[2];
                    }
                }
                parts = replacedValue.split("/");

                var date = new Date(parts[2], parts[1] - 1, parts[0]);
                return this.optional(element) || (!isNaN(date.getTime()) && date.getFullYear() == parts[2] && date.getMonth() == parts[1] - 1 && date.getDate() == parts[0]);
            }
        },
	
		Datepickers: (function() {
			var selectors = {
				datepicker: '[data-js-datepicker]',
				dobPicker: '.e-field--dob',
				futurePicker: '[data-js-datepicker-future]'
			};

			return {
				Init: function() {
                    var _this = this;
                    _this.Datepickers = _this.Datepickers || [];

					$(selectors.datepicker).each(function(_, el) {
                        var picker = $(el);

                        for (var i = 0; i < _this.Datepickers.length; i++) {
                            if (_this.Datepickers[i]._o.field === el) {
                                return;
                            }
                        }

                        var ausDateFormat = /^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{2,4})$/;
                        if (ausDateFormat.test(el.value)) {
                            var match = ausDateFormat.exec(el.value);
                            el.value = match[3] + '-' + match[2] + '-' + match[1];
                        }

						// Base options
						var pickerOptions = {
							field: el,
							showDaysInNextAndPreviousMonths: true,
							enableSelectionDaysInNextAndPreviousMonths: true,
							format: "DD/MM/YYYY",
							toString: function(date, format) {
								// you should do formatting based on the passed format,
								// but we will just return 'D/M/YYYY' for simplicity
								var day = date.getDate();
								var dayString = (day < 10 ? "0" : "") + day.toString();
								var month = date.getMonth() + 1;
								var monthString = (month < 10 ? "0" : "") + month.toString();
								var year = date.getFullYear();
								return dayString + '/' + monthString + '/' + year;
							},
							parse: function(dateString, format) {
								// dateString is the result of `toString` method
								var parts = dateString.split('/');
								var day = parseInt(parts[0], 10);
								var month = parseInt(parts[1] - 1, 10);
								var year = parseInt(parts[2], 10);
								return new Date(year, month, day);
							}
						};

						// Date of birth options
						if (picker.is(selectors.dobPicker)) {
							pickerOptions.yearRange = [1900, new Date().getFullYear()];
							pickerOptions.maxDate = new Date();
						}

						// Future options
						if (picker.is(selectors.futurePicker)) {
							pickerOptions.yearRange = 10;
							pickerOptions.minDate = new Date();
						}

						_this.Datepickers.push(new Pikaday(pickerOptions));
					});
				},
				Datepickers: []
			}
        })(),
	}
})(jQuery);

$(function() {
    FormModule.Init();
});;
