// *********** HERE STARTS circle-mode.js *************

window.addEventListener("load", initCircleMode);

circleMode = false;

function initCircleMode() {
	document.querySelector("#circle-mode").addEventListener('click', function() {		
		if(circleMode) {
			circleMode = false;
			document.querySelector("#circle-mode i").innerText = "trip_origin";

			s.graph.nodes().forEach(function(n) {
				n.x = n.originalX;
				n.y = n.originalY;
				n.size = 10;
			});
			
			s.refresh();
			
		}
		else {	
			circleMode = true;
			document.querySelector("#circle-mode i").innerText = "shuffle";
			
			s.graph.nodes().forEach(function(n) {
				n.x = n.circleX;
				n.y = n.circleY;		
			});
			
			s.refresh();
		}
	});
}

function isInRect (x, y, rect) {
	if (x < -10000 || x > 10000) return true;
	if (y < -10000 || y > 10000) return true;
	
	var ans = true;
	var c = crossProd (rect[0], rect[1], x, y);
	
	for(var i=1; i<4; i++) {	
		var temp = crossProd (rect[i], rect[(i+1)%4], x, y);
		if (c*temp < 0) ans = false;
	}
	return ans;
}

function crossProd(r1, r2, x, y) {
	return r1[0]*r2[1] + r2[0]*y + x*r1[1] - r1[0]*y - r2[0]*r1[1] - x*r2[1]; 
}


// *********** HERE STARTS graf.js *************

window.addEventListener("load", initGraf);

// s is the sigma graph
// graf is the JSON graph
var s, graf;

// query dario JSON for the graph information
function xhr(method, url, params, callback) {
	var http = new XMLHttpRequest();
	if (method == "POST") {
		http.open(method, url, true);
	} else {
		if (params != "") {
			http.open(method, url+"?"+params, true);
		} else {
			http.open(method, url, true);
		}
	}
	http.onload = function() {
		if(this.status != 200) {
			console.warn("Attention, status code "+this.status+" when loading via xhr url "+url);
		}
		callback(this.responseText, this.status);
	};
	if (method == "POST") {
		http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
		http.send(params);
	} else {
		http.send();
	}
}


