<!DOCTYPE html>
<meta charset="utf-8">
<style>

.node circle {
  fill: #999;
}

.node text {
  font: 10px sans-serif;
}

.node--internal circle {
  fill: #555;
}

.node--internal text {
  text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}

.link {
  fill: none;
  stroke: #555;
  stroke-opacity: 0.4;
  stroke-width: 1.5px;
}

</style>
<svg width="960" height="512"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/acorn/4.0.11/acorn.min.js"></script>
<script>

fetch("../apps/loader/js/main.js")
	.then(response => response.text())
	.then(text => {
		const ast = acorn.parse(text, {
			sourceType: "module",
		    // collect ranges for each node
		    ranges: true,
		    // collect comments in Esprima's format
		    onComment: null,
		    // collect token ranges
		    onToken: null
		})
		
		console.info(ast)

		drawAst(ast)
	})

/*
 *
 */
function drawAst(ast) {
	
	// Create SVG element
	//---------------------------
	let svg = d3.select("svg")
	const width = svg.attr("width")
	const height = svg.attr("height")
	let g = svg.append("g").attr("transform", "translate(40,0)")
	
	// Convert data
	//---------------------------
	const data = acornToHierarchy(ast)
	
	// Create D3 Hierarchy
	//---------------------------
	let root = d3.hierarchy(data).sort((a, b) => {
		return (a.height - b.height) || a.data.name.localeCompare(b.data.name);
	})

	// Create D3 Cluster
	//---------------------------
	let tree = d3.cluster().size([height, width - 200])
	tree(root)
	
	// Create SVG elements
	//---------------------------
	let link = g.selectAll(".link")
		.data(root.descendants().slice(1))
		.enter().append("path")
			.attr("class", "link")
			.attr("d", d => {
				return `M${d.y},${d.x}C${d.parent.y + 100},${d.x} ${d.parent.y + 100},${d.parent.x} ${d.parent.y},${d.parent.x}`
			})
	
	let node = g.selectAll(".node")
		.data(root.descendants())
		.enter().append("g")
			.attr("class", d => "node" + (d.children ? " node--internal" : " node--leaf"))
			.attr("transform", d => `translate(${d.y},${d.x})`)
	
	node.append("circle")
		.attr("r", 5)
	
	node.append("text")
		.attr("dy", 3)
		.attr("x", d => d.children ? -8 : 8)
		.style("text-anchor", d => d.children ? "end" : "start")
		.text(d => d.data.name)
}

/*
 *
 */
function acornToHierarchy(ast) {
	
	console.info(JSON.stringify(ast))
	
	let data = {}
	
	for (const clazz of ast.body) {
		if (clazz.type === "ClassDeclaration") {
			data.name = clazz.id.name
			data.children = []
			
			for (const method of clazz.body.body) {
				if (method.type === "MethodDefinition") {
					data.children.push({
						name: method.key.name,
						children: []
					})
				}
			}
		}
	}
	
	/*
	const data = {
		"name": "Eve",
		"children": [{
			"name": "Cain"
		}, {
			"name": "Seth",
			"children": [{
				"name": "Enos"
			}, {
				"name": "Noam"
			}]
		}, {
			"name": "Abel"
		}, {
			"name": "Awan",
			"children": [{
				"name": "Enoch"
			}]
		}, {
			"name": "Azura"
		}]
	}
	*/
	
	return data
}















</script>