/* ===================================
		GESTION DES CARTES
	=================================== */
function enableCardReservation() {
	document.getElementById('message').textContent = 'Selectionne la carte à réserver';

	const selectableCards = game.cards.filter(obj => 'XYZ'.includes(obj.slot) && obj.slot!='');
	selectableCards.forEach(card =>{
		elmCard = document.getElementById('C'+card.cardID);
		elmCard.classList.add('selectable');
		elmCard.setAttribute('onclick', 'selectCardToReserve(this)');
	});
	for(let i=1; i<=3; i++) {
		const cSlot = document.getElementById(`stackLevel${i}`);
		const card = cSlot.lastChild;
		if(card) {
			card.classList.add('selectable'); 
			card.setAttribute('onclick', 'selectCardToReserve(this)');
		}
	}
}

function enableCardPurchase() {
	document.getElementById('message').textContent = 'Selectionne la carte à acheter';

	// Evaluation des capacités d'acquisition du joueur
	const playerCapacity = game.player.buyingCapacity();
	trace('Player buying capacity:', 2);
	trace(playerCapacity, 2);
	// Parcours des cartes du plateau et ajout des cartes en réserve du joueur
	const selectableCards = game.cards.filter(obj => 'XYZ'.includes(obj.slot) && obj.slot!='' || obj.slot=='R'+game.player.tag());
	selectableCards.forEach(card => {
		const elmCard = document.getElementById('C'+card.cardID);
		if(card.isBuyable(playerCapacity)) {
			elmCard.classList.add('selectable');
			elmCard.setAttribute('onclick', 'selectCardToPurchase(this)');
		} else elmCard.classList.add('unselectable');
	});
}

function selectCardToPurchase(elmCard) {
	// Désactiver toutes les Carte 'sélectionnable' et marquer la carte sélectionnée
	const selCards = document.querySelectorAll('.card.selectable');
	selCards.forEach(elm => {
		elm.classList.remove('selectable');
		elm.removeAttribute('onclick');
		elm.classList.add('unselectable');
	});
	elmCard.classList.add('mark');

	const card = game.cards.findByID(elmCard.dataset.id);
	trace(`Select card #${card.id} to purchase`, 1);
	const playerCapacity = game.player.buyingCapacity();
	const playerCardCapacity = playerCapacity.cards;
	const playerTokenCapacity = playerCapacity.tokens;
	// Identification des Jetons nécessaires à la transaction
	tokensColors.forEach(color => {
		if(card[`${color}Cost`]>0) {
			var tokenDue = card[`${color}Cost`]-playerCardCapacity[color];
			if(tokenDue>0) {
				// Isoler les Jetons du joueur de cette couleur
				const coloredTokens = game.tokens.filter(token =>token.color==color && token.slot==game.player.tag());
				// Mettre les Jetons utilisés par cette transaction de côté
				const tokenNb = (coloredTokens.length>=tokenDue)? tokenDue : coloredTokens.length;
				for(let i=1; i<=tokenNb; i++) {
					const tokenUsed = coloredTokens.pop();
					tokenTransaction.push(tokenUsed)
				}
				// S'il en manque, on complète avec des Jetons Or du Joueur
				const goldenTokens = game.tokens.filter(token =>token.color=='gold' && token.slot==game.player.tag());
				if(tokenDue>playerTokenCapacity[color]) {
					const goldNb = tokenDue-tokenNb;
					for(let i=1; i<=goldNb; i++) {
						const tokenUsed = goldenTokens.pop();
						tokenTransaction.push(tokenUsed)
					}
				}
			}				
		}
	});

	trace('Token used for this transaction: '), 2;
	trace(tokenTransaction, 2);
	// Si la carte n'a pas de couleur, il faut en sélectionner une
	if(card.color=='') {
		enableCardSlotSelection();
	} else actCardPurchase();
}

