$(function () {

    function createImg(src) {
        var $img = $('<img />')
        $img.attr("src", src);
        $img.attr("class", "my-img-thumbnail pointer to-delete");
        $img.on("click", function (){
            showimage(src);
        });
        return $img;
	}
    $(".to-add").on("dragend", function (e) {

        var src = $(e.target).attr("src");
        if (images.indexOf(src) < 0) {

			images.push(src);

			var $img = createImg(src);
			$img.on("dragend", function (e) {
				var src = $(e.target).attr("src");
				var idx = images.indexOf(src);
				if (idx >= 0) {
					images.splice(idx, 1);
				}

				$(e.target).remove();
			});


			$("#new-report-img").append($img)
		}
    });



	$('.sup-collapse').click(function () {
		var dupTitle = $(this).parents('li').find('.sup-title');
		dupTitle.toggle();
	});

	//SVG
	var svg = d3.select("svg"),
	    width = +svg.attr("width"),
	    height = +svg.attr("height");

	var color = {
		1: '#E36402',
		2: '#1995CF',
		6 : '#FFC000',
		2.1: '#FFC000'
		// 1: '#CB8E01',
		// 2: '#7E511C',
		// // 2: '#1B80B2',
		// 2.1: '#1B80B2',
		// 6: '#9C4858'
	};

	var simulation = d3.forceSimulation()
	    .force("link", d3.forceLink().id(function(d) { return d.id; }))
	    .force("charge", d3.forceManyBody().strength(-200))
	    .force("center", d3.forceCenter(width / 2 - 10, height / 2 - 20));

    var urlParams = new URLSearchParams(window.location.search);
	d3.json("/graph?masterId=" + urlParams.get("masterId"), function(error, graph) {
	  if (error) throw error;

	  var defs = svg.append("defs");

	  var dropShadowFilter = defs.append('svg:filter')
	      .attr('id', 'dropShadow')
		  .attr('filterUnits', "userSpaceOnUse")
		  .attr('width', '150%')
		  .attr('height', '150%');
	    dropShadowFilter.append('svg:feGaussianBlur')
	      .attr('in', 'SourceGraphic') 
	      .attr('stdDeviation', 3)
	      .attr('result', 'blur'); 
	   //  dropShadowFilter.append('svg:feColorMatrix')
	   //    .attr('in', 'blur-out') 
		  // .attr('type', 'hueRotate')
		  // .attr('values', 30)	
	   //    .attr('result', 'color-out'); 
	   //  dropShadowFilter.append('svg:feOffset')
		  // .attr('in', 'color-out')
	   //    .attr('dx', 2)
	   //    .attr('dy', 2)
	   //    .attr('result', 'the-shadow');
	   //  dropShadowFilter.append('svg:feBlend')
	   //    .attr('in', 'SourceGraphic')
	   //    .attr('in2', 'the-shadow')
		  // .attr('mode', 'normal');

	  let link = svg.append("g")
	      .attr("class", "links")
	    .selectAll("line")
	    .data(graph.links)
	    .enter().append("line")
	      .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

	  let node = svg.append("g")
	      .attr("class", "nodes")
	    .selectAll("g")
	    .data(graph.nodes)
	    .enter().append("g")
	      .attr("class", "node")
	      .on("mouseover", nodemouseover)
	      .on("mouseout", nodemouseout)
	      .on("click", nodeclick)
	      .on("dblclick", nodedblclick);


	  let circle = node.append("circle")
		      .attr("r", function(d) { return 40/d.group; })
		      .attr("fill", function(d) { return color[d.group]; })
		      .style("stroke", function(d) { return color[d.group]; })
		      .style("filter", "url(#dropShadow)")
		      .call(d3.drag()
		          .on("start", dragstarted)
		          .on("drag", dragged)
		          .on("end", dragended));

	  let label = node.append("text")
	  	  	.attr("dy", ".35em")
	  	  	.text(function(d) { return d.name; });

	  var marker = svg.append('marker')
		  .attr('id', 'arrowhead')
		  .attr('refX', 12) // Controls the shift of the arrow head along the path
		  .attr('refY', 2)
		  .attr('markerWidth', 6)
		  .attr('markerHeight', 4)
		  .attr('orient', 'auto')
		  .attr('fill', '#509AE5')
		  .append('path')
		    .attr('d', 'M 0,0 V 4 L6,2 Z');
	  
	  link.attr('marker-end', 'url()');

	  simulation
	      .nodes(graph.nodes)
	      .on("tick", ticked);

	  simulation.force("link")
	      .links(graph.links);

	  function offsetEdge(d) {
	  	var sourceSize = 47/d.source.group;
	  	var targetSize = 47/d.target.group;

	  	var sourceCirc = sourceSize * 2 * Math.PI;
	  	var targetCirc = targetSize * 2 * Math.PI;
	  	var stRatio = sourceCirc/targetCirc;

	  	var diffX = d.target.y - d.source.y;
	  	var diffY = d.target.x - d.source.x;

	  	var angle0 = ( Math.atan2( diffY, diffX ) + ( Math.PI / 2 ) );
	  	var angle1 = angle0 + ( (Math.PI * 0.75) + (3 * 0.25) );
	  	var angle2 = angle0 + ( (Math.PI * 0.25) - (3 * 0.25) );

	  	var x1 = d.source.x + (sourceSize * Math.cos(angle1));
	  	var y1 = d.source.y - (sourceSize * Math.sin(angle1));
	  	var x2 = d.target.x + (targetSize * Math.cos(angle2));
	  	var y2 = d.target.y - (targetSize * Math.sin(angle2));

	  	return {x1: x1, y1: y1, x2: x2, y2: y2};
	  }

	  function ticked() {

	    link
	        .attr("x1", function(d) { return offsetEdge(d).x1; })
	        .attr("y1", function(d) { return offsetEdge(d).y1; })
	        .attr("x2", function(d) { return offsetEdge(d).x2; })
	        .attr("y2", function(d) { return offsetEdge(d).y2; });

	    circle
	        .attr("cx", function(d) { return d.x; })
	        .attr("cy", function(d) { return d.y; });

	    label
	    	.attr("x", function(d) { return d.x + 8; })
	    	.attr("y", function(d) { return d.y; });
	  }

	  let linkedByIndex = {};
	  graph.links.forEach((d) => {
	    linkedByIndex[`${d.source.index},${d.target.index}`] = true;
	  });

	  function isConnected(a, b) {
	    return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) || a.index === b.index;
	  }

	  function isConnectedAsSource(a, b) {
	    return linkedByIndex[`${a.index},${b.index}`];
	  }

	  function isConnectedAsTarget(a, b) {
	    return linkedByIndex[`${b.index},${a.index}`];
	  }

	  function isEqual(a, b) {
	    return a.index === b.index;
	  }

	  function nodeclick(d) {

			circle.transition()
		      .duration(750)
		      .attr("r", function(d) { return 47/d.group; })
		      .style("filter", null);

		    node
		      .transition(500)
		      .style('opacity', o => {
		      	const isConnectedValue = isConnected(o, d);
		      	if (isConnectedValue) {
		      		return 1.0;
		      	}
		      	return 0.2;
		      })
		      .style("filter", o => {
		      	const isConnectedValue = isConnected(o, d);
		      	if (isConnectedValue) {
		      		return null;
		      	}
		      	return 'url(#dropShadow)';
		      });

		    link
		      .transition(500)
		      .style('stroke-opacity', o => (o.source === d || o.target === d ? 1 : 0.2))
		      .transition(500)
		      .attr('marker-end', o => (o.source === d || o.target === d ? 'url(#arrowhead)' : 'url()'));


		    $.get(
              d.href,
              function (data) {
                  $('.detail-div').css('background-color', 'white');
                  $('.detail-div').html(data);
              }
          )

		}

		function nodedblclick(d) {

			circle.transition()
		      .duration(750)
		      .attr("r", function(d) { return 47/d.group; })
		      .style("filter", "url(#dropShadow)");

		    node
		      .transition(500)
		      .style("filter", "url(#dropShadow)");

		    link
		      .transition(500);
		}

		function nodemouseover(d) {
			circle.transition()
		      .duration(750)
		      .attr("r", function(d) { return 55/d.group; });
		}

		function nodemouseout(d) {
		}
	});

	function dragstarted(d) {
	  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
	  d.fx = d.x;
	  d.fy = d.y;
	}

	function dragged(d) {
	  d.fx = d3.event.x;
	  d.fy = d3.event.y;
	}

	function dragended(d) {
	  if (!d3.event.active) simulation.alphaTarget(0);
	  d.fx = null;
	  d.fy = null;
	}
});