function initGraf() {
	// create new methods for sigma library
	updateSigma();
	
	// create graf, s is the sigma graf
	s = new sigma({
		renderers: [{
			container: "graf",
			type: "webgl"
		}],
		settings: {
			defaultEdgeColor: "#fff",
			edgeColor: "default",
			defaultLabelColor: "#fff",
			autoRescale: false,
			zoomMax: 30,
			// enableEdgeHovering: true,
			font: "Roboto",
			labelThreshold: 5
		}
	});

	
	// query for JSON for graph data
	xhr("GET", "api.php", "action=getgraf", function(responseText, status) {
		// graf is the JSON data
		graf = JSON.parse(responseText);

		// does graf.nodes have a size attribute?
		var rectBorrar = [[0,0], [0,0], [0,0], [0,0]];
		for (var i in graf.nodes) {
			if (graf.nodes[i].name == "Erase")    rectBorrar[0] = [ graf.nodes[i].x , graf.nodes[i].y ];
			if (graf.nodes[i].name == "Borrar")   rectBorrar[1] = [ graf.nodes[i].x , graf.nodes[i].y ];
			if (graf.nodes[i].name == "Esborrar") rectBorrar[2] = [ graf.nodes[i].x , graf.nodes[i].y ];
			if (graf.nodes[i].name == "Delete")   rectBorrar[3] = [ graf.nodes[i].x , graf.nodes[i].y ];
		}
		
		var sizegraf = 0;
		for (var i in graf.nodes) {
			if ( isInRect(graf.nodes[i].x, graf.nodes[i].y, rectBorrar) ) continue;	
			sizegraf++;
		}		
		var nnode = 0;
		for (var i in graf.nodes) {
			var ncolor = null;
			
			if(graf.nodes[i].sex =="F") ncolor = "#d61c08";
			else if(graf.nodes[i].sex == "M") ncolor = "#0159aa";
			else ncolor = "#0ca80a";
			
			// post-processing for year corrections
			if(1970 < graf.nodes[i].year && graf.nodes[i].year < 2004) graf.nodes[i].year += 18;
			
			var newX = 5000*Math.cos( 2*Math.PI*nnode/sizegraf );
			var newY = 5000*Math.sin( 2*Math.PI*nnode/sizegraf );	
			
			if (isInRect(graf.nodes[i].x, graf.nodes[i].y, rectBorrar) ) continue;	
			
			s.graph.addNode({
				// we add color, originalColor, size, originalX..Y, circleX..Y atributes
				id: graf.nodes[i].id,
				year: graf.nodes[i].year,
				sex: graf.nodes[i].sex,
				label: graf.nodes[i].name,
				x: graf.nodes[i].x,
				y: graf.nodes[i].y, 
				circleX: newX,
				circleY: newY,
				originalX: graf.nodes[i].x,
				originalY: graf.nodes[i].y, 
				size: 10,
				color: ncolor,
				originalColor: ncolor
			});
			nnode++;
		
		}

		for (var i in graf.edges) {
			if (isInRect(graf.nodes[graf.edges[i].a].x, graf.nodes[graf.edges[i].a].y, rectBorrar)) continue;	
			if (isInRect(graf.nodes[graf.edges[i].b].x, graf.nodes[graf.edges[i].b].y, rectBorrar)) continue;	
			
			s.graph.addEdge({
				id: i,
				source: graf.edges[i].a,
				target: graf.edges[i].b,
				size: Math.min(4, Math.max((7/(2*Math.pow(20, 2)))*Math.pow(graf.edges[i].votes, 2) + 1/2, 0.5))
			});
		
		}

		s.bind('clickNode', function(e) {			
			var nodeId = e.data.node.id,
				toKeep = s.graph.neighbors(nodeId);
				// toKeep[nodeId] = e.data.node;
			
			
			s.graph.nodes().forEach(function(n) {
				if (toKeep[n.id] || n.id == nodeId) {
					n.color = n.originalColor;
				} else {
					n.color = '#333';
				}
			});

			s.graph.edges().forEach(function(e) {
				if ((e.source == nodeId || e.target == nodeId) && (toKeep[e.source] || toKeep[e.target])) {
					e.color = '#fff';
				} else {
					e.color = '#333';
				}
			});
			
			if (circleMode) {
				s.graph.nodes().forEach(function (n) {
					n.x = n.circleX;
					n.y = n.circleY;
					n.size = 10;
				});
				
				e.data.node.x = 0;
				e.data.node.y = 0;
				e.data.node.size = 30;
			}
			
			s.refresh();

			dialog.show(nodeId, toKeep);
		});


		s.refresh();
		initSearchBar();

		autocomplete(document.querySelector("#search-input"), graf.nodes, "search");
	});
}

function updateSigma() {
	// returns set of neighouts
	sigma.classes.graph.addMethod("neighbors", function(nodeId) {
		var k,
		neighbors = {},
		index = this.allNeighborsIndex[nodeId] || [];

		for (k in index) {
			neighbors[k] = this.nodesIndex[k];
		}

		return neighbors;
	});
	
	// returns number of neighbours from a set of years
	sigma.classes.graph.addMethod("numNeighborsFromYears", function(nodeId, showYearsCopy) {
		var k,
		neighbors = 0,
		index = this.allNeighborsIndex[nodeId] || [];

		for (k in index) {
			if(this.nodesIndex){
				if (showYearsCopy.has("" + this.nodesIndex[k].year)) neighbors++;
				else if (this.nodesIndex[k].year == 0) neighbors++;
			}
		}
		
		return neighbors;
	});
}


// *********** HERE STARTS limit-years.js *************

window.addEventListener("load", addYearList);

var limitYears = false;
var showYears = new Set();

