/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Simple AI class (draws/discards at intervals)
var AIPlayer = Container.expand(function () {
	var self = Container.call(this);
	self.hand = [];
	self.name = "AI";
	self.knocked = false;
	// AI makes a move (draw/discard/knock)
	self.makeMove = function () {
		if (game.gameOver) return;
		// If hand value >= 28, knock with 50% chance, always knock at 31
		var best = bestHandValue(self.hand);
		if (best.value === 31) {
			game.aiKnock();
			return;
		}
		if (best.value >= 28 && Math.random() < 0.5) {
			game.aiKnock();
			return;
		}
		// Draw from discard if it helps, else draw from deck
		var topDiscard = game.discardPile && game.discardPile.length > 0 ? game.discardPile[game.discardPile.length - 1] : null;
		var wantDiscard = false;
		if (topDiscard) {
			// Would taking this card improve hand?
			var replaced = -1,
				bestWithDiscard = best;
			for (var i = 0; i < self.hand.length; ++i) {
				var testHand = self.hand.slice();
				testHand[i] = topDiscard;
				var val = bestHandValue(testHand);
				if (val.value > bestWithDiscard.value) {
					bestWithDiscard = val;
					replaced = i;
				}
			}
			if (bestWithDiscard.value > best.value) {
				wantDiscard = true;
			}
		}
		if (wantDiscard) {
			// Take from discard
			var card = game.discardPile.pop();
			self.hand.push(card);
			// Discard lowest value card
			var idx = lowestValueCardIndex(self.hand);
			var discard = self.hand.splice(idx, 1)[0];
			game.discardPile.push(discard);
			game.animateAIDraw(card, 'discard');
			game.animateAIDiscard(discard);
		} else {
			// Draw from deck
			if (!game.deck || game.deck.length === 0) {
				// Can't draw, must knock
				game.aiKnock();
				return;
			}
			var card = game.deck.pop();
			self.hand.push(card);
			// Discard lowest value card
			var idx = lowestValueCardIndex(self.hand);
			var discard = self.hand.splice(idx, 1)[0];
			game.discardPile.push(discard);
			game.animateAIDraw(card, 'deck');
			game.animateAIDiscard(discard);
		}
	};
	return self;
});
// Card class: represents a single card (visual and data)
var Card = Container.expand(function () {
	var self = Container.call(this);
	// Card data
	self.suit = null; // '♠', '♥', '♦', '♣'
	self.rank = null; // 1-13 (Ace-King)
	self.faceUp = true;
	self.cardIndex = -1; // index in deck, for uniqueness
	// Visuals
	var cardFront = self.attachAsset('cardFront', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var cardBack = self.attachAsset('cardBack', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cardBack.visible = false;
	// Text overlays
	var rankText = new Text2('', {
		size: 70,
		fill: "#222"
	});
	rankText.anchor.set(0.5, 0.2);
	self.addChild(rankText);
	var suitText = new Text2('', {
		size: 90,
		fill: "#222"
	});
	suitText.anchor.set(0.5, 0.6);
	self.addChild(suitText);
	// Set card data and visuals
	self.setCard = function (suit, rank, faceUp, cardIndex) {
		self.suit = suit;
		self.rank = rank;
		self.faceUp = faceUp !== false;
		self.cardIndex = cardIndex;
		self.updateVisual();
	};
	// Update visuals based on faceUp
	self.updateVisual = function () {
		cardFront.visible = self.faceUp;
		cardBack.visible = !self.faceUp;
		if (self.faceUp) {
			rankText.setText(cardRankToString(self.rank));
			suitText.setText(self.suit);
			// Color for suit
			if (self.suit === '♥' || self.suit === '♦') {
				if (rankText.style && typeof rankText.style.setFill === "function") {
					rankText.style.setFill("#d22");
					suitText.style.setFill("#d22");
				} else {
					if (typeof rankText.setFill === "function") {
						rankText.setFill("#d22");
						suitText.setFill("#d22");
					} else {
						if (rankText.style) {
							rankText.style.fill = "#d22";
						}
						if (suitText.style) {
							suitText.style.fill = "#d22";
						}
					}
				}
			} else {
				if (rankText.style && typeof rankText.style.setFill === "function") {
					rankText.style.setFill("#222");
					suitText.style.setFill("#222");
				} else {
					if (rankText.style && typeof rankText.style.setFill === "function") {
						rankText.style.setFill("#222");
						suitText.style.setFill("#222");
					} else {
						// fallback for older Text2 versions
						if (typeof rankText.setFill === "function") {
							rankText.setFill("#222");
							suitText.setFill("#222");
						} else {
							if (typeof rankText.setFill === "function") {
								rankText.setFill("#222");
								suitText.setFill("#222");
							} else if (rankText.style) {
								rankText.style.fill = "#222";
								suitText.style.fill = "#222";
							}
						}
					}
				}
			}
		} else {
			rankText.setText('');
			suitText.setText('');
		}
	};
	// Flip card
	self.flip = function (toFaceUp) {
		self.faceUp = toFaceUp;
		self.updateVisual();
	};
	// For drag highlight
	self.highlight = function (color, duration) {
		tween(self, {
			scaleX: 1.1,
			scaleY: 1.1
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: duration || 100,
					easing: tween.easeIn
				});
			}
		});
	};
	// For simple card tap feedback
	self.flash = function () {
		LK.effects.flashObject(self, 0xffff99, 200);
	};
	// Card tap event (handled in game)
	self.down = function (x, y, obj) {};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x0a3a1a
});
/**** 
* Game Code
****/ 
// Draw pile highlight
// Discard pile highlight
// Card front (white, will overlay suit/rank)
// Card back
// Card data
var SUITS = ['♠', '♥', '♦', '♣'];
var RANKS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; // Ace-King
// Layout
var HAND_Y = 2200;
var HAND_X_START = 400;
var HAND_SPACING = 260;
var AI_HAND_Y = 400;
var AI_HAND_X_START = 400;
var PILE_X = 1024;
var DRAW_PILE_Y = 1200;
var DISCARD_PILE_Y = 1500;
// Game state
var deck = [];
var discardPile = [];
var playerHand = [];
var aiHand = [];
var ai = null;
var selectedCardIndex = -1;
var draggingCard = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var canDraw = true;
var canDiscard = false;
var gameOver = false;
var aiMoveTimeout = null;
var playerKnocked = false;
var aiKnocked = false;
var turn = 'player'; // 'player' or 'ai'
var timerText = null;
var timer = null;
var timeLeft = 60; // seconds
// GUI
var infoText = null;
var knockButton = null;
var discardHighlight = null;
var drawHighlight = null;
// Helper: Card rank to string
function cardRankToString(rank) {
	if (rank === 1) return 'A';
	if (rank === 11) return 'J';
	if (rank === 12) return 'Q';
	if (rank === 13) return 'K';
	return '' + rank;
}
// Helper: Card value for 31
function cardValue(card) {
	if (!card) return 0;
	if (card.rank > 10) return 10;
	if (card.rank === 1) return 11;
	return card.rank;
}
// Helper: Best hand value (max sum of one suit)
function bestHandValue(hand) {
	var suitTotals = {
		'♠': 0,
		'♥': 0,
		'♦': 0,
		'♣': 0
	};
	for (var i = 0; i < hand.length; ++i) {
		var c = hand[i];
		suitTotals[c.suit] += cardValue(c);
	}
	var bestSuit = '♠',
		bestValue = suitTotals['♠'];
	for (var s = 0; s < SUITS.length; ++s) {
		if (suitTotals[SUITS[s]] > bestValue) {
			bestSuit = SUITS[s];
			bestValue = suitTotals[SUITS[s]];
		}
	}
	return {
		suit: bestSuit,
		value: bestValue
	};
}
// Helper: Find lowest value card index in hand
function lowestValueCardIndex(hand) {
	var best = bestHandValue(hand);
	var minIdx = -1,
		minVal = 100;
	for (var i = 0; i < hand.length; ++i) {
		var c = hand[i];
		// If not in best suit, prefer to discard
		if (c.suit !== best.suit) return i;
		// Otherwise, lowest value in best suit
		var v = cardValue(c);
		if (v < minVal) {
			minVal = v;
			minIdx = i;
		}
	}
	return minIdx >= 0 ? minIdx : 0;
}
// Helper: Shuffle array
function shuffle(arr) {
	for (var i = arr.length - 1; i > 0; --i) {
		var j = Math.floor(Math.random() * (i + 1));
		var t = arr[i];
		arr[i] = arr[j];
		arr[j] = t;
	}
}
// Helper: Create a new deck (array of Card objects)
function createDeck() {
	var cards = [];
	var idx = 0;
	for (var s = 0; s < SUITS.length; ++s) {
		for (var r = 0; r < RANKS.length; ++r) {
			var c = new Card();
			c.setCard(SUITS[s], RANKS[r], false, idx++);
			cards.push(c);
		}
	}
	shuffle(cards);
	return cards;
}
// Helper: Remove all children from a container
function removeAll(container) {
	while (container.children.length > 0) {
		var c = container.children[0];
		if (c.destroy) c.destroy();else container.removeChild(c);
	}
}
// Helper: Animate card to position
function animateCardTo(card, x, y, onFinish) {
	tween(card, {
		x: x,
		y: y
	}, {
		duration: 250,
		easing: tween.cubicOut,
		onFinish: onFinish
	});
}
// Helper: Show info text
function showInfo(msg, color) {
	infoText.setText(msg);
	if (typeof infoText.setFill === "function") {
		infoText.setFill(color || "#fff");
	} else if (infoText.style) {
		infoText.style.fill = color || "#fff";
	}
	infoText.visible = true;
	tween(infoText, {
		alpha: 1
	}, {
		duration: 100
	});
	LK.setTimeout(function () {
		tween(infoText, {
			alpha: 0
		}, {
			duration: 600,
			onFinish: function onFinish() {
				infoText.visible = false;
			}
		});
	}, 1200);
}
// Helper: End game
function endGame(msg, color) {
	gameOver = true;
	showInfo(msg, color);
	LK.setTimeout(function () {
		LK.showGameOver();
	}, 1200);
}
// Helper: Win game
function winGame(msg, color) {
	gameOver = true;
	showInfo(msg, color);
	LK.setTimeout(function () {
		LK.showYouWin();
	}, 1200);
}
// Helper: Update timer
function updateTimer() {
	timerText.setText(timeLeft + "s");
	if (timeLeft <= 0) {
		endGame("Time's up!", "#f44");
	}
}
// Helper: Lay out player's hand
function layoutPlayerHand() {
	for (var i = 0; i < playerHand.length; ++i) {
		var c = playerHand[i];
		c.x = HAND_X_START + i * HAND_SPACING;
		c.y = HAND_Y;
		c.zIndex = 10 + i;
		c.scaleX = c.scaleY = 1;
		c.faceUp = true;
		c.updateVisual();
	}
}
// Helper: Lay out AI's hand (face down)
function layoutAIHand() {
	for (var i = 0; i < aiHand.length; ++i) {
		var c = aiHand[i];
		c.x = AI_HAND_X_START + i * HAND_SPACING;
		c.y = AI_HAND_Y;
		c.zIndex = 10 + i;
		c.faceUp = false;
		c.updateVisual();
	}
}
// Helper: Lay out piles
function layoutPiles() {
	// Draw pile
	if (deck.length > 0) {
		var top = deck[deck.length - 1];
		top.x = PILE_X - 180;
		top.y = DRAW_PILE_Y;
		top.zIndex = 100;
		top.faceUp = false;
		top.updateVisual();
		top.visible = true;
	}
	// Discard pile
	if (discardPile.length > 0) {
		var top = discardPile[discardPile.length - 1];
		top.x = PILE_X + 180;
		top.y = DISCARD_PILE_Y;
		top.zIndex = 100;
		top.faceUp = true;
		top.updateVisual();
		top.visible = true;
	}
}
// Helper: Remove all cards from stage
function removeAllCards() {
	for (var i = 0; i < deck.length; ++i) deck[i].visible = false;
	for (var i = 0; i < discardPile.length; ++i) discardPile[i].visible = false;
	for (var i = 0; i < playerHand.length; ++i) playerHand[i].visible = false;
	for (var i = 0; i < aiHand.length; ++i) aiHand[i].visible = false;
}
// Helper: Animate AI draw
game.animateAIDraw = function (card, from) {
	card.visible = true;
	if (from === 'deck') {
		card.x = PILE_X - 180;
		card.y = DRAW_PILE_Y;
	} else {
		card.x = PILE_X + 180;
		card.y = DISCARD_PILE_Y;
	}
	animateCardTo(card, AI_HAND_X_START + (aiHand.length - 1) * HAND_SPACING, AI_HAND_Y, function () {
		layoutAIHand();
	});
};
// Helper: Animate AI discard
game.animateAIDiscard = function (card) {
	animateCardTo(card, PILE_X + 180, DISCARD_PILE_Y, function () {
		layoutPiles();
	});
};
// Helper: AI knock
game.aiKnock = function () {
	aiKnocked = true;
	showInfo("AI knocks!", "#ff0");
	// Reveal AI hand
	for (var i = 0; i < aiHand.length; ++i) {
		aiHand[i].faceUp = true;
		aiHand[i].updateVisual();
	}
	// Compare hands after short delay
	LK.setTimeout(function () {
		var playerVal = bestHandValue(playerHand).value;
		var aiVal = bestHandValue(aiHand).value;
		if (aiVal > playerVal) {
			endGame("AI wins! (" + aiVal + " vs " + playerVal + ")", "#f44");
		} else if (playerVal > aiVal) {
			winGame("You win! (" + playerVal + " vs " + aiVal + ")", "#4f4");
		} else {
			endGame("Draw! (" + playerVal + ")", "#fff");
		}
	}, 1200);
};
// Helper: Player knock
function playerKnock() {
	if (gameOver || playerKnocked) return;
	playerKnocked = true;
	showInfo("You knock!", "#ff0");
	// Reveal AI hand
	for (var i = 0; i < aiHand.length; ++i) {
		aiHand[i].faceUp = true;
		aiHand[i].updateVisual();
	}
	// Compare hands after short delay
	LK.setTimeout(function () {
		var playerVal = bestHandValue(playerHand).value;
		var aiVal = bestHandValue(aiHand).value;
		if (playerVal > aiVal) {
			winGame("You win! (" + playerVal + " vs " + aiVal + ")", "#4f4");
		} else if (aiVal > playerVal) {
			endGame("AI wins! (" + aiVal + " vs " + playerVal + ")", "#f44");
		} else {
			endGame("Draw! (" + playerVal + ")", "#fff");
		}
	}, 1200);
}
// Helper: Start AI move timer
function startAIMove() {
	if (aiMoveTimeout) LK.clearTimeout(aiMoveTimeout);
	aiMoveTimeout = LK.setTimeout(function () {
		if (!gameOver && ai && !aiKnocked) {
			ai.makeMove();
			// If AI didn't knock, return turn to player
			if (!aiKnocked) {
				turn = 'player';
				canDraw = true;
				canDiscard = false;
				showInfo("Your turn!", "#fff");
			}
		}
	}, 900);
}
// Helper: Start timer
function startTimer() {
	if (timer) LK.clearInterval(timer);
	timer = LK.setInterval(function () {
		if (gameOver) return;
		timeLeft -= 1;
		updateTimer();
	}, 1000);
}
// Helper: Reset game state
function resetGame() {
	// Remove all cards
	removeAllCards();
	deck = createDeck();
	discardPile = [];
	playerHand = [];
	aiHand = [];
	ai = new AIPlayer();
	selectedCardIndex = -1;
	draggingCard = null;
	canDraw = true;
	canDiscard = false;
	gameOver = false;
	aiMoveTimeout = null;
	playerKnocked = false;
	aiKnocked = false;
	turn = 'player';
	timeLeft = 60;
	// Deal 3 cards to each
	for (var i = 0; i < 3; ++i) {
		var c = deck.pop();
		c.faceUp = true;
		c.visible = true;
		playerHand.push(c);
		game.addChild(c);
	}
	for (var i = 0; i < 3; ++i) {
		var c = deck.pop();
		c.faceUp = false;
		c.visible = true;
		aiHand.push(c);
		game.addChild(c);
	}
	// Discard one card to start
	var c = deck.pop();
	c.faceUp = true;
	c.visible = true;
	discardPile.push(c);
	game.addChild(c);
	// Add remaining deck cards to stage (face down)
	for (var i = 0; i < deck.length; ++i) {
		deck[i].faceUp = false;
		deck[i].visible = true;
		game.addChild(deck[i]);
	}
	// Add AI hand to stage
	for (var i = 0; i < aiHand.length; ++i) {
		aiHand[i].faceUp = false;
		aiHand[i].visible = true;
		game.addChild(aiHand[i]);
	}
	// Layout
	layoutPlayerHand();
	layoutAIHand();
	layoutPiles();
	// Update GUI
	updateHandValueText();
	updateTimer();
	// Start timer
	startTimer();
	// Show info
	showInfo("Your turn!", "#fff");
}
// Helper: Update hand value text
function updateHandValueText() {
	var val = bestHandValue(playerHand);
	handValueText.setText("Best: " + val.value + " " + val.suit);
	if (val.value === 31) {
		winGame("31! You win!", "#4f4");
	}
}
// GUI: Info text
infoText = new Text2('', {
	size: 90,
	fill: "#fff"
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 1024;
infoText.y = 900;
infoText.alpha = 0;
infoText.visible = false;
LK.gui.top.addChild(infoText);
// GUI: Timer
timerText = new Text2('60s', {
	size: 90,
	fill: "#fff"
});
timerText.anchor.set(0.5, 0);
timerText.x = 1024;
timerText.y = 110;
LK.gui.top.addChild(timerText);
// GUI: Hand value
var handValueText = new Text2('', {
	size: 80,
	fill: "#fff"
});
handValueText.anchor.set(0.5, 0);
handValueText.x = 1024;
handValueText.y = HAND_Y + 200;
LK.gui.top.addChild(handValueText);
// GUI: Knock button
knockButton = new Text2('Knock', {
	size: 90,
	fill: "#fff",
	font: "Impact"
});
knockButton.anchor.set(0.5, 0.5);
knockButton.x = 1800;
knockButton.y = HAND_Y + 100;
knockButton.interactive = true;
knockButton.buttonMode = true;
knockButton.alpha = 0.95;
knockButton.down = function (x, y, obj) {
	if (gameOver || !canDraw) return;
	playerKnock();
};
LK.gui.bottom.addChild(knockButton);
// GUI: Discard highlight
discardHighlight = LK.getAsset('discardHighlight', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: PILE_X + 180,
	y: DISCARD_PILE_Y
});
discardHighlight.alpha = 0;
game.addChild(discardHighlight);
// GUI: Draw highlight
drawHighlight = LK.getAsset('drawHighlight', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: PILE_X - 180,
	y: DRAW_PILE_Y
});
drawHighlight.alpha = 0;
game.addChild(drawHighlight);
// --- Input Handling ---
// Touch/click down
game.down = function (x, y, obj) {
	if (gameOver) return;
	// If it's player's turn
	if (turn !== 'player') return;
	// Check if drawing from deck
	if (canDraw && deck.length > 0) {
		var top = deck[deck.length - 1];
		var dx = x - (PILE_X - 180),
			dy = y - DRAW_PILE_Y;
		if (Math.abs(dx) < 110 && Math.abs(dy) < 160) {
			// Draw from deck
			canDraw = false;
			canDiscard = true;
			var card = deck.pop();
			card.faceUp = true;
			card.visible = true;
			playerHand.push(card);
			animateCardTo(card, HAND_X_START + (playerHand.length - 1) * HAND_SPACING, HAND_Y, function () {
				layoutPlayerHand();
				updateHandValueText();
			});
			drawHighlight.alpha = 0.2;
			LK.setTimeout(function () {
				drawHighlight.alpha = 0;
			}, 200);
			return;
		}
	}
	// Check if drawing from discard
	if (canDraw && discardPile.length > 0) {
		var top = discardPile[discardPile.length - 1];
		var dx = x - (PILE_X + 180),
			dy = y - DISCARD_PILE_Y;
		if (Math.abs(dx) < 110 && Math.abs(dy) < 160) {
			// Draw from discard
			canDraw = false;
			canDiscard = true;
			var card = discardPile.pop();
			card.faceUp = true;
			card.visible = true;
			playerHand.push(card);
			animateCardTo(card, HAND_X_START + (playerHand.length - 1) * HAND_SPACING, HAND_Y, function () {
				layoutPlayerHand();
				updateHandValueText();
			});
			discardHighlight.alpha = 0.2;
			LK.setTimeout(function () {
				discardHighlight.alpha = 0;
			}, 200);
			return;
		}
	}
	// If can discard, check if a card in hand is tapped
	if (canDiscard) {
		for (var i = 0; i < playerHand.length; ++i) {
			var c = playerHand[i];
			var dx = x - c.x,
				dy = y - c.y;
			if (Math.abs(dx) < 110 && Math.abs(dy) < 160) {
				// Discard this card
				canDiscard = false;
				var discard = playerHand.splice(i, 1)[0];
				discard.faceUp = true;
				discard.visible = true;
				discardPile.push(discard);
				animateCardTo(discard, PILE_X + 180, DISCARD_PILE_Y, function () {
					layoutPiles();
				});
				discardHighlight.alpha = 0.2;
				LK.setTimeout(function () {
					discardHighlight.alpha = 0;
				}, 200);
				layoutPlayerHand();
				updateHandValueText();
				// End turn, AI moves
				turn = 'ai';
				startAIMove();
				return;
			}
		}
	}
};
// Touch/click up
game.up = function (x, y, obj) {
	// No drag in this version
};
// Touch/click move
game.move = function (x, y, obj) {
	// No drag in this version
};
// Main update loop
game.update = function () {
	// No per-frame logic needed
};
// Start game
resetGame(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Simple AI class (draws/discards at intervals)
var AIPlayer = Container.expand(function () {
	var self = Container.call(this);
	self.hand = [];
	self.name = "AI";
	self.knocked = false;
	// AI makes a move (draw/discard/knock)
	self.makeMove = function () {
		if (game.gameOver) return;
		// If hand value >= 28, knock with 50% chance, always knock at 31
		var best = bestHandValue(self.hand);
		if (best.value === 31) {
			game.aiKnock();
			return;
		}
		if (best.value >= 28 && Math.random() < 0.5) {
			game.aiKnock();
			return;
		}
		// Draw from discard if it helps, else draw from deck
		var topDiscard = game.discardPile && game.discardPile.length > 0 ? game.discardPile[game.discardPile.length - 1] : null;
		var wantDiscard = false;
		if (topDiscard) {
			// Would taking this card improve hand?
			var replaced = -1,
				bestWithDiscard = best;
			for (var i = 0; i < self.hand.length; ++i) {
				var testHand = self.hand.slice();
				testHand[i] = topDiscard;
				var val = bestHandValue(testHand);
				if (val.value > bestWithDiscard.value) {
					bestWithDiscard = val;
					replaced = i;
				}
			}
			if (bestWithDiscard.value > best.value) {
				wantDiscard = true;
			}
		}
		if (wantDiscard) {
			// Take from discard
			var card = game.discardPile.pop();
			self.hand.push(card);
			// Discard lowest value card
			var idx = lowestValueCardIndex(self.hand);
			var discard = self.hand.splice(idx, 1)[0];
			game.discardPile.push(discard);
			game.animateAIDraw(card, 'discard');
			game.animateAIDiscard(discard);
		} else {
			// Draw from deck
			if (!game.deck || game.deck.length === 0) {
				// Can't draw, must knock
				game.aiKnock();
				return;
			}
			var card = game.deck.pop();
			self.hand.push(card);
			// Discard lowest value card
			var idx = lowestValueCardIndex(self.hand);
			var discard = self.hand.splice(idx, 1)[0];
			game.discardPile.push(discard);
			game.animateAIDraw(card, 'deck');
			game.animateAIDiscard(discard);
		}
	};
	return self;
});
// Card class: represents a single card (visual and data)
var Card = Container.expand(function () {
	var self = Container.call(this);
	// Card data
	self.suit = null; // '♠', '♥', '♦', '♣'
	self.rank = null; // 1-13 (Ace-King)
	self.faceUp = true;
	self.cardIndex = -1; // index in deck, for uniqueness
	// Visuals
	var cardFront = self.attachAsset('cardFront', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var cardBack = self.attachAsset('cardBack', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cardBack.visible = false;
	// Text overlays
	var rankText = new Text2('', {
		size: 70,
		fill: "#222"
	});
	rankText.anchor.set(0.5, 0.2);
	self.addChild(rankText);
	var suitText = new Text2('', {
		size: 90,
		fill: "#222"
	});
	suitText.anchor.set(0.5, 0.6);
	self.addChild(suitText);
	// Set card data and visuals
	self.setCard = function (suit, rank, faceUp, cardIndex) {
		self.suit = suit;
		self.rank = rank;
		self.faceUp = faceUp !== false;
		self.cardIndex = cardIndex;
		self.updateVisual();
	};
	// Update visuals based on faceUp
	self.updateVisual = function () {
		cardFront.visible = self.faceUp;
		cardBack.visible = !self.faceUp;
		if (self.faceUp) {
			rankText.setText(cardRankToString(self.rank));
			suitText.setText(self.suit);
			// Color for suit
			if (self.suit === '♥' || self.suit === '♦') {
				if (rankText.style && typeof rankText.style.setFill === "function") {
					rankText.style.setFill("#d22");
					suitText.style.setFill("#d22");
				} else {
					if (typeof rankText.setFill === "function") {
						rankText.setFill("#d22");
						suitText.setFill("#d22");
					} else {
						if (rankText.style) {
							rankText.style.fill = "#d22";
						}
						if (suitText.style) {
							suitText.style.fill = "#d22";
						}
					}
				}
			} else {
				if (rankText.style && typeof rankText.style.setFill === "function") {
					rankText.style.setFill("#222");
					suitText.style.setFill("#222");
				} else {
					if (rankText.style && typeof rankText.style.setFill === "function") {
						rankText.style.setFill("#222");
						suitText.style.setFill("#222");
					} else {
						// fallback for older Text2 versions
						if (typeof rankText.setFill === "function") {
							rankText.setFill("#222");
							suitText.setFill("#222");
						} else {
							if (typeof rankText.setFill === "function") {
								rankText.setFill("#222");
								suitText.setFill("#222");
							} else if (rankText.style) {
								rankText.style.fill = "#222";
								suitText.style.fill = "#222";
							}
						}
					}
				}
			}
		} else {
			rankText.setText('');
			suitText.setText('');
		}
	};
	// Flip card
	self.flip = function (toFaceUp) {
		self.faceUp = toFaceUp;
		self.updateVisual();
	};
	// For drag highlight
	self.highlight = function (color, duration) {
		tween(self, {
			scaleX: 1.1,
			scaleY: 1.1
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: duration || 100,
					easing: tween.easeIn
				});
			}
		});
	};
	// For simple card tap feedback
	self.flash = function () {
		LK.effects.flashObject(self, 0xffff99, 200);
	};
	// Card tap event (handled in game)
	self.down = function (x, y, obj) {};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x0a3a1a
});
/**** 
* Game Code
****/ 
// Draw pile highlight
// Discard pile highlight
// Card front (white, will overlay suit/rank)
// Card back
// Card data
var SUITS = ['♠', '♥', '♦', '♣'];
var RANKS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; // Ace-King
// Layout
var HAND_Y = 2200;
var HAND_X_START = 400;
var HAND_SPACING = 260;
var AI_HAND_Y = 400;
var AI_HAND_X_START = 400;
var PILE_X = 1024;
var DRAW_PILE_Y = 1200;
var DISCARD_PILE_Y = 1500;
// Game state
var deck = [];
var discardPile = [];
var playerHand = [];
var aiHand = [];
var ai = null;
var selectedCardIndex = -1;
var draggingCard = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var canDraw = true;
var canDiscard = false;
var gameOver = false;
var aiMoveTimeout = null;
var playerKnocked = false;
var aiKnocked = false;
var turn = 'player'; // 'player' or 'ai'
var timerText = null;
var timer = null;
var timeLeft = 60; // seconds
// GUI
var infoText = null;
var knockButton = null;
var discardHighlight = null;
var drawHighlight = null;
// Helper: Card rank to string
function cardRankToString(rank) {
	if (rank === 1) return 'A';
	if (rank === 11) return 'J';
	if (rank === 12) return 'Q';
	if (rank === 13) return 'K';
	return '' + rank;
}
// Helper: Card value for 31
function cardValue(card) {
	if (!card) return 0;
	if (card.rank > 10) return 10;
	if (card.rank === 1) return 11;
	return card.rank;
}
// Helper: Best hand value (max sum of one suit)
function bestHandValue(hand) {
	var suitTotals = {
		'♠': 0,
		'♥': 0,
		'♦': 0,
		'♣': 0
	};
	for (var i = 0; i < hand.length; ++i) {
		var c = hand[i];
		suitTotals[c.suit] += cardValue(c);
	}
	var bestSuit = '♠',
		bestValue = suitTotals['♠'];
	for (var s = 0; s < SUITS.length; ++s) {
		if (suitTotals[SUITS[s]] > bestValue) {
			bestSuit = SUITS[s];
			bestValue = suitTotals[SUITS[s]];
		}
	}
	return {
		suit: bestSuit,
		value: bestValue
	};
}
// Helper: Find lowest value card index in hand
function lowestValueCardIndex(hand) {
	var best = bestHandValue(hand);
	var minIdx = -1,
		minVal = 100;
	for (var i = 0; i < hand.length; ++i) {
		var c = hand[i];
		// If not in best suit, prefer to discard
		if (c.suit !== best.suit) return i;
		// Otherwise, lowest value in best suit
		var v = cardValue(c);
		if (v < minVal) {
			minVal = v;
			minIdx = i;
		}
	}
	return minIdx >= 0 ? minIdx : 0;
}
// Helper: Shuffle array
function shuffle(arr) {
	for (var i = arr.length - 1; i > 0; --i) {
		var j = Math.floor(Math.random() * (i + 1));
		var t = arr[i];
		arr[i] = arr[j];
		arr[j] = t;
	}
}
// Helper: Create a new deck (array of Card objects)
function createDeck() {
	var cards = [];
	var idx = 0;
	for (var s = 0; s < SUITS.length; ++s) {
		for (var r = 0; r < RANKS.length; ++r) {
			var c = new Card();
			c.setCard(SUITS[s], RANKS[r], false, idx++);
			cards.push(c);
		}
	}
	shuffle(cards);
	return cards;
}
// Helper: Remove all children from a container
function removeAll(container) {
	while (container.children.length > 0) {
		var c = container.children[0];
		if (c.destroy) c.destroy();else container.removeChild(c);
	}
}
// Helper: Animate card to position
function animateCardTo(card, x, y, onFinish) {
	tween(card, {
		x: x,
		y: y
	}, {
		duration: 250,
		easing: tween.cubicOut,
		onFinish: onFinish
	});
}
// Helper: Show info text
function showInfo(msg, color) {
	infoText.setText(msg);
	if (typeof infoText.setFill === "function") {
		infoText.setFill(color || "#fff");
	} else if (infoText.style) {
		infoText.style.fill = color || "#fff";
	}
	infoText.visible = true;
	tween(infoText, {
		alpha: 1
	}, {
		duration: 100
	});
	LK.setTimeout(function () {
		tween(infoText, {
			alpha: 0
		}, {
			duration: 600,
			onFinish: function onFinish() {
				infoText.visible = false;
			}
		});
	}, 1200);
}
// Helper: End game
function endGame(msg, color) {
	gameOver = true;
	showInfo(msg, color);
	LK.setTimeout(function () {
		LK.showGameOver();
	}, 1200);
}
// Helper: Win game
function winGame(msg, color) {
	gameOver = true;
	showInfo(msg, color);
	LK.setTimeout(function () {
		LK.showYouWin();
	}, 1200);
}
// Helper: Update timer
function updateTimer() {
	timerText.setText(timeLeft + "s");
	if (timeLeft <= 0) {
		endGame("Time's up!", "#f44");
	}
}
// Helper: Lay out player's hand
function layoutPlayerHand() {
	for (var i = 0; i < playerHand.length; ++i) {
		var c = playerHand[i];
		c.x = HAND_X_START + i * HAND_SPACING;
		c.y = HAND_Y;
		c.zIndex = 10 + i;
		c.scaleX = c.scaleY = 1;
		c.faceUp = true;
		c.updateVisual();
	}
}
// Helper: Lay out AI's hand (face down)
function layoutAIHand() {
	for (var i = 0; i < aiHand.length; ++i) {
		var c = aiHand[i];
		c.x = AI_HAND_X_START + i * HAND_SPACING;
		c.y = AI_HAND_Y;
		c.zIndex = 10 + i;
		c.faceUp = false;
		c.updateVisual();
	}
}
// Helper: Lay out piles
function layoutPiles() {
	// Draw pile
	if (deck.length > 0) {
		var top = deck[deck.length - 1];
		top.x = PILE_X - 180;
		top.y = DRAW_PILE_Y;
		top.zIndex = 100;
		top.faceUp = false;
		top.updateVisual();
		top.visible = true;
	}
	// Discard pile
	if (discardPile.length > 0) {
		var top = discardPile[discardPile.length - 1];
		top.x = PILE_X + 180;
		top.y = DISCARD_PILE_Y;
		top.zIndex = 100;
		top.faceUp = true;
		top.updateVisual();
		top.visible = true;
	}
}
// Helper: Remove all cards from stage
function removeAllCards() {
	for (var i = 0; i < deck.length; ++i) deck[i].visible = false;
	for (var i = 0; i < discardPile.length; ++i) discardPile[i].visible = false;
	for (var i = 0; i < playerHand.length; ++i) playerHand[i].visible = false;
	for (var i = 0; i < aiHand.length; ++i) aiHand[i].visible = false;
}
// Helper: Animate AI draw
game.animateAIDraw = function (card, from) {
	card.visible = true;
	if (from === 'deck') {
		card.x = PILE_X - 180;
		card.y = DRAW_PILE_Y;
	} else {
		card.x = PILE_X + 180;
		card.y = DISCARD_PILE_Y;
	}
	animateCardTo(card, AI_HAND_X_START + (aiHand.length - 1) * HAND_SPACING, AI_HAND_Y, function () {
		layoutAIHand();
	});
};
// Helper: Animate AI discard
game.animateAIDiscard = function (card) {
	animateCardTo(card, PILE_X + 180, DISCARD_PILE_Y, function () {
		layoutPiles();
	});
};
// Helper: AI knock
game.aiKnock = function () {
	aiKnocked = true;
	showInfo("AI knocks!", "#ff0");
	// Reveal AI hand
	for (var i = 0; i < aiHand.length; ++i) {
		aiHand[i].faceUp = true;
		aiHand[i].updateVisual();
	}
	// Compare hands after short delay
	LK.setTimeout(function () {
		var playerVal = bestHandValue(playerHand).value;
		var aiVal = bestHandValue(aiHand).value;
		if (aiVal > playerVal) {
			endGame("AI wins! (" + aiVal + " vs " + playerVal + ")", "#f44");
		} else if (playerVal > aiVal) {
			winGame("You win! (" + playerVal + " vs " + aiVal + ")", "#4f4");
		} else {
			endGame("Draw! (" + playerVal + ")", "#fff");
		}
	}, 1200);
};
// Helper: Player knock
function playerKnock() {
	if (gameOver || playerKnocked) return;
	playerKnocked = true;
	showInfo("You knock!", "#ff0");
	// Reveal AI hand
	for (var i = 0; i < aiHand.length; ++i) {
		aiHand[i].faceUp = true;
		aiHand[i].updateVisual();
	}
	// Compare hands after short delay
	LK.setTimeout(function () {
		var playerVal = bestHandValue(playerHand).value;
		var aiVal = bestHandValue(aiHand).value;
		if (playerVal > aiVal) {
			winGame("You win! (" + playerVal + " vs " + aiVal + ")", "#4f4");
		} else if (aiVal > playerVal) {
			endGame("AI wins! (" + aiVal + " vs " + playerVal + ")", "#f44");
		} else {
			endGame("Draw! (" + playerVal + ")", "#fff");
		}
	}, 1200);
}
// Helper: Start AI move timer
function startAIMove() {
	if (aiMoveTimeout) LK.clearTimeout(aiMoveTimeout);
	aiMoveTimeout = LK.setTimeout(function () {
		if (!gameOver && ai && !aiKnocked) {
			ai.makeMove();
			// If AI didn't knock, return turn to player
			if (!aiKnocked) {
				turn = 'player';
				canDraw = true;
				canDiscard = false;
				showInfo("Your turn!", "#fff");
			}
		}
	}, 900);
}
// Helper: Start timer
function startTimer() {
	if (timer) LK.clearInterval(timer);
	timer = LK.setInterval(function () {
		if (gameOver) return;
		timeLeft -= 1;
		updateTimer();
	}, 1000);
}
// Helper: Reset game state
function resetGame() {
	// Remove all cards
	removeAllCards();
	deck = createDeck();
	discardPile = [];
	playerHand = [];
	aiHand = [];
	ai = new AIPlayer();
	selectedCardIndex = -1;
	draggingCard = null;
	canDraw = true;
	canDiscard = false;
	gameOver = false;
	aiMoveTimeout = null;
	playerKnocked = false;
	aiKnocked = false;
	turn = 'player';
	timeLeft = 60;
	// Deal 3 cards to each
	for (var i = 0; i < 3; ++i) {
		var c = deck.pop();
		c.faceUp = true;
		c.visible = true;
		playerHand.push(c);
		game.addChild(c);
	}
	for (var i = 0; i < 3; ++i) {
		var c = deck.pop();
		c.faceUp = false;
		c.visible = true;
		aiHand.push(c);
		game.addChild(c);
	}
	// Discard one card to start
	var c = deck.pop();
	c.faceUp = true;
	c.visible = true;
	discardPile.push(c);
	game.addChild(c);
	// Add remaining deck cards to stage (face down)
	for (var i = 0; i < deck.length; ++i) {
		deck[i].faceUp = false;
		deck[i].visible = true;
		game.addChild(deck[i]);
	}
	// Add AI hand to stage
	for (var i = 0; i < aiHand.length; ++i) {
		aiHand[i].faceUp = false;
		aiHand[i].visible = true;
		game.addChild(aiHand[i]);
	}
	// Layout
	layoutPlayerHand();
	layoutAIHand();
	layoutPiles();
	// Update GUI
	updateHandValueText();
	updateTimer();
	// Start timer
	startTimer();
	// Show info
	showInfo("Your turn!", "#fff");
}
// Helper: Update hand value text
function updateHandValueText() {
	var val = bestHandValue(playerHand);
	handValueText.setText("Best: " + val.value + " " + val.suit);
	if (val.value === 31) {
		winGame("31! You win!", "#4f4");
	}
}
// GUI: Info text
infoText = new Text2('', {
	size: 90,
	fill: "#fff"
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 1024;
infoText.y = 900;
infoText.alpha = 0;
infoText.visible = false;
LK.gui.top.addChild(infoText);
// GUI: Timer
timerText = new Text2('60s', {
	size: 90,
	fill: "#fff"
});
timerText.anchor.set(0.5, 0);
timerText.x = 1024;
timerText.y = 110;
LK.gui.top.addChild(timerText);
// GUI: Hand value
var handValueText = new Text2('', {
	size: 80,
	fill: "#fff"
});
handValueText.anchor.set(0.5, 0);
handValueText.x = 1024;
handValueText.y = HAND_Y + 200;
LK.gui.top.addChild(handValueText);
// GUI: Knock button
knockButton = new Text2('Knock', {
	size: 90,
	fill: "#fff",
	font: "Impact"
});
knockButton.anchor.set(0.5, 0.5);
knockButton.x = 1800;
knockButton.y = HAND_Y + 100;
knockButton.interactive = true;
knockButton.buttonMode = true;
knockButton.alpha = 0.95;
knockButton.down = function (x, y, obj) {
	if (gameOver || !canDraw) return;
	playerKnock();
};
LK.gui.bottom.addChild(knockButton);
// GUI: Discard highlight
discardHighlight = LK.getAsset('discardHighlight', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: PILE_X + 180,
	y: DISCARD_PILE_Y
});
discardHighlight.alpha = 0;
game.addChild(discardHighlight);
// GUI: Draw highlight
drawHighlight = LK.getAsset('drawHighlight', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: PILE_X - 180,
	y: DRAW_PILE_Y
});
drawHighlight.alpha = 0;
game.addChild(drawHighlight);
// --- Input Handling ---
// Touch/click down
game.down = function (x, y, obj) {
	if (gameOver) return;
	// If it's player's turn
	if (turn !== 'player') return;
	// Check if drawing from deck
	if (canDraw && deck.length > 0) {
		var top = deck[deck.length - 1];
		var dx = x - (PILE_X - 180),
			dy = y - DRAW_PILE_Y;
		if (Math.abs(dx) < 110 && Math.abs(dy) < 160) {
			// Draw from deck
			canDraw = false;
			canDiscard = true;
			var card = deck.pop();
			card.faceUp = true;
			card.visible = true;
			playerHand.push(card);
			animateCardTo(card, HAND_X_START + (playerHand.length - 1) * HAND_SPACING, HAND_Y, function () {
				layoutPlayerHand();
				updateHandValueText();
			});
			drawHighlight.alpha = 0.2;
			LK.setTimeout(function () {
				drawHighlight.alpha = 0;
			}, 200);
			return;
		}
	}
	// Check if drawing from discard
	if (canDraw && discardPile.length > 0) {
		var top = discardPile[discardPile.length - 1];
		var dx = x - (PILE_X + 180),
			dy = y - DISCARD_PILE_Y;
		if (Math.abs(dx) < 110 && Math.abs(dy) < 160) {
			// Draw from discard
			canDraw = false;
			canDiscard = true;
			var card = discardPile.pop();
			card.faceUp = true;
			card.visible = true;
			playerHand.push(card);
			animateCardTo(card, HAND_X_START + (playerHand.length - 1) * HAND_SPACING, HAND_Y, function () {
				layoutPlayerHand();
				updateHandValueText();
			});
			discardHighlight.alpha = 0.2;
			LK.setTimeout(function () {
				discardHighlight.alpha = 0;
			}, 200);
			return;
		}
	}
	// If can discard, check if a card in hand is tapped
	if (canDiscard) {
		for (var i = 0; i < playerHand.length; ++i) {
			var c = playerHand[i];
			var dx = x - c.x,
				dy = y - c.y;
			if (Math.abs(dx) < 110 && Math.abs(dy) < 160) {
				// Discard this card
				canDiscard = false;
				var discard = playerHand.splice(i, 1)[0];
				discard.faceUp = true;
				discard.visible = true;
				discardPile.push(discard);
				animateCardTo(discard, PILE_X + 180, DISCARD_PILE_Y, function () {
					layoutPiles();
				});
				discardHighlight.alpha = 0.2;
				LK.setTimeout(function () {
					discardHighlight.alpha = 0;
				}, 200);
				layoutPlayerHand();
				updateHandValueText();
				// End turn, AI moves
				turn = 'ai';
				startAIMove();
				return;
			}
		}
	}
};
// Touch/click up
game.up = function (x, y, obj) {
	// No drag in this version
};
// Touch/click move
game.move = function (x, y, obj) {
	// No drag in this version
};
// Main update loop
game.update = function () {
	// No per-frame logic needed
};
// Start game
resetGame();