var fs = require('fs');
const exec = require('child_process').exec;


var path = process.argv[2];
var nNodes = +process.argv[3];
var PATH_TO_GENERATED_CONF = __dirname + '/generated_sgct_config.xml';

var WINDOW_SIZE = {x: 640, y: 360};
var WINDOW_COLUMNS = 4;

run();

function run(){
	if(process.argv.length !== 4){
		console.log("Error! Expected 2 arguments:");
		console.log("<path/to/openspace-binary> <# nodes to generate>");
		return;
	}
	if(!path) return new Error("bad path!");
	if(!nNodes) return new Error("bad nNodes!");

	var s = generateConfigSrcForN_nodes();


	fs.writeFile(PATH_TO_GENERATED_CONF, s, function(err) {
	    if(err) {
	        return console.log(err);
	    }

	    console.log("SGCT config generated!");
	    execChildProcesses();
	}); 
}

function execChildProcesses(){
	for (var i = 0; i < nNodes; i++) {
		var cmd = path;
		cmd += " -sgct " + PATH_TO_GENERATED_CONF
		cmd += " -local " + i;
		if(i > 0){
			cmd += " --slave";
		}

		console.log(cmd);
		exec(cmd, function(err, stdout, stderr){
  			if (err) {
    			console.error(err);
    			return;		
    		}
    		console.log(stdout);
    		console.error(stderr);
    	});
	}	
}


function generateConfigSrcForN_nodes(){
	var s = "";
	s += '\
<?xml version="1.0" ?>\n\
<Cluster masterAddress="127.0.0.1" firmSync="false">';
	
	for (var i = 0; i < nNodes; i++) {
		s += generateNode(i);
	}
	
	s += '\n\
	<User eyeSeparation="0.065"> \n\
		<Pos x="0.0" y="0.0" z="4.0" /> \n\
	</User>\n\
</Cluster>';
	
	return s;
}

function generateNode(i){
	var x = 10 + (i%WINDOW_COLUMNS) * (WINDOW_SIZE.x + 5);;
	var y = 30 + Math.floor(i/WINDOW_COLUMNS) * (WINDOW_SIZE.y + 30);
	return '\n\
	<Node address="127.0.0.' + (i+1) + '" port="2040' + (i+1) + '" swapLock="false">\n\
		<Window fullScreen="false">\n\
			<Pos x="'+ x +'" y="' + y + '" />\n\
			<!-- 16:9 aspect ratio -->\n\
			<Size x="' + WINDOW_SIZE.x + '" y="' + WINDOW_SIZE.y + '" />\n\
			<Viewport>\n\
				<Pos x="0.0" y="0.0" />\n\
				<Size x="1.0" y="1.0" />\n\
				<Viewplane>\n\
					<!-- Lower left -->\n\
					<Pos x="-1.778" y="-1.0" z="0.0" />\n\
					<!-- Upper left -->\n\
					<Pos x="-1.778" y="1.0" z="0.0" />\n\
					<!-- Upper right -->\n\
					<Pos x="1.778" y="1.0" z="0.0" />\n\
				</Viewplane>\n\
			</Viewport>\n\
		</Window>\n\
	</Node>';
}

@@ -62,17 +62,44 @@
 .exec;%0A%0A
+var REQUIRED_ARGUMENTS = 2;
 %0A
-
 var path
@@ -149,16 +149,17 @@
 rgv%5B3%5D;%0A
+%0A
 var PATH
@@ -222,16 +222,155 @@
 .xml';%0A%0A
+function argIndexOf(param)%7B%0A%09return process.argv.indexOf(param, REQUIRED_ARGUMENTS+2);%0A%7D%0A%0Avar FIRM_SYNC = argIndexOf(%22--firmsync%22) != -1;%0A%0A
 var WIND
@@ -418,17 +418,17 @@
 LUMNS = 
-4
+2
 ;%0A%0Arun()
@@ -474,13 +474,32 @@
 gth 
-!== 4
+%3C REQUIRED_ARGUMENTS + 2
 )%7B%0A%09
@@ -516,15 +516,8 @@
 og(%22
-Error! 
 Expe
@@ -521,17 +521,51 @@
 xpected 
-2
+at least %22 + REQUIRED_ARGUMENTS + %22
  argumen
@@ -1507,21 +1507,33 @@
 rmSync=%22
-false
+' + FIRM_SYNC + '
 %22%3E';%0A%09%0A%09
@@ -1798,16 +1798,17 @@
 IZE.x + 
+1
 5);;%0A%09va
@@ -1866,17 +1866,17 @@
 IZE.y + 
-3
+4
 0);%0A%09ret

Add firmSync as an option to run_multiple_nodes.js