/* ===================================
		GESTION DES JETONS
	=================================== */
function enableTokenSelection(opt=null) {
	trace(`Enable token selection (option: ${opt})`, 1);
	// Parcours des cases contenant des jetons pour les rendre sélectionnables et ajouter le listener
	const selectableTokens = game.tokens.filter(obj => obj.slot=='C');
	selectableTokens.forEach(token => {
		const elmToken = document.getElementById('T'+token.tokenID);
		switch(opt) {
			case 'one':
				document.getElementById('message').textContent = 'Prends un jeton'
				elmToken.classList.add((token.color!='gold')? 'selectable' : 'unselectable');
				if(token.color!='gold') elmToken.setAttribute('onclick', 'selectToken(this)');
				break;
			case 'gold':
				document.getElementById('message').textContent = 'Prends un jeton Or'
				elmToken.classList.add((token.color=='gold')? 'selectable' : 'unselectable');
				if(token.color=='gold') elmToken.setAttribute('onclick', 'selectGoldToken(this)');
				break;
			case 'white':
			case 'blue':
			case 'green':
			case 'red':
			case 'black':
				const colorTranslation = {'white':'Blanc', 'blue':'Bleu', 'green':'Vert', 'red':'Rouge', 'black':'Noir', 'pearl':'Perle', 'gold':'Or'}
				document.getElementById('message').textContent = `Prends un jeton ${colorTranslation[opt]} sur le plateau`;
				elmToken.classList.add((token.color==opt)? 'selectable' : 'unselectable');
				if(token.color==opt) elmToken.setAttribute('onclick', 'selectColoredToken(this)');
				break;
			default:
				document.getElementById('message').textContent = 'Désigne le premier jeton de ta sélection'
				elmToken.classList.add((token.color!='gold')? 'selectable' : 'unselectable');
				if(token.color!='gold') elmToken.setAttribute('onclick', 'selectFirstToken(this)');
		}
	});
}

function enableTokenTheft() {
	document.getElementById('message').textContent = 'Prends un jeton à ton adversaire';
	const opponentTokenSlotList = document.querySelectorAll('#opponentDeck #tokens .tokenPlayerSlot');
	opponentTokenSlotList.forEach(elmSlot => {
		const elmTokenList = elmSlot.querySelectorAll('.token');
		if(elmTokenList.length>0) {
			const elmToken = elmTokenList[elmTokenList.length-1];
			if(elmToken.dataset.color!='gold') {
				elmToken.classList.add('selectable');
				elmToken.setAttribute('onclick','selectTokenForTheft(this)');
			}
		}
	});
}

function selectTokenForTheft(elmToken) {
	const token = game.tokens.findByID(elmToken.dataset.id).moveToSlot(game.player.tag()).report();
	sendInfo(`te vole un jeton`);
	restoreBoard();
	concludeTransaction(true);
}

function selectFirstToken(elmToken) {
	document.getElementById('message').textContent = 'Désigne le dernier jeton de ta sélection'
	// Suppression de l'état sélectionnable et passage en mode non-sélectionnable
	const tokenOnBoard = game.tokens.filterBySlot('C');
	tokenOnBoard.forEach(token => {
		const divToken = document.getElementById('T'+token.tokenID);
		if(divToken!=elmToken) divToken.classList.remove('selectable');
		if(divToken!=elmToken) divToken.classList.add('unselectable');
		if(divToken!=elmToken) divToken.removeAttribute('onclick'); else divToken.setAttribute('onclick', 'selectLastToken(this)');
	});
	const cell = elmToken.parentNode;
	trace(`Select first token (#${elmToken.id}' in slot $${cell.id} coord: ${cell.dataset.coord}`, 5);
	tkX = parseInt(cell.dataset.coord.at(0));
	tkY = parseInt(cell.dataset.coord.at(2));
	for(let i=0; i<=7*Math.PI/4; i+=Math.PI/4) {
		offsetX = Math.round(Math.sin(i));
		offsetY = Math.round(Math.cos(i));
		for(let j=1; j<=2; j++) {
			trace(` - slot ${tkX+j*offsetX}.${tkY+j*offsetY}`, 8);
			const cell = document.querySelector(`[data-coord="${tkX+j*offsetX}.${tkY+j*offsetY}"]`);
			if(!cell) {
				trace(` ... out of board => break`, 8);
				break;
			}
			const token = cell.firstChild;
			if(token) {
				const imgName = token.firstChild.src;
				if(imgName.endsWith('gold_token.png')) {
					trace(` ... gold => break`, 8);
					break;
				}
				cell.firstChild.classList.remove('unselectable');
				cell.firstChild.classList.add('selectable');
				cell.firstChild.setAttribute('onclick', 'selectLastToken(this)');
			} else {
				trace(` ... empty => break`, 8);
				break;
			}
		}
	}
}
function selectLastToken(elmToken) {
	var cell = elmToken.parentNode;
	trace(`Select token #${elmToken.id} (last) in slot $${cell.id} coord: ${cell.dataset.coord}`, 5);
	const rootX = parseInt(cell.dataset.coord.at(0));
	const rootY = parseInt(cell.dataset.coord.at(2));
	// Nombre de Jetons à sélectionner
	const nToken = Math.max(Math.abs(tkX-rootX), Math.abs(tkY-rootY));
	const tokenList = [];
	// Sélection des Jetons
	var tkColor = ''; var nColor;
	var nPearl = 0; var nColor = 0;
	for(let i=0; i<=nToken; i++) {
		var slot = document.querySelector(`[data-coord="${tkX+i*Math.sign(rootX-tkX)}.${tkY+i*Math.sign(rootY-tkY)}"]`);
		var tokenID = parseInt(slot.firstChild.dataset.id);
      // Mise à jour du token
		const token = game.tokens.find(obj => obj.tokenID==tokenID);
		token.moveToSlot(game.player.tag());
      // Ajout du Jeton dans la liste à communiquer à Node
		tokenList.push(token);
		// Gestion des règles d'attribution d'un Privilège à l'adversaire
		if(!tkColor) tkColor=token.color;
		if(token.color==tkColor) nColor++;
		if(token.color=='pearl') nPearl++;
	}
	// Transmission des Jetons modifiés à Node
	parent.nodeSend(playerLogin, 'Update Data', {'gameID':gameID, 'tokens':tokenList});
	// Attribution éventuelle d'un privilège
	if(nColor==3 || nPearl>=2) givePrivilegeTo(game.player.opponentTag());
	sendInfo(`a pris des jetons`);
	// Rétablissement du plateau des Jeton
	//cancelTokenSelection();
	restoreBoard();
	// Suppression du bouton d'annulation
	disableCancelAction();
   // Fin de tour
   endTurn();
}

function selectToken(elmToken) {
	trace(`Pick Token #${elmToken.dataset.id} with privilege`, 3);
	game.tokens.findByID(elmToken.dataset.id).moveToSlot(game.player.tag()).report();
	sendInfo(`a pris un jetons sur le plateau en échange d'un privilège`);
	// Restitution du Privilège
	restorePrivilege(game.player.tag());
	// Rétablissement du plateau des Jeton
	restoreBoard();
	// Suppression du bouton d'annulation
	disableCancelAction();
}

function selectGoldToken(elmToken) {
	const elmCard = document.querySelector('.card.mark');
	elmCard.classList.remove('mark');
	trace(`Pick Card #${elmCard.dataset.id} and Golden Token #${elmToken.id} for card reserve`, 5);
	// Récupération du Jeton sélectionné et transfert dans le sac
	game.tokens.findByID(elmToken.dataset.id).moveToSlot(game.player.tag()).report();
	// Récupération de la carte sélectionnée et transfert dans la réserve du joueur
	const card = game.cards.findByID(elmCard.dataset.id);
	const slotOrigin = card.slot;
	card.moveToSlot('R'+game.player.tag()).report();
	if(!slotOrigin.startsWith('stack')) reloadCard(card.level);
	sendInfo(`a réservé une carte`);
	// Rétablissement du plateau de jeu
	restoreBoard();
	// fin de tour
	endTurn();
}

function selectColoredToken(elmToken) {
	trace(`Pick Colored Token #${elmToken.id} with card action`, 5);
	game.tokens.findByID(elmToken.dataset.id).moveToSlot(game.player.tag()).report();
	sendInfo(`a pris un jetons sur le plateau grace au bonus de sa carte`);
	// Rétablissement du plateau de jeu
	restoreBoard();
	concludeTransaction(true);
}

function tokenReload() {
	trace(`Reload token`, 1);
	// Collecte des cases vides
	var freeSlot = [];
	for(let i=1; i<=25; i++) {
		const slot = document.getElementById(`S${i}`);
		if(!slot.firstChild) freeSlot.push(i);
	}
	// Jeton à replacer sur le plateau
	const availableTokens = game.tokens.filterBySlot('');
	// Mélange des jetons
	randomize(availableTokens);
	// Tirage des jetons pour les mettre dans les cases vides du plateau
	availableTokens.forEach(token => { token.moveToSlot('C').report(); });
	givePrivilegeTo(game.player.opponentTag());

	game.step = 'mdt';
	sendInfo(`a rechargé le plateau en jetons`);
	playerOptions();
}

/* ===================================
		PROTOTYPES
	=================================== */
// Objet: Liste de Jetons
const tokensPrototype = Object.create(Array.prototype);
tokensPrototype.findByID = function(tokenID) {
	tokenID = parseInt(tokenID);
	return this.find(token => token.tokenID==tokenID);
}
tokensPrototype.filterBySlot = function(slot) {
	return this.filter(token => token.slot==slot);
}
tokensPrototype.report = function() {
	parent.nodeSend(playerLogin, 'Update Data', {'tokens':this});
}

// Objet: Jeton
const tokenPrototype = {
	create: function() { 
		// Création du conteneur
		const container = document.createElement('div');
		container.id = 'T'+this.tokenID;
		container.classList.add('token');
		container.setAttribute('data-id',this.tokenID);
		container.setAttribute('data-color', this.color);
		// Création de l'image
		const img = document.createElement('img');
		img.setAttribute('src', `../images/${this.color}_token.png`);
		img.setAttribute('alt', `T${this.tokenID}`);
		img.classList.add('tokenImage');
		// Ajout de l'image dans la div
		container.appendChild(img);
		// Ajout dans la div 'void'
		document.getElementById('void').appendChild(container);
	},

	display: function() {
		const container = document.getElementById('T'+this.tokenID);
		container.parentNode.removeChild(container);
		if(this.slot=='') var newSlot = document.getElementById(`void`);
		if(this.slot=='A') var newSlot = slotPlayerA('tokens', this.color);
		if(this.slot=='B') var newSlot = slotPlayerB('tokens', this.color);
		if(this.slot=='C') var newSlot = document.getElementById(`S${this.rank}`);
		// Ajustement de la position dans le deck
		const applyOffset = (this.slot=='A' || this.slot=='B');
		if(applyOffset) container.style.top=4-2*(this.rank-1)+'px'; else container.style.top=0;
		if(applyOffset) container.style.left=4-3*(this.rank-1)+'px'; else container.style.left=0;
		// Transfert dans le nouveau slot
		newSlot.appendChild(container);
	},

	moveToSlot: function(slot) {
		if(slot=='C') {
			var inx = 0; let elmSlot;
			do {
				inx++;
				elmSlot = document.getElementById('S'+inx);
			} while (elmSlot.hasChildNodes());
			this.rank = inx;
		} else this.rank=game.tokens.filter(token => token.slot==slot && token.color==this.color).length+1;
		this.slot = slot;
		this.display();
		return this;
	},

	report: function() {
		parent.nodeSend(playerLogin, 'Update Data', {'tokens':[this]});
		return this;
	}
};
