String.prototype.toTitleCase = function() {
	return this.replace(/\w\S*/g, function(txt) {
		return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
	});
}

String.prototype.toSentenceCase = function() {
	return this.charAt(0).toUpperCase() + this.substr(1).toLowerCase();
}

String.prototype.toContent = function() {
	return this.replace(/-/g, " ");
}

const copyColourFallback = (copyInfo, attr) => {
	console.log("fallback")
	var textArea = document.createElement('textarea');
	textArea.value = copyInfo;

	// Avoid scrolling to bottom
	textArea.style.top = '0';
	textArea.style.left = '0';
	textArea.style.position = 'fixed';

	document.body.appendChild(textArea);
	textArea.focus();
	textArea.select();

	try {
		var successful = document.execCommand('copy');
		setTimeout(function () {
			if (successful) {
				//copyInfo.success();
				showMessage(`Copied ${attr}.`)
			} else {
				//copyInfo.error();
				showMessage(`Copy failed (${attr}).`, false)
			}
		}, 1);
	} catch (err) {
		setTimeout(function () {
			showMessage(`Copy failed (${attr}). ${err.Message}`, false);
			
			//copyInfo.error(err);
		}, 1);
	}
	document.body.removeChild(textArea);
}

const showMessage = (m, s) => {
	s = s == undefined ? true : s;
	console.log("Copy success (navigator.clipboard)");
	$("body").prepend("<div id='copystatus' style='display: none;'><div class='"+(s ? "succeeded" : "failed")+"'>" + m + "</div></div>");
	$("#copystatus > div").css("top", (window.scrollY + 100)+ "px");
	$("#copystatus").fadeIn(1000, function(){
		$(this).fadeOut( 1000, function() {
			$(this).remove();
		});
	})
}

const oneClickSelect = (e, t = e.currentTarget) => {
	// In here, "this" is the element
	var range, selection;
	if (window.getSelection) {
		selection = window.getSelection();
		range = document.createRange();
		range.selectNodeContents(t);
		selection.removeAllRanges();
		selection.addRange(range);
	} else if (document.body.createTextRange) {
		range = document.body.createTextRange();
		range.moveToElementText(t);
		range.select();
	}
}

const getURLVars = () => {
	var oResult = {};
	if (location.search.length > 0) {
		var aQueryString = (location.search.substr(1)).split("&");
		for (var i = 0; i < aQueryString.length; i++) {
			var aTemp = aQueryString[i].split("=");
			if (aTemp[1].length > 0) {
				oResult[aTemp[0]] = decodeURIComponent(aTemp[1].replace(/\+/g, '%20'));
			}
		}
	}
	return oResult;
}

