/* globals OpenSeadragon, SVG */
var ajax_url = '';
var strokeWidth = 2;
var fontSize = 12;
var zoomPadd = 40;
$(function() {
	if (!$('#markers').length) {
		return;
	}
	// Create markers
	var markers = [
		//{attr: { id: 'marker_circle', refX: 0, refY:0, viewBox: '-6 -6 12 12', markerUnits: 'strokeWidth' }, path: 'M 0, 0  m -5, 0  a 5,5 0 1,0 10,0  a 5,5 0 1,0 -10,0'},
		//{attr: { id: 'marker_square', refX: 0, refY:0, viewBox: '-5 -5 10 10', markerUnits: 'strokeWidth' }, path: 'M 0,0 m -5,-5 L 5,-5 L 5,5 L -5,5 Z'}, 
		{attr: { id: 'marker_arrow', refX: 5, refY:0, viewBox: '-5 -5 10 10', markerUnits: 'strokeWidth', orient: 'auto' }, path: 'M 5 5 L -5 0 L 5 -5 Z' },
		{attr: { id: 'marker_stub', refX: 0, refY:0, viewBox: '-1 -5 2 10', markerUnits: 'strokeWidth' }, path: 'M 0,0 m -1,-5 L 1,-5 L 1,5 L -1,5 Z' }
	];
	var mrkrs = SVG('markers').size(0, 0);
	$.each(markers, function(k, m) {
		mrkrs.marker(5, 5, function(add) {
			add.path(m.path);
		}).attr(m.attr);
	});
	// Show image
	$('#anatomy a, #examples a, #expression a').on('click', function() {
		$(this).closest('.menufix').find('.selected').removeClass('selected');
		$(this).addClass('selected');
	});
	$(window).on('hashchange', function() {
		var $link = !window.location.hash? $('#examples a:first') : $('a[href="'+window.location.hash+'"]:first');
		if ($link.length) {
			$link.trigger('click');
			$.get(ajax_url+'&get_img='+$link.attr('id').replace('img_', ''), showImageWrapper, 'json');
		}
	}).trigger('hashchange');
	
	// Toggle channels
	$('body').on('click', '.channel_form button', function() {
		$(this).toggleClass('channel_inactive');
		$.get(ajax_url+'&get_img='+$('#image_id').val()+'&channels='+getDictionaryChannels(), function(response) {
			var vwr = getViewer();
			vwrOpen(vwr, response);
		}, 'json');
		return false;
	});
	// Annotation list actions
	$('.annot_div').on('click', 'a', annotationListAction);
	// Update text_div
	$('.text_div').on('updateText', updateText);
	// Click on annotation in image
	$('#img_div').on('click', 'g.annotation text', function() {
		var id = $(this).closest('g.annotation').attr('id');
		$('div[name="#'+id+'"] a.label').trigger('click');
	});
});
var current_image_type = '';
function showImageWrapper(response) {
	if (response.type === 'zarr') {
		$('#osdViewerWrapper').hide();
		$('#codexViewerWrapper').show();
		showImageZarr(response);
	} else {
		$('#osdViewerWrapper').show();
		$('#codexViewerWrapper').hide();
		showImage(response);
	}

}

