/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
// Animal class
var Animal = Container.expand(function (assetId) {
	var self = Container.call(this);
	// Attach animal asset
	var animalGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Escape state
	self.escaped = false;
	// Movement velocity
	self.vx = 0;
	self.vy = 0;
	// Used for mouth open "boost"
	self.boostTimer = 0;
	// Update method
	self.update = function () {
		if (self.escaped) return;
		// Apply velocity
		self.x += self.vx;
		self.y += self.vy;
		// Friction
		self.vx *= 0.92;
		self.vy *= 0.92;
		// Clamp inside snake tummy
		if (self.x < tummy.x - tummy.width / 2 + animalGraphics.width / 2) {
			self.x = tummy.x - tummy.width / 2 + animalGraphics.width / 2;
			self.vx *= -0.5;
		}
		if (self.x > tummy.x + tummy.width / 2 - animalGraphics.width / 2) {
			self.x = tummy.x + tummy.width / 2 - animalGraphics.width / 2;
			self.vx *= -0.5;
		}
		if (self.y < tummy.y - tummy.height / 2 + animalGraphics.height / 2) {
			self.y = tummy.y - tummy.height / 2 + animalGraphics.height / 2;
			self.vy *= -0.5;
		}
		if (self.y > tummy.y + tummy.height / 2 - animalGraphics.height / 2) {
			self.y = tummy.y + tummy.height / 2 - animalGraphics.height / 2;
			self.vy *= -0.5;
		}
	};
	// Escape animation
	self.escape = function () {
		self.escaped = true;
		tween(self, {
			y: self.y - 600,
			alpha: 0
		}, {
			duration: 900,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				self.visible = false;
			}
		});
	};
	return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obsGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Movement
	self.vx = 0;
	self.vy = 0;
	self.update = function () {
		self.x += self.vx;
		self.y += self.vy;
		// Bounce off tummy walls
		if (self.x < tummy.x - tummy.width / 2 + obsGraphics.width / 2) {
			self.x = tummy.x - tummy.width / 2 + obsGraphics.width / 2;
			self.vx *= -1;
		}
		if (self.x > tummy.x + tummy.width / 2 - obsGraphics.width / 2) {
			self.x = tummy.x + tummy.width / 2 - obsGraphics.width / 2;
			self.vx *= -1;
		}
		if (self.y < tummy.y - tummy.height / 2 + obsGraphics.height / 2) {
			self.y = tummy.y - tummy.height / 2 + obsGraphics.height / 2;
			self.vy *= -1;
		}
		if (self.y > tummy.y + tummy.height / 2 - obsGraphics.height / 2) {
			self.y = tummy.y + tummy.height / 2 - obsGraphics.height / 2;
			self.vy *= -1;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Success flash
// Obstacle
// Animal shapes (different colors)
// Snake tummy (background, semi-transparent)
/*
We use simple shapes for animals and obstacles for now.
Each animal will be a different colored ellipse.
The snake's tummy is a large, semi-transparent ellipse in the center.
Obstacles are red ellipses.
*/
// Use facekit: show camera feed as background
facekit.enabled = true;
// Center of the game
var centerX = 2048 / 2;
var centerY = 2732 / 2;
// Snake tummy (background, not interactive)
var tummy = LK.getAsset('snakeTummy', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: centerX,
	y: centerY,
	alpha: 0.7
});
game.addChild(tummy);
// List of animal types and their asset ids
var animalTypes = [{
	id: 'animal_pig',
	name: 'Pig'
}, {
	id: 'animal_cat',
	name: 'Cat'
}, {
	id: 'animal_bee',
	name: 'Bee'
}, {
	id: 'animal_frog',
	name: 'Frog'
}, {
	id: 'animal_polarbear',
	name: 'Polar Bear'
}, {
	id: 'animal_elephant',
	name: 'Elephant'
}, {
	id: 'animal_bird',
	name: 'Bird'
}, {
	id: 'animal_snail',
	name: 'Snail'
}, {
	id: 'animal_axolotl',
	name: 'Axolotl'
}, {
	id: 'animal_fox',
	name: 'Pink Fox'
}, {
	id: 'animal_boybat',
	name: 'Boy Bat'
}, {
	id: 'animal_wolf',
	name: 'Wolf'
}, {
	id: 'animal_chinchilla',
	name: 'Chinchilla'
}, {
	id: 'animal_moth',
	name: 'Moth'
}];
// Shuffle animals for random placement
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;
	}
}
shuffle(animalTypes);
// Create animals
var animals = [];
for (var i = 0; i < animalTypes.length; i++) {
	var a = new Animal(animalTypes[i].id);
	// Place animals in a circle inside the tummy
	var angle = i / animalTypes.length * Math.PI * 2;
	var radius = 500;
	a.x = centerX + Math.cos(angle) * radius;
	a.y = centerY + Math.sin(angle) * radius;
	a.name = animalTypes[i].name;
	animals.push(a);
	game.addChild(a);
}
// Obstacles
var obstacles = [];
for (var i = 0; i < 4; i++) {
	var obs = new Obstacle();
	// Place randomly inside tummy
	obs.x = centerX + (Math.random() - 0.5) * 700;
	obs.y = centerY + (Math.random() - 0.5) * 900;
	// Random velocity
	obs.vx = (Math.random() - 0.5) * 7;
	obs.vy = (Math.random() - 0.5) * 7;
	obstacles.push(obs);
	game.addChild(obs);
}
// Score: animals escaped
var animalsEscaped = 0;
// Score text
var scoreTxt = new Text2('0 / ' + animals.length, {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Instructions text
var instructions = new Text2('Move your face to guide the animals!\nOpen your mouth to help them escape!', {
	size: 70,
	fill: "#fff"
});
instructions.anchor.set(0.5, 0);
LK.gui.bottom.addChild(instructions);
// Main animal to control (the first in the array)
var mainAnimal = animals[0];
// Helper: get facekit mouth center, fallback to center
function getFaceX() {
	if (facekit.mouthCenter && typeof facekit.mouthCenter.x === 'number') {
		return facekit.mouthCenter.x;
	}
	return centerX;
}
function getFaceY() {
	if (facekit.mouthCenter && typeof facekit.mouthCenter.y === 'number') {
		return facekit.mouthCenter.y;
	}
	return centerY;
}
// Helper: check if animal is at escape zone (top of tummy)
function isAtEscapeZone(animal) {
	// Escape zone: top 120px of tummy
	return animal.y < tummy.y - tummy.height / 2 + 120;
}
// Helper: check collision between two containers (circle approx)
function isColliding(a, b) {
	var dx = a.x - b.x;
	var dy = a.y - b.y;
	var dist = Math.sqrt(dx * dx + dy * dy);
	var r1 = a.width || 90;
	var r2 = b.width || 60;
	return dist < r1 / 2 + r2 / 2 - 10;
}
// Flash effect for escape
function flashEscape() {
	var flash = LK.getAsset('escapeFlash', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: centerX,
		y: centerY,
		alpha: 0.7
	});
	game.addChild(flash);
	tween(flash, {
		alpha: 0
	}, {
		duration: 600,
		onFinish: function onFinish() {
			flash.destroy();
		}
	});
}
// Game update
game.update = function () {
	// Update all animals
	for (var i = 0; i < animals.length; i++) {
		animals[i].update();
	}
	// Update obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].update();
	}
	// Control main animal with face
	if (!mainAnimal.escaped) {
		// Move towards face position
		var fx = getFaceX();
		var fy = getFaceY();
		// Clamp to tummy area
		var tx = Math.max(tummy.x - tummy.width / 2 + 90, Math.min(tummy.x + tummy.width / 2 - 90, fx));
		var ty = Math.max(tummy.y - tummy.height / 2 + 90, Math.min(tummy.y + tummy.height / 2 - 90, fy));
		// Smooth follow
		mainAnimal.vx += (tx - mainAnimal.x) * 0.08;
		mainAnimal.vy += (ty - mainAnimal.y) * 0.08;
		// If mouth open, give a boost upwards
		if (facekit.mouthOpen) {
			mainAnimal.vy -= 2.5;
			mainAnimal.boostTimer = 8;
		} else if (mainAnimal.boostTimer > 0) {
			mainAnimal.vy -= 1.2;
			mainAnimal.boostTimer--;
		}
		// If at escape zone, escape!
		if (isAtEscapeZone(mainAnimal)) {
			mainAnimal.escape();
			animalsEscaped++;
			scoreTxt.setText(animalsEscaped + ' / ' + animals.length);
			flashEscape();
			// Next animal becomes main
			var found = false;
			for (var i = 0; i < animals.length; i++) {
				if (!animals[i].escaped) {
					mainAnimal = animals[i];
					found = true;
					break;
				}
			}
			if (!found) {
				// All escaped!
				LK.showYouWin();
			}
		}
	}
	// Collisions: main animal with obstacles
	if (!mainAnimal.escaped) {
		for (var i = 0; i < obstacles.length; i++) {
			if (isColliding(mainAnimal, obstacles[i])) {
				// Flash red, reset animal to center
				LK.effects.flashScreen(0xff0000, 600);
				mainAnimal.x = centerX;
				mainAnimal.y = centerY + 400;
				mainAnimal.vx = 0;
				mainAnimal.vy = 0;
			}
		}
	}
	// Collisions: animals with each other (push apart)
	for (var i = 0; i < animals.length; i++) {
		for (var j = i + 1; j < animals.length; j++) {
			if (animals[i].escaped || animals[j].escaped) continue;
			var dx = animals[i].x - animals[j].x;
			var dy = animals[i].y - animals[j].y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			var minDist = 90;
			if (dist < minDist && dist > 0) {
				var overlap = (minDist - dist) / 2;
				var ox = dx / dist * overlap;
				var oy = dy / dist * overlap;
				animals[i].x += ox;
				animals[i].y += oy;
				animals[j].x -= ox;
				animals[j].y -= oy;
			}
		}
	}
};
// No touch controls: all control is via facekit
// No music, no sound, no pause, no game over handling (handled by LK) /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
// Animal class
var Animal = Container.expand(function (assetId) {
	var self = Container.call(this);
	// Attach animal asset
	var animalGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Escape state
	self.escaped = false;
	// Movement velocity
	self.vx = 0;
	self.vy = 0;
	// Used for mouth open "boost"
	self.boostTimer = 0;
	// Update method
	self.update = function () {
		if (self.escaped) return;
		// Apply velocity
		self.x += self.vx;
		self.y += self.vy;
		// Friction
		self.vx *= 0.92;
		self.vy *= 0.92;
		// Clamp inside snake tummy
		if (self.x < tummy.x - tummy.width / 2 + animalGraphics.width / 2) {
			self.x = tummy.x - tummy.width / 2 + animalGraphics.width / 2;
			self.vx *= -0.5;
		}
		if (self.x > tummy.x + tummy.width / 2 - animalGraphics.width / 2) {
			self.x = tummy.x + tummy.width / 2 - animalGraphics.width / 2;
			self.vx *= -0.5;
		}
		if (self.y < tummy.y - tummy.height / 2 + animalGraphics.height / 2) {
			self.y = tummy.y - tummy.height / 2 + animalGraphics.height / 2;
			self.vy *= -0.5;
		}
		if (self.y > tummy.y + tummy.height / 2 - animalGraphics.height / 2) {
			self.y = tummy.y + tummy.height / 2 - animalGraphics.height / 2;
			self.vy *= -0.5;
		}
	};
	// Escape animation
	self.escape = function () {
		self.escaped = true;
		tween(self, {
			y: self.y - 600,
			alpha: 0
		}, {
			duration: 900,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				self.visible = false;
			}
		});
	};
	return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obsGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Movement
	self.vx = 0;
	self.vy = 0;
	self.update = function () {
		self.x += self.vx;
		self.y += self.vy;
		// Bounce off tummy walls
		if (self.x < tummy.x - tummy.width / 2 + obsGraphics.width / 2) {
			self.x = tummy.x - tummy.width / 2 + obsGraphics.width / 2;
			self.vx *= -1;
		}
		if (self.x > tummy.x + tummy.width / 2 - obsGraphics.width / 2) {
			self.x = tummy.x + tummy.width / 2 - obsGraphics.width / 2;
			self.vx *= -1;
		}
		if (self.y < tummy.y - tummy.height / 2 + obsGraphics.height / 2) {
			self.y = tummy.y - tummy.height / 2 + obsGraphics.height / 2;
			self.vy *= -1;
		}
		if (self.y > tummy.y + tummy.height / 2 - obsGraphics.height / 2) {
			self.y = tummy.y + tummy.height / 2 - obsGraphics.height / 2;
			self.vy *= -1;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Success flash
// Obstacle
// Animal shapes (different colors)
// Snake tummy (background, semi-transparent)
/*
We use simple shapes for animals and obstacles for now.
Each animal will be a different colored ellipse.
The snake's tummy is a large, semi-transparent ellipse in the center.
Obstacles are red ellipses.
*/
// Use facekit: show camera feed as background
facekit.enabled = true;
// Center of the game
var centerX = 2048 / 2;
var centerY = 2732 / 2;
// Snake tummy (background, not interactive)
var tummy = LK.getAsset('snakeTummy', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: centerX,
	y: centerY,
	alpha: 0.7
});
game.addChild(tummy);
// List of animal types and their asset ids
var animalTypes = [{
	id: 'animal_pig',
	name: 'Pig'
}, {
	id: 'animal_cat',
	name: 'Cat'
}, {
	id: 'animal_bee',
	name: 'Bee'
}, {
	id: 'animal_frog',
	name: 'Frog'
}, {
	id: 'animal_polarbear',
	name: 'Polar Bear'
}, {
	id: 'animal_elephant',
	name: 'Elephant'
}, {
	id: 'animal_bird',
	name: 'Bird'
}, {
	id: 'animal_snail',
	name: 'Snail'
}, {
	id: 'animal_axolotl',
	name: 'Axolotl'
}, {
	id: 'animal_fox',
	name: 'Pink Fox'
}, {
	id: 'animal_boybat',
	name: 'Boy Bat'
}, {
	id: 'animal_wolf',
	name: 'Wolf'
}, {
	id: 'animal_chinchilla',
	name: 'Chinchilla'
}, {
	id: 'animal_moth',
	name: 'Moth'
}];
// Shuffle animals for random placement
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;
	}
}
shuffle(animalTypes);
// Create animals
var animals = [];
for (var i = 0; i < animalTypes.length; i++) {
	var a = new Animal(animalTypes[i].id);
	// Place animals in a circle inside the tummy
	var angle = i / animalTypes.length * Math.PI * 2;
	var radius = 500;
	a.x = centerX + Math.cos(angle) * radius;
	a.y = centerY + Math.sin(angle) * radius;
	a.name = animalTypes[i].name;
	animals.push(a);
	game.addChild(a);
}
// Obstacles
var obstacles = [];
for (var i = 0; i < 4; i++) {
	var obs = new Obstacle();
	// Place randomly inside tummy
	obs.x = centerX + (Math.random() - 0.5) * 700;
	obs.y = centerY + (Math.random() - 0.5) * 900;
	// Random velocity
	obs.vx = (Math.random() - 0.5) * 7;
	obs.vy = (Math.random() - 0.5) * 7;
	obstacles.push(obs);
	game.addChild(obs);
}
// Score: animals escaped
var animalsEscaped = 0;
// Score text
var scoreTxt = new Text2('0 / ' + animals.length, {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Instructions text
var instructions = new Text2('Move your face to guide the animals!\nOpen your mouth to help them escape!', {
	size: 70,
	fill: "#fff"
});
instructions.anchor.set(0.5, 0);
LK.gui.bottom.addChild(instructions);
// Main animal to control (the first in the array)
var mainAnimal = animals[0];
// Helper: get facekit mouth center, fallback to center
function getFaceX() {
	if (facekit.mouthCenter && typeof facekit.mouthCenter.x === 'number') {
		return facekit.mouthCenter.x;
	}
	return centerX;
}
function getFaceY() {
	if (facekit.mouthCenter && typeof facekit.mouthCenter.y === 'number') {
		return facekit.mouthCenter.y;
	}
	return centerY;
}
// Helper: check if animal is at escape zone (top of tummy)
function isAtEscapeZone(animal) {
	// Escape zone: top 120px of tummy
	return animal.y < tummy.y - tummy.height / 2 + 120;
}
// Helper: check collision between two containers (circle approx)
function isColliding(a, b) {
	var dx = a.x - b.x;
	var dy = a.y - b.y;
	var dist = Math.sqrt(dx * dx + dy * dy);
	var r1 = a.width || 90;
	var r2 = b.width || 60;
	return dist < r1 / 2 + r2 / 2 - 10;
}
// Flash effect for escape
function flashEscape() {
	var flash = LK.getAsset('escapeFlash', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: centerX,
		y: centerY,
		alpha: 0.7
	});
	game.addChild(flash);
	tween(flash, {
		alpha: 0
	}, {
		duration: 600,
		onFinish: function onFinish() {
			flash.destroy();
		}
	});
}
// Game update
game.update = function () {
	// Update all animals
	for (var i = 0; i < animals.length; i++) {
		animals[i].update();
	}
	// Update obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].update();
	}
	// Control main animal with face
	if (!mainAnimal.escaped) {
		// Move towards face position
		var fx = getFaceX();
		var fy = getFaceY();
		// Clamp to tummy area
		var tx = Math.max(tummy.x - tummy.width / 2 + 90, Math.min(tummy.x + tummy.width / 2 - 90, fx));
		var ty = Math.max(tummy.y - tummy.height / 2 + 90, Math.min(tummy.y + tummy.height / 2 - 90, fy));
		// Smooth follow
		mainAnimal.vx += (tx - mainAnimal.x) * 0.08;
		mainAnimal.vy += (ty - mainAnimal.y) * 0.08;
		// If mouth open, give a boost upwards
		if (facekit.mouthOpen) {
			mainAnimal.vy -= 2.5;
			mainAnimal.boostTimer = 8;
		} else if (mainAnimal.boostTimer > 0) {
			mainAnimal.vy -= 1.2;
			mainAnimal.boostTimer--;
		}
		// If at escape zone, escape!
		if (isAtEscapeZone(mainAnimal)) {
			mainAnimal.escape();
			animalsEscaped++;
			scoreTxt.setText(animalsEscaped + ' / ' + animals.length);
			flashEscape();
			// Next animal becomes main
			var found = false;
			for (var i = 0; i < animals.length; i++) {
				if (!animals[i].escaped) {
					mainAnimal = animals[i];
					found = true;
					break;
				}
			}
			if (!found) {
				// All escaped!
				LK.showYouWin();
			}
		}
	}
	// Collisions: main animal with obstacles
	if (!mainAnimal.escaped) {
		for (var i = 0; i < obstacles.length; i++) {
			if (isColliding(mainAnimal, obstacles[i])) {
				// Flash red, reset animal to center
				LK.effects.flashScreen(0xff0000, 600);
				mainAnimal.x = centerX;
				mainAnimal.y = centerY + 400;
				mainAnimal.vx = 0;
				mainAnimal.vy = 0;
			}
		}
	}
	// Collisions: animals with each other (push apart)
	for (var i = 0; i < animals.length; i++) {
		for (var j = i + 1; j < animals.length; j++) {
			if (animals[i].escaped || animals[j].escaped) continue;
			var dx = animals[i].x - animals[j].x;
			var dy = animals[i].y - animals[j].y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			var minDist = 90;
			if (dist < minDist && dist > 0) {
				var overlap = (minDist - dist) / 2;
				var ox = dx / dist * overlap;
				var oy = dy / dist * overlap;
				animals[i].x += ox;
				animals[i].y += oy;
				animals[j].x -= ox;
				animals[j].y -= oy;
			}
		}
	}
};
// No touch controls: all control is via facekit
// No music, no sound, no pause, no game over handling (handled by LK)