
function doReady(cb){
	return (document.readyState!=='loading') ? cb() : document.addEventListener('DOMContentLoaded',cb,{once:true});
}
doReady(function(){
	try {
		document.querySelector('nav#toc a.link-toc').href = document.querySelector('nav#site-nav a.action-toc').href;
	}catch(err){}

	try{new bootstrap.Collapse(document.querySelector('nav#toc a.list-group-item.active').parentElement).show();}catch(e){}

});

jQuery(document).ready(function(){
	
	if ('ElementQueries' in window) ElementQueries.listen();
	
	
	// user themeing
	window.userStylesDefault = {
		SiteTheme: false,
		ArticleWidth: '100%',
		TextSize: '1rem',
		BW: false,
		Links: false
	};
	window.userStyles = {};
	if ('localStorage' in window && 'theme' in localStorage) {
		window.userStyles = JSON.parse(localStorage.theme);
		Object.keys(window.userStyles).forEach(function(item){
			if (window.userStyles[item].toString()!=='false'){
				var el = document.querySelector('#settings [id="Menu'+item+'"]');
				//console.log(item, window.userStyles[item].toString(),el);
				if (el===null) return;
				if (el.nodeName==='INPUT' && el.type==='checkbox'){
					el.checked = true;
				} else if (el.nodeName==='SELECT') {
					el.value = window.userStyles[item];
				}
			}
		});
	}
	
	window.updateUserStyle = function(object){
		function Parse(str,v){
			return str.replace(/%s/gi,v);
		}
		var styleTemplates = {
			SiteTheme: '',
			ArticleWidth: '[data-adjust] {width: %s;}',
			TextSize: 'article, .text-article, .text-body, #settings div.ts > div.col-4, .homeContent, .homeContent p, .toc-full div.section .articles > article > .article-content-wrapper > p   {font-size: %s;}',
			BW: '#PageContent { filter: grayscale(100%); }',
			Links: 'main > *:not(nav):not(#topLogo) a[href] { %s }'
		};
		var propTemplates = {
			Links: {
				highlight: 'background-color: #ffc107;color: #212529;padding: 0.25rem;',
				underline: 'text-decoration: solid underline 0.15rem;',
			}
		};
		var stylesheet = '';
		var object = mergeObjects(window.userStylesDefault,window.userStyles,object);
		
		var Keys = Object.keys(object);
		//var SiteTheme = Keys.shift();
		Keys.forEach(function(item){
			Cookie.$.set('theme_'+item,object[item],9999);
			var thisVal = window.userStyles[item] = object[item];
			var thisCssVal = thisVal;
			if (item in propTemplates && thisVal in propTemplates[item]) thisCssVal = propTemplates[item][thisVal];
			
			if (object[item].toString()!=='false') stylesheet += Parse(styleTemplates[item],thisCssVal);
		});
		localStorage.theme = JSON.stringify(window.userStyles);
		document.querySelector('style#css-user').innerHTML = stylesheet;
	};
	
	(function userSettings(){
		function siteTheme(){
			if (this!==window){
				var theValue = (this.value||false);
				var themeStyle = document.querySelector('link#theme');
				if (theValue===false && themeStyle!==null){
					jQuery(themeStyle).remove();
					Cookie.$.remove('theme_SiteTheme');
					return;
				} else if (theValue!==false && themeStyle===null) {
					var head = document.head;
					themeStyle = document.createElement("link");
					themeStyle.id = "theme";
					themeStyle.type = "text/css";
					themeStyle.rel = "stylesheet";
					head.appendChild(themeStyle);
				}
				themeStyle.href = '/assets/css/theme.'+theValue+'.css';
			}
		}
		
		/*if (Cookie.$.get('theme_SiteTheme')!=='undefined' && Cookie.$.get('theme_SiteTheme')!=='false') {
			jQuery('select#MenuTheme').val(Cookie.$.get('theme_SiteTheme'));
		}*/
		jQuery('select#MenuSiteTheme').change(siteTheme);
		
		function textSize(ev){
			var that = this;
			var theId = this.parentElement.id;
			var fsEl = jQuery('#settings #'+theId+' div.col-4');
			var fontSize = parseInt(fsEl.css('font-size').replace(/[A-z]/gi,''));
			if (that.nodeName==='BUTTON') var fontSize = (jQuery(that).is(':last-of-type')) ? fontSize+1 : fontSize-1;
			updateUserStyle({
				TextSize: fontSize+'px'
			});
			fsEl.css('font-size',fontSize);
			fsEl.text(fontSize+'px');
		}
		
		
		jQuery('#settings div.ts > div.col-4').each(function(index,el){
			textSize.call(el);
		});
		jQuery('#settings div.ts > button.col-4').click(textSize);
		
		jQuery('#settings #MenuContentSize button').click(function(ev){
			ev.preventDefault();
			var newClasses = this.dataset.value;
			var TestDiv = document.createElement('div');
			TestDiv.className=newClasses;
			TestDiv.style.opacity = 0;
			document.body.appendChild(TestDiv);
			console.log(TestDiv);
			var newWidth = TestDiv.offsetWidth;
			TestDiv.remove();
			updateUserStyle({
				ArticleWidth: newWidth+'px'
			});
		});
		
		jQuery('#settings input[type="checkbox"]').change(function(){
			var object = {};
			var thisVal = this.id.split('Menu')[1];
			object[thisVal] = this.checked;
			updateUserStyle(object);
		});
		
		jQuery('#settings select').change(function(){
			var object = {};
			var thisVal = this.id.split('Menu')[1];
			object[thisVal] = this.value;
			updateUserStyle(object);
		});
		
		
		
		jQuery('#settings a#MenuReset').click(function(){
			try{document.querySelector('link#theme').remove();}catch(e){}
			var Keys = Object.keys(window.userStylesDefault);
			//var SiteTheme = Keys.shift();
			Keys.forEach(function(item){
				Cookie.$.remove('theme_'+item);
			});
			delete localStorage.theme;
			window.userStyles = {};
			jQuery('#settings div.ts > div.col-4').each(function(index,el){
				textSize.call(el);
			});
			updateUserStyle({});
		});
		
		var gutterSelect = false;
		switch(true){
			case (location.pathname==='/'):
			gutterSelect = '.homeContent > [data-adjust]';
			break;
			
			case (/^\/Editions\/[\w\-]{1,}\/?$/gi.test(location.pathname)):
			gutterSelect = '.toc-full [data-adjust]';
			break;
			
			default: 
			gutterSelect = 'article > #article-content';
		}
		
		if (gutterSelect!==false && document.querySelector(gutterSelect)!==null ) interact(gutterSelect).resizable({
			edges: { left: gutterSelect+' > .gutter.left', right: gutterSelect+' > .gutter.right' },
			listeners: {			
				move: function(event) {
					var target = event.target;
					target.style.width = event.rect.width + 'px';
				}
			}
		}).on('resizestart',function(event){
			event.target.setAttribute('is-adjusting','true');
		}).on('resizeend',function(event){
			updateUserStyle({
				ArticleWidth: event.rect.width+'px'
			});
			event.target.removeAttribute('style');
			event.target.removeAttribute('is-adjusting');
		});
	})();
	
	
	//
	
	jQuery('#navMain .action-toc').click(function(ev){
		ev.preventDefault();
		var that = this;
		jQuery('body').toggleClass('tocActive');
		var isActive = jQuery('body').hasClass('tocActive');
		
		if (isActive==true){
			
		}
		responsive();
	});
	jQuery('#navMain [data-section]').on('shown.bs.collapse hidden.bs.collapse',function(){
		console.log('wow');
		window.responsive();
	});
	
	// Menus 
	jQuery('nav#site-nav .container .settings > a').click(function(ev){
		ev.preventDefault();
		try{jQuery('section[data-active]').removeAttr('data-active');}catch(e){}
		document.querySelector(this.hash).setAttribute('data-active','');
	});
	
	jQuery('#PageContent section .menu-close').click(function(){
		try{jQuery('section[data-active]').removeAttr('data-active');}catch(e){}
	});
	
	// nav dynamic width
	window.dynamicNav = function(attempt){
		var attempt = (attempt||0);
		if (typeof attempt==='number' && attempt>3) { return console.log('quit trying!'); };
		console.log('attempt ',attempt);
		window.responsive();
		var navWidth = jQuery('nav#site-nav .container').width();
		var navItems = jQuery('nav#site-nav .container > .left').children();
		var navItemsWidth = 0;
		if (jQuery('nav#site-nav .container > .right').length!==0){
			navItemsWidth = navItemsWidth + jQuery('nav#site-nav .container > .right').width();
		}
		navItems.each(function(index,item){
			//console.log(item,jQuery(item).outerWidth(true));
			navItemsWidth = (navItemsWidth+(jQuery(item).outerWidth(true)));
		});
		console.log(navWidth,navItemsWidth);
		if (navItemsWidth > navWidth) {
			console.log('nav has NO space');
			// probably mobile, nav is too long to fit on screen.
			// let's remove the last item we can and loop through.
			var elToMove = false;
			if (jQuery('nav#site-nav .container > .right').length!==0){
				console.log('right nop');
				elToMove = jQuery('nav#site-nav .container > .right');
			} else {
				elToMove = jQuery(navItems[navItems.length-1]);
			}
			
			if (elToMove!==false){
				elToMove.attr('data-width',jQuery(elToMove).outerWidth(true));
				jQuery('nav#expanded-nav').append(elToMove);
				console.log('removing item',elToMove);
				attempt = attempt+1;
				console.log('now attempt ', attempt);
				window.dynamicNav(attempt);
			}
		} else if (navWidth > navItemsWidth) {
			console.log('nav HAS space');
			if (jQuery('#expanded-nav').children().length!==0){
				var moreNavItems = jQuery('nav#expanded-nav').children();
				var moreNavLastItem = moreNavItems[moreNavItems.length-1];
				console.log(moreNavItems,moreNavLastItem);
				console.log((navItemsWidth+jQuery(moreNavLastItem).data('width')),navWidth);
				if ((navItemsWidth+jQuery(moreNavLastItem).data('width')) < navWidth){
					var appendTo = (moreNavLastItem.classList.contains('right')) ? 'nav#site-nav .container' : 'nav#site-nav .container > .left';
					console.log('adding item',moreNavLastItem);
					jQuery(appendTo).append(moreNavLastItem);
					attempt = attempt+1;
					window.dynamicNav(attempt);
				}
			}
		}
		
		if (jQuery('nav#more').text()===''){
			jQuery('nav#site-nav .container .action-toc').hide();
		} else {
			jQuery('nav#site-nav .container .action-toc').show();
		}
	}
	
	window.dynamicNavTimeout = false;
	jQuery(window).resize(function(){
		if (window.dynamicNavTimeout!==false) clearTimeout(window.dynamicNavTimeout);
		window.dynamicNavTimeout = setTimeout(window.dynamicNav,100);
	});
	setTimeout(function(){window.dynamicNav();},300);
	
	window.responsive = function(){
		var topHeight = jQuery('#topLogo').height() + jQuery('#navMain').height();
		var isMobile = (window.innerWidth<767) ? true : false;
		
		if (document.querySelector('nav#more')!==null) jQuery('#navMain').css('bottom', function(){
			return ( (isMobile) ? (this.querySelector('nav#more').clientHeight*-1) : 'initial' );
		});
		
		var vh = window.innerHeight * 0.01;
		document.documentElement.style.setProperty('--vh', `${vh}px`);
		
		var button = document.querySelector('#navMain .action-toc');
		if (isMobile===false && button!==null){
			var coords = jQuery(button).position();
			jQuery('nav#more').css({
				top: function(){return ((jQuery(this).outerHeight(true) * -1)+(-77))},
				left: coords.left,
				maxHeight: ((window.innerHeight-topHeight)-60),
				width: function(){return (jQuery('main .container:first').width() * 0.25)},
			});
		}
		if (isMobile===false ){
			jQuery('#PageContent > section > .container').css('margin-top',(topHeight-53));
		}
	};
	jQuery(window).resize(responsive);
	setTimeout(function(){responsive();},300);
	jQuery('nav#toc [data-section]').on('shown.bs.collapse hidden.bs.collapse',responsive);
	
	jQuery('body').click(function(ev){
		if ((jQuery(ev.target).closest('nav#navMain').length!==1) && (jQuery('body').hasClass('tocActive')) ){
			jQuery('body').removeClass('tocActive');
			responsive();
		}
	});
	
	jQuery('section#archive .card').matchHeight();
	
	return setTimeout(function(){jQuery('#page-loader').fadeOut();},500);
});

window.getSelected = function(){
		var t = false;
		if (window.getSelection) {
			t = window.getSelection();
		} else if (document.getSelection) {
			t = document.getSelection();
		} else if (document.selection) {
			t = document.selection.createRange().text;
		}
		return t;
	}
	
	window.clearSelected = function(){
		if (window.getSelection) {
			if (window.getSelection().empty) {  // Chrome
				window.getSelection().empty();
			} else if (window.getSelection().removeAllRanges) {  // Firefox
				window.getSelection().removeAllRanges();
			}
		} else if (document.selection) {  // IE?
			document.selection.empty();
		}
	}
	
	window.mergeObjects = function(){
		var newObject = {};
		for (var a = 0; a < arguments.length; a++) {
			var obj = arguments[a];
			Object.keys(obj).forEach(function(item){
				newObject[item] = obj[item];
			});
		}
		return newObject;
	}

Cookie = function(){
	var thisPrototypes = {
		reload: function(){
			var cookies = {};
			document.cookie.replace(/([^=;]+)=([^;]*)/gi, function(m,key,value) {cookies[key.replace(/(^\s+|\s+$)/g,'')] = value.replace(/(^\s+|\s+$)/g,'');});
			Cookie = cookies = window.mergeObjects(cookies,{$: thisPrototypes});
			Object.freeze(cookies.$);
			if ('Proxy' in window){
				return new Proxy(cookies, {
					set: function (target, key, value) {
						if (typeof value!=='string') throw new Error('Value can only be a string.');
						target[key] = value;
						return Cookie.$.set(key,value);
						return true;
					},
					deleteProperty: function (target, key) {
						delete target[key];
						Cookie.$.remove(key);
						return true;
					}				
				});
			}
			Object.seal(cookies);
			return cookies;
		},
		
		get: function(name){
			if (typeof name==='undefined') return;
			if (!name in Cookie) return;
			return Cookie[name];
		},
		
		remove: function(name){
			if (typeof name==='undefined') return;
			if (!name in Cookie) return;
			return thisPrototypes.set(name,'',-5);
		},
		
		set: function(name, value, exdays) {
			if (typeof name==='undefined') return;
			if (typeof value==='undefined') return;
			if (typeof exdays==='undefined') exdays=7;
			if (/^[\s]{1,}$/.test(name)==true) return false;
			if (/^[\s]{1,}$/.test(value)==true) return false;
			var d = new Date();
			d.setTime(d.getTime() + (exdays*24*60*60*1000));
			var expires = "expires="+ d.toUTCString();
			var newCookie = name + "=" + value + ";" + expires + ";path=/";
			document.cookie = newCookie;
			thisPrototypes.reload();
			return newCookie;
		}
	};
	return thisPrototypes.reload();
}();

// from https://stackoverflow.com/a/36191841
function cssPropertyValueSupported(prop, value) {
  var d = document.createElement('div');
  d.style[prop] = value;
  return d.style[prop] === value;
}

// from https://stackoverflow.com/a/7557433
function isElementInViewport(el) {
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }
    var rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
    );
}