function showImageZarr(response) {
	// Check if previous viwer exists & reset containers
	var imgDiv = $('#avivator_root').get(0);
	imgDiv.dataset.src = location.origin + '/' + response.url;
	imgDiv.channels = response.metadata.channels;
	$('#text_div').data('text_url', '').trigger('updateText');
	if (response && response.controls) {
		$('#control_div').html(response.controls);
	}
	if (imgDiv.avivatorLoaded) {
		const event = new CustomEvent('changeImage', {detail: {url: imgDiv.dataset.src, channels: imgDiv.channels}});
		imgDiv.dispatchEvent(event);
	} else {
		window.runAvivator(imgDiv.id, imgDiv.dataset.src, imgDiv.channels);
		imgDiv.avivatorLoaded = true;
	}
	$(imgDiv).data({
		'dictionary': response.dictionary,
		'entry': response.entry
	});
}
function showImage(response) {
	// Check if previous viwer exists & reset containers
	var vwr = getViewer();
	if (vwr) {
		vwr.destroy();
		vwr = null;
	}
	$('#img_div').html('');
	$('#control_div').html('');
	$('#text_div').data('text_url', '').trigger('updateText');
	updateAnnotationList(vwr);
	if (response && response.controls) {
		$('#control_div').html(response.controls);
	}
	// Check if image is still in processing
	if (response && response.type == 'processing') {
		$('#img_div').html('Image still processing, please try again later.');
		return;
	}
	else if (response && response.type == 'plain_image') {
		$('#img_div').html('<img src="'+response.url+'">');
		return;
	}
	// Create openseadragon
	vwr = OpenSeadragon({
		id: 'img_div',
		showHomeControl: false,
		showZoomControl: true,
		showFullPageControl: true,
		navigatorPosition: 'ABSOLUTE',
		navigatorTop: 35,
		navigatorLeft: 5,
		navigatorHeight: 120,
		navigatorWidth: 120,
		showNavigator: true,
		navigatorSizeRatio: 0.1,
		navigatorMaintainSizeRatio: true,
		maxZoomPixelRatio: 1,
		prefixUrl: "/images_static/",
	});
	$('#img_div').data({'viewer':vwr, 'dictionary':response.dictionary, 'entry':response.entry});
	if (response && response.type && response.url) {
		vwrOpen(vwr, response);
		// Add SVG overlay
		vwr.overlay = vwr.svgOverlay();
		$(vwr.overlay.node()).parent().attr('id', 'SVGoverlay').addClass('SVGoverlay');
		vwr.drawing = SVG.get('SVGoverlay');
		vwr.gDrawing = vwr.drawing.select('g').first();
		vwr.activeExample = null;
		// Zoom & Pan handler
		vwr.addHandler('animation', function(e) {
			var vwr = e.eventSource;
			var scale = vwr.gDrawing.transform().scaleX;
			var zoom = vwr.viewport.getZoom()/vwr.viewport.getMaxZoom();
			// Show/hide depending on zoom
			vwr.gDrawing.select('g.annotation').each(function() {
				if (this.attr().zoom > zoom && !$('#ignore_zoom_dependent_display:checked').length) {
					this.hide();
				} else {
					this.show();
				}
			});
			// Scale annot elements
			vwr.gDrawing.select('[stroke-width]').attr('stroke-width', strokeWidth/scale);
			// Scale and position text
			vwr.gDrawing.select('g.annotation text').each(function() {
				var tb = this.bbox();
				var ta = this.attr();
				var vpSize = getSeadragonPoint(vwr, tb.width, tb.height, true);
				var padX = 0.5*vpSize.y;
				var padY = 0.1*vpSize.y;
				var tx = ta.x;
				var bx = ta.x;
				var ty = ta.y + vpSize.y/1.5 + padY;
				var by = ta.y - padY;
				if (ta['text-anchor']=='start') {
					tx += padX/2;
				}
				else if (ta['text-anchor']=='end') {
					bx -= vpSize.x + padX;
					tx -= padX/2;
				}
				else if (ta['text-anchor']=='middle') {
					bx -= vpSize.x/2 + padX;
				}
				if (ta['type'] == 'arrow' || ta['type'] == 'section') {
					ty -= vpSize.y/2;
					by -= vpSize.y/2;
				}
				// text
				this.attr('transform', 'translate('+tx+', '+ty+') scale('+(1/scale)+')');
				// background
				var txtBox = this.parent().select('.txtBox').first();
				txtBox.attr({'x':bx, 'y':by, 'width':(vpSize.x+2*padX), 'height':(vpSize.y+2*padY)/*, 'rx':(0.2*vpSize.y), 'ry':(0.2*vpSize.y)*/});
			});
		});
		// Use annotation list in full screen mode
		vwr.addHandler('pre-full-page', function(e) {
			if (e.fullPage) {
				var $div = $('<div></div>');
				$('.seadragonMeta').each(function() {
					$(this).data('parent', $(this).parent());
					$div.append($(this));
				});
				vwr.addControl($div[0], {anchor: OpenSeadragon.ControlAnchor.TOP_LEFT});
				vwr.navigator.element.parentNode.style.width = ($('#annot_div').outerWidth()-4)+'px';
			}
		});
		vwr.addHandler('full-screen', function(e) {
			if (!e.fullScreen) {
				$('.seadragonMeta').each(function() {
					$(this).appendTo($(this).data('parent'));
				});
				vwr.navigator.element.parentNode.style.width = '120px';
				vwr.navigator.element.parentNode.style.width = '120px';
			}
			vwr.raiseEvent('animation');
		});
		// Marking if vwr is in animation (used to wait with channel toggle until animation is finished)
		vwr.addHandler('animation-start', function(e) {
			vwr.inAnimation = true;
		});
		vwr.addHandler('animation-finish', function(e) {
			vwr.inAnimation = false;
		});
		// Go to saved zoom and pan on open (used when toggling channel in IF)
		vwr.addHandler('open', function(e) {
			if (vwr.zoom) {
				vwr.viewport.zoomTo(vwr.zoom, vwr.center, true);
			}
			if (vwr.center) {
				vwr.viewport.panTo(vwr.center, true);
			}
		});
		// Add custom controls to seadragon
		var $div = $('<div></div>');
		$('.seadragonControl').each(function() {
			$div.append($(this));
		});
		vwr.addControl($div[0], {anchor: OpenSeadragon.ControlAnchor.ABSOLUTE});
	}
	$("div[title='Zoom in']").css({'cursor':'pointer'});
	$("div[title='Zoom out']").css({'cursor':'pointer'});
	$("div[title='Toggle full page']").css({'cursor':'pointer'});
	if (response && response.annotations) {
		$.each(response.annotations.annotations, function(k, annotation) {
			vwr.gDrawing.svg(annotation);
		});
		vwr.gDrawing.select('g.active').removeClass('active');
		updateAnnotationList(vwr);
		vwr.raiseEvent('animation');
		
	}
}
function goToAnnotation(vwr, annotation) {
	var ra, webPoint;
	var aa = annotation.attr();
	vwr.viewport.panTo(new OpenSeadragon.Point(aa.x, aa.y), false);
	var zoom = aa.zoom*vwr.viewport.getMaxZoom();
	if (aa.type=='rect') {
		ra = annotation.select('rect').first().attr();
		webPoint = getSeadragonPoint(vwr, ra.width, ra.height, true, true);
		zoom = Math.min((vwr.viewport.containerSize.x-zoomPadd) / webPoint.x, (vwr.viewport.containerSize.y-zoomPadd) / webPoint.y);
		zoom = vwr.viewport.imageToViewportZoom(zoom);
	}
	else if (aa.type == 'circle') {
		ra = annotation.select('circle').first().attr();
		webPoint = getSeadragonPoint(vwr, 2*ra.r, 0, true, true);
		zoom = Math.min((vwr.viewport.containerSize.x-zoomPadd) / webPoint.x, (vwr.viewport.containerSize.y-zoomPadd) / webPoint.x);
		zoom = vwr.viewport.imageToViewportZoom(zoom);
	}
	else if (aa.type == 'ellipse') {
		ra = annotation.select('ellipse').first().attr();
		webPoint = getSeadragonPoint(vwr, 2*ra.rx, 2*ra.ry, true, true);
		zoom = Math.min((vwr.viewport.containerSize.x-zoomPadd) / webPoint.x, (vwr.viewport.containerSize.y-zoomPadd) / webPoint.y);
		zoom = vwr.viewport.imageToViewportZoom(zoom);
	}
	vwr.viewport.zoomTo(Math.min(zoom, vwr.viewport.getMaxZoom()));
}
function updateAnnotationList(vwr) {
	var $annot_div = $('#annot_div').html('');
	if (vwr) {
		$(vwr.gDrawing.node).find('>g.example').each(function(k, example) {
			listAnnotation(vwr, $annot_div, $(example));
		});
		if (!vwr.activeExample) {
			setTimeout(function() { $annot_div.find('a[href="#goto"]:first').trigger('click'); }, 250);
		}
	}
}
function listAnnotation(vwr, $parent_div, $g) {
	var txt = $g.find('>text').html();
	var id = $g.attr('id');
	var eyeClass = ($g.hasClass('hidden') || $g.parents('.hidden').length || (!$g.hasClass('example') && $g.parent().hasClass('dic_hidden')))? 'fa-eye-slash' : 'fa-eye';
	var $div = $('<div></div>').attr({'name':'#'+id}).addClass($g.hasClass('annotation')?'annotation':'example').appendTo($parent_div);
	if (vwr.activeExample && vwr.activeExample.attr('id') == id) {
		$div.addClass('active');
	}
	$('<a></a>').attr({'href':'#toggle', 'class':'fa '+eyeClass, 'title':'Toggle display'}).appendTo($div)/*.trigger('click')*/;
	$('<a></a>').attr({'href':'#goto', 'class':'label'}).html(txt?txt:'<i>region</i>').appendTo($div);
	if ($g.hasClass('example')) {
		$parent_div = $div;
	}
	// List all sub examples and annotations
	$g.find('>g.annotation, >g.example').each(function(k, annotation) {
		listAnnotation(vwr, $parent_div, $(annotation));
	});
}
function annotationListAction() {
	var vwr = getViewer();
	var annotation = vwr.gDrawing.select($(this).closest('div').attr('name')).first();
	//activateExample(vwr);
	if ($(this).attr('href') == '#goto') {
		vwr.activeExample = vwr.gDrawing.select($(this).closest('div.example').attr('name')).first();
		activateExample(vwr);
		goToAnnotation(vwr, annotation);
		var name = encodeURIComponent(vwr.activeExample.select('text').first().text());
		var markdown_name = encodeURIComponent(getMarkdownName(vwr.activeExample.attr('id')));
		var name2 = encodeURIComponent(annotation.select('text').first().text());
		var markdown_name2 = (annotation.attr('id') == vwr.activeExample.attr('id'))? '' : encodeURIComponent(getMarkdownName(annotation.attr('id')));
		$('#text_div').data('text_url', ajax_url+'&name='+name+'&markdown_name='+markdown_name+'&name2='+name2+'&markdown_name2='+markdown_name2).trigger('updateText');
		updateAnnotationList(vwr);
	}
	else if ($(this).attr('href') == '#toggle') {
		annotation.toggleClass('hidden');
		toggleAnnotation(annotation, annotation.hasClass("hidden"));
		updateAnnotationList(vwr);
	}
	else if ($(this).attr('href') == '#edit') {
		var txt = annotation.select('text').first();
		var newTxt = prompt("Please enter annotation description", txt.text());
		if (typeof newTxt == 'string') {
			txt.plain(newTxt);
			saveAnnotations();
			vwr.raiseEvent('animation');
		}
	}
	else if ($(this).attr('href') == '#markdown') {
		var win = window.open('markdown.php?markdown_name='+getMarkdownName($(this).closest('div').attr('name').replace('#', '')), 'editMarkdown', 'width=1000,height=700,resizable=1,scrollbars=1');
	}
	/*else if ($(this).attr('href') == '#resize') {
		vwr.setMouseNavEnabled(false);
		var line = annotation.select('line').first();
		line
		console.log(line);
		line.selectize().resize();
	}*/
	else if ($(this).attr('href') == '#moveUp') {
		annotation.backward();
		saveAnnotations();
	}
	else if ($(this).attr('href') == '#delete') {
		if (confirm('Delete annotation?')) {
			annotation.remove();
			saveAnnotations();
		}
	}
	return false;
}

