/* globals d3, OpenSeadragon, intLegend, intPlot, geneFilters */
var OsViewer;

// eslint-disable-next-line no-unused-vars
function interactionPlot(id, settings, data) {
	if (typeof settings.nodeSize === 'undefined') {
		settings.nodeSize = 20;
	}
	if (typeof settings.width === 'undefined') {
		settings.width = 940;
	}
	if (typeof settings.height === 'undefined') {
		settings.height = 650;
	}
	if (typeof settings.showLabels === 'undefined') {
		settings.showLabels = true;
	}
	if (typeof settings.passive === 'undefined') {
		settings.passive = false;
	}

	var plot = {};
	plot.svg = d3.select('#' + id)
		.append('svg')
		.attr('width', settings.width)
		.attr('height', settings.height);

	plot.link = plot.svg
		.append('g')
		.attr('class', 'link');

	plot.node = plot.svg
		.append('g')
		.attr('class', 'nodecontainer'+ (settings.passive?' passive':''));

	plot.addData = function(inData, idx) {
		if (!inData || !inData.nodes) {
			return;
		}
		var p = this;

		var nodes = p.node.selectAll('g')
			.data(inData.nodes, function(d) { return d.id; })
			.enter()
			.append('g')
			.attr('transform', function (d) { return 'translate(' + d.x + ',' + d.y + ')'; })
			.attr('cx', function (d) { return d.x; })
			.attr('cy', function (d) { return d.y; })
			.attr('id', function (d) { return d.id; })
			.attr('class', function (d) { return d.class + ' ' + idx; });

		if (!settings.passive) {
			nodes.call(d3.drag().on('drag', function () {
					nudge(p, d3.select(this), d3.event);
				}));
		}

		p.links = p.link.selectAll('line')
			.data(inData.links, function(d) { return d.class; })
			.enter()
			.append('line')
			.attr('x1', function (d) { return p.node.select('#'+d.source).attr('cx'); })
			.attr('y1', function (d) { return p.node.select('#'+d.source).attr('cy'); })
			.attr('x2', function (d) { return p.node.select('#'+d.target).attr('cx'); })
			.attr('y2', function (d) { return p.node.select('#'+d.target).attr('cy'); })
			.attr('title', function (d) { return d.title; })
			.attr('class', function (d) { return d.class + ' ' + idx; });

		var anchor = nodes.append('a')
			.attr('xlink:href', function (d) { return d.url; })
			.attr('title', function (d) { return d.title; })
			.on('mouseover', function(d) {
				d3.selectAll('.'+d.id)
					.classed('highlight', true);
			}).on('mouseout', function() {
				d3.selectAll('g.link line').classed('highlight', false);
			});

		anchor.append('circle')
			.attr('r', settings.nodeSize);

		if (settings.showLabels) {
			anchor.append('text')
				.each(function (d) {
					var arr = d.name.split(' ');
					if (arr !== undefined) {
						for (var i = 0; i < arr.length; i++) {
							d3.select(this).append('tspan')
									.text(arr[i])
									.attr('dy', 0.35.toPrecision(3) + 'em')
									.attr('x', '-0.5');
						}
					}
				});
		}
	};
	plot.removeData = function(idx) {
		var p = this;
		p.svg.selectAll('.'+idx).remove();
	};
	if (typeof data !== 'undefined') {
		plot.addData(data, 'idx1');
	}
	return plot;
}

