// ==========================================================================
//
// Hash
// Enables linking to each modal
//
// ==========================================================================
(function(document, window, $) {
	'use strict';

	// Simple $.escapeSelector polyfill (for jQuery prior v3)
	if (!$.escapeSelector) {
		$.escapeSelector = function(sel) {
			var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
			var fcssescape = function(ch, asCodePoint) {
				if (asCodePoint) {
					// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
					if (ch === '\0') {
						return '\uFFFD';
					}

					// Control characters and (dependent upon position) numbers get escaped as code points
					return (
						ch.slice(0, -1) +
						'\\' +
						ch.charCodeAt(ch.length - 1).toString(16) +
						' '
					);
				}

				// Other potentially-special ASCII characters get backslash-escaped
				return '\\' + ch;
			};

			return (sel + '').replace(rcssescape, fcssescape);
		};
	}

	// Create new history entry only once
	var shouldCreateHistory = true;

	// Variable containing last hash value set by envirabox
	// It will be used to determine if envirabox needs to close after hash change is detected
	var currentHash = null;

	// Throttling the history change
	var timerID = null;

	// Get info about gallery name and current index from url
	function parseUrl() {
		var hash = window.location.hash.substr(1);
		var rez = hash.split('-');
		var index =
			rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1])
				? parseInt(rez.pop(-1), 10) || 1
				: 1;
		var gallery = rez.join('-');

		// Index is starting from 1
		if (index < 1) {
			index = 1;
		}

		return {
			hash: hash,
			index: index,
			gallery: gallery,
		};
	}

	// Trigger click evnt on links to open new envirabox instance
	function triggerFromUrl(url) {
		var $el;

		if (url.gallery !== '') {
			// If we can find element matching 'data-envirabox' atribute, then trigger click event for that ..
			$el = $(
				"[data-envirabox='" + $.escapeSelector(url.gallery) + "']",
			).eq(url.index - 1);

			if (!$el.length) {
				// .. if not, try finding element by ID
				$el = $('#' + $.escapeSelector(url.gallery) + '');
			}

			if ($el.length) {
				shouldCreateHistory = false;

				$el.trigger('click');
			}
		}
	}

	// Get gallery name from current instance
	function getGalleryID(instance) {
		var opts;

		if (!instance) {
			return false;
		}

		opts = instance.current ? instance.current.opts : instance.opts;

		return opts.hash || (opts.$orig ? opts.$orig.data('envirabox') : '');
	}

	// Star when DOM becomes ready
	$(function() {
		// Small delay is used to allow other scripts to process "dom ready" event
		setTimeout(function() {
			// Check if this module is not disabled
			if ($.envirabox.defaults.hash === false) {
				return;
			}

			// Update hash when opening/closing envirabox
			$(document).on({
				'onInit.eb': function(e, instance) {
					var url, gallery;

					if (
						instance.group[instance.currIndex].opts.hash ===
						false
					) {
						return;
					}

					url = parseUrl();
					gallery = getGalleryID(instance);

					// Make sure gallery start index matches index from hash
					if (gallery && url.gallery && gallery == url.gallery) {
						instance.currIndex = url.index - 1;
					}
				},

				'beforeShow.eb': function(e, instance, current) {
					var gallery;

					if (!current || current.opts.hash === false) {
						return;
					}

					gallery = getGalleryID(instance);

					// Update window hash
					if (gallery && gallery !== '') {
						if (window.location.hash.indexOf(gallery) < 0) {
							instance.opts.origHash =
								window.location.hash;
						}

						currentHash =
							gallery +
							(instance.group.length > 1
								? '-' + (current.index + 1)
								: '');

						if ('replaceState' in window.history) {
							if (timerID) {
								clearTimeout(timerID);
							}

							timerID = setTimeout(function() {
								window.history[
									shouldCreateHistory
										? 'pushState'
										: 'replaceState'
								](
									{},
									document.title,
									window.location.pathname +
										window.location.search +
										'#' +
										currentHash,
								);

								timerID = null;

								shouldCreateHistory = false;
							}, 300);
						} else {
							window.location.hash = currentHash;
						}
					}
				},

				'beforeClose.eb': function(e, instance, current) {
					var gallery, origHash;

					if (timerID) {
						clearTimeout(timerID);
					}

					if (current.opts.hash === false) {
						return;
					}

					gallery = getGalleryID(instance);
					origHash =
						instance && instance.opts.origHash
							? instance.opts.origHash
							: '';

					// Remove hash from location bar
					if (gallery && gallery !== '') {
						if ('replaceState' in history) {
							window.history.replaceState(
								{},
								document.title,
								window.location.pathname +
									window.location.search +
									origHash,
							);
						} else {
							window.location.hash = origHash;

							// Keep original scroll position
							$(window)
								.scrollTop(instance.scrollTop)
								.scrollLeft(instance.scrollLeft);
						}
					}

					currentHash = null;
				},
			});

			// Check if need to close after url has changed
			$(window).on('hashchange.eb', function() {
				var url = parseUrl();

				if ($.envirabox.getInstance()) {
					if (
						currentHash &&
						currentHash !== url.gallery + '-' + url.index &&
						!(url.index === 1 && currentHash == url.gallery)
					) {
						currentHash = null;

						$.envirabox.close();
					}
				} else if (url.gallery !== '') {
					triggerFromUrl(url);
				}
			});

			// Check current hash and trigger click event on matching element to start envirabox, if needed
			triggerFromUrl(parseUrl());
		}, 50);
	});
})(document, window, window.jQuery);
