/*
* MePlusYou Plugin to control CarouFredSel Plugin
*/

(function ($) {
	if (!$.mpySlider) {
		$.mpySlider = new Object();
	};

	$.mpySlider = function (el, customOptions) {
		// To avoid scope issues, use 'base' instead of 'this'
		// to reference this class from internal events and functions.
		var base = this;

		// Access to jQuery and DOM versions of element
		base.$container = $(el);
		base.container = el;

		// Add a reverse reference to the DOM object
		base.$container.data("mpySlider", base);

		// Overwrites defaultsOptions with customOptions
		base.options = $.extend({}, $.mpySlider.defaultOptions, customOptions);

		if (base.$container.attr("id")) {
			base.containerSelector = "#" + base.$container.attr("id");
		} else {
			base.containerSelector = "." + $.trim(base.$container.attr("class")).replace(/\s/gi, ".");
		}

		if (base.$container.parent().attr("id") == "modalContainer") {
			base.inModal = true;
			alert(base.inModal);
		} else { base.inModal = false }

		// PLUGIN VARIABLES
		base.jsonData = base.options.jsonData || null;

		// Carousel Settings
		base.carousel = (base.options.carouselSelector) ? base.$container.find(base.options.carouselSelector) : null;
		base.carouselAnimationStyle = base.options.carouselAnimationStyle;
		base.carouselAnimationSpeed = base.options.carouselAnimationSpeed;
		base.carouselSlideDuration = base.options.carouselSlideDuration;
		base.carouselSlidesVisible_LG = base.options.carouselSlidesVisible_LG || null;
		base.carouselSlidesVisible_MD = base.options.carouselSlidesVisible_MD || null;
		base.carouselSlidesVisible_SM = base.options.carouselSlidesVisible_SM || null;
		base.carouselSlidesVisible_XS = base.options.carouselSlidesVisible_XS || null;
		base.carouselSlidesVisible = base.options.carouselSlidesVisible;
		base.carouselSlidingOffset_LG = base.options.carouselSlidingOffset_LG || null;
		base.carouselSlidingOffset_MD = base.options.carouselSlidingOffset_MD || null;
		base.carouselSlidingOffset_SM = base.options.carouselSlidingOffset_SM || null;
		base.carouselSlidingOffset_XS = base.options.carouselSlidingOffset_XS || null;
		base.carouselSlidingOffset = base.options.carouselSlidingOffset;
		base.gallery = base.options.gallery;
		base.carouselIsGallery = base.options.carouselIsGallery;
		base.carouselGalleryRowColumn = base.options.carouselGalleryRowColumn;
		base.carouselGalleryRowColumn_XS = base.options.carouselGalleryRowColumn_XS || null;
		base.carouselGalleryRowColumn_SM = base.options.carouselGalleryRowColumn_SM || null;
		base.carouselGalleryRowColumn_MD = base.options.carouselGalleryRowColumn_MD || null;
		base.carouselGalleryRowColumn_LG = base.options.carouselGalleryRowColumn_LG || null;
		base.carouselIsInfinite = base.options.carouselIsInfinite;
		base.carouselDebug = base.options.carouselDebug;
		base.pauseOnHover = base.options.pauseOnHover;
		base.cssAnimations = ($("body").hasClass("Explorer8") || $("body").hasClass("Explorer9")) ? false : true;

		// Navigation Settings
		base.hasNavigation = base.options.hasNavigation;
		base.navigation = (base.options.navigationSelector) ? base.$container.find(base.options.navigationSelector) : null;

		// Pagination Settings
		base.hasPagination = base.options.hasPagination;
		base.paginationStyle = base.options.paginationStyle;
		base.paginationSelector = base.options.paginationSelector;
		base.paginationIcon = base.options.paginationIcon;
		base.paginationCounterDivider = base.options.paginationCounterDivider;
		base.pagination = (base.options.paginationSelector) ? base.$container.find(base.options.paginationSelector) : base.$container.find(".sliderPagination");

		// Thumbnail Settings
		base.thumbnails = (base.options.thumbnailSelector) ? base.$container.find(base.options.thumbnailSelector) : null;
		base.thumbnailAnimationStyle = base.options.thumbnailAnimationStyle;
		base.thumbnailAnimationSpeed = base.options.thumbnailAnimationSpeed;
		base.thumbnailImagesVisible = base.options.thumbnailImagesVisible;
		base.thumbnailSlidingOffset = base.options.thumbnailSlidingOffset;
		base.thumbnailClickEvent = base.options.thumbnailClickEvent;

		// Content Settings
		base.headline = base.$container.find(base.options.headlineContainer);
		base.headlineTag = base.options.headlineTag || "";
		base.subHeadline = base.$container.find(base.options.subHeadlineContainer);
		base.subHeadlineTag = base.options.subHeadlineTag || "";
		base.content = base.$container.find(base.options.contentSelector);
		base.fadeSpeed = base.options.contentFadeSpeed || 300;

		base.nav = true;
		base.cont = true;
		base.thumb = true;
		base.firstTime = true;

		// External Functions
		base.arrivingLeavingFunction = base.options.arrivingLeavingFunction;
		base.arrivingFunction = base.options.arrivingFunction;
		base.leavingFunction = base.options.leavingFunction;
		base.activeFunction = base.options.activeFunction;

		// INITIATION: Constructor Method
		base.init = function () {
			base.setupBootstrapSizes();
			base.checkForElements();
			if (base.jsonData) { // Check if using JSON
				if (typeof base.jsonData == 'string') { // Check if ajax is needed
					base.getJSON();
				} else { // json is a variable on the page
					if (base.thumb) { base.initiateThumbnails(); }
					if (base.gallery) {
						base.loadImages(0);
					} else {
						base.lazyLoadImages(0);
					}
				}
			} else { // Images are already on the page
				if (base.carouselIsGallery) {
				    base.addImagesToGallery();
				} else {
					base.carouselSlides = base.carousel.children().css({
						"float": "left",
						"display": "block"
					});
					base.initiateCarousel();
					if (base.cont) { base.setupHeadingsAndContent(base.carouselSlides.first()); }
					if (base.thumb && base.thumbnails) { base.initiateThumbnails(); }
					base.updateCarouselHeight(base.carouselSlides.first().find("img"));
					$(window).load(function () {
						base.updateCarouselHeight();
					});
                    //Adding an H2 tag for ADA - to explain functionality to screen readers
				    base.$container.find(".caroufredsel_wrapper").prepend('<h2 class="sr-only"> Carousel </h2>');
				}
			}
			base.setupBootstrapSizes();
		};

		base.setupBootstrapSizes = function () {
			if (bootstrapSize) {
				base.bootstrapSize = bootstrapSize;
			} else {
				base.bootstrapSize = "LG";
				//console.log("bootstrapSize is undefined");
			};
			$('input[name="bootstrapSize"]').change(function () {
				base.bootstrapSize = bootstrapSize;
				base.reInitialize();
			});
			$(window).on("orientationchange", function () {
				base.bootstrapSize = bootstrapSize;
				base.reInitialize();
			});
		};

		// HTML ELEMENTS: Checks HTML for needed elements
		base.checkForElements = function () {
			if (!base.carousel.length) {
				//alert('Carousel plugin cannot find "' + base.options.carouselSelector + '" selector. Please add this selector or define your own using the variable "carouselSelector".');
			}
			//if (base.options.hasNavigation) {
			//	if (!base.navigation.length) {
			//		alert('Carousel pluging cannot find "' + base.options.navigationSelector + '" selector.  Please add this selector or define your own using the variable "navigationSelector".');
			//		base.nav = false;
			//	}
			//} else { base.nav = false; }
			//console.log("thumbnailSelector" + base.options.thumbnailSelector);
			if (base.options.thumbnailSelector) {
				if (!base.thumbnails) {
					//alert('carousel pluging cannot find "' + base.options.thumbnailSelector + '" selector.  please add this selector or define your own using the variable "thumbnailSelector".');
					base.thumb = false;
				}
			} else { base.thumb = false; }
			if (base.jsonData) {
				base.json = true;
				if (base.jsonData.length == 1) { base.thumb = false; }
			}
		};

		// JSON: Gets JSON string
		base.getJSON = function () {
			$.getJSON(base.jsonData).done(function (jsonData) {
				base.jsonData = jsonData;
				base.initiateCarousel();
				if (base.thumb) { base.initiateThumbnails(); }
				base.addImagesToCarousel(0);
			});
		};

		// NAVIGATION: Sets up the Navigation if there is one
		base.setupPagination = function (passedSlideNumber) {
			var pagSelector = base.containerSelector + " " + base.pagination.selector;
			var slideNumber = (typeof passedSlideNumber == "undefined") ? 1 : passedSlideNumber;
			if (base.paginationStyle == "counter") {
				if (base.jsonData) {
					if (base.jsonData.length == 1) {
						base.pagination.hide();
						if(base.thumb) $(base.options.thumbnailSelector).hide();
					} else {
						base.pagination.text(slideNumber + "/" + base.jsonData.length);
					}
				} else {
					base.pagination.text(slideNumber + "/" + base.carouselSlides.length);
				}
			} else if (base.paginationStyle == "icon") {
				//if (base.paginationIcon) {
				//	var slides = (base.jsonData) ? base.jsonData.length : base.carouselSlides.length;
				//	for (var i = 0; i < base.jsonData.length; i++) {
				//		base.pagination.append('<a href="#" class="pagIcon"><img src="' + base.paginationIcon + '" /></a>');
				//	}
				//	base.paginationIcons = base.pagination.find(".pagIcon");
				//	base.paginationIcons.first().addClass("active");
				//} else {
				//	alert("Pagination Icon Image not specified. Please do so using the paginationIcon setting.");
				//}
				base.carousel.trigger("configuration", {
					pagination: {
						container: pagSelector,
						anchorBuilder: function(nr, item) {
							return '<a class="paginationIcon" href="#' + nr + '"><span>' + nr + '</span></a>';
						}
					}
				});
			} else if (base.paginationStyle == "number") {
				base.carousel.trigger("configuration", {
					pagination: {
						container: pagSelector
					}
				});
			}
			(base.carouselSlides.length <= base.determineCarouselSlidesVisible) ? base.navigation.hide() : base.navigation.show();
		};

		// SLIDES VISIBLE
		base.determineCarouselSlidesVisible = function () {
			if (base.bootstrapSize == "XS" && base.carouselSlidesVisible_XS) {
				return base.carouselSlidesVisible_XS
			} else if (base.bootstrapSize == "SM" && base.carouselSlidesVisible_SM) {
				return base.carouselSlidesVisible_SM
			} else if (base.bootstrapSize == "MD" && base.carouselSlidesVisible_MD) {
				return base.carouselSlidesVisible_MD
			} else if (base.bootstrapSize == "LG" && base.carouselSlidesVisible_LG) {
				return base.carouselSlidesVisible_LG
			} else {
				return base.carouselSlidesVisible;
			}
		};

		// GALLERY ROW COLUM
		base.determineGalleryRowColumn = function () {
			if (base.bootstrapSize == "XS" && base.carouselGalleryRowColumn_XS) {
				return base.carouselGalleryRowColumn_XS
			} else if (base.bootstrapSize == "SM" && base.carouselGalleryRowColumn_SM) {
				return base.carouselGalleryRowColumn_SM
			} else if (base.bootstrapSize == "MD" && base.carouselGalleryRowColumn_MD) {
				return base.carouselGalleryRowColumn_MD
			} else if (base.bootstrapSize == "LG" && base.carouselGalleryRowColumn_LG) {
				return base.carouselGalleryRowColumn_LG
			} else {
				return base.carouselGalleryRowColumn;
			}
		};

		// SLIDES TO SCROLL
		base.determineCarouselSlidingOffset = function () {
			if (base.bootstrapSize == "XS" && base.carouselSlidingOffset_XS) {
				return base.carouselSlidingOffset_XS
			} else if (base.bootstrapSize == "SM" && base.carouselSlidingOffset_SM) {
				return base.carouselSlidingOffset_SM
			} else if (base.bootstrapSize == "MD" && base.carouselSlidingOffset_MD) {
				return base.carouselSlidingOffset_MD
			} else if (base.bootstrapSize == "LG" && base.carouselSlidingOffset_LG) {
				return base.carouselSlidingOffset_LG
			} else {
				return base.carouselSlidingOffset;
			}
		};

		// BOOTSTRAP SLIDES: Determine Slides and Scrolling Based On Bootstrap Sizes
		base.reInitialize = function () {
			var slidesVisible = base.determineCarouselSlidesVisible();
			base.carousel.trigger('configuration', {
				items: {
					visible: {
						min: slidesVisible,
						max: slidesVisible
					}
				}
			});
			var carouselSlidingOffset = base.determineCarouselSlidingOffset();
			base.carousel.trigger('configuration', {
				scroll: {
					items: carouselSlidingOffset
				}
			});
			if (base.carouselIsGallery) {
				base.carouselGalleryRowColumn = base.determineGalleryRowColumn();
				base.addImagesToGallery();
			}
			base.updateCarouselHeight();
			base.updateThumbnailHeight();
		};

		// CAROUSEL: Adds CarouFredSel Plugin to Carousel
		base.initiateCarousel = function () {
			var carouselWidth = (base.inModal) ? $(".modal .modal-body").css("width") : base.carousel.css("width");
			var slidesVisible = base.determineCarouselSlidesVisible();
			var slideWidth = (parseInt(carouselWidth) / parseInt(base.carouselSlidesVisible));
			base.carousel.carouFredSel({
				responsive: true,
				circular: true,
				debug: base.carouselDebug,
				infinite: base.carouselIsInfinite,
				prev: base.containerSelector + " .prev",
				next: base.containerSelector + " .next",
				width: carouselWidth,
				height: 'variable',
				auto: {
					timeoutDuration: base.carouselSlideDuration
				},
				items: {
					height: 'variable',
					visible: {
						min: slidesVisible,
						max: slidesVisible
					},
					width: 1170
				},
				scroll: {
					fx: base.carouselAnimationStyle,
					duration: base.carouselAnimationSpeed,
					items: base.carouselSlidingOffset,
					pauseOnHover: base.pauseOnHover,
					onBefore: function (data) { // onBefore: As soon as the animation begins for the next slide
						var slideNumber = data.items.visible.eq(0).data("slide-number") + 1;
						if (base.thumb && base.thumbnailClickEvent) { base.removeThumbnailClickEvent(); }
						if (base.hasPagination) {
							if (base.paginationStyle == "counter") { base.setupPagination(slideNumber); }
						}

						if (base.cont) { base.setupHeadingsAndContent(data.items.visible); }
						base.carousel.children().removeClass("active");
                       
                        var list= base.carousel.children();
                        for (var i = 0; i < list.length; i++) {
                            list[i].setAttribute('aria-hidden','true');
                            if (list[i].getElementsByTagName('a')[0]) {
                                list[i].getElementsByTagName('a')[0].setAttribute('tabindex','-1');
                            }    
                        }

						data.items.old.eq(0).addClass("leaving");
						data.items.visible.eq(0).addClass("arriving");
						if (base.arrivingFunction) { base.arrivingFunction(data.items.visible.eq(0), "arriving"); }
						if (base.leavingFunction) { base.leavingFunction(data.items.old.eq(0), "leaveing"); }
						if (base.arrivingLeavingFunction) {
							base.arrivingLeavingFunction(data.items.visible.eq(0), data.items.old.eq(0), (base.carousel.children().length - 1));
						}
					},
					onAfter: function (data) { // onAfter: Once the transition animation has finished
						if (base.thumb && base.thumbnailClickEvent) { base.thumbnailClickEvent(); }
						base.carousel.children().removeClass("active");
						data.items.old.eq(0).removeClass("leaving");
						data.items.visible.eq(0).addClass("active").removeClass("arriving");

                        var list= data.items.visible;
                        for (var i = 0; i < list.length; i++) {
                            list[i].setAttribute('aria-hidden','false');
                            if (list[i].getElementsByTagName('a')[0]) {
                                list[i].getElementsByTagName('a')[0].setAttribute('tabindex','0');
                            }
                        }

						if (base.activeFunction) { base.activeFunction(data.items.visible.eq(0), "active"); }
					}
				},
				onCreate: function (data) { // onCreate: As soon as the carousel is created
					base.carouselSlides = base.carousel.children();
					base.carousel.addClass("mpyCarousel");
					if (base.hasPagination) {
						var slideStart = (typeof ($(".modal-body").attr("starting-slide")) == "undefined") ? 1 : $(".modal-body").attr("starting-slide");
						base.setupPagination(slideStart);
					}
					data.items.eq(0).addClass("active");
					if (base.arrivingFunction) { base.arrivingFunction(data.items.eq(0), "active"); }
					if (base.thumb && base.thumbnailClickEvent) { base.thumbnailClickEvent(); }
					base.$container.swipe({
						swipeLeft: function (event, direction, distance, duration, fingerCount) {
							$(base.containerSelector + " .next").trigger("click");
						},
						swipeRight: function (event, direction, distance, duration, fingerCount) {
							$(base.containerSelector + " .prev").trigger("click");
						}
					});
					base.updateCarouselHeight();
				}
			}, { transition: base.cssAnimations });
		};

		// THUMBNAILS: Adds CarouFredSel Plugin to Thumbnails
		base.initiateThumbnails = function () {
			if (base.thumb) {
				// Initiate Thumbnails Carousel
				base.thumbnails.carouFredSel({
					responsive: true,
					circular: base.carouselIsCircular,
					auto: {
						play: false,
					},
					items: {
						visible: base.thumbnailImagesVisible,
						width: 135
					},
					scroll: {
						fx: base.thumbnailAnimationStyle,
						duration: base.thumbnailAnimationSpeed,
						items: base.thumbnailSlidingOffset,
						onBefore: function (data) {
							base.thumbnails.children().removeClass("active");
							data.items.visible.eq(0).addClass("active");
						}
					},
					onCreate: function () {
						base.thumbnails.parent().addClass("sliderThumbnailsWrapper");
					}
				}, { transition: base.cssAnimations });
				if (base.thumbnailClickEvent) { base.thumbnailClickEvent(); }
			}
		};

		// REMOVE SLIDES: Removes all slides from the carousel
		base.removeSlides = function () {
			if (base.carousel.children().length) {
				if (base.carousel.hasClass("mpyCarousel")) {
					base.carousel.trigger('removeItem', [base.carousel.children()]);
				} else {
					base.carousel.html("");
				}
			}
		};

		// GALLERY: Adds Images to Gallery
		base.addImagesToGallery = function () {
			if (base.jsonData) { // Check if using ajax
				base.carousel.html("");
				var rows = 2;
				var columns = base.determineCarouselSlidesVisible() / rows;
				var slides = base.jsonData.length / base.determineCarouselSlidesVisible();
				var slideWidth = base.$container.find(".caroufredsel_wrapper").css("width");
			    var itemIndex = 0;
				for (var i = 0; i < slides; i++) {
					var carouselSlide = '<div class="carouselSlide" data-slide-number="' + i + '" >';
					for (var j = 0; j < rows; j++) {
						carouselSlide += '<div class="row evenSpacedColumns padding-bottom-15">';
						for (var k = 0; k < columns; k++) {
						    carouselSlide += '<div class="col-xs-3 galleryItem"><img src="' + base.jsonData[itemIndex]["ImageUrl"] + '" class="img-responsive" alt="' + base.jsonData[itemIndex]["Alt"] + '" /></div>';
							itemIndex++;
						}
						carouselSlide += '</div>';
					}
					carouselSlide += '</div>';
					base.carousel.trigger('insertItem', [carouselSlide, "end", false, 1]);
				}
				base.carousel.children().find("img").first().load(function () {
					base.carousel.trigger('updateSizes');
					base.carousel.children().css({
						"width": slideWidth,
						"float": "left",
						"display": "block"
					});
				});


			}

			base.removeSlides();

			var galleryCallouts = $J("#hiddenDiv").children();

			var calloutIndex = 0;
			var calloutCount = galleryCallouts.length;
			var callouts = base.carouselGalleryRowColumn.row * base.carouselGalleryRowColumn.col;
			var slides = calloutCount / callouts;

			for (var i = 0; i < slides ; i++) {
				var output = '<div class="carouselSlide" data-slide-number="' + i + '">';
				for (var j = 0; j < base.carouselGalleryRowColumn.row; j++) {
					output += '<div class="row evenSpacedColumns padding-bottom-15 padding-right-15">';
					for (var k = 0; k < base.carouselGalleryRowColumn.col; k++) {
						output += (galleryCallouts[calloutIndex]) ? galleryCallouts[calloutIndex].outerHTML : "";
						calloutIndex++;
					}
					output += '</div>';
				}
				output += '</div>';
				if (base.carousel.hasClass("mpyCarousel")) {
					base.carousel.trigger('insertItem', [output, "end", false, 1]);
				} else {
					base.carousel.append(output);
					base.initiateCarousel();
					base.updateCarouselHeight();
				}
			}
			base.carousel.find(".carouselSlide").addClass("show");
			base.carouselSlides = base.carousel.children();
			if (base.hasPagination) {
				base.setupPagination(1);
			}
		};

		// LAZY LOAD: Lazy Load Image Using json String
		base.lazyLoadImages = function (i) {
			if (i < base.jsonData.length) {
				// Load Ajax Carousel Images
				var carouselSlide = '<div class="carouselSlide" data-slide-number="' + i + '" ';
				$.each(base.jsonData[i], function (key, value) {
					if (key != "Id" && key != "ImageUrl" && key != "Alt") {
						carouselSlide += 'data-' + key + '="' + value + '" ';
					}
				});
				if (base.jsonData[i]["ModalUrl"])
				{
					carouselSlide += 'style="float: left; display: block;"><img src="' + base.jsonData[i]["ModalUrl"] + '" ';
				}
				else {
					carouselSlide += 'style="float: left; display: block;"><img src="' + base.jsonData[i]["ImageUrl"] + '" ';
				}
				
				if (base.jsonData[i]["Alt"]) { carouselSlide += 'alt="' + base.jsonData[i]["Alt"] + '" '; }
				carouselSlide += 'class="img-responsive" /></div>';

				if (i == 0) {
					base.carousel.append(carouselSlide);
					base.initiateCarousel();
				} else {
					base.carousel.trigger('insertItem', [carouselSlide, "end", false, 1]);
				}

				// Load Ajax Thumbnail Images
				if (base.thumb && base.thumbnails.length) {
					var thumbnailSlide = '<div class="sliderThumb';
					if (i == 0) { thumbnailSlide += ' active'; }
					thumbnailSlide += '" data-slide-number="' + i + '" style="float: left; display:none;">';
					thumbnailSlide += '<img src="' + base.jsonData[i]["ImageUrl"] + '" class="img-responsive" alt="' + base.jsonData[i]["Alt"] + '" />';
					thumbnailSlide += '</div>';

					base.thumbnails.trigger('insertItem', [thumbnailSlide, "end", false, 1]);
				}
				// Lazy Load till all images are loaded
				base.carousel.find('div[data-slide-number="' + i + '"] img').load(function () {
					$(this).css('display', 'block').unbind('load');
					if (i == 0) {
						setTimeout(function () {
							base.carousel.trigger('updateSizes');
							if (base.thumb) { base.updateThumbnailHeight(); }
						}, 20);
					}
					i++;
					base.lazyLoadImages(i);
					
				});
			} else { // Once Lazy Loading finishes
				base.carouselSlides = base.carousel.children();
				if (base.cont) { base.setupHeadingsAndContent(base.carouselSlides.first()); }
				if (base.nav) {
					var slideStart = (typeof ($(".modal-body").attr("starting-slide")) == "undefined") ? 1 : parseInt($(".modal-body").attr("starting-slide")) + 1;
					base.setupPagination(slideStart);
				}
				if (base.thumb && base.thumbnailClickEvent) { base.thumbnailClickEvent(); }

				// Synchronises thumbnails carousel if user has thumbnails
				if (base.thumb) {
					base.thumbnails.children().css("display", "block");
					base.carousel.trigger('configuration', {
						synchronise: [base.thumbnails.selector, false, true, 0]
					});
					setTimeout(function () {
						base.updateThumbnailHeight();
					}, 500);
				}
			}
		};

		// LOAD: Load Image Using json String
		base.loadImages = function (i) {
			if (i < base.jsonData.length) {
				// Load Ajax Carousel Images
				var carouselSlide = '<div class="carouselSlide" data-slide-number="' + i + '" ';
				$.each(base.jsonData[i], function (key, value) {
					if (key != "Id" && key != "ImageUrl" && key != "Alt") {
						carouselSlide += 'data-' + key + '="' + value + '" ';
					}
				});
				if (base.jsonData[i]["ModalUrl"]) {
					carouselSlide += 'style="float: left; display: block;"><img src="' + base.jsonData[i]["ModalUrl"] + '" ';
				}
				else {
					carouselSlide += 'style="float: left; display: block;"><img src="' + base.jsonData[i]["ImageUrl"] + '" ';
				}

				if (base.jsonData[i]["Alt"]) { carouselSlide += 'alt="' + base.jsonData[i]["Alt"] + '" '; }
				carouselSlide += 'class="img-responsive" /></div>';

				if (i == 0) {
					base.carousel.append(carouselSlide);
					base.initiateCarousel();
				} else {
					base.carousel.trigger('insertItem', [carouselSlide, "end", false, 1]);
				}

				// Load Ajax Thumbnail Images
				if (base.thumb && base.thumbnails.length) {
					var thumbnailSlide = '<div class="sliderThumb';
					if (i == 0) { thumbnailSlide += ' active'; }
					thumbnailSlide += '" data-slide-number="' + i + '" style="float: left; display:none;">';
					thumbnailSlide += '<img src="' + base.jsonData[i]["ImageUrl"] + '" class="img-responsive" />';
					thumbnailSlide += '</div>';

					base.thumbnails.trigger('insertItem', [thumbnailSlide, "end", false, 1]);
				}
				i++;
				base.loadImages(i);
				if (base.thumb) { base.updateThumbnailHeight(); }
			} else { // Once Lazy Loading finishes
				base.carousel.trigger('updateSizes');
				base.carouselSlides = base.carousel.children();
				if (base.cont) { base.setupHeadingsAndContent(base.carouselSlides.first()); }
				if (base.nav) {
					var slideStart = (typeof ($(".modal-body").attr("starting-slide")) == "undefined") ? 1 : parseInt($(".modal-body").attr("starting-slide")) + 1;
					base.setupPagination(slideStart);
				}
				if (base.thumb && base.thumbnailClickEvent) { base.thumbnailClickEvent(); }

				// Synchronises thumbnails carousel if user has thumbnails
				if (base.thumb) {
					base.thumbnails.children().css("display", "block");
					base.carousel.trigger('configuration', {
						synchronise: [base.thumbnails.selector, false, true, 0]
					});
					base.updateThumbnailHeight();
				}
			}
		};

		// UPDATE SIZES: Update Carousel's Heigth After First Image Loads
		base.updateCarouselHeight = function (firstImage) {
			base.carousel.trigger('updateSizes');
			base.carousel.find("img").first().load(function () {
				base.carousel.trigger('updateSizes');
			});
		},

		// UPDATE SIZES: Update Thumbnail's Heigth After First Image Loads
		base.updateThumbnailHeight = function (firstImage) {
			if (base.thumb) {
				base.thumbnails.trigger('updateSizes');
				base.thumbnails.find("img:last").load(function () {
					base.thumbnails.trigger('updateSizes');
					
				});
			}
		};

		// HEADLINES/CONTENT: Sets up Headings and Content if they exist
		base.setupHeadingsAndContent = function (slide) {
			var headline = slide.data("headline");
			var subHeadline = slide.data("subheadline");
			var content = slide.data("content");
			var contentString;
			var fadeSpeed = (base.firstTime) ? 0 : base.fadeSpeed;

			var elements = [];

			if (base.headline) elements.push(base.headline)
			if (base.subHeadline) elements.push(base.subHeadline)
			if (base.content) elements.push(base.content)

			var elms = [];

			$(elements).each(function () {
				if (this.selector) {
					elms.push(base.containerSelector + " " + this.selector);
				}
			});

			var string = elms.join(", ");

			$(string).fadeOut(fadeSpeed, function () {
				base.headline.html("");
				base.subHeadline.html("");
				base.content.html("");
				if (base.headline.length && headline) {
					if (base.headlineTag != "") {
						contentString = '<' + base.headlineTag + '>' + headline + '</' + base.headlineTag + '>';
					} else { contentString = headline; }
					base.headline.append(contentString);
				}

				if (base.subHeadline) {
					if (base.subHeadline.length && subHeadline) {
						if (base.subHeadlineTag != "") {
							contentString = '<' + base.subHeadlineTag + '>' + subHeadline + '</' + base.subHeadlineTag + '>';
						} else { contentString = subHeadline; }
						base.subHeadline.append(contentString);
					}
				}
				if (base.content) {
					if (base.content.length && content) {
						base.content.append(content);
					}
				}
			}).fadeIn(base.fadeSpeed, function () {
				base.firstTime = false;
			});
		};

		// ADD EVENT: Add Thumbnail Click Event
		base.thumbnailClickEvent = function () {
			if (base.thumb) {
				base.thumbnails.find("div").click(function () {
					var slide = $(this).data("slide-number");
					base.carousel.trigger('slideTo', [base.carousel.find('div[data-slide-number="' + slide + '"]')]);
					base.thumbnails.trigger('slideTo', slide);
				}).css('cursor', 'pointer');
				base.thumbnails.find("div").on("tap", function () {
					var slide = $(this).data("slide-number");
					base.carousel.trigger('slideTo', [base.carousel.find('div[data-slide-number="' + slide + '"]')]);
					base.thumbnails.trigger('slideTo', slide);
				});
			}
		};

		// REMOVE EVENT: Remove Thumbnail Click Event
		base.removeThumbnailClickEvent = function () {
			if (base.thumb) {
				base.thumbnails.find("div").unbind('click');
			}
		};

		// INIT CALL: Run initializer
		base.init();
	};

	// PLUGIN DEFAULT OPTIONS
	$.mpySlider.defaultOptions = {
		//jsonData: myJsonString,				// Pass JSON Data to the plugin. Empty means slides are already on the page

		// Carousel Settings
		carouselSelector: '.sliderCarousel',	// Default selector if user does not specify one
		carouselAnimationStyle: 'crossfade',	// Examples: 'scroll', fade', crossfade'
		carouselAnimationSpeed: 2000,			// Speed of animation between slides
		carouselSlideDuration: 5000,			// How long to stay on each slide before animating
		carouselSlidesVisible: 1,				// How many slides are showing at once
		//carouselSlidesVisible_XS: 1,			// How many slides are showing at once on bootstrap XS
		//carouselSlidesVisible_SM: 2,			// How many slides are showing at once on bootstrap SM
		//carouselSlidesVisible_MD: 3,			// How many slides are showing at once on bootstrap MD
		//carouselSlidesVisible_LG: 4,			// How many slides are showing at once on bootstrap LG
		carouselSlidingOffset: 1,				// How many slides away to animate to
		//carouselSlidingOffset_XS: 1,			// How many slides away to animate to on bootstrap XS
		//carouselSlidingOffset_SM: 2,			// How many slides away to animate to on bootstrap SM
		//carouselSlidingOffset_MD: 3,			// How many slides away to animate to on bootstrap MD
		//carouselSlidingOffset_LG: 4,			// How many slides away to animate to on bootstrap LG
		gallery: false,							// Gallery without using Lazy Load for images
		carouselIsGallery: false,				// Allows for multiple rows using json Slides
		carouselGalleryRowColumn: {row: 2, col: 4},
		carouselGalleryRowColumn_XS: { row: 1, col: 1 },
		carouselGalleryRowColumn_SM: { row: 1, col: 3 },
		carouselGalleryRowColumn_MD: { row: 2, col: 3 },
		carouselGalleryRowColumn_LG: { row: 2, col: 4 },
		carouselIsInfinite: true,				// Carousel will go back to first slide after the last slide
		carouselDebug: false,					// Plugin will display console log messages if true
		pauseOnHover: true,						// Carousel will pause on hover if true

		// Navigation Settings
		hasNavigation: true,					// Defaults to true (ex: Prev & Next buttons)
		navigationSelector: '.sliderNavigation', // Adding a selector will let you have a navigation

		// Pagination Settings
		hasPagination: true,					// Defaults to true (ex: < 1 2 3 4 5 >)
		paginationStyle: 'counter',				// Type of pagination Ex: 'number', 'icon', 'counter'
		paginationSelector: '.sliderPagination',// Default selector where pagination will be inserted
		paginationIcon: null,					// Url of icon image (ex: "/images/slider/icon.png")
		paginationCounterDivider: "/",			// Character that devides the slider counter (ex: 1/5, 1-5, 1~5)

		// Thumbnail Settings
		//thumbnailSelector: '.sliderThumbnails',// Adding a selector will add thumbnail images
		thumbnailAnimationStyle: 'scroll',		// Examples: 'scroll', fade', crossfade'
		thumbnailAnimationSpeed: 2000,			// Speed of thumbnail animation between slides
		thumbnailImagesVisible: 3,				// How many thumbnail images are showing at once
		thumbnailSlidingOffset: 1,				// How many thumbnail images away to animate to
		thumbnailClickEvent: true,				// Clicking a thumbnail will go to that slide

		// Content Settings
		//headlineContainer: '.headline',		// Adding a selector will let you add a headline
		//headlineTag: 'h4',					// Change headline HTML tag (default: h3)
		//subHeadlineContainer: '.subHeadline',	// Adding a selector will let you add a subHeadline
		//subHeadlineTag: 'h5',					// Change subHeadline HTML tag (default: h4)
		//contentSelector: '.content',			// Adding a selector will let you add content
		contentFadeSpeed: 300,					// 0 means it will just show instead of fade

		// Callback Functions
		arrivingLeavingFunction: null,			// A function can be called when both arriving and leaving class is added
		arrivingFunction: null,					// A function can be called when arriving class is added
		leavingFunction: null,					// A function can be called when leaving class is added
		activeFunction: null					// A function can be called when active class is added
	};

	$.fn.mpySlider = function (customOptions) {
		return this.each(function () {
			(new $.mpySlider(this, customOptions));
		});
	};

	// This function breaks the chain, but returns
	// the mpySlider.carousel if it has been attached to the object.
	$.fn.getmpySlider = function () {
		this.data("mpySlider");
	};

})(jQuery);