// eslint-disable-next-line no-unused-vars
function interactionPlotLegend(id, nodeSize, width, height) {
	if (typeof nodeSize === 'undefined') {
		nodeSize = 8;
	}
	if (typeof width === 'undefined') {
		width = 200;
	}
	if (typeof height === 'undefined') {
		height = 220;
	}

	var legend = {};
	legend.svg = d3.select('#' + id)
			.append('svg')
			.attr('width', width)
			.attr('height', height);
	var links = [
		{name: 'Matching filter', type: 'circle', class: 'filterMatch'},
		/*{name: 'IntAct BioGrid OpenCell', type: 'line', class: 'int_intact_biogrid_opencell'},
		{name: 'IntAct BioGrid', type: 'line', class: 'int_intact_biogrid'},
		{name: 'IntAct OpenCell', type: 'line', class: 'int_intact_opencell'},
		{name: 'BioGrid OpenCell', type: 'line', class: 'int_biogrid_opencell'},*/
		{name: '4 datasets', type: 'line', class: 'int_count_4'},
		{name: '3 datasets', type: 'line', class: 'int_count_3'},
		{name: '2 datasets', type: 'line', class: 'int_count_2'},
		{name: '1 dataset', type: 'line', class: 'int_count_1'},
	];
	legend.general = legend.svg
			.append('g')
			.attr('class', 'general')
			.attr('transform', 'translate(4, '+(height-(links.length)*2*nodeSize)+')');
	legend.highlight = legend.svg
			.append('g')
			.attr('class', 'highlight')
			.attr('transform', 'translate(4, 0)');

	legend.updateLegend = function(data, lgnd) {
		lgnd.selectAll('g.lgndItem').remove();
		var lgndItem = lgnd.selectAll('g')
				.data(data)
				.enter()
				.append('g')
				.attr('class', 'lgndItem')
				.attr('transform', function (d, i) { return 'translate(0, '+((i)*nodeSize*2+10)+')'; });

		lgndItem.each(function(d) {
			d3.select(this)
					.append('text')
					.attr('dy', 0.5 + 'em')
					.attr('x', nodeSize*2 + 4)
					.text(d.name)
					.call(D3wrap, width-10);
			if (d.type === 'line') {
				d3.select(this)
					.append('line')
					.attr('x1', 0)
					.attr('y1', 2)
					.attr('x2', nodeSize*2)
					.attr('y2', 2)
					.attr('title', function (dThis) { return dThis.name; })
					.attr('class', function (dThis) { return dThis.class; });
			} else if (d.type === 'circle') {
				d3.select(this).append('circle')
					.attr('r', nodeSize)
					.attr('cx', nodeSize)
					.attr('title', function (dThis) { return dThis.name; })
					.attr('class', function (dThis) { return dThis.class??null; })
					.style('fill', function (dThis) { return dThis.fill??null; })
					.style('stroke', function (dThis) { return dThis.stroke??null; });
			}
		});
	};

	legend.updateLegend(links, legend.general);
	return legend;
}
function nudge(plot, el, ev) {
	el
		.attr('transform', function(d) {
			d.x = parseFloat(d.x) + Math.round(ev.dx, 0);
			d.y = parseFloat(d.y) + Math.round(ev.dy, 0);
			return 'translate(' + d.x + ',' + d.y + ')';
		})
		.attr('cx', function(d) { return parseFloat(d.x) + Math.round(ev.dx, 0); })
		.attr('cy', function(d) { return parseFloat(d.y) + Math.round(ev.dy, 0); });

	plot.svg.selectAll('g.link line').each(function(d) {
		if (d.source === el.attr('id')) {
			d3.select(this)
				.attr('x1', el.attr('cx'))
				.attr('y1', el.attr('cy'));
		}
		if (d.target === el.attr('id')) {
			d3.select(this)
					.attr('x2', el.attr('cx'))
					.attr('y2', el.attr('cy'));
		}
	});
	if (d3.event.preventDefault) {
		d3.event.preventDefault();
	} else {
		d3.event.returnValue = false;
	}
	$(el.node()).closest('.cytoscapeplot_interaction').trigger('change');
}

function filterInteractionGenes() {
	$('.cytoscapeplot_interaction circle').removeClass('filterMatch');
	$.each(geneFilters.genes, function(i, gene) {
		$('.cytoscapeplot_interaction #int'+gene+' circle').addClass('filterMatch');
	});
}