function toggleAnnotation(annotation, hide) {
	annotation.select("g.annotation, g.example").each(function(k, elems) {
		var elem = elems[k];
		if (hide) {
			elem.addClass("hidden");
		} else {
			elem.removeClass("hidden");
		}
	});
	if (!hide) {
		annotation.parents("g.example, g.annotation").forEach(function (elem) {
			elem.removeClass("hidden");
		});
	}
}
function updateText() {
	var url;
	if (url = $(this).data('text_url')) {
		$(this).load(url);
	}
	else {
		$(this).html('');
	}
}
function activateExample(vwr) {
	if (vwr.activeExample.hasClass('active')) {
		return;
	}
	vwr.gDrawing.select('g.example').removeClass('active').addClass('hidden');
	$(vwr.activeExample.node).addClass('active').removeClass('hidden').removeClass('dic_hidden');
	$(vwr.activeExample.node).parents('g.example').removeClass('hidden').addClass('dic_hidden');
	$(vwr.activeExample.node).find('g.example').removeClass('hidden').removeClass('dic_hidden');
	if ($(vwr.activeExample.node).attr('channels')) {
		var channels = $(vwr.activeExample.node).attr('channels').split('_');
		$('.channel_form button').addClass('channel_inactive');
		for (var i=0; i<channels.length; i++) {
			if (i < channels.length-1) {
				$('.channel_form button[name="'+channels[i]+'"]').removeClass('channel_inactive');
			}
			else {
				$('.channel_form button[name="'+channels[i]+'"]').trigger('click');
			}
		}
	}
	//$('#annot_div div.example').removeClass('active');
	//$('#annot_div div.example[name="#'+vwr.activeExample.attr('id')+'"').addClass('active').find('>.fa-eye-slash').removeClass('fa-eye-slash').addClass('fa-eye');
}
var thumbRequest = null;
function setHomePosition() {
	var vwr = getViewer();
	if (!vwr.activeExample) {
		alert('No active example, please create or select one.');
		return false;
	}
	var center = vwr.viewport.getCenter(true);
	var viewportBounds = vwr.viewport.getBounds(true);
	var imagePoint1 = vwr.viewport.viewportToImageCoordinates(new OpenSeadragon.Point(viewportBounds.x, viewportBounds.y));
	var imagePoint2 = vwr.viewport.viewportToImageCoordinates(new OpenSeadragon.Point(viewportBounds.x+viewportBounds.width, viewportBounds.y+viewportBounds.height));
	var data = {
		'zoom': vwr.viewport.getZoom()/vwr.viewport.getMaxZoom(),
		'x': center.x,
		'y': center.y,
		'crop_x1': Math.round(imagePoint1.x),
		'crop_y1': Math.round(imagePoint1.y),
		'crop_x2': Math.round(imagePoint2.x),
		'crop_y2': Math.round(imagePoint2.y),
		'channels': getDictionaryChannels()
	};
	vwr.activeExample.attr(data);
	/*data.crop_image_id = $('#image_id').val();
	if (thumbRequest) thumbRequest.abort();
	thumbRequest = $.ajax({
		type: "POST",
		url: ajax_url,
		data: data,
		success: function(data) {
			console.log('thumb done');
			vwr.activeExample.attr({'thumbnail':data});
			saveAnnotations();
		}
	});*/
	saveAnnotations();
	return false;
}

