(function ($) {
	'use strict';
	$.fn.AcmeTicker = function (options) {
		/*Merge options and default options*/
		let opts = $.extend({}, $.fn.AcmeTicker.defaults, options);

		/*Functions Scope*/
		let thisTicker = $(this), intervalID, timeoutID, isPause = false;

		/*Always wrap, used in many place*/
		thisTicker.wrap("<div class='acmeticker-wrap'></div>");

		/*Wrap is always relative*/
		thisTicker.parent().css({
			position: 'relative'
		})
		/*Hide expect first*/
		thisTicker.children("li").not(":first").hide();

		/*Lets init*/
		init();
		function init() {
			switch (opts.type) {
				case 'vertical':
				case 'horizontal':
					vertiZontal()
					break;

				case 'marquee':
					marQuee()
					break;

				case 'typewriter':
					typeWriter()
					break;

				default:
					break
			}
		}

		/*Vertical - horizontal
		* **Do not change code lines*/
		function vertiZontal(prevNext = false) {
			let speed = opts.speed,
				autoplay = opts.autoplay,
				direction = opts.direction;

			if (prevNext) {
				speed = 0;
				autoplay = 0;
				clearInterval(intervalID);
				intervalID = false;
			}

			function play() {
				if (isPause) {
					clearInterval(intervalID);
					intervalID = false;
					return false;
				}
				let dChild,
					eqType,
					mType,
					mVal;

				dChild = thisTicker.find('li:first');
				if (direction === 'up' || direction === 'right') {
					eqType = '-=';
				}
				else {
					eqType = '+=';
				}
				if (opts.type === 'horizontal') {
					mType = 'left';
					mVal = dChild.outerWidth(true);
				}
				else {
					mType = 'margin-top';
					mVal = dChild.outerHeight(true);
				}
				if (prevNext === 'prev') {
					thisTicker.find('li:last').detach().prependTo(thisTicker);
				}
				else {
					dChild.detach().appendTo(thisTicker);
				}

				thisTicker.find('li').css({
					opacity: '0',
					display: 'none'
				});
				thisTicker.find('li:first').css({
					opacity: '1',
					position: 'absolute',
					display: 'block',
					[mType]: eqType + mVal + 'px',
				});
				thisTicker.find('li:first').animate(
					{ [mType]: '0px' },
					speed,
					function () {
						clearInterval(intervalID);
						intervalID = false;
						vertiZontal();
					});
			}
			if (intervalID) {
				return false
			}
			intervalID = setInterval(play, autoplay);
		}

		/*Type-Writer
		* **Do not change code lines*/
		function typeWriter(prevNext = false) {
			if (isPause) {
				return false;
			}
			if (prevNext) {
				clearInterval(intervalID);
				intervalID = false;

				clearTimeout(timeoutID);
				timeoutID = false;

				if (prevNext === 'prev') {
					thisTicker.find('li:last').detach().prependTo(thisTicker);
				}
				else {
					thisTicker.find('li:first').detach().appendTo(thisTicker);
				}
			}

			let speed = opts.speed,
				autoplay = opts.autoplay,
				typeEl = thisTicker.find('li:first'),
				wrapEl = typeEl.children(),
				count = 0;

			if (typeEl.attr('data-text')) {
				wrapEl.text(typeEl.attr('data-text'))
			}

			let allText = typeEl.text();

			thisTicker.find('li').css({
				opacity: '0',
				display: 'none'
			});

			function tNext() {
				thisTicker.find('li:first').detach().appendTo(thisTicker);

				clearTimeout(timeoutID);
				timeoutID = false;

				typeWriter();
			}

			function type() {
				count++;
				let typeText = allText.substring(0, count);
				if (!typeEl.attr('data-text')) {
					typeEl.attr('data-text', allText);
				}

				if (count <= allText.length) {
					wrapEl.text(typeText);
					typeEl.css({
						opacity: '1',
						display: 'block',
					});
				}
				else {
					clearInterval(intervalID);
					intervalID = false;
					timeoutID = setTimeout(tNext, autoplay);
				}
			}
			if (!intervalID) {
				intervalID = setInterval(type, speed);
			}
		}

		/*marQuee
		* **Do not change code lines*/
		function marQuee() {
			/*Marquee Special*/
			let speed = opts.speed,
				direction = opts.direction,
				wrapWidth,
				dir = 'left',
				totalTravel,
				defTiming,
				listWidth = 0,
				mPause = false;

			mInit();
			function mInit() {
				thisTicker.css({
					position: 'absolute'
				})
				thisTicker.find('li').css({
					display: 'inline-block',
					marginRight: '10px',
				});
				let tickerList = thisTicker.find("li");
				wrapWidth = thisTicker.parent().outerWidth(true);

				if (direction === 'right') {
					dir = 'right'
				}

				/*Calculating ticker width*/
				thisTicker.width(10000);/*temporary width to prevent inline elements wrapping to initial width of ticker*/
				tickerList.each(function () {
					listWidth += $(this).outerWidth(true) + 5;/*+5 for some missing px*/
				});
				thisTicker.width(listWidth);

				totalTravel = listWidth + wrapWidth;
				defTiming = totalTravel / speed;

				marQueeIt(listWidth, listWidth / speed);
			}

			function marQueeIt(lPos, lSpeed) {
				thisTicker.animate(
					{ [dir]: '-=' + lPos },
					lSpeed,
					"linear",
					function () {
						thisTicker.css({
							[dir]: wrapWidth
						});
						marQueeIt(totalTravel, defTiming);
					}
				);
			}

			function mRestart() {
				let offset = thisTicker.offset(),
					rOffset = direction === 'right' ? (listWidth - offset.left) : offset.left,
					remainingSpace = rOffset + listWidth,
					remainingTime = remainingSpace / speed;

				marQueeIt(remainingSpace, remainingTime);
			}
			function mToggle() {
				mPause = !mPause;
				$(document).trigger('acmeTickerToggle', thisTicker, mPause)
				if (mPause) {
					thisTicker.stop();
				}
				else {
					mRestart();
				}
			}

			opts.controls.toggle && opts.controls.toggle.on('click', function (e) {
				mToggle();
			});
			if (opts.pauseOnHover) {
				thisTicker.on('mouseenter', function () {
					thisTicker.stop();
				}).on('mouseleave', function () {
					mRestart();
				});
			}
			if (opts.pauseOnFocus) {
				thisTicker.on('focusin', function () {
					thisTicker.stop();
				}).on('focusout', function () {
					mRestart();
				});
			}
		}
		/*marQuee End*/

		/*Actions/Controls*/
		if (opts.type !== 'marquee') {
			opts.controls.prev && opts.controls.prev.on('click', function (e) {
				e.preventDefault();
				switch (opts.type) {
					case 'typewriter':
						typeWriter('prev')
						break;

					default:
						vertiZontal('prev')
						break
				}
			});
			opts.controls.next && opts.controls.next.on('click', function (e) {
				e.preventDefault();
				switch (opts.type) {
					case 'typewriter':
						typeWriter('next')
						break;

					default:
						vertiZontal('next')
						break
				}
			});
			function restart() {
				if (!isPause) {
					init();
				}
			}
			opts.controls.toggle && opts.controls.toggle.on('click', function (e) {
				e.preventDefault();
				isPause = !isPause;
				$(document).trigger('acmeTickerToggle', thisTicker, isPause)
				restart();
			});
			if (opts.pauseOnHover) {
				thisTicker.on('mouseenter', function () {
					isPause = true;
					restart();
				}).on('mouseleave', function () {
					isPause = false;
					restart();
				});
			}
			if (opts.pauseOnFocus) {
				thisTicker.on('focusin', function () {
					isPause = true;
					restart();
				}).on('focusout', function () {
					isPause = false;
					restart();
				});
			}
		}
	};

	// plugin defaults - added as a property on our plugin function
	$.fn.AcmeTicker.defaults = {
		/*Note: Marquee only take speed not autoplay*/
		type: 'horizontal',/*vertical/horizontal/marquee/typewriter*/
		autoplay: 2000,/*true/false/number*/ /*For vertical/horizontal 4000*//*For typewriter 2000*/
		speed: 50,/*true/false/number*/ /*For vertical/horizontal 600*//*For marquee 0.05*//*For typewriter 50*/
		direction: 'up',/*up/down/left/right*//*For vertical up/down*//*For horizontal/marquee right/left*//*For typewriter direction doesnot work*/
		pauseOnFocus: true,
		pauseOnHover: true,
		controls: {
			prev: '',/*Can be used for vertical/horizontal/typewriter*//*not work for marquee*/
			next: '',/*Can be used for vertical/horizontal/typewriter*//*not work for marquee*/
			toggle: ''/*Can be used for vertical/horizontal/marquee/typewriter*/
		}
	};
})(jQuery);