/*
	This script replicates the functionality of the GT-statement in QSP.

	In QSP, you can have several jumps in a row after each user-input without a hazzle.
	That's not the case in SugarCube.
	Since the first passage doesn't stop rendering when the second one is called the output is scrambled.
	For the user, that usually looks like a black- or whitescreen.

	To solve this issue, gt-commands are only excecuted once a passage is completely rendered.
	To achieve that, they get queued in `pendingGTs` and called on the `:passageend`-event.
*/


/**
 * Indicates the number of currently running gt-commands.
 * Gets reset to 0 on the `:passageend`-event.
 * Since multiple running gt-events are to be avoided, a number bigger than 1 indicates a bug.
 * @type {number}
 */
let gtExecutionCounter = 0;


/**
 * The queued gt-events (FIFO). One entry is the array of arguments the gt-command has to be executed with.
 * @type {(string|number)[]}
 */
const pendingGTs = [];


/** Execute the next gt-command from `pendingGTs` if the queue is not empty. */
const executeNextPendingGT = ()=>{
	if(!pendingGTs.length)
		return;
	const nextPendingGT = pendingGTs.shift();
	setup.qsp_gt(...nextPendingGT);
}

$(document).on(':passageend', function (ev) {
	gtExecutionCounter = 0;
	executeNextPendingGT();
});





setup.qsp_gt = function(...args){
	if(++gtExecutionCounter > 1){
		pendingGTs.push(args);
		return;
	}

	const _recursion_limit = 5;

	setup.recursionCounterGT ??= [0,0];
	const recursionInterval = Math.floor(Date.now() / 500);
	if(setup.recursionCounterGT[0] < recursionInterval)
		setup.recursionCounterGT = [recursionInterval,0];
	setup.recursionCounterGT[1] += 1;
	if(setup.recursionCounterGT[1] > _recursion_limit){
		console.error('Recursion limit reached in GT: (args, here)',args,State.variables.here);
		return;
	}

	let destination = '';
	let destinationArgs = [];

	if(typeof args[0] == 'string'){
		destination = args[0];
		destinationArgs = args.slice(1);
	}else if(Array.isArray(args[0])){
		destination = args[0][0];
		destinationArgs = args[0].slice(1);
	}else{
		console.error(`Argument not reckognized in setup.gt()`,args[0]);
	}



	State.variables.ARGSstack = [destinationArgs];

	console.log("GT",args,destination,destinationArgs,State.variables.ARGSstack);

	Engine.play(destination.toLowerCase());
}

Macro.add('gt', {
	skipArgs : false,
	handler  : function () {
		try{
			setup.qsp_gt(...this.args);
		}
		catch (ex) {
			return this.error('ERROR in gt-widget: ' + ex.message);
		}
	}
});
