
/*jslint browser: true*/

"use strict";

/*jshint esversion: 6 */

var visual_editor = "";
var code_editor = "";
var is_visual_editor = true;
var is_menu_open = false;
var is_bookmark_aside_shown = false;
var has_line_numbering = false;
var is_collab = false;
var is_mathjax = false;

var header = "";
var footer = "";

var url_canonical = "https://freeshell.de/alkeon/api/upload.php";

var visual_editor = true;
var template_id = 0;
var DEBUG = false;

const mathjax_library = 'js/mathjax.js';

var array_b64_images = [];

function reload_mathjax(){
	if(is_mathjax){
		MathJax = {
			tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]}
		};
		let script = document.createElement('script');
		script.src = mathjax_library;
		document.head.appendChild(script);
	}
}

function remove_mathjax() {
	if(MathJax.startup != null){
		let jax = MathJax.startup.document.getMathItemsWithin(document.body);
		for (var i = 0, m = jax.length; i < m; i++) {

			let tex = "$" + jax[i].math + "$";
			let root = jax[i].typesetRoot;
			let render_parent = jax[i].typesetRoot.parentElement

			render_parent.insertBefore(document.createTextNode(tex),root);
			render_parent.removeChild(root);

		}
	}
}

function change_input() {
	const header = document.getElementsByTagName("H1")[0];
	if(header != null){
		document.getElementById('title').innerText = header.innerText;
	}
}

function set_loading_file_popup_visibility(is_visible) {
	if(is_visible)
		document.getElementById('loading-file-popup').style.display = 'block';
	else
		document.getElementById('loading-file-popup').style.display = 'none';
}

function startEditors() {
	
	document.body.ondrop = function(e){
		e.preventDefault();
		drop(e);
	};

	let element_visual = document.getElementById("visual-editor");
	if(element_visual !== null) {
		start_visual_editor(element_visual);
	}

	let element = document.getElementById("code-editor");
	if(element !== null) {
		start_code_editor(element);
	}
	
	document.getElementById("file").addEventListener('change', function (event) {
		let input = document.querySelector("#file");
		let file = input.files[0];
		load_file(file);
		input.value = null;
	});
	
	let focusable_div = element_visual.querySelector('.visual-editor > div');
	setTimeout(function() {
		focusable_div.focus();
	}, 0);

}

function start_visual_editor(element){
	let options = {
		"clear_button": true,
		"link": true,
		"heading": true,
		"list": true,
		"table": true,
		"image": true,
		"block": true,
		"code": true,
		"embed": true,
		"save": true,
		"load": true,
		"undo": true,
		"redo": true
	};
	visual_editor = new creta(1, element, options);
	let div = document.createElement("div");
	let save_toolbar = element.querySelector('.save_toolbar');
	save_toolbar.onclick = function(){save();};
	let template_button = document.querySelector('.accept-template');
	
	template_button.onclick = function(){set_template_id(4);};
	let autoload_button = document.querySelector('.accept-autoload');
	
	autoload_button.onclick = function(){
		accepted_autoload();
		this.parentElement.style.display = 'none';
	};
	div.innerHTML =	`<div class="button left pdf" onclick="editor2pdf()">
				<div class="tooltip">
					<img width=24 height=24 src="icons/pdf.svg" alt="Convert to PDF icon">
					<div class="tooltiptext">Convert to PDF by sending text to server.</div>
				</div>
			</div>
			<div class="button left disabled pdf-disabled" style="display:none;">
				<div class="tooltip">
					<img width=24 height=24 src="icons/pdf.svg" alt="Convert to PDF icon">
					<div class="tooltiptext">Convert to PDF by sending text to server.</div>
				</div>
			</div>
			<div class="button left close_pdf" onclick="close_pdf_viewer()" style="display:none;">
				<div class="tooltip">
					<img width=24 height=24 src="icons/close_pdf.svg" alt="Close PDF tab">
					<div class="tooltiptext">Close PDF tab.</div>
				</div>
			</div>
			<div class="button left" onclick="download_file()">
				<div class="tooltip">
					<img src="icons/download.svg" alt="Download savestate icon">
					<div class="tooltiptext">Download document to file</div>
				</div>
			</div>
			<div class="button left">
				<div class="tooltip">
					<input type="file" style="display:none;" id="file">
					<label for="file" class="btn command"><img src="icons/upload.svg" alt="Upload savestate icon"></label>
					<div class="tooltiptext">Upload document to file</div>
				</div>
			</div>
			<div class="button right btn command tjs" onclick="start_togetherjs()" style="display:none;">
				<div class="tooltip">
					<img width=24 height=24 src="icons/collab.svg" alt="Collaborate">
				</div>
			</div>
			<div class="change-editor right tooltip">
				<input class="checkbox_change_editor" type="checkbox" onclick="changeEditor()">
				<div class="checkbox-text"><img width=24 height=24 alt="code editor" src="icons/code.svg"></div>
				<div class="tooltiptext">Convert between languages</div>
			</div>`;
	
	visual_editor.add_ui_element(element, div);
	
	div.appendChild(get_error_popup_div());
	
	visual_editor.add_ui_element(element, div);
	
}