function highlightInteractionGenes(id, highlight) {
	var $el = $('#'+id).closest('.cytoscapeplot_interaction');
	if (!highlight) highlight = $el.closest('.interactionWrapper').find('.slideToggle').find('.active').attr('id');
	if (highlight == 'highlight_off') {
		clearInteractionHighlight(id);
		return;
	}
	var ensgs = [];
	$el.find('.nodecontainer g').each(function() { ensgs.push(this.id.replace('int', '')); });
	$.getJSON({
		url: '/interaction/interaction_ajax.php',
		data: {
			highlight: highlight,
			gene: $el.find('.nodecontainer g.centerGene').attr('id').replace('int', ''),
			ensgs: ensgs.join(','),
		}
	}).done(function (data) {
		clearInteractionHighlight(id);
		$.each(data.genes, function(gene, fill) {
			$el.find('#int'+gene+' circle').css('fill', fill);
		});
		filterInteractionGenes();
		var l = $el.data('intLegend');
		if (l) l.updateLegend(data.lgnd, l.highlight);
	});
}
function clearInteractionHighlight(id) {
	var $el = $('#'+id).closest('.cytoscapeplot_interaction');
	$el.find('.nodecontainer g circle').css('fill', '');
	var l = $el.data('intLegend');
	if (l) l.updateLegend([], l.highlight);
}

function attemptInteractionFullscreen() {
	const element = $(this).closest('.interactionWrapper')[0];
	if (!document.fullscreenElement) {
		element.dataset.originalWidth = element.clientWidth.toString();
		element.dataset.originalHeight = element.clientHeight.toString();
	}
	if (element.requestFullscreen) {
		element.requestFullscreen();
	} else if (element.mozRequestFullScreen) {
		element.mozRequestFullScreen();
	} else if (element.webkitRequestFullscreen) {
		element.webkitRequestFullscreen();
	} else if (element.msRequestFullscreen) {
		element.msRequestFullscreen();
	} else {
		throw new Error('Cannot open fullscreen');
	}
}