function repaint() {
	//targetYear: graf.nodes[e.source].year,
	if(limitYears) {
		var added = new Set();
		
		s.graph.nodes().forEach(function(n) {
			var numNeig = s.graph.numNeighborsFromYears(n.id, showYears);
			
			if ((n.year == 0 && (n.sex == 'F' || n.sex == 'M') )
					|| numNeig == 0
					|| (!showYears.has("" + n.year) && (n.year != 0) )) {
				n.hidden = true;
			}
			else {
				n.hidden = false;
				added.add(n.id);
			}
		});
		
		s.graph.edges().forEach(function(e) {
			if(!added.has(e.source) && !added.has(e.target)){
				e.hidden = true;
			}
			else e.hidden = false;
		}); 
	}
	else {
		s.graph.nodes().forEach(function(n) {
			n.hidden = false;
		});
		
		s.graph.edges().forEach(function(e) {
			e.hidden = false;
		});
	}
}

function altYearList() {
	var yearlist = document.querySelector("#year-list");
	
	if(yearlist.style.display == "none"){
		yearlist.style.display = "block";
		document.querySelector("#settings i").innerText = "close";
		yearLimits = true;
	}
	else{
		yearlist.style.display = "none";
		document.querySelector("#settings i").innerText = "settings";
		yearLimits = true;
	}
}

function addYearList() {	
	var ylistspan = document.querySelector("#year-list-span")
	for(var year=2006; year<2019; year++) {
		var yin = document.createElement("input");
		yin.type = "checkbox";
		yin.class = "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored";
		yin.name = "" + year;
		yin.addEventListener("change", function(){ 
			limitYears = true;
			
			if(this.checked) {
				showYears.add(this.name);
			}
			else {
				showYears.delete(this.name);
			}
			
			if(showYears.size == 0) limitYears = false;
			
			repaint();
			
			s.refresh();
		});
		
		var lab = document.createElement("label");
		lab.innerHTML = "" + year + "<br>";
		
		ylistspan.appendChild(yin);
		ylistspan.appendChild(lab);
	}
	
	document.querySelector("#settings").addEventListener("click", altYearList);
}

// *********** HERE STARTS search-bar.js *************


function altSearchBar() {
	if (document.querySelector(".md-google-search__metacontainer").style.display == "none") {
		document.querySelector(".md-google-search__metacontainer").style.display = "block";
		document.querySelector("#search i").innerText = "fullscreen";
	} else {
		document.querySelector(".md-google-search__metacontainer").style.display = "none";
		document.querySelector(".autocomplete-container").style.display = "none";
		document.querySelector("#search i").innerText = "search";
	}
}

function initSearchBar() {
	document.querySelector("#search").addEventListener("click", altSearchBar);
	if (window.innerWidth > 700) altSearchBar();
}
// *********** HERE STARTS dialog.js *************

window.addEventListener("load", initDialog);

var dialog = {
	fill: function(data, text, html=false) {
		var el = document.querySelectorAll("*[data-fill=\""+data+"\"]");
		for (var i in el) {
			if (html === true) {
				el[i].innerHTML = text;
			} else {
				el[i].innerText = text;
			}
		}
	},
	show: function(id, neighbors) {
		var neighbors = Object.values(neighbors);

		this.fill("name", graf.nodes[id].name);
		this.fill("year", graf.nodes[id].year);
		this.fill("sex", graf.nodes[id].sex);
		this.fill("id", "#"+id);
		this.fill("n-edges", neighbors.length);

		var list = "";
		neighbors.forEach(function (a) {
			list += "<li><b>"+graf.nodes[id].name+" - "+a.label+":</b> "+(graf.edges[id+"_"+a.id] ? graf.edges[id+"_"+a.id].votes : graf.edges[a.id+"_"+id].votes)+" vots</li>";
		});
		this.fill("edges", list, true);

		if (window.innerWidth > 700) {
			document.querySelector("#dialog").style.display = "block";
			document.querySelector("#backdrop-container").style.display = "block";
		} else {
			document.querySelector("#summary-dialog").style.display = "block";
		}
	},
	close: function() {
		document.querySelector("#dialog").style.display = "none";
		document.querySelector("#summary-dialog").style.display = "none";
		document.querySelector("#backdrop-container").style.display = "none";

		s.graph.nodes().forEach(function(n) {
			n.color = n.originalColor;
		});

		s.graph.edges().forEach(function(e) {
			e.color = e.originalColor;
		});

		if(circleMode) {
			s.graph.nodes().forEach(function (n) {
				n.x = n.circleX;
				n.y = n.circleY;
				n.size = 10;
			});
		}
		else {
			s.graph.nodes().forEach(function (n) {
				n.x = n.originalX;
				n.y = n.originalY;
				n.size = 10;
			});
		}
		s.refresh();

	},
	max: function() {
		document.querySelector("#summary-dialog").style.display = "none";
		document.querySelector("#dialog").style.display = "block";
	},
	min: function() {
		document.querySelector("#dialog").style.display = "none";
		document.querySelector("#summary-dialog").style.display = "block";
	}
};


function initDialog() {
	document.querySelector("#quit-dialog").addEventListener("click", dialog.close);
	document.querySelector("#quit2-dialog").addEventListener("click", dialog.close);
	document.querySelector("#max-dialog").addEventListener("click", dialog.max);
	document.querySelector("#min-dialog").addEventListener("click", dialog.min);
}

// *********** HERE STARTS camera.js *************


window.addEventListener('load', initCamera);

function cameraGoto(nodeX, nodeY) {
	sigma.misc.animation.camera( s.camera,
		{ x: nodeX, y: nodeY, ratio: 1 },
		{ duration: s.settings('animationsTime') || 300 }
	);
}

function is_touch_device() {
	  var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
	  var mq = function(query) {
	    return window.matchMedia(query).matches;
	  }

	  if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
	    return true;
	  }

	  // include the 'heartz' as a way to have a non matching MQ to help terminate the join
	  // https://git.io/vznFH
	  var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
	  return mq(query);
}

function initCamera() {
	
	if(!is_touch_device()) {
		
		document.querySelector("#zoomin").addEventListener("click", function() {
			s.camera.goTo({
				ratio: Math.max(s.camera.settings("zoomMin"), s.camera.ratio / Math.sqrt(2))
			});
		});
	
		document.querySelector("#zoomout").addEventListener("click", function() {
			s.camera.goTo({
				ratio: Math.min(s.camera.settings("zoomMax"), s.camera.ratio * Math.sqrt(2))
			});
		});
	}
	else{
		document.querySelector("#zoomin").style.display = "none";
		document.querySelector("#zoomout").style.display = "none";
		
		document.querySelector("#circle-mode").style.bottom = "110px";
		document.querySelector("#settings").style.bottom = "60px";
		document.querySelector("#search").style.bottom = "10px";
	}
}

// *********** HERE STARTS easter-egg.js *************

window.addEventListener("load", initEasterEgg);

var seq = [38, 38, 40, 40, 37, 39, 37, 39, 65, 66, 13];
var cur = 0;

function justdoit() {
	s.graph.nodes().forEach(function(n) {
		switch(n.color) {
			case "#d61c08":
			n.color = "#0159aa";
			break;

			case "#0159aa":
			n.color = "#0ca80a";
			break;

			case "#0ca80a":
			n.color = "#d61c08";
			break;
		}
	});

	s.refresh();
	setTimeout(justdoit, 333);
}


function initEasterEgg() {
	document.addEventListener("keydown", function() {
		if (event.key == "f" && event.target.getAttribute("id") != "search-input") altSearchBar();
		if (event.which == seq[cur]) {
			if (cur < seq.length) {
				++cur;
				if (cur == seq.length) {
					justdoit();
				}
			}
		} else cur = 0;
	});
}