function get_error_popup_div(){
	let popup = document.createElement("div");
	popup.className = 'popup block_popup';
	popup.style = "display:none;";
	popup.id = "error-ui";

	let popup_text = document.createElement("div");
	popup_text.id = 'text_error';
	
	let close_button_div = document.createElement("div");
	close_button_div.className = 'close_button';
	close_button_div.onclick = function(){
		this.parentElement.style.display = 'none';
	};

	close_button_div.appendChild(document.createTextNode("🗙"));
	
	popup.appendChild(document.createElement('br'));
	popup.appendChild(popup_text);
	popup.appendChild(close_button_div);
	
	return popup;
}

function start_code_editor(element){
	let options = {
		"clear_button": true,
		"save": true,
		"load": true,
		"undo": true,
		"redo": true
	};
	code_editor = new creta(2, element, options);
	let div = document.createElement("div");
	div.innerHTML =	`<div class="button left" onclick="download_file()">
				<div class="tooltip">
					<img src="icons/download.svg" alt="Download savestate icon">
					<div class="tooltiptext">Download document to file</div>
				</div>
			</div>
			<div class="button left">
				<div class="tooltip">
					<input type="file" style="display:none;" id="file">
					<label for="file" class="btn command"><img src="icons/upload.svg" alt="Upload savestate icon"></label>
					<div class="tooltiptext">Upload document to file</div>
				</div>
			</div>
			<div class="button right btn command tjs" onclick="start_togetherjs()" style="display:none;">
				<div class="tooltip">
					<img width=24 height=24 src="icons/collab.svg" alt="Collaborate">
				</div>
			</div>
			<div class="change-editor right tooltip">
				<input class="checkbox_change_editor" type="checkbox" onclick="changeEditor()">
				<div class="checkbox-text"><img width=24 height=24 alt="code editor" src="icons/code.svg"></div>
				<div class="tooltiptext">Convert between languages</div>
			</div>`;
	code_editor.add_ui_element(element, div);
	div.innerHTML += 	`<div id="error-ui" class="popup overflow-popup" style="display:none;">
					<div id="text_error">Write container class</div>
					<div class="close_button" onclick="this.parentElement.parentElement.style.display = 'none';">🗙</div>
				</div>`;
	code_editor.add_ui_element(element, div);
	code_editor.change_visibility(element);

}

var activated = false;
function start_togetherjs(){
	if(activated){
		let tjs = document.getElementsByClassName('tjs');
		for(let i = 0; i < tjs.length; ++i){
			tjs[i].style.color = 'black';
			tjs[i].style.backgroundColor = 'white';
		}
		activated = false;
	}else{
		let tjs = document.getElementsByClassName('tjs');
		for(let i = 0; i < tjs.length; ++i){
			tjs[i].style.color = 'black';
			tjs[i].style.backgroundColor = 'white';
		}
		activated = true;
	}
	TogetherJS();
	return false;
}

function start_menu(){
	if(is_menu_open){
		document.getElementById('options').style.display = "none";
		document.getElementById("editors").classList.remove("limit_width");
		document.getElementById('editors').classList.remove("hide-if-mobile");
		document.getElementById('bookmarks').classList.remove("hide-if-mobile");
		document.getElementById('options').classList.remove("options-width");
		is_menu_open = false;
	}else{
		document.getElementById('options').style.display = "block";
		document.getElementById('options').classList.add("options-width");
		document.getElementById('editors').classList.add("hide-if-mobile");
		document.getElementById('bookmarks').classList.add("hide-if-mobile");
		document.getElementById("editors").classList.add("limit_width");
		is_menu_open = true;

	}
	return false;
}