module.exports = {
	url: getURLVars(),
	cookie: {	
		set: (name, value, expires, path, domain, secure) => {
			switch(typeof expires) {
				case "number" : 
					var d = new Date()
					expires = d.setTime(d + (expires*24*60*60*1000));
				break;
				case "object" : 
					expires = expires.toGMTString();
			}
			document.cookie= name + "=" + escape(value) +
				((expires) ? "; expires=" + expires : "") +
				("; path=/") +
				((domain) ? "; domain=" + domain : "") +
				((secure) ? "; secure" : "");
		},
		get: (cname) => {
			var name = cname + "=";
			var ca = document.cookie.split(";");
			for(var i = 0; i <ca.length; i++) {
				var c = ca[i];
				while (c.charAt(0)===" ") {
					c = c.substring(1);
				}
				if (c.indexOf(name) === 0) {
					return c.substring(name.length,c.length);
				}
			}
			return "";
		},
		remove: (cnane) => {
			setCookie(cname, "", -1);
		},
	},
	colour: {
		// showMessage: (m, s) => {
		// 	showMessage(m, s);
		// },
		copy:  (w, t) => {
			let c = t.parentNode.getAttribute("data-" + (w=="var" ? "token" : w));
			c = w == "var" ? `var(${c})` : c;

			if (navigator.clipboard) {
				navigator.clipboard.writeText(c).then(function() {
					showMessage(`Copied ${w}.`);
				}, function(e) {
					copyColourFallback(c,w);
				});
			} else {
				copyColourFallback(c, w);
			}
		},
		positionTooltip: () => {
			$("color-pill > span").each(function(){
				if ((Number($("p").css('font-size').replace("px","")) * 10)  > $(this).offset().left) {
					$(this).children("div.tooltip-tc").attr("tip-position", "right");
				} else {
					$(this).children("div.tooltip-tc").attr("tip-position", "bottom");
				}
			})
		}
	},
	init: (args = {}) => {
		const url = getURLVars();

		if (url.p !== undefined) {
			document.querySelectorAll("main article:not([data-path^='" + url.p + "'])").forEach((a) => {
				a.remove();
			});

			if (url.p == -1) {
				document.querySelector("title").innerHTML = `${url.p.toContent().toTitleCase()} | ${$("title").attr("data-site")}`;
			} else {
				document.querySelector("title").innerHTML = `${url.p.substring(url.p.lastIndexOf("/")+1).toContent().toTitleCase()} | ${$("title").attr("data-site")}`
			}
			document.querySelector("nav ul li a[href='./?p=" + (url.p.indexOf("/") == -1 ? url.p : url.p.substring(0, url.p.indexOf("/")) ) + "']").parentNode.classList.add("active");
		} else {
			document.querySelector("nav ul li a[href='./']").parentNode.classList.add("active");
		}

		document.querySelectorAll("article").forEach((a) => {
			if ( a.getAttribute("data-template") != "none" ) {
				let path = "patterns/" + a.getAttribute("data-path") + (a.getAttribute("data-core") == "true" ? "-core" : "") + "/index.html";
				const ASYNC = true;
				let ajx = new XMLHttpRequest();
				ajx.onreadystatechange = () => {
					if (ajx.readyState == 4) {
					
						switch (ajx.status) {
							case 200: 
								a.innerHTML = a.innerHTML + ajx.responseText;
								
								switch (a.getAttribute("data-template")) {
								 	case "pug": 
								 		a.querySelectorAll("pre").forEach((aa) => {
								 			aa.innerHTML = `<code class="${aa.getAttribute("class")}">${aa.innerHTML}</code>`;
								 		})
								 	break;
								 	case "md": 
								 		a.querySelectorAll("code").forEach((aa) => {
								 			aa.classList.add("language-html");
								 		})
								 	break;
								}
								a.querySelectorAll("code").forEach((c)=> {
									c.classList.add("line-numbers");
									c.innerHTML = c.innerHTML.replace(/</g, "&lt;");
									c.classList.add("copy-to-clipboard-button");
								})
								if (typeof args.success == "function") args.success(a);

								Prism.highlightAll();

								a.querySelectorAll("code").forEach((c)=> {
									c.onclick = (e) => {
										oneClickSelect(e);
									}
								})


								module.exports.colour.positionTooltip();
								window.onresize = () => {
									module.exports.colour.positionTooltip();
								}

								a.querySelectorAll("name > span, color-pill > span").forEach((pill) => {
									pill.onclick = (e) => {
										e.preventDefault();
										let w = "";
										if (e.metaKey || e.ctrlKey || e.keyCode == 91 || e.keyCode == 224) {
											w = "var";
										} else if (e.altKey) {
											w = "token"
										} else if (e.shiftKey) {
											w = "rgb";
										} else {
											w = "hex";
										}
										module.exports.colour.copy(w, pill);
									}
								})
							break;

							case 404: 
								if (typeof args.notFound == "function") args.notFound(a, path);
							break;

							default:
								console.log("uncaught http error", { status: ajx.status, path: a.getAttribute("data-path") });
						}
					}
				};
				ajx.open("GET", path, ASYNC);
				ajx.send();
			}
		})
	}
};