$(function() {
	$('#filterGenes').on('change', filterInteractionGenes);
	$('.slideToggle').on('toggle', function() {$(this).closest('.interactionWrapper').find('.cytoscapeplot_interaction').trigger('highlightGenes');});
	$('.interactionFullscreen').on('click', attemptInteractionFullscreen);
	$('.interactionReset').on('click', function() {$(this).closest('.interactionWrapper').find('.cytoscapeplot_interaction').trigger('reset');});
	$('.cytoscapeplot_interaction').on('change', function() {
		$(this).closest('.interactionWrapper').find('.interactionReset').show();
	});

	$('.cytoscapeplot_interaction').on('click', 'a', function (evt, force) {
		if (evt.ctrlKey) {
			return true;
		}
		if ($(this).closest('.nodecontainer').hasClass('passive')) {
			return true;
		}
		var $g = $(this).closest('g');
		if (!force && $g.hasClass('centerGene')) {
			return false;
		}
		if ($g.attr('id')) {
			var el = $(this).closest('.cytoscapeplot_interaction');
			var p = el.data('intPlot');
			if (!$g.attr('idx')) {
				$.getJSON({
					url: '/interaction/interaction_ajax.php',
					data: {
						ensg_id: $g.attr('id').replace('int', ''),
						assay_id: $g.closest('.cytoscapeplot_interaction').attr('id').replace('intPlot', ''),
						cx: $g.attr('cx'),
						cy: $g.attr('cy'),
					}
				}).done(function (data) {
					var idx = 'idx'+Math.floor(Math.random() * 26) + Date.now();
					$g.addClass('expanded').attr('idx', idx);
					var fromIdx = $g.attr('class').match(/idx\d+/g);
					if (fromIdx) {
						idx += ' '+fromIdx.join(' ');
					}
					p.addData(data, idx);
					filterInteractionGenes();
					el.trigger('highlightGenes');
					$g.closest('.cytoscapeplot_interaction').trigger('change');
				});
			} else {
				p.removeData($g.attr('idx'));
				$g.attr('idx', null);
			}
		}
		return false;
	});

	$('.cytoscapeplot_interaction').on('highlightGenes', function(evt, highlight) {
		highlightInteractionGenes(evt.target.id, highlight);
	});
	$('.cytoscapeplot_interaction').on('clearHighlight', function(evt) {
		clearInteractionHighlight(evt.target.id);
	});
	$('.cytoscapeplot_interaction').on('reset', function() {
		var $g = $(this).find('.centerGene');
		if (!$g.attr('idx')) {
			$g.attr('idx', 'idx1');
		}
		$g.removeClass('idx1').find('a').trigger('click', true).trigger('click', true);
	});

	// METABOLIC DETAILS
	$('#metabolic_detail').each(function() {
		var $table = $(this);
		if (!$(this).find('#pathwaySeadragon').length) return;
		// Seadragon
		OsViewer = OpenSeadragon({
			id:	"pathwaySeadragon",
			prefixUrl: "/images_static/",
			preserveViewport: true,
			showHomeControl: false,
			mouseNavEnabled: true,
			showZoomControl: true,
			showFullPageControl: true,
			gestureSettingsMouse: { dblClickToZoom: true, clickToZoom: false },
		});
		$.get($(this).find('#pathwaySeadragon').attr('src'), function(svg) {
			var $svg = $(svg);
			var ensg_id = $table.attr('ensg_id');
			$svg.find('g.subsystem text').remove();
			// Load seadragon
			var org_w = 1*$svg.attr('width');
			var org_h = 1*$svg.attr('height');
			var tSize = 1000;
			OsViewer.open({
				width: org_w,
				tileSource: {
					height: org_h,
					width: org_w,
					tileSize: tSize,
					getTileUrl: function() {
						return '/images_static/pixel.php?w='+tSize+'&h='+tSize;
					}
				}
			});
			// Add SVG overlays
			var overlay = OsViewer.svgOverlay();
			$svg.children().each(function() {
				overlay.node().appendChild(this);
			});
			// Add pointers for toobox buttons & gene labels
			$("div[title='Zoom in']").css({'cursor': 'pointer'});
			$("div[title='Zoom out']").css({'cursor': 'pointer'});
			$("div[title='Toggle full page']").css({'cursor': 'pointer'});
			$('g.enz').css({'cursor': 'pointer'});
			// Navigate to gene page on gene label click
			$('g.enz').click(function() {
				window.location.href = '/'+$(this).attr('class').match(/ENSG\d+/)[0]+'/interaction';
			});
			// Highlight current
			$('g.'+ensg_id).addClass('pathwayCurrent');
			// Zoom to links
			$('tr.enz .pathwayLinks a').on("click", function() {
				var this_ensg_id = $(this).closest('tr').attr('class').match(/ENSG\d+/)[0];
				var $gs = $('g.'+this_ensg_id);
				var idx = $(this).parent().data('idx');
				if (typeof idx === 'undefined') {
					idx = 0;
				} else {
					idx += $(this).hasClass('next')? 1 : -1;
				}
				if (idx < 0) {
					idx = $gs.length-1;
				} else if (idx > $gs.length-1) {
					idx = 0;
				}
				$(this).parent().data('idx', idx);
				var $g = $gs.eq(idx);
				var x = $g.offset().left - $g.closest('svg').offset().left;
				var y = $g.offset().top - $g.closest('svg').offset().top;
				OsViewer.viewport.panTo(OsViewer.viewport.viewerElementToViewportCoordinates(new OpenSeadragon.Point(x, y)), false);
				OsViewer.viewport.zoomTo(0.0007);
				return false;
			});
			// Hover highlight
			$('tr.enz, g.enz').on("mouseover", function() {
				$('.'+$(this).attr('class').match(/ENSG\d+/)[0]).addClass('pathwayHighlight');
			}).on("mouseout", function() {
				$('.'+$(this).attr('class').match(/ENSG\d+/)[0]).removeClass('pathwayHighlight');
			});
			$('tr.enz').find('td:gt(1)').on("mouseover", function() {
				$(this).closest('table').find('tbody tr td:nth-child('+($(this).index()+1)+')').addClass('pathwayHighlight');
			}).on("mouseout", function() {
				$(this).closest('table').find('tbody tr td:nth-child('+($(this).index()+1)+')').removeClass('pathwayHighlight');
			});
		}, 'text');
	});
});