function save(){

	try{
		if(is_visual_editor)
			remove_mathjax();
	}catch(e){}
	try{
		visual_editor.save();

		var name = document.getElementById('title');
		localStorage.setItem('name', name.innerHTML);

		var select_titles = document.getElementById('select-title').checked;
		if(select_titles){
			select_titles = 1;
		}else{
			select_titles = 0;
		}
		localStorage.setItem('select_title', select_titles);

		var line_numbers = document.getElementById('line-numbers').checked;
		if(line_numbers){
			line_numbers = 1;
		}else{
			line_numbers = 0;
		}
		localStorage.setItem('line_numbers', line_numbers);

		var set_debug_text = document.getElementById('set-debug').checked;
		if(set_debug_text){
			set_debug_text = 1;
		}else{
			set_debug_text = 0;
		}
		localStorage.setItem('is_debug', set_debug_text);
		
		localStorage.setItem('template', template_id);

		localStorage.setItem('custom_start', document.querySelector('.start').value);

		localStorage.setItem('custom_end', document.querySelector('.end').value);

		localStorage.setItem('tjs', document.getElementById('set-collab').checked);

		localStorage.setItem('mathjax', document.getElementById('set-mathjax').checked);

	}catch(e){
		console.log("Couldn't save history " + e);
	}
	if(is_visual_editor)
		reload_mathjax();
}

var autoSave = window.setInterval(function(){
	save();
	change_input();
	if(is_bookmark_aside_shown){
		if(is_visual_editor){
			set_bookmarks(document.querySelector("#visual-editor").querySelector(".visual-editor").innerHTML);
		}else{
			set_bookmarks(document.querySelector("#code-editor").querySelector(".visual-editor").innerHTML);
		}
	}
	visual_editor.save();
}, 6000 * 5);


window.onbeforeprint = function(){

	save();
	//Print PDF from HTML browser if there isn't API server
	
	//Hide UX elements
	let nav = document.getElementsByTagName("nav")[0];
	let toolbar = document.getElementById("visual-editor").querySelector(".edit-controls");
	let options = document.getElementById("options");
	let bookmarks = document.getElementById("bookmarks");
	bookmarks.style.display = "none";
	options.style.display = "none";
	nav.style.display = "none";
	toolbar.style.display = "none";

	//Free viewport, this solves issues with one page only documents
	let main = document.getElementsByTagName("main")[0];
	main.removeAttribute('id');

	//Hide images and tables delete buttons
	let delete_buttons = document.querySelectorAll(".deletebutton");
	for (let element of delete_buttons) {
		element.style.display = "none";
	}

};

window.onafterprint = function(){

	//Show UX elements
	let pdf_icon = visual_editor.element.querySelector('.pdf');
	pdf_icon.style.display = "flex";
	let pdf_disabled_icon =  visual_editor.element.querySelector('.pdf-disabled');
	pdf_disabled_icon.style.display = "none";
	let toolbar = document.getElementById("visual-editor").querySelector(".edit-controls");
	let nav = document.getElementsByTagName("nav")[0];
	nav.style.display = "block";
	toolbar.style.display = "block";

	//Limit viewport to screen size
	let main = document.getElementsByTagName("main")[0];
	main.id = "viewport";

	//Show images and tables delete buttons
	let delete_buttons = document.querySelectorAll(".deletebutton");
	for (let element of delete_buttons) {
		element.style.display = "";
	}

};


function load(){

	visual_editor.load();
	try{
		if(localStorage.getItem("line-numbers") != null){
			if(localStorage.getItem("line-numbers") == true){
				document.getElementById('line-numbers').click();
			}
		}
		if(localStorage.getItem("select-title") != null){
			if(localStorage.getItem("select-title") == true){
				document.getElementById('select-title').click();
			}
		}
		if(localStorage.getItem("name") != null){
			document.getElementById('title').innerHTML = localStorage.getItem("name");
		}
		if(localStorage.getItem("is-debug") != null){
			if(localStorage.getItem("is-debug") == true){
				document.getElementById('set-debug').click();
			}
		}

		if(localStorage.getItem("custom-start") != null){
			document.querySelector('.start').innerHTML = localStorage.getItem("custom-start");
		}

		if(localStorage.getItem("custom-end") != null){
			document.querySelector('.end').innerHTML = localStorage.getItem("custom-end");
		}
		
		if(localStorage.getItem("template") != null ){
			switch(parseInt(localStorage.getItem("template"))){
				case 0: document.getElementById('notes').click();break;
				case 1: document.getElementById('thesis').click();break;
				case 2: document.getElementById('presentation').click();break;
				case 3: document.getElementById('custom').checked = true;break;
				case 4: document.getElementById('paper').click();break;
			}
		}
		
		if(localStorage.getItem("tjs") != null && localStorage.getItem("set-collab") == "true"){
			document.getElementById('set-collab').click();
		}
		
		if(localStorage.getItem("mathjax") != null && localStorage.getItem("mathjax") == "true"){
			document.getElementById('set-mathjax').click();
		}
	
	}catch(e){
		console.log("Couldn't load history " + e);
	}
	
	if(get_param('file')){
		document.getElementById('autoload-popup').style.display = 'block';
	}
	
	reload_mathjax();

}

function get_param(name){
   if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
      return decodeURIComponent(name[1]);
}

function accepted_autoload(){
	const options = {
		  method: 'GET',
		  mode: 'cors'
		  };
	fetch(get_param('file'), options).then(response => response.blob())
		.then(blob => load_file(blob)).catch((error) => {
			fail_found("Autoload files only allowed of same site files");
		});
}

function changeEditor(){

	if(is_visual_editor){

		is_visual_editor = false;
		
		visual_to_code_editor();

		document.getElementById('code-editor').style.display = 'flex';
		document.getElementById('visual-editor').style.display = 'none';
		let all_checkbox = document.getElementsByClassName('checkbox_change_editor');
		for(let checkbox_position = 0; checkbox_position < all_checkbox.length; ++checkbox_position){
			all_checkbox[checkbox_position].checked = true;
		}

	}else{

		is_visual_editor = true;

		code_to_visual_editor();

		document.getElementById('code-editor').style.display = 'none';
		document.getElementById('visual-editor').style.display = 'flex';
		let all_checkbox = document.getElementsByClassName('checkbox_change_editor');
		for(let checkbox_position = 0; checkbox_position < all_checkbox.length; ++checkbox_position){
			all_checkbox[checkbox_position].checked = false;
		}
	}
}

function visual_to_code_editor(){

	remove_mathjax();
	let editor_content = visual_editor.get_text();
	log_text("visual editor content " + editor_content);
	let h2t = new html2tedi();
	editor_content = h2t.convert(editor_content);
	log_text("html2tedi " + editor_content);
	code_editor.set_text_code(editor_content);
	save();
	
	let p = document.querySelector("#bookmarks");
	if(is_bookmark_aside_shown){
		set_bookmarks(document.querySelector("#code-editor").querySelector(".visual-editor").innerHTML);
		p.style.display = "block";
	} else {
		p.style.display = "none";
	}
	array_b64_images = visual_editor.get_images_b64();
	document.getElementById('set-mathjax').disabled = true;
}

function code_to_visual_editor(){

	let editor_content = code_editor.get_text_code();
	log_text("code editor content " + editor_content);
	let t2h = new tedi2html();
	editor_content = t2h.convert(editor_content);
	log_text("tedi2html " + editor_content);
	visual_editor.set_images_b64(array_b64_images);
	visual_editor.set_text(editor_content);
	save();
	
	let p = document.getElementById('bookmarks');
	if(is_bookmark_aside_shown){
		set_bookmarks(document.querySelector("#visual-editor").querySelector(".visual-editor").innerHTML);
		p.style.display = "block";
	}else{
		p.style.display = "none";
	}
	document.getElementById('set-mathjax').disabled = false;
	reload_mathjax();
}

function fail_found(text){
	document.getElementById('error-ui').style.display = "block";
	document.getElementById('text_error').innerHTML = text;
}

function set_line_numbering(){
	if(has_line_numbering){
		document.getElementById('enumerate-lines').href = "";

		has_line_numbering = false;
	} else {
		document.getElementById('enumerate-lines').href = "css/enumerate_lines.css";
		has_line_numbering = true;
	}
	return false;
}

function set_debug(){
	if(DEBUG){
		visual_editor.DEBUG = false;
		code_editor.DEBUG = false;
		DEBUG = false;
	}else{
		visual_editor.DEBUG = true;
		code_editor.DEBUG = true;
		DEBUG = true;
	}
	return false;
}

function show_template_popup(){
	document.getElementById('template-popup').style.display = 'block';
}

function show_bookmarks_aside(){

	if(is_bookmark_aside_shown){
		is_bookmark_aside_shown = false;
	}else{
		if(is_visual_editor)
			set_bookmarks(document.querySelector("#visual-editor").querySelector(".visual-editor").innerHTML);
			
		else
			set_bookmarks(document.querySelector("#code-editor").querySelector(".visual-editor").innerHTML);
		
		is_bookmark_aside_shown = true;
	}

	let p = document.getElementById('bookmarks');
	if(is_bookmark_aside_shown)
		p.style.display = "block";
	else
		p.style.display = "none";
	
	return false;
}

function log_text(line){
	if(DEBUG)
		console.log(line);

}

function set_template_id(id){ 
	template_id = id;
	set_template(id);
}

function set_template(){
	if(template_id == 0){
		header = 	`\\documentclass[12pt]{article}
				\\usepackage{afterpage}
				\\usepackage{ltablex}
				\\usepackage{amssymb}
				\\usepackage{float}
				\\usepackage{amsmath}
				\\usepackage{caption}
				\\usepackage{array}
				\\usepackage{xltabular}
				\\usepackage{longtable}
				\\usepackage{changepage}
				\\usepackage{enumitem}
				\\usepackage{booktabs}
				\\usepackage{hyperref}
				\\hypersetup{
					colorlinks=true,
					linkcolor=blue,
					filecolor=magenta,
					urlcolor=blue,
				}\n
				\\urlstyle{same}
				\\newcommand{\\tabitem}{~~\\llap{\\textbullet}~~}
				\\usepackage{graphicx}\n
				\\DeclareGraphicsExtensions{.eps, .jpg, .png, .jpeg}
				\\begin{document}`;
		footer = '\\end{document}';

	}else if(template_id == 1){
		header = 	`\\documentclass[11pt,a4paper]{report}\n
	  			\\usepackage[utf8]{inputenc}\n
	  			\\usepackage{hyperref}\n
	  			\\usepackage{verbatim}\n
	  			\\usepackage{graphicx}\n
	  			\\usepackage{underscore}\n
	  			\\usepackage{afterpage}
	  			\\usepackage[spanish]{babel}
	  			\\usepackage{ltablex}
	  			\\usepackage{amssymb}
	  			\\usepackage{float}
	  			\\usepackage{caption}
	  			\\usepackage{array}
	  			\\usepackage{xltabular}
	  			\\usepackage{longtable}
	  			\\usepackage{changepage}
	  			\\usepackage{enumitem}
	  			\\usepackage{booktabs}
	  			\\usepackage{hyperref}
				\\hypersetup{
					colorlinks=true,
					linkcolor=blue,
					filecolor=magenta,
					urlcolor=blue,
				}\n
	  			\\urlstyle{same}\n
	  			\\DeclareGraphicsExtensions{.eps, .jpg, .png, .jpeg}
	  			\\newcommand{\\tabitem}{~~\\llap{\\textbullet}~~}
	  			\\usepackage[protrusion = true,final]{microtype}\n
	  			\\setlength{\\emergencystretch}{10pt}
	  			\n\n
	  			\\title{` + document.getElementById("name").value + "}" +
				`\\hypersetup{pageanchor=false}\n
				\n\\setlength\\parskip{1em}\n
				\\begin{document}\n
	  			\\maketitle\n
	  			\\newpage\n
	  			\\listoffigures\n
	  			\\listoftables
	  			\\thispagestyle{empty}\n
	  			\\tableofcontents\n
	  			\\newpage\n
	  			\\setcounter{page}{1}\n`;
		footer = '\\end{document}';

	}else if(template_id == 2){
		header = 	`\\documentclass[t]{beamer}
				\\usetheme{Madrid}
				\\usepackage{afterpage}
				\\usepackage{amssymb}
				\\usepackage{float}
				\\usepackage{array}
				\\usepackage{amsmath}
				\\usepackage{xltabular}\n
				\\usepackage{graphicx}
				\\usepackage{longtable}
				\\usepackage{changepage}
				\\usepackage{enumitem}
				\\usepackage{booktabs}
				\\usepackage{hyperref}
				\\hypersetup{
					colorlinks=true,
					linkcolor=blue,
					filecolor=magenta,
					urlcolor=blue,
				}\n
				\\urlstyle{same}\n
				\\DeclareGraphicsExtensions{.eps, .jpg, .png, .jpeg}
				\\usepackage{booktabs}
				\\usepackage{xpatch}
				\\listoffigures
				\\title{` + document.getElementById("name").value + "}\\begin{document}\\frame{\\titlepage}";
		
		footer = '\\end{document}';
	}else if(template_id == 3){
		header = 	`\\documentclass[11pt,a4paper]{book}\n
	  			\\usepackage[utf8]{inputenc}\n
	  			\\usepackage{hyperref}\n
	  			\\usepackage{verbatim}\n
	  			\\usepackage{graphicx}\n
	  			\\usepackage{underscore}\n
	  			\\usepackage{afterpage}
	  			\\usepackage[spanish]{babel}
	  			\\usepackage{ltablex}
	  			\\usepackage{amssymb}
	  			\\usepackage{float}
	  			\\usepackage{caption}
	  			\\usepackage{array}
	  			\\usepackage{xltabular}
	  			\\usepackage{longtable}
	  			\\usepackage{changepage}
	  			\\usepackage{enumitem}
	  			\\usepackage{booktabs}
	  			\\usepackage{hyperref}
	  			\\hypersetup{
	  				colorlinks=true,
	  				linkcolor=blue,
	  				filecolor=magenta,
	  				urlcolor=blue,
	  			}\n
	  			\\urlstyle{same}\n
	  			\\DeclareGraphicsExtensions{.eps, .jpg, .png, .jpeg}
	  			\\newcommand{\\tabitem}{~~\\llap{\\textbullet}~~}
	  			\\usepackage[protrusion = true,final]{microtype}\n
	  			\\setlength{\\emergencystretch}{10pt}\n\n
	  			\\title{` + document.getElementById("name").value + "}" +
	  			`\\hypersetup{pageanchor=false}
				\\setlength\\parskip{1em}\n
				\\begin{document}\n
				\\maketitle\n
				\\newpage\n
				\\thispagestyle{empty}\n
	  			\n
	  			\\newpage\n
	  			\\setcounter{page}{1}\n`;

		footer = '\\end{document}';
	}else if(template_id == 4){
		
		header = document.querySelector('.start').value;
		footer = document.querySelector('.end').value;
	}
}

function download_file(){

	let editor_content;
	if(is_visual_editor){
		remove_mathjax();
		
		editor_content = visual_editor.get_text();
		
		editor_content = (new html2tedi()).convert(editor_content);
		
		array_b64_images = visual_editor.get_images_b64();
		
		reload_mathjax();
	}else
		editor_content = code_editor.get_text_code();
	
	if(array_b64_images.length == 0)
		array_b64_images = visual_editor.get_images_b64();

	editor_content = editor_content.replace(/&lt;/g, "<");
	editor_content = editor_content.replace(/&gt;/g, ">");
	editor_content = editor_content.replace(/&nbsp;/g, " ");
	generate(editor_content, array_b64_images);
}

function drop(e){
	let files = e.dataTransfer.files;
	if(files[0].type === "application/zip"){
		load_file(files[0]);
	}
}

function generate(text, b64_images, index_filename = "index.te") {

	var zip = new JSZip();
	zip.file(index_filename, text);
	var array_length = b64_images.length;
	for(var i = 0; i < array_length; ++i){
		var b64 = b64_images[i].search("base64");
		var buf = atob(b64_images[i].substring(b64 + 7, b64_images[i].length));
		zip.file("image" + i, b64_images[i].substring(b64 + 7, b64_images[i].length), {base64: true});
	}
	zip.generateAsync({type:"blob"})
	.then(function(content) {
		const title = document.getElementById('title');
		if(url_canonical != "" && document.getElementById('save-api').checked){
			let formData = new FormData();
			formData.append("fileToUpload", new File([content], title.innerText + ".zip"));
			formData.append("token", document.getElementById('api-token').value);

			let xhr = new XMLHttpRequest();
			xhr.open('POST', url_canonical, true);
			xhr.send(formData);
		}else{
			saveAs(content, title.innerText + ".zip");
		}
	});
}

function load_file(file){
	let zip = new JSZip();
	set_loading_file_popup_visibility(true);
	zip.loadAsync(file).then(function(contents) {
		var zip_files_count = Object.keys(contents.files).length;
		var e = 0;
		var index_file = false;
		Object.keys(contents.files).forEach(function(filename) {
			if(filename == "index.te"){
				zip.file(filename).async('string').then(function(file_content) {

					let s = file_content;
					s = s.replace(/&nbsp;/g, " ");
					s = s.replace(/</g, "&lt;");
					s = s.replace(/>/g, "&gt;");
					code_editor.set_text_code(s);
					index_file = true;
					e += 1;
				
					if(e == zip_files_count){
						if(!index_file)
							fail_found("<br>Couldn't load uploaded file correctly");

						let text = code_editor.get_text_code();
						text = (new tedi2html()).convert(text);
						visual_editor.set_images_b64(array_b64_images);
						visual_editor.set_text(text);
						if(is_visual_editor)
							reload_mathjax();
							
						change_input();
						set_loading_file_popup_visibility(false);
					}
				});
			}else{
				zip.file(filename).async('base64').then(function(file_content) {
					var file_content_text = atob(file_content);
					let position = 5;
					if(isNaN(parseInt(filename.substring(position, filename.length))))
						position = 6;
					let image_num = parseInt(filename.substring(position, filename.length));
					if(/%!PS-Adobe-3.0/.test(file_content_text)){
						array_b64_images[image_num] = "data:image/x-eps;base64," + file_content;
						
					}else if(/<dc:format>image\/svg\+xml<\/dc:format>/.test(file_content_text) ||
						/<svg/.test(file_content_text)){
						
						array_b64_images[image_num] = "data:image/svg+xml;base64," + file_content;
					}else{
						array_b64_images[image_num] = "data:image/jpeg;base64," + file_content;
					}
					
					e += 1;
						
					if(e == zip_files_count){
						if(!index_file)
							fail_found("<br>Couldn't load uploaded file correctly");

						let text = code_editor.get_text_code();
						text = (new tedi2html()).convert(text);
						visual_editor.set_images_b64(array_b64_images);
						visual_editor.set_text(text);
						if(is_visual_editor)
							reload_mathjax();
						change_input();
						set_loading_file_popup_visibility(false);
					}
				});
			}
		});
	}, function(error) {
		fail_found("<br>Couldn't load uploaded file" . error);
		set_loading_file_popup_visibility(false);
	});
}

function set_collab(){
	if(!is_collab){
		var script = document.createElement("script");
		script.src = "js/togetherjs.js";
		script.id = "tjs-js";
		document.head.appendChild(script);
		setTimeout(set_togetherjs, 1000);
		is_collab = true;
		let tjs = document.getElementsByClassName('tjs');
		for(let i = 0; i < tjs.length; ++i)
			tjs[i].style.display = 'flex';
	}
}

function set_mathjax(){
	if(is_mathjax){
		try{
			remove_mathjax();
		}catch(e){}
		
		is_mathjax = false;
	}else{
		is_mathjax = true;
		reload_mathjax();
	}
}

function set_togetherjs(){
		
		TogetherJSConfig_hubBase = "https://togetherjs-hub.glitch.me/";
		TogetherJs_enableAnalytics = false;
		TogetherJSConfig_disableWebRTC = true;
		TogetherJSConfig_youtube = false;
		TogetherJSConfig_ignoreForms = true;
		TogetherJSConfig_dontShowClicks = true;
		TogetherJS.hub.on("text-send", function (msg) {
			if(!msg.sameUrl) {
				return;
			}
			document.getElementById('visual-editor').innerHTML = msg.output;
			log_text(msg.output);
		});
		let element = document.getElementById('visual-editor');
		element.addEventListener('keyup', function (event) {
			// grab text for sending as a message to collaborate
			var sharedtext = element.innerHTML;

			if(TogetherJS.running) {
				TogetherJS.send({
					type: "text-send",
					output: sharedtext
				});
				log_text(sharedtext);
			}
		});
}

function editor2pdf(){
	let s = "";

	if(is_visual_editor){
		let pdf_icon = visual_editor.element.querySelector('.pdf');
		pdf_icon.style.display = "none";
		let pdf_disabled_icon =  visual_editor.element.querySelector('.pdf-disabled');
		pdf_disabled_icon.style.display = "flex";
		s = visual_editor.get_text();
		array_b64_images = visual_editor.get_images_b64();
		
		s = (new html2tedi()).convert(s);
		
	} else {
		s = code_editor.get_text();
	}
	s = s.replace(/&lt;/g, "<");
	s = s.replace(/&gt;/g, ">");

	s = (new tedi2tex()).convert(s, header, footer);
	s = s.replace(/&amp;/g, "&");
	var httpRequest = new XMLHttpRequest();

	httpRequest.onreadystatechange = function (data) {
		
		if(httpRequest.readyState == 4) {
			if(httpRequest.status == 200){
				var pdf_icon = document.querySelector('.pdf');
				pdf_icon.style.display = "flex";
				var pdf_disabled_icon = document.querySelector('.pdf-disabled');
				pdf_disabled_icon.style.display = "none";
				var options = {disablePageMode: true};
				if(!PDFObject.supportsPDFs){
				
					let downloadLink = document.createElement("a");

					downloadLink.href = "data:application/pdf;base64," + JSON.parse(httpRequest.response).content;
					downloadLink.download = Math.floor(Date.now() / 1000) + ".pdf";
					downloadLink.click();
					
				}else{

					PDFObject.embed("data:application/pdf;base64," + JSON.parse(httpRequest.response).content, "#pdf", options);
					document.querySelector("#pdf").style.display = "flex";
					document.querySelector(".close_pdf").style.display = "flex";
				}
			}else if(httpRequest.status == 0){

				let pdf_icon = visual_editor.element.querySelector('.pdf');
				window.print();

			}else{
				fail_found(JSON.parse(httpRequest.response).er);
				let pdf_icon = visual_editor.element.querySelector('.pdf');
				pdf_icon.style.display = "flex";
				let pdf_disabled_icon =  visual_editor.element.querySelector('.pdf-disabled');
				pdf_disabled_icon.style.display = "none";
			}

		}
	};
	httpRequest.open('POST', api_address);
	httpRequest.setRequestHeader('Content-Type', 'application/json');

	let data = {'content': s , 'images_array':  array_b64_images };

	httpRequest.send(JSON.stringify(data));
}

function close_pdf_viewer(){
	document.querySelector("#pdf").style.display = "none";
	document.querySelector(".close_pdf").style.display = "none";
}

function select_bookmark(element_text, header_number, header_position){
	if(is_visual_editor){
		let a = document.getElementById("visual-editor").querySelector(".visual-editor").querySelectorAll("div > h" + header_number);
		let selection = window.getSelection();
		let range = document.createRange();
		if(element_text.includes(a[header_position].innerText)){
			
			if(!visual_editor.is_scrolled_into_view(a[header_position]))
				a[header_position].scrollIntoView();
			range.selectNode(a[header_position]);

			selection.removeAllRanges();
			selection.addRange(range);
		}
	}else{
		let a = document.getElementById("code-editor").querySelector(".visual-editor").querySelectorAll("div");
		let selection = window.getSelection();
		let range = document.createRange();
		for(let i = 0; i < a.length; ++i){
			if(a[i].innerText.length > 0 && element_text.length > 0){
				if(a[i].innerText.includes(element_text)){
					
					if(!code_editor.is_scrolled_into_view(a[i]))
						a[i].scrollIntoView();
					range.selectNode(a[i]);

					selection.removeAllRanges();
					selection.addRange(range);
				}
			}
		}
	}
}

function insert_bookmark(text, element_name, number){

	var p = document.querySelector(".bookmark-links");
	var link = document.createElement("a");
	link.appendChild(document.createTextNode(text));
	link.setAttribute("onclick", "select_bookmark('" + text + "'," + element_name + ", " + number + ")");
	link.setAttribute("class", "header" + element_name);
	
	p.appendChild(link);
	p.appendChild(document.createElement("br"));
	
}

function export_markdown(){

	let editor_content;
	if(is_visual_editor){
		editor_content = visual_editor.get_text();
		
		editor_content = (new html2tedi()).convert(editor_content);
		
		array_b64_images = visual_editor.get_images_b64();
	}else
		editor_content = code_editor.get_text_code();
	
	editor_content = editor_content.replace(/&lt;/g, "<");
	editor_content = editor_content.replace(/&gt;/g, ">");
	editor_content = editor_content.replace(/&nbsp;/g, " ");
	
	editor_content = (new tedi2md()).convert(editor_content);
	
	if(array_b64_images.length == 0)
		array_b64_images = visual_editor.get_images_b64();

	editor_content = editor_content.replace(/&lt;/g, "<");
	editor_content = editor_content.replace(/&gt;/g, ">");
	editor_content = editor_content.replace(/&nbsp;/g, " ");
	generate(editor_content, array_b64_images, "index.md");
}

function set_bookmarks(text){
	let p = document.querySelector('.bookmark-links');
	p.innerHTML = "";
	if(is_visual_editor){

		let position = text.regexIndexOf("<h");
		let position_end = text.regexIndexOf("</h");
		let titles_number = [0,0,0];
		while(position != -1 && position_end != -1){
			let level = text[position + 2];
			text = text.erase(position, 4);
			position_end = text.regexIndexOf("</h");
			text = text.erase(position_end, 5);
			
			insert_bookmark(text.substring(position, position_end), parseInt(level), titles_number[parseInt(level) - 1]);
			titles_number[parseInt(level) - 1] += 1;
			position = text.regexIndexOf("<h");
			position_end = text.regexIndexOf("</h");
		}
	}else{
		let position = text.regexIndexOf("#");
		let position_end = text.regexIndexOf("</div>", position);
		while(position != -1){

			insert_bookmark(text.substring(position, position_end));
			
			position = text.regexIndexOf("#", position_end);
			position_end = text.regexIndexOf("</div>", position);
			
		}
	}
}