var saveRequest = null;
function saveAnnotations() {
	var vwr = getViewer();
	var data = {'save_image_id': $('#image_id').val(), 'image_name':$('.control_div input#image_name').val(), 'description':$('.control_div input#description').val(), 'data':{}};
	if (vwr) {
		data.data.annotations = [];
		vwr.gDrawing.each(function() {
			data.data.annotations.push(this.svg());
		});
	}
	if (saveRequest) {
		saveRequest.abort();
	}
	saveRequest = $.ajax({
		type: "POST",
		url: ajax_url,
		data: data,
		dataType: 'json',
		success: function(data) {
			updateAnnotationList(vwr);
			$('#table_div tr.selected td.annotations').html(data.thumbnail_blob + $(vwr.gDrawing.node).find('g.annotation').length);
		}
	});
}
function getViewer() {
	return $('#img_div').data('viewer');
}
function vwrOpen(vwr, response) {
	// Wait for ongoning animation before switching images
	if (vwr.inAnimation) {
		setTimeout(function() {
			vwrOpen(vwr, response);
		}, 100);
		return;
	}
	vwr.center = vwr.viewport.getCenter(true);
	vwr.zoom = vwr.viewport.getZoom();
	if (response.type == 'dzi') {
		vwr.open(response.url);
	}
	else {
		vwr.open({type:response.type, url:response.url});
	}
}
function getMarkdownName(id) {
	return '/learn/dictionary/'+$('#img_div').data('dictionary')+'/'+$('#img_div').data('entry')+'/'+$('#image_id').val()+'/'+id;
}
function getDictionaryChannels() {
	var channels = [];
	$.each(['blue', 'red', 'green', 'yellow'], function(k, channel) {
		if ($('.channel_form').find('button[name='+channel+']:not(.channel_inactive)').length) {
			channels.push(channel);
		}
	});
	return channels.join('_');
}

function getSeadragonPoint(vwr, x, y, relativeZero, toImg) {
	var fromPoint = new OpenSeadragon.Point(x*1, y*1);
	var toPoint = toImg? vwr.viewport.viewportToImageCoordinates(fromPoint) : vwr.viewport.pointFromPixel(fromPoint);
	if (relativeZero) {
		var zeroPoint = getSeadragonPoint(vwr, 0, 0, false, toImg);
		toPoint.x -= zeroPoint.x;
		toPoint.y -= zeroPoint.y;
	}
	return toPoint;
}