(function() { 
	'use strict';

	// update nodes {{{

	function describeTimeElementDate(element) { // {{{

		if (!(element instanceof HTMLTimeElement)) {
			return "unknown";
		}

		const startYear = element.getAttribute('startyear');
		const startMonth = element.getAttribute('startmonth');
		const startDay = element.getAttribute('startday');

		if (!startYear || !startMonth || !startDay || isNaN(startYear) || isNaN(startMonth) || isNaN(startDay)) {
			return 'Invalid date attributes on the <time> element';
		}

		const timeElementDate = new Date(startYear, startMonth - 1, startDay);
		timeElementDate.setHours(0, 0, 0, 0);

		const today = new Date();
		today.setHours(0, 0, 0, 0);

		const dayDifference = Math.round((timeElementDate - today) / (1000 * 60 * 60 * 24));

		const daysOfWeek = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
		const dayOfWeek = daysOfWeek[timeElementDate.getDay()];

		const monthsOfYear = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
		const month = monthsOfYear[timeElementDate.getMonth()];

		var ret = [dayOfWeek, month];

		if (dayDifference === 0) {
			ret.push('today');
		} else if (dayDifference === 1) {
			ret.push('tomorrow');
		} else if (dayDifference === -1) {
			ret.push('yesterday');
		} else {
			if (dayDifference < 0) {
				ret.push('late');
				// if (dayDifference > -8) {
				// 	ret.push('last');
				// } else {
				// 	ret.push('older');
				// }
			} else {
				ret.push('future');
				// if (dayDifference < 8) {
				// 	ret.push('next');
				// } else {
				// 	ret.push('later');
				// }
			}
		}

		return ret;
	}

	// }}}

	function safeGetContent(parent, selector) { // {{{
		var element = parent.querySelector(selector);
		if (element !== null) {
				var content = element.innerText;
				if (content !== null) {
						return content;
				}
		}
		return ""
	}

	// }}}
	
	function removeClassesStartingWith(element, prefix) { // {{{
		const classes = element.classList;
		for (const className of classes) {
		if (className.startsWith(prefix)) {
			element.classList.remove(className);
		}
		}
	}

	// }}}

	function createImages(node, imgSrcs) {  // {{{
		var inject = node.querySelector('.inject');
		if (inject === null) {
			var inject = document.createElement("div");
			inject.className = 'inject';
			node.appendChild(inject);
		}
		var imgs = inject.querySelectorAll('img');
		if (imgs.length != imgSrcs.length) {
			inject.innerHTML = '';
			imgSrcs.forEach(imgSrc => {
				var img = document.createElement("img");
				img.src = imgSrc;
				img.style.display = "none";
				
				img.onload = function () {
					const maxDimension = 100;
					const aspectRatio = img.naturalWidth / img.naturalHeight;
					
					if (aspectRatio > 1) { 
						img.style.width = `${maxDimension}px`;
						img.style.height = `${maxDimension / aspectRatio}px`;
					} else {
						img.style.height = `${maxDimension}px`;
						img.style.width = `${maxDimension * aspectRatio}px`;
					}
					img.style.display = "block";
				};

				img.onclick = function () {
					// open link in new tab
					window.open(imgSrc, '_blank');
				};

				inject.appendChild(img);
			});
		}
	}

	// }}}

	function updateProject(projectNode) { // {{{

		removeClassesStartingWith(projectNode, "backlinked");
		removeClassesStartingWith(projectNode, "link");
		removeClassesStartingWith(projectNode, "tag");
		removeClassesStartingWith(projectNode, "time");

		const names = [];
		const notes = [];
		const breadcrumbNodes = [];

		for (let i = 0; i < projectNode.children.length; i++) {
			const child = projectNode.children[i];
			if (child.classList.contains('name')) {
				names.push(child);
			}
			if (child.classList.contains('notes')) {
				notes.push(child);
			}
			if (child.classList.contains('_1zok2')) {
				breadcrumbNodes.push(child.querySelector('.breadcrumbs'));
			}
		}

		[notes, names].forEach(function(ns) {
			if (ns.length > 0) {

				const n = ns[0];

				const text = safeGetContent(n, ".content > .innerContentContainer");

				if (text.startsWith("!")) {
					const links = n.querySelectorAll('a.contentLink');
					const imgSrcs = [];
					for (var i = 0; i < links.length; i++) {
						var link = links[i];
						link.textContent = "link";
						var imgSrc = link.href;
						imgSrcs.push(imgSrc);
					}
					if (imgSrcs.length > 0) {
						createImages(n, imgSrcs);
					}
				}

				const tags = n.querySelectorAll('.contentTag');
				tags.forEach(tag => {

					var tagText = safeGetContent(tag, ".contentTagText").trim();
					if (tagText !== "") {
						projectNode.classList.add("tagged");
						projectNode.classList.add("tagged-" + tagText);

					}
				});

				const links = n.querySelectorAll('.contentLink');
				links.forEach(link => {
					link.spellcheck = false;
					const nonLetterRegex = /[^a-zA-Z0-9]/g;
					var linkFull = link.innerText.trim().replace(nonLetterRegex, '');
					if (linkFull.startsWith("x") || linkFull.startsWith("y") || linkFull.startsWith("z")) {
						var className = "linked-" + linkFull;
						var linkClassName = "link-" + linkFull;
						projectNode.classList.add("linked");
						projectNode.classList.add(className);
						link.classList.add("link");
						link.classList.add(linkClassName);
					}
				});

				const times = n.querySelectorAll('time');
				times.forEach(time => {
					var relatives = describeTimeElementDate(time);
					projectNode.classList.add("timed");
					relatives.forEach(relative => {
						projectNode.classList.add("timed-" + relative);
					});
				});

				if (isIosSafari()) {
					const content = n.querySelector('.content');
					removeKeyboard(content);
				}

			 }
		});

	}

	// }}}
	
	function updateAll() {
		const projectNodes = document.querySelectorAll('.project');
		projectNodes.forEach(projectNode => {
			updateProject(projectNode);
		});
	}

	const observer = new MutationObserver((mutations) => {
		for (const mutation of mutations) {
			var nodes = null;
			if (mutation.addedNodes.length > 0) {
				nodes = mutation.addedNodes;
			} else if (mutation.removedNodes.length > 0) {
				nodes = mutation.addedNodes;
			}
			if ( nodes !== null ) {
				var node = mutation.target;
				if ( node !== null ) {
					var projectNode = node.closest('.project');
					if ( projectNode !== null && projectNode !== node ) {
						updateProject(projectNode);
					}
				}
			}
		}
	});

	observer.observe(document.body, { childList: true, subtree: true });

	updateAll();

	// }}}
	
	// hide keyboard on iOS Safari {{{

	function isIosSafari() {
		 const ua = navigator.userAgent;
		 return (
			 /iPhone|iPad|iPod/.test(ua) &&
			 /Safari/.test(ua)
		 );
	}

		
	function removeKeyboard(contentElement) {
		if (!('allowEditing' in contentElement)) {
			contentElement.allowEditing = false;
		}

		contentElement.addEventListener('focus', (e) => {
			if (!contentElement.allowEditing) {
				e.preventDefault();
				contentElement.blur();
			}
		});

		contentElement.addEventListener('dblclick', (e) => {
			contentElement.allowEditing = true;

			// Small delay to ensure focus is handled correctly
			setTimeout(() => {
				contentElement.focus();
			}, 0);
		});

		contentElement.addEventListener('blur', () => {
			contentElement.allowEditing = false;
		});
	}

	// }}}

})();