/*!-----------------------------------------------------------------------------
 * Vegas - Fullscreen Backgrounds and Slideshows.
 * v2.5.4 - built 2021-01-30
 * Licensed under the MIT License.
 * http://vegas.jaysalvat.com/
 * ----------------------------------------------------------------------------
 * Copyright (C) 2010-2021 Jay Salvat
 * http://jaysalvat.com/
 * --------------------------------------------------------------------------*/

(function ($) {
	'use strict';

	var defaults = {
		slide:                   0,
		delay:                   5000,
		loop:                    true,
		preload:                 false,
		preloadImage:            false,
		preloadVideo:            false,
		timer:                   true,
		overlay:                 false,
		autoplay:                true,
		shuffle:                 false,
		cover:                   true,
		color:                   null,
		align:                   'center',
		valign:                  'center',
		firstTransition:         null,
		firstTransitionDuration: null,
		transition:              'fade',
		transitionDuration:      1000,
		transitionRegister:      [],
		animation:               null,
		animationDuration:       'auto',
		animationRegister:       [],
		slidesToKeep:            1,
		init:  function () {},
		play:  function () {},
		pause: function () {},
		walk:  function () {},
		slides: [
			// {
			//  src:                null,
			//  color:              null,
			//  delay:              null,
			//  align:              null,
			//  valign:             null,
			//  transition:         null,
			//  transitionDuration: null,
			//  animation:          null,
			//  animationDuration:  null,
			//  cover:              true,
			//  video: {
			//      src: [],
			//      mute: true,
			//      loop: true
			// }
			// ...
		]
	};

	var videoCache = {};

	var Vegas = function (elmt, options) {
		this.elmt         = elmt;
		this.settings     = $.extend({}, defaults, $.vegas.defaults, options);
		this.slide        = this.settings.slide;
		this.total        = this.settings.slides.length;
		this.noshow       = this.total < 2;
		this.paused       = !this.settings.autoplay || this.noshow;
		this.ended        = false;
		this.$elmt        = $(elmt);
		this.$timer       = null;
		this.$overlay     = null;
		this.$slide       = null;
		this.timeout      = null;
		this.first        = true;

		this.transitions = [
			'fade', 'fade2',
			'blur', 'blur2',
			'flash', 'flash2',
			'negative', 'negative2',
			'burn', 'burn2',
			'slideLeft', 'slideLeft2',
			'slideRight', 'slideRight2',
			'slideUp', 'slideUp2',
			'slideDown', 'slideDown2',
			'zoomIn', 'zoomIn2',
			'zoomOut', 'zoomOut2',
			'swirlLeft', 'swirlLeft2',
			'swirlRight', 'swirlRight2'
		];

		this.animations = [
			'kenburns',
			'kenburnsLeft', 'kenburnsRight',
			'kenburnsUp', 'kenburnsUpLeft', 'kenburnsUpRight',
			'kenburnsDown', 'kenburnsDownLeft', 'kenburnsDownRight'
		];

		if (!(this.settings.transitionRegister instanceof Array)) {
			this.settings.transitionRegister = [ this.settings.transitionRegister ];
		}

		if (!(this.settings.animationRegister instanceof Array)) {
			this.settings.animationRegister = [ this.settings.animationRegister ];
		}

		this.transitions = this.transitions.concat(this.settings.transitionRegister);
		this.animations  = this.animations.concat(this.settings.animationRegister);

		this.support = {
			objectFit:  'objectFit'  in document.body.style,
			transition: 'transition' in document.body.style || 'WebkitTransition' in document.body.style,
			video:      $.vegas.isVideoCompatible()
		};

		if (this.settings.shuffle === true) {
			this.shuffle();
		}

		this._init();
	};

	Vegas.prototype = {
		_init: function () {
			var $content,
				$contentScroll,
				$overlay,
				$timer,
				isBody  = this.elmt.tagName === 'BODY',
				timer   = this.settings.timer,
				overlay = this.settings.overlay,
				self    = this;

			// Preloading
			this._preload();

			// Div with scrollable content
			if (!isBody) {
				$contentScroll = $('<div class="vegas-content-scrollable">');

				$content = $('<div class="vegas-content">')
					.css('overflow', this.$elmt.css('overflow'))
					.css('padding',  this.$elmt.css('padding'));

				// Some browsers don't compute padding shorthand
				if (!this.$elmt.css('padding')) {
					$content
						.css('padding-top',    this.$elmt.css('padding-top'))
						.css('padding-bottom', this.$elmt.css('padding-bottom'))
						.css('padding-left',   this.$elmt.css('padding-left'))
						.css('padding-right',  this.$elmt.css('padding-right'));
				}

				this.$elmt.css('padding', 0);

				this.$elmt.clone(true).children().appendTo($content);
				this.elmt.innerHTML = '';
			}

			// Timer
			if (timer && this.support.transition) {
				$timer = $('<div class="vegas-timer"><div class="vegas-timer-progress">');
				this.$timer = $timer;
				this.$elmt.prepend($timer);
			}

			// Overlay
			if (overlay) {
				$overlay = $('<div class="vegas-overlay">');

				if (typeof overlay === 'string') {
					$overlay.css('background-image', 'url(' + overlay + ')');
				}

				this.$overlay = $overlay;
				this.$elmt.prepend($overlay);
			}

			// Container
			this.$elmt.addClass('vegas-container');

			if (!isBody) {
				this.$elmt.append($contentScroll);
				$contentScroll.append($content);
			}

			setTimeout(function () {
				self.trigger('init');
				self._goto(self.slide);

				if (self.settings.autoplay) {
					self.trigger('play');
				}
			}, 1);
		},

		_preload: function () {
			var img, i;

			for (i = 0; i < this.settings.slides.length; i++) {
				if (this.settings.preload || this.settings.preloadImages) {
					if (this.settings.slides[i].src) {
						img = new Image();
						img.src = this.settings.slides[i].src;
					}
				}

				if (this.settings.preload || this.settings.preloadVideos) {
					if (this.support.video && this.settings.slides[i].video) {
						if (this.settings.slides[i].video instanceof Array) {
							this._video(this.settings.slides[i].video);
						} else {
							this._video(this.settings.slides[i].video.src);
						}
					}
				}
			}
		},

		_random: function (array) {
			return array[Math.floor(Math.random() * array.length)];
		},

		_slideShow: function () {
			var self = this;

			if (this.total > 1 && !this.ended && !this.paused && !this.noshow) {
				this.timeout = setTimeout(function () {
					self.next();
				}, this._options('delay'));
			}
		},

		_timer: function (state) {
			var self = this;

			clearTimeout(this.timeout);

			if (!this.$timer) {
				return;
			}

			this.$timer
				.removeClass('vegas-timer-running')
				.find('div')
				.css('transition-duration', '0ms');

			if (this.ended || this.paused || this.noshow) {
				return;
			}

			if (state) {
				setTimeout(function () {
					self.$timer
						.addClass('vegas-timer-running')
						.find('div')
						.css('transition-duration', self._options('delay') - 100 + 'ms');
				}, 100);
			}
		},

		_video: function (srcs) {
			var video,
				source,
				cacheKey = srcs.toString();

			if (videoCache[cacheKey]) {
				return videoCache[cacheKey];
			}

			if (!(srcs instanceof Array)) {
				srcs = [ srcs ];
			}

			video = document.createElement('video');
			video.preload = true;

			srcs.forEach(function (src) {
				source = document.createElement('source');
				source.src = src;
				video.appendChild(source);
			});

			videoCache[cacheKey] = video;

			return video;
		},

		_fadeOutSound: function (video, duration) {
			var self   = this,
				delay  = duration / 10,
				volume = video.volume - 0.09;

			if (volume > 0) {
				video.volume = volume;

				setTimeout(function () {
					self._fadeOutSound(video, duration);
				}, delay);
			} else {
				video.pause();
			}
		},

		_fadeInSound: function (video, duration) {
			var self   = this,
				delay  = duration / 10,
				volume = video.volume + 0.09;

			if (volume < 1) {
				video.volume = volume;

				setTimeout(function () {
					self._fadeInSound(video, duration);
				}, delay);
			}
		},

		_options: function (key, i) {
			if (i === undefined) {
				i = this.slide;
			}

			if (this.settings.slides[i][key] !== undefined) {
				return this.settings.slides[i][key];
			}

			return this.settings[key];
		},

		_goto: function (nb) {
			if (typeof this.settings.slides[nb] === 'undefined') {
				nb = 0;
			}

			this.slide = nb;

			var $slide,
				$inner,
				$video,
				$slides       = this.$elmt.children('.vegas-slide'),
				src           = this.settings.slides[nb].src,
				videoSettings = this.settings.slides[nb].video,
				delay         = this._options('delay'),
				align         = this._options('align'),
				valign        = this._options('valign'),
				cover         = this._options('cover'),
				color         = this._options('color') || this.$elmt.css('background-color'),
				self          = this,
				total         = $slides.length,
				video,
				img;

			var transition         = this._options('transition'),
				transitionDuration = this._options('transitionDuration'),
				animation          = this._options('animation'),
				animationDuration  = this._options('animationDuration');

			if (this.settings.firstTransition && this.first) {
				transition = this.settings.firstTransition || transition;
			}

			if (this.settings.firstTransitionDuration && this.first) {
				transitionDuration = this.settings.firstTransitionDuration || transitionDuration;
			}

			if (this.first) {
				this.first = false;
			}

			if (cover !== 'repeat') {
				if (cover === true) {
					cover = 'cover';
				} else if (cover === false) {
					cover = 'contain';
				}
			}

			if (transition === 'random' || transition instanceof Array) {
				if (transition instanceof Array) {
					transition = this._random(transition);
				} else {
					transition = this._random(this.transitions);
				}
			}

			if (animation === 'random' || animation instanceof Array) {
				if (animation instanceof Array) {
					animation = this._random(animation);
				} else {
					animation = this._random(this.animations);
				}
			}

			if (transitionDuration === 'auto' || transitionDuration > delay) {
				transitionDuration = delay;
			}

			if (animationDuration === 'auto') {
				animationDuration = delay;
			}

			$slide = $('<div class="vegas-slide"></div>');

			if (this.support.transition && transition) {
				$slide.addClass('vegas-transition-' + transition);
			}

			// Video

			if (this.support.video && videoSettings) {
				if (videoSettings instanceof Array) {
					video = this._video(videoSettings);
				} else {
					video = this._video(videoSettings.src);
				}

				video.loop  = videoSettings.loop !== undefined ? videoSettings.loop : true;
				video.muted = videoSettings.mute !== undefined ? videoSettings.mute : true;

				if (video.muted === false) {
					video.volume = 0;
					this._fadeInSound(video, transitionDuration);
				} else {
					video.pause();
				}

				$video = $(video)
					.addClass('vegas-video')
					.css('background-color', color);

				if (this.support.objectFit) {
					$video
						.css('object-position', align + ' ' + valign)
						.css('object-fit', cover)
						.css('width',  '100%')
						.css('height', '100%');
				} else if (cover === 'contain') {
					$video
						.css('width',  '100%')
						.css('height', '100%');
				}

				$slide.append($video);

				// Image

			} else {
				img = new Image();

				$inner = $('<div class="vegas-slide-inner"></div>')
					.css('background-image',    'url("' + src + '")')
					.css('background-color',    color)
					.css('background-position', align + ' ' + valign);

				if (cover === 'repeat') {
					$inner.css('background-repeat', 'repeat');
				} else {
					$inner.css('background-size', cover);
				}

				if (this.support.transition && animation) {
					$inner
						.addClass('vegas-animation-' + animation)
						.css('animation-duration',  animationDuration + 'ms');
				}

				$slide.append($inner);
			}

			if (!this.support.transition) {
				$slide.css('display', 'none');
			}

			if (total) {
				$slides.eq(total - 1).after($slide);
			} else {
				this.$elmt.prepend($slide);
			}

			$slides
				.css('transition', 'all 0ms')
				.each(function () {
					this.className  = 'vegas-slide';

					if (this.tagName === 'VIDEO') {
						this.className += ' vegas-video';
					}

					if (transition) {
						this.className += ' vegas-transition-' + transition;
						this.className += ' vegas-transition-' + transition + '-in';
					}
				}
				);

			self._timer(false);

			function go () {
				self._timer(true);

				setTimeout(function () {
					if (transition) {
						if (self.support.transition) {
							$slides
								.css('transition', 'all ' + transitionDuration + 'ms')
								.addClass('vegas-transition-' + transition + '-out');

							$slides.each(function () {
								var video = $slides.find('video').get(0);

								if (video) {
									video.volume = 1;
									self._fadeOutSound(video, transitionDuration);
								}
							});

							$slide
								.css('transition', 'all ' + transitionDuration + 'ms')
								.addClass('vegas-transition-' + transition + '-in');
						} else {
							$slide.fadeIn(transitionDuration);
						}
					}

					for (var i = 0; i < $slides.length - self.settings.slidesToKeep; i++) {
						$slides.eq(i).remove();
					}

					self.trigger('walk');
					self._slideShow();
				}, 100);
			}
			if (video) {
				if (video.readyState === 4) {
					video.currentTime = 0;
				}

				video.play();
				go();
			} else {
				img.src = src;

				if (img.complete) {
					go();
				} else {
					img.onload = go;
				}
			}
		},

		_end: function () {
			this.ended = !this.settings.autoplay;
			this._timer(false);
			this.trigger('end');
		},

		shuffle: function () {
			var temp,
				rand;

			for (var i = this.total - 1; i > 0; i--) {
				rand = Math.floor(Math.random() * (i + 1));
				temp = this.settings.slides[i];

				this.settings.slides[i] = this.settings.slides[rand];
				this.settings.slides[rand] = temp;
			}
		},

		play: function () {
			if (this.paused) {
				this.paused = false;
				this.next();
				this.trigger('play');
			}
		},

		pause: function () {
			this._timer(false);
			this.paused = true;
			this.trigger('pause');
		},

		toggle: function () {
			if (this.paused) {
				this.play();
			} else {
				this.pause();
			}
		},

		playing: function () {
			return !this.paused && !this.noshow;
		},

		current: function (advanced) {
			if (advanced) {
				return {
					slide: this.slide,
					data:  this.settings.slides[this.slide]
				};
			}
			return this.slide;
		},

		jump: function (nb) {
			if (nb < 0 || nb > this.total - 1 || nb === this.slide) {
				return;
			}

			this.slide = nb;
			this._goto(this.slide);
		},

		next: function () {
			this.slide++;

			if (this.slide >= this.total) {
				if (!this.settings.loop) {
					return this._end();
				}

				this.slide = 0;
			}

			this._goto(this.slide);
		},

		previous: function () {
			this.slide--;

			if (this.slide < 0) {
				if (!this.settings.loop) {
					this.slide++;
					return;
				} else {
					this.slide = this.total - 1;
				}
			}

			this._goto(this.slide);
		},

		trigger: function (fn) {
			var params = [];

			if (fn === 'init') {
				params = [ this.settings ];
			} else {
				params = [
					this.slide,
					this.settings.slides[this.slide]
				];
			}

			this.$elmt.trigger('vegas' + fn, params);

			if (typeof this.settings[fn] === 'function') {
				this.settings[fn].apply(this.$elmt, params);
			}
		},

		options: function (key, value) {
			var oldSlides = this.settings.slides.slice();

			if (typeof key === 'object') {
				this.settings = $.extend({}, defaults, $.vegas.defaults, key);
			} else if (typeof key === 'string') {
				if (value === undefined) {
					return this.settings[key];
				}
				this.settings[key] = value;
			} else {
				return this.settings;
			}

			// In case slides have changed
			if (this.settings.slides !== oldSlides) {
				this.total  = this.settings.slides.length;
				this.noshow = this.total < 2;
				this._preload();
			}
		},

		destroy: function () {
			clearTimeout(this.timeout);

			this.$elmt.removeClass('vegas-container');
			this.$elmt.find('> .vegas-slide').remove();
			this.$elmt.find('> .vegas-wrapper').clone(true).children().appendTo(this.$elmt);
			this.$elmt.find('> .vegas-wrapper').remove();

			if (this.settings.timer) {
				this.$timer.remove();
			}

			if (this.settings.overlay) {
				this.$overlay.remove();
			}

			this.elmt._vegas = null;
		}
	};

	$.fn.vegas = function(options) {
		var args = arguments,
			error = false,
			returns;

		if (options === undefined || typeof options === 'object') {
			return this.each(function () {
				if (!this._vegas) {
					this._vegas = new Vegas(this, options);
				}
			});
		} else if (typeof options === 'string') {
			this.each(function () {
				var instance = this._vegas;

				if (!instance) {
					throw new Error('No Vegas applied to this element.');
				}

				if (typeof instance[options] === 'function' && options[0] !== '_') {
					returns = instance[options].apply(instance, [].slice.call(args, 1));
				} else {
					error = true;
				}
			});

			if (error) {
				throw new Error('No method "' + options + '" in Vegas.');
			}

			return returns !== undefined ? returns : this;
		}
	};

	$.vegas = {};
	$.vegas.defaults = defaults;

	$.vegas.isVideoCompatible = function () {
		return !/(Android|webOS|Phone|iPad|iPod|BlackBerry|Windows Phone)/i.test(navigator.userAgent);
	};

})(window.jQuery || window.Zepto || window.m4q);
