// Create a new directed graph
global = {};
var init = function() {
	initFile();
	$.ajax({
		url : "./CMManager",
		data : {
			"action" : "getControlFlowByFileName",
			"path" : "A2.yjs"
		},
		dataType : "jsonp"
	}).done(function(result) {
		// console.log(result);
		global.r = result;
		drawMethod(global.r.sub);
	});
	$('#tabdiv').editableSelect({
		filter : false
	});
	$("#tabdiv").on('select.editable-select', function(e) {
		switchProject();
	});
	$('#tabdiv').addClass("ui-selectmenu-button");
	$('#tabdiv').addClass("ui-selectmenu-button-closedn");
	$('#tabdiv').addClass("ui-corner-all");
	$('#tabdiv').addClass("ui-button");
	$('#tabdiv').addClass("ui-widget");
};
var initFile = function() {
	var prefix = "ws://";
	if (document.location.href.startsWith("https"))
		prefix = "wss://";
	url = prefix
			+ document.location.host
			+ (document.location.pathname.replace("contractflowchart.html",
					"SCExecutor"));

	var wssocket = new WebSocket(url);
	// console.log("[ideapi.js] wssocket的url = " + url);
	global.filewssocket = wssocket;
	wssocket.onerror = function(error) {
		console.log(error);
	};
	wssocket.onopen = function(error) {
		var pingObj = {};
		pingObj.action = "ping";
		wssocket.send(JSON.stringify(pingObj));
		listProjects();
	};
	wssocket.onmessage = FileHandler;
};
var listProjects = function(off) {
	console.log("[ideapi.js] listProjects : ");
	var pingObj = {};
	pingObj.action = "listProjects";
	global.filewssocket.send(JSON.stringify(pingObj));
}

var FileHandler = function(event) {
	console.log("[ideapi.js] FileHandler : ");
	// console.log(event);
	data = event.data;
	// console.log("   -->" + data);
	try {
		var obj = JSON.parse(data);
		switch (obj.action) {
		case 'ping':
			// console.log("[ideapi.js] FileHandler case 'ping' : ");
		case 'poing':
			break;
		case 'onListProjects':
			onListProjects(obj);
			break;
		default:
			logComm(obj);
			break;
		}
	} catch (err) {
		console.log(err);
	}

};
var logComm = function(obj) {
	console.log(obj);
};
var switchProject = function() {
	var fileName = $("#tabdiv")[0].value;
	if (fileName != global.lastProject) {
		global.lastProject = fileName;
	} else
		return;
	// console.log("[FileName, switch] " + fileName);
	$.ajax({
		url : "./CMManager",
		data : {
			"action" : "getControlFlowByFileName",
			"path" : fileName
		},
		dataType : "jsonp"
	}).done(function(result) {
		// console.log(result);
		global.r = result;
		for ( var k in global.r) {
			drawMethod(global.r[k]);
			break;
		}
	});
	$("#tabdiv").on('select.editable-select', function(e) {
		switchProject();
	});
}
var onListProjects = function(obj) {
	var data = JSON.parse(obj.data);
	global.projects = data;
	$("#tabdiv").editableSelect('clear');
	// $("#tabdiv").html("");
	global.contractName2ID = {};
	for (var i = 0; i < data.length; i++) {
		$("#tabdiv").editableSelect('add', data[i]);
	}
	if (data.length > 0)
		$("#tabdiv").editableSelect()[0].value = data[0];
};
var drawMethod = function(method) {
	var states = {};
	for (var i = 0; i < method.blocks.length; i++) {
		var block = method.blocks[i];
		var desp = {};
		desp.description = stmt2Str(block.stmts);
		desp.description += "<br/>" + block.original;
		// console.log(desp.description);
		if (block.type != "Continuous")
			desp.fill = "#f77";
		states[block.name] = desp;
	}
	drawCFGraph(states, method.edges);
};
var stmt2Str = function(l) {
	var str = "";
	for (var i = 0; i < l.length; i++)
		str += "<span style='text-overflow:ellipsis'>"
				+ l[i].replace(/\//g, ".") + "</span>" + "<br/>";
	return str;
}

var drawCFGraph = function(states, edges) {
	var g = new dagreD3.graphlib.Graph().setGraph({});
	// Add states to the graph, set labels, and style
	Object.keys(states).forEach(function(state) {
		var value = states[state];
		value.label = state;
		value.rx = value.ry = 5;
		g.setNode(state, value);
	});
	for (var i = 0; i < edges.length; i++)
		g.setEdge(edges[i].from, edges[i].to, edges[i].label);
	// Set up the edges

	// Create the renderer
	var render = new dagreD3.render();
	$("svg").html("");
	// var width = $("svg").width();
	// $("svg").css("width", width);

	// Set up an SVG group so that we can translate the final graph.
	var svg = d3.select("svg"), inner = svg.append("g");

	// Set up zoom support
	var zoom = d3.zoom().on("zoom", function() {
		inner.attr("transform", d3.event.transform);
	});
	svg.call(zoom);

	// Simple function to style the tooltip for the given node.
	var styleTooltip = function(name, description) {
		return "<p class='name'>" + name + "</p><p class='description'>"
				+ description + "</p>";
	};

	// Run the renderer. This is what draws the final graph.
	render(inner, g);

	inner.selectAll("g.node").attr("title", function(v) {
		return styleTooltip(v, g.node(v).description)
	}).each(function(v) {
		$(this).tipsy({
			gravity : "w",
			opacity : 1,
			html : true
		});
	});
	var initialScale = 0.75;

    var tWidth = (svg._groups[0][0].clientWidth  - g.graph().width * initialScale) / 2; //水平居中

	// Center the graph
	svg.call(zoom.transform, d3.zoomIdentity.translate(tWidth, 20)
			.scale(initialScale));

	svg.attr('height', g.graph().height * initialScale + 40);
}