function actCardPurchase() {
	disableCancelAction();

	// Récupération de la carte
	const elmCard = document.querySelector('.card.mark');
	const card = game.cards.findByID(elmCard.dataset.id);
	// Affichage et Report de la Carte
	trace('Validate Card purchase', 3);
	trace(card, 3);
	const slotOrigin = card.slot;
	card.moveToSlot(game.player.tag()).report();
	// Affich	ge et Report des Jetons utilisés
	if(tokenTransaction) tokenTransaction.forEach(obj => game.tokens.findByID(obj.tokenID).moveToSlot('').report());

	restoreBoard();
	if(!slotOrigin.startsWith('R')) reloadCard(card.level);

	// Traitement des spécificités de la Carte
	switch(card.power) {
		case 'gem':
			game.data.step = 'standby';
			playerOptions();
			var tkCount = game.tokens.filter(token => token.slot=='C' && token.color==card.color).length;
			if(tkCount>0) { sendInfo(`a acheté une carte et peut prendre un jeton`); enableTokenSelection(card.color);}
			else concludeTransaction(true);
			break;
		case 'play':
			game.data.step='gen';
			if(card.cardID<100) sendInfo(`a acheté une carte et rejoue`);
			else sendInfo(`rejoue grace à sa carte royale acquise`);
			playerOptions();
			concludeTransaction(false);
			break;
		case 'privilege':
			const playerPrivilegesCount = game.privileges.filterBySlot(game.player.tag()).length;
			console.log(playerPrivilegesCount);
			if(playerPrivilegesCount<3) {
				if(card.cardID<100) sendInfo(`a acheté une carte et gagne un privilège`);
				else sendInfo(`gagne un privilège avec sa carte royale acquise`)
				givePrivilegeTo(game.player.tag());
			} else {
				if(card.cardID<100) sendInfo(`a acheté une carte mais ne peut pas bénéficier d'un privilège supplémentaire`);
				else sendInfo(`prend une carte royale mais ne peut pas bénéficier d'un privilège supplémentaire`)
			}
			concludeTransaction(true);
			break;
		case 'theft':
			game.data.step = 'standby';
			playerOptions();
			var tkCount = game.tokens.filter(token => token.slot==game.player.opponentTag() && token.color!='gold').length;
			if(tkCount>0) {
				if(card.cardID<100) sendInfo(`a acheté une carte et va te voler un jeton`);
				else sendInfo(`va te voler un jeton grâce avec sa carte royale acquise`)
				enableTokenTheft();
			}
			else {
				if(card.cardID<100) sendInfo(`a acheté une carte mais ne peut pas te voler un jeton`);
				else sendInfo(`ne peut pas te voler un jeton malgré avec sa carte royale acquise`)
				concludeTransaction(true);
			}
			break;
		case '':
			if(card.cardID<100) sendInfo(`a acheté une carte`);
			else sendInfo(`a fait l'acquisition d'une carte royale`);
			concludeTransaction(true);
	}
}

function concludeTransaction(endOfTurn=false) {
	// Actualisation du score du Joueur
	game.player.score();
	if(game.player.victory) {
		game.data.playerTurn = '';
		game.data.status = 'terminated'
		displayGameInfo();
		// Transmission des données de jeu à Node
		parent.nodeSend(playerLogin, 'Update Data', {'gameID':gameID, 'gameData':game.data});
	}

	// Vider les tokens de transaction
	tokenTransaction.length = 0;
	// Gestion des Cartes Royales
	if(game.data.status!='terminated') {
		const nRoyalCards = game.cards.filter(card => card.slot==game.player.tag() && card.id>100).length;
		if((game.player.crowns>=3 && nRoyalCards==0) || game.player.crowns>=6 && nRoyalCards==1) {
			game.data.step = 'standby';
			playerOptions();
			endOfTurn = false;
			enableRoyalSelection();
		};
	}
	if(endOfTurn) endTurn();
}

function enableCardSlotSelection() {
	document.getElementById('message').textContent = 'Selectionne une de tes piles de cartes';

	cardsColors.forEach(color =>{
		const cSlot = document.querySelector(`#myDeck #cards #${color}`);
		if(cSlot.hasChildNodes()) {
			cSlot.classList.add('selectable');
			cSlot.setAttribute('onclick', 'selectCardSlot(this)');
		}
	});
}
function selectCardSlot(elmSlot) {
	const color = elmSlot.id;
	// Récupération de la carte
	const elmCard = document.querySelector('.card.mark');
	const card = game.cards.findByID(elmCard.dataset.id);
	card.color = color;
	actCardPurchase();
}

function enableRoyalSelection() {
	document.getElementById('message').textContent = 'Prends une carte Royale';

	const availableRoyalCards = game.cards.filterBySlot('R');
	availableRoyalCards.forEach(card => {
		const elmCard = document.getElementById('C'+card.cardID);
		elmCard.classList.add('selectable');
		elmCard.setAttribute('onclick','selectRoyale(this)');
	});
	sendInfo('prend une carte royale');
}
function selectRoyale(elmCard) {
	// Désactiver toutes les Carte 'sélectionnable' et marquer la carte sélectionnée
	const selCards = document.querySelectorAll('.card.selectable');
	selCards.forEach(elm => {
		elm.classList.remove('selectable');
		elm.removeAttribute('onclick');
	});
	elmCard.classList.add('mark');
	actCardPurchase();
}

function selectCardToReserve(elmCard) {
	trace('Select Card to reserve', 1);
	elmCard.classList.add('mark');
	// Désactiver toute les cartes sauf celle sélectionnée
	const selCards = document.querySelectorAll('.card.selectable');
	selCards.forEach(elm => {
		elm.classList.remove('selectable'); 
		elm.removeAttribute('onclick');
		if(elm!=elmCard) elm.classList.add('unselectable'); 
	});
	enableTokenSelection('gold');
}

function reloadCard(level) {
	trace('Reload card to board slots level '+level, 1);
	const slotID=['X', 'Y', 'Z'];
	const cardsAvailableByLevel = game.cards.filter(card => card.level==level && card.slot=='');
	if(cardsAvailableByLevel.length>0) {
		const slotList = document.querySelectorAll(`[data-slot='${slotID[level-1]}']`);
		const emptySlots = Array.prototype.filter.call(slotList, function(slot) {	return !slot.querySelector('.card'); });
		if(emptySlots.length>0 && cardsAvailableByLevel) {
			const drawnCard = cardsAvailableByLevel.pop();
			game.cards.findByID(drawnCard.cardID).moveToSlot(slotID[level-1]).report();
		}
	}
}

/* ===================================
		PROTOTYPES
	=================================== */
// Objet: Liste de Cartes
const cardsPrototype = Object.create(Array.prototype);
cardsPrototype.findByID = function(cardID) {
	cardID = parseInt(cardID);
	return this.find(card => card.cardID==cardID);
}
cardsPrototype.filterBySlot = function(slot) {
	return this.filter(card => card.slot==slot);
}
cardsPrototype.report = function() {
	parent.nodeSend(playerLogin, 'Update Data', {'cards':this});
}

// Objet: Carte
const cardPrototype = {
	create: function() { 
		// Création du conteneur
		const container = document.createElement('div');
		container.id = 'C'+this.cardID;
		container.classList.add('card');
		container.setAttribute('data-id',this.cardID);
		// Création de l'image
		const img = document.createElement('img');
		img.setAttribute('src', `../images/C${this.cardID}.png`);
		img.setAttribute('alt', `C${this.cardID}`);
		img.classList.add('cardImage');
		// Ajout de l'image dans la div
		container.appendChild(img);
			/*
			// Pour Test : Affichage de l'ID de la carte
			var divTag = document.createElement('div');
			divTag.classList.add('ID');
			divTag.textContent = this.cardID;
			container.appendChild(divTag);		
			*/
		// Ajout dans la div 'void'
		document.getElementById('void').appendChild(container);
	},

	display: function() {
		const container = document.getElementById('C'+this.cardID);
		container.parentNode.removeChild(container);
		if('XYZ'.includes(this.slot)) var newSlot = document.getElementById(`${this.slot}${this.rank}`);
		if(this.slot=='') var newSlot = document.getElementById(`stackLevel${this.level}`);
		if(this.slot=='A') var newSlot = slotPlayerA('cards', this.color);
		if(this.slot=='B') var newSlot = slotPlayerB('cards', this.color);
		if(this.slot=='RA') var newSlot = slotPlayerA('cards', 'reserve');
		if(this.slot=='RB') var newSlot = slotPlayerB('cards', 'reserve');
		if(this.slot=='R') var newSlot = document.getElementById(`${this.slot}${this.rank}`);
		// Ajustement de la position dans le deck
		const applyOffset = (this.slot.includes('A') || this.slot.includes('B'));
		if(applyOffset) container.style.top=28*(this.rank-1)+'px'; else container.style.top=0;
		// Ajout de la classe 'reserve' si la carte est dans le slot de réserve du joueur
		if(this.slot=='R'+game.player.tag()) container.classList.add('reserve'); else container.classList.remove('reserve')
		// Carte retournée si dans un Stack du plateau ou dans la réserve de l'adversaire
		if(this.slot=='' || this.slot==`R${game.player.opponentTag()}`) container.querySelector('img').setAttribute('src', `../images/back_L${this.level}`); else container.querySelector('img').setAttribute('src', `../images/C${this.cardID}`);
		// Transfert dans le nouveau slot
		newSlot.appendChild(container);
	},

	moveToSlot: function(slot) {
		if(slot) {
			if(slot=='A' || slot=='B') this.rank = game.cards.filter(card => card.slot==slot && card.color==this.color).length+1;
			if(slot=='RA' || slot=='RB') this.rank = game.cards.filter(card => card.slot==slot).length+1;
			if('XYZ'.includes(slot)) {
				const slotList = document.querySelectorAll(`[data-slot='${slot}']`);
				const emptySlots = Array.prototype.filter.call(slotList, function(slot) { return !slot.querySelector('.card'); });
				if(emptySlots) this.rank = emptySlots[0].dataset.rank;
			}
		} else this.rank = game.cards.filter(card => card.slot==slot).length+1;
		this.slot = slot;
		this.display();
		return this;
	},

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

	isBuyable: function(playerCapacity) {
		// Si la Carte n'a pas de couleur, s'assurer que le joueur peut l'associer à une Carte existante
		if(this.color=='' && !game.cards.filter(obj => obj.slot==game.player.tag() && obj.color!='neutral')) return false;
		// Estimation de la capacité d'acquisition de la Carte
		var goldCapacity = playerCapacity.tokens['gold'];
		var buyable = true;
		tokensColors.forEach(color => {
			if(this[`${color}Cost`]) {
				var delta = playerCapacity.global[color]-this[`${color}Cost`];
				// Ai-je assez de Gemme de cette couleur
				trace(` ... color :${color} / Capacity-Cost = ${delta}`, 8);
				if(delta<0) {
					// Et si je rajoute des jeton Or
					trace(` ... Delta+Gold =${delta+goldCapacity}`, 8);
					if(delta+goldCapacity>=0) goldCapacity = delta+goldCapacity; else buyable = false;
				}
			}
		});
		return buyable;
	}
}
