/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	currentLevel: 1
});
/**** 
* Classes
****/ 
var Agent = Container.expand(function () {
	var self = Container.call(this);
	// Agent properties
	self.speed = 10;
	self.state = 'ready'; // ready, charging, breaching, recovering
	self.chargeSpeed = 0;
	// Create agent asset
	var agentAsset = self.attachAsset('agent', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create battering ram
	var ramAsset = self.attachAsset('ram', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 300,
		y: 0
	});
	// Method to charge at the door
	self.charge = function () {
		if (self.state !== 'ready') {
			return;
		}
		self.state = 'charging';
		self.chargeSpeed = 0;
	};
	// Method to update agent's position and state
	self.update = function () {
		if (self.state === 'charging') {
			// Increase charge speed
			self.chargeSpeed += 1;
			self.x += self.chargeSpeed;
		} else if (self.state === 'recovering') {
			// Move back to starting position
			self.x -= self.speed;
			if (self.x <= self.startX) {
				self.x = self.startX;
				self.state = 'ready';
			}
		}
	};
	// Method to reset agent
	self.reset = function (startX, startY) {
		self.startX = startX;
		self.startY = startY;
		self.x = startX;
		self.y = startY;
		self.state = 'ready';
		self.chargeSpeed = 0;
	};
	return self;
});
var Door = Container.expand(function () {
	var self = Container.call(this);
	// Door properties
	self.health = 100;
	self.breachable = false;
	self.breached = false;
	// Create door asset
	var doorAsset = self.attachAsset('door', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Doorknob removed
	// Breach effect (hidden initially)
	var breachEffect = self.attachAsset('breach_effect', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0
	});
	// Method to animate the breach
	self.breach = function () {
		if (self.breached) {
			return;
		}
		self.breached = true;
		// Flash the breach effect
		breachEffect.alpha = 0.8;
		tween(breachEffect, {
			alpha: 0
		}, {
			duration: 500
		});
		// Play door breaking sound
		LK.getSound('breach').play();
		// Animate door opening
		tween(doorAsset, {
			rotation: Math.PI / 2
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Play the FBI OPEN UP sound after door opens
				LK.getSound('fbi_open_up').play();
			}
		});
	};
	// Method to reset door
	self.reset = function () {
		doorAsset.rotation = 0;
		self.breached = false;
		self.health = 100;
		breachEffect.alpha = 0;
	};
	// Method to set the door's difficulty level
	self.setLevel = function (level) {
		// Adjust door properties based on level
		self.health = 100 + level * 20;
	};
	return self;
});
var InstructionText = Container.expand(function () {
	var self = Container.call(this);
	// Create instruction text
	var instructionText = new Text2('TAP AND HOLD TO CHARGE\nRELEASE AT THE RIGHT MOMENT', {
		size: 60,
		fill: 0xFFFFFF
	});
	instructionText.anchor.set(0.5, 0);
	self.addChild(instructionText);
	// Method to update instruction text
	self.updateText = function (text) {
		instructionText.setText(text);
	};
	return self;
});
var LevelInfo = Container.expand(function () {
	var self = Container.call(this);
	// Create level text
	var levelText = new Text2('LEVEL 1', {
		size: 80,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0.5, 0);
	self.addChild(levelText);
	// Create score text
	var scoreText = new Text2('SCORE: 0', {
		size: 60,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(0.5, 0);
	scoreText.y = 100;
	self.addChild(scoreText);
	// Method to update level display
	self.updateLevel = function (level) {
		levelText.setText('LEVEL ' + level);
	};
	// Method to update score display
	self.updateScore = function (score) {
		scoreText.setText('SCORE: ' + score);
	};
	return self;
});
var ProgressBar = Container.expand(function () {
	var self = Container.call(this);
	// Properties
	self.currentValue = 0;
	self.maxValue = 100;
	// Background bar
	var bgBar = self.attachAsset('progressBarBg', {
		anchorX: 0,
		anchorY: 0.5
	});
	// Progress bar
	var progressBar = self.attachAsset('progressBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	// Target zone for perfect timing
	var targetZone = self.attachAsset('targetZone', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.7
	});
	// Update the progress bar display
	self.updateProgress = function (value) {
		self.currentValue = value;
		if (value > self.maxValue) {
			self.currentValue = self.maxValue;
		}
		if (value < 0) {
			self.currentValue = 0;
		}
		var percentage = self.currentValue / self.maxValue;
		progressBar.scale.x = percentage;
	};
	// Set the target zone position
	self.setTargetZone = function (min, max) {
		var center = (min + max) / 2;
		var width = max - min;
		targetZone.x = bgBar.width * center;
		targetZone.scale.x = width;
	};
	// Check if the current value is in the target zone
	self.isInTargetZone = function () {
		var minTarget = (targetZone.x - targetZone.width * targetZone.scale.x / 2) / bgBar.width * self.maxValue;
		var maxTarget = (targetZone.x + targetZone.width * targetZone.scale.x / 2) / bgBar.width * self.maxValue;
		return self.currentValue >= minTarget && self.currentValue <= maxTarget;
	};
	// Reset the progress bar
	self.reset = function () {
		self.updateProgress(0);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x333333
});
/**** 
* Game Code
****/ 
// Game variables
var currentLevel = storage.currentLevel || 1;
var score = 0;
var highScore = storage.highScore || 0;
var isCharging = false;
var gameState = 'ready'; // ready, charging, breaching, success, fail
// Create game elements
var door = new Door();
var agent = new Agent();
var progressBar = new ProgressBar();
var levelInfo = new LevelInfo();
var instructionText = new InstructionText();
// Initialize level parameters based on difficulty
var levelParams = {
	chargeSpeed: 1,
	targetMin: 0.7,
	targetMax: 0.8,
	timeLimit: 5000
};
// Set up game timer
var gameTimer = null;
// Initialize game layout
function initGame() {
	// Play background music
	LK.playMusic('game_theme');
	// Set up door
	door.x = 2048 / 2 + 500;
	door.y = 2732 / 2;
	door.setLevel(currentLevel);
	game.addChild(door);
	// Set up agent
	agent.reset(400, 2732 / 2);
	game.addChild(agent);
	// Set up progress bar
	progressBar.x = 2048 / 2 - 750;
	progressBar.y = 2732 - 300;
	progressBar.setTargetZone(levelParams.targetMin, levelParams.targetMax);
	game.addChild(progressBar);
	// Set up level info
	levelInfo.x = 2048 / 2;
	levelInfo.y = 150;
	levelInfo.updateLevel(currentLevel);
	levelInfo.updateScore(score);
	game.addChild(levelInfo);
	// Set up instruction text
	instructionText.x = 2048 / 2;
	instructionText.y = 2732 - 450;
	game.addChild(instructionText);
	// Update level parameters based on current level
	updateLevelParams();
}
// Update level parameters based on difficulty
function updateLevelParams() {
	levelParams.chargeSpeed = 1 + currentLevel * 0.2;
	levelParams.targetMin = Math.max(0.4, 0.8 - currentLevel * 0.05);
	levelParams.targetMax = Math.min(0.9, levelParams.targetMin + 0.1);
	levelParams.timeLimit = Math.max(2000, 5000 - currentLevel * 200);
	// Update progress bar target zone
	progressBar.setTargetZone(levelParams.targetMin, levelParams.targetMax);
}
// Reset level for next attempt
function resetLevel() {
	door.reset();
	agent.reset(400, 2732 / 2);
	progressBar.reset();
	gameState = 'ready';
	isCharging = false;
	if (gameTimer) {
		LK.clearTimeout(gameTimer);
		gameTimer = null;
	}
	instructionText.updateText('TAP AND HOLD TO CHARGE\nRELEASE AT THE RIGHT MOMENT');
}
// Start next level
function nextLevel() {
	currentLevel++;
	storage.currentLevel = currentLevel;
	// Update level display
	levelInfo.updateLevel(currentLevel);
	// Update level parameters
	updateLevelParams();
	// Reset level
	resetLevel();
}
// Handle successful breach
function handleSuccess() {
	gameState = 'success';
	// Calculate score based on timing accuracy
	var accuracyBonus = progressBar.isInTargetZone() ? 100 : 50;
	var levelBonus = currentLevel * 50;
	var levelScore = 100 + accuracyBonus + levelBonus;
	// Update total score
	score += levelScore;
	levelInfo.updateScore(score);
	// Update high score if needed
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
	}
	// Show success message
	instructionText.updateText('PERFECT BREACH! +' + levelScore + ' POINTS');
	// Play success sound
	LK.getSound('success').play();
	// Go to next level after delay
	LK.setTimeout(function () {
		nextLevel();
	}, 2000);
}
// Handle failed breach
function handleFail(reason) {
	gameState = 'fail';
	// Show fail message
	instructionText.updateText('BREACH FAILED: ' + reason);
	// Play fail sound
	LK.getSound('fail').play();
	// Reset level after delay
	LK.setTimeout(function () {
		resetLevel();
	}, 2000);
}
// Game input handlers
game.down = function (x, y, obj) {
	if (gameState !== 'ready') {
		return;
	}
	// Start charging
	isCharging = true;
	gameState = 'charging';
	// Set time limit for charge
	gameTimer = LK.setTimeout(function () {
		if (gameState === 'charging') {
			handleFail('TIME EXPIRED');
		}
	}, levelParams.timeLimit);
};
game.up = function (x, y, obj) {
	if (gameState !== 'charging' || !isCharging) {
		return;
	}
	// Stop charging and check breach success
	isCharging = false;
	gameState = 'breaching';
	// Clear timeout
	if (gameTimer) {
		LK.clearTimeout(gameTimer);
		gameTimer = null;
	}
	// Check if breach was successful based on progress bar
	if (progressBar.currentValue > 0) {
		if (progressBar.isInTargetZone()) {
			// Perfect breach
			door.breach();
			handleSuccess();
		} else if (progressBar.currentValue > levelParams.targetMax * 100) {
			// Too much force
			handleFail('TOO MUCH FORCE');
		} else {
			// Not enough force
			handleFail('NOT ENOUGH FORCE');
		}
	} else {
		// No charge
		handleFail('NO CHARGE APPLIED');
	}
};
// Game update function
game.update = function () {
	// Update agent
	agent.update();
	// Update charging progress
	if (gameState === 'charging' && isCharging) {
		var newValue = progressBar.currentValue + levelParams.chargeSpeed;
		progressBar.updateProgress(newValue);
		// If progress exceeds max, auto-release
		if (progressBar.currentValue >= 100) {
			// Simulate releasing the charge
			game.up(0, 0, null);
		}
	}
};
// Initialize the game
initGame(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	currentLevel: 1
});
/**** 
* Classes
****/ 
var Agent = Container.expand(function () {
	var self = Container.call(this);
	// Agent properties
	self.speed = 10;
	self.state = 'ready'; // ready, charging, breaching, recovering
	self.chargeSpeed = 0;
	// Create agent asset
	var agentAsset = self.attachAsset('agent', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create battering ram
	var ramAsset = self.attachAsset('ram', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 300,
		y: 0
	});
	// Method to charge at the door
	self.charge = function () {
		if (self.state !== 'ready') {
			return;
		}
		self.state = 'charging';
		self.chargeSpeed = 0;
	};
	// Method to update agent's position and state
	self.update = function () {
		if (self.state === 'charging') {
			// Increase charge speed
			self.chargeSpeed += 1;
			self.x += self.chargeSpeed;
		} else if (self.state === 'recovering') {
			// Move back to starting position
			self.x -= self.speed;
			if (self.x <= self.startX) {
				self.x = self.startX;
				self.state = 'ready';
			}
		}
	};
	// Method to reset agent
	self.reset = function (startX, startY) {
		self.startX = startX;
		self.startY = startY;
		self.x = startX;
		self.y = startY;
		self.state = 'ready';
		self.chargeSpeed = 0;
	};
	return self;
});
var Door = Container.expand(function () {
	var self = Container.call(this);
	// Door properties
	self.health = 100;
	self.breachable = false;
	self.breached = false;
	// Create door asset
	var doorAsset = self.attachAsset('door', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Doorknob removed
	// Breach effect (hidden initially)
	var breachEffect = self.attachAsset('breach_effect', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0
	});
	// Method to animate the breach
	self.breach = function () {
		if (self.breached) {
			return;
		}
		self.breached = true;
		// Flash the breach effect
		breachEffect.alpha = 0.8;
		tween(breachEffect, {
			alpha: 0
		}, {
			duration: 500
		});
		// Play door breaking sound
		LK.getSound('breach').play();
		// Animate door opening
		tween(doorAsset, {
			rotation: Math.PI / 2
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Play the FBI OPEN UP sound after door opens
				LK.getSound('fbi_open_up').play();
			}
		});
	};
	// Method to reset door
	self.reset = function () {
		doorAsset.rotation = 0;
		self.breached = false;
		self.health = 100;
		breachEffect.alpha = 0;
	};
	// Method to set the door's difficulty level
	self.setLevel = function (level) {
		// Adjust door properties based on level
		self.health = 100 + level * 20;
	};
	return self;
});
var InstructionText = Container.expand(function () {
	var self = Container.call(this);
	// Create instruction text
	var instructionText = new Text2('TAP AND HOLD TO CHARGE\nRELEASE AT THE RIGHT MOMENT', {
		size: 60,
		fill: 0xFFFFFF
	});
	instructionText.anchor.set(0.5, 0);
	self.addChild(instructionText);
	// Method to update instruction text
	self.updateText = function (text) {
		instructionText.setText(text);
	};
	return self;
});
var LevelInfo = Container.expand(function () {
	var self = Container.call(this);
	// Create level text
	var levelText = new Text2('LEVEL 1', {
		size: 80,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0.5, 0);
	self.addChild(levelText);
	// Create score text
	var scoreText = new Text2('SCORE: 0', {
		size: 60,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(0.5, 0);
	scoreText.y = 100;
	self.addChild(scoreText);
	// Method to update level display
	self.updateLevel = function (level) {
		levelText.setText('LEVEL ' + level);
	};
	// Method to update score display
	self.updateScore = function (score) {
		scoreText.setText('SCORE: ' + score);
	};
	return self;
});
var ProgressBar = Container.expand(function () {
	var self = Container.call(this);
	// Properties
	self.currentValue = 0;
	self.maxValue = 100;
	// Background bar
	var bgBar = self.attachAsset('progressBarBg', {
		anchorX: 0,
		anchorY: 0.5
	});
	// Progress bar
	var progressBar = self.attachAsset('progressBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	// Target zone for perfect timing
	var targetZone = self.attachAsset('targetZone', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.7
	});
	// Update the progress bar display
	self.updateProgress = function (value) {
		self.currentValue = value;
		if (value > self.maxValue) {
			self.currentValue = self.maxValue;
		}
		if (value < 0) {
			self.currentValue = 0;
		}
		var percentage = self.currentValue / self.maxValue;
		progressBar.scale.x = percentage;
	};
	// Set the target zone position
	self.setTargetZone = function (min, max) {
		var center = (min + max) / 2;
		var width = max - min;
		targetZone.x = bgBar.width * center;
		targetZone.scale.x = width;
	};
	// Check if the current value is in the target zone
	self.isInTargetZone = function () {
		var minTarget = (targetZone.x - targetZone.width * targetZone.scale.x / 2) / bgBar.width * self.maxValue;
		var maxTarget = (targetZone.x + targetZone.width * targetZone.scale.x / 2) / bgBar.width * self.maxValue;
		return self.currentValue >= minTarget && self.currentValue <= maxTarget;
	};
	// Reset the progress bar
	self.reset = function () {
		self.updateProgress(0);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x333333
});
/**** 
* Game Code
****/ 
// Game variables
var currentLevel = storage.currentLevel || 1;
var score = 0;
var highScore = storage.highScore || 0;
var isCharging = false;
var gameState = 'ready'; // ready, charging, breaching, success, fail
// Create game elements
var door = new Door();
var agent = new Agent();
var progressBar = new ProgressBar();
var levelInfo = new LevelInfo();
var instructionText = new InstructionText();
// Initialize level parameters based on difficulty
var levelParams = {
	chargeSpeed: 1,
	targetMin: 0.7,
	targetMax: 0.8,
	timeLimit: 5000
};
// Set up game timer
var gameTimer = null;
// Initialize game layout
function initGame() {
	// Play background music
	LK.playMusic('game_theme');
	// Set up door
	door.x = 2048 / 2 + 500;
	door.y = 2732 / 2;
	door.setLevel(currentLevel);
	game.addChild(door);
	// Set up agent
	agent.reset(400, 2732 / 2);
	game.addChild(agent);
	// Set up progress bar
	progressBar.x = 2048 / 2 - 750;
	progressBar.y = 2732 - 300;
	progressBar.setTargetZone(levelParams.targetMin, levelParams.targetMax);
	game.addChild(progressBar);
	// Set up level info
	levelInfo.x = 2048 / 2;
	levelInfo.y = 150;
	levelInfo.updateLevel(currentLevel);
	levelInfo.updateScore(score);
	game.addChild(levelInfo);
	// Set up instruction text
	instructionText.x = 2048 / 2;
	instructionText.y = 2732 - 450;
	game.addChild(instructionText);
	// Update level parameters based on current level
	updateLevelParams();
}
// Update level parameters based on difficulty
function updateLevelParams() {
	levelParams.chargeSpeed = 1 + currentLevel * 0.2;
	levelParams.targetMin = Math.max(0.4, 0.8 - currentLevel * 0.05);
	levelParams.targetMax = Math.min(0.9, levelParams.targetMin + 0.1);
	levelParams.timeLimit = Math.max(2000, 5000 - currentLevel * 200);
	// Update progress bar target zone
	progressBar.setTargetZone(levelParams.targetMin, levelParams.targetMax);
}
// Reset level for next attempt
function resetLevel() {
	door.reset();
	agent.reset(400, 2732 / 2);
	progressBar.reset();
	gameState = 'ready';
	isCharging = false;
	if (gameTimer) {
		LK.clearTimeout(gameTimer);
		gameTimer = null;
	}
	instructionText.updateText('TAP AND HOLD TO CHARGE\nRELEASE AT THE RIGHT MOMENT');
}
// Start next level
function nextLevel() {
	currentLevel++;
	storage.currentLevel = currentLevel;
	// Update level display
	levelInfo.updateLevel(currentLevel);
	// Update level parameters
	updateLevelParams();
	// Reset level
	resetLevel();
}
// Handle successful breach
function handleSuccess() {
	gameState = 'success';
	// Calculate score based on timing accuracy
	var accuracyBonus = progressBar.isInTargetZone() ? 100 : 50;
	var levelBonus = currentLevel * 50;
	var levelScore = 100 + accuracyBonus + levelBonus;
	// Update total score
	score += levelScore;
	levelInfo.updateScore(score);
	// Update high score if needed
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
	}
	// Show success message
	instructionText.updateText('PERFECT BREACH! +' + levelScore + ' POINTS');
	// Play success sound
	LK.getSound('success').play();
	// Go to next level after delay
	LK.setTimeout(function () {
		nextLevel();
	}, 2000);
}
// Handle failed breach
function handleFail(reason) {
	gameState = 'fail';
	// Show fail message
	instructionText.updateText('BREACH FAILED: ' + reason);
	// Play fail sound
	LK.getSound('fail').play();
	// Reset level after delay
	LK.setTimeout(function () {
		resetLevel();
	}, 2000);
}
// Game input handlers
game.down = function (x, y, obj) {
	if (gameState !== 'ready') {
		return;
	}
	// Start charging
	isCharging = true;
	gameState = 'charging';
	// Set time limit for charge
	gameTimer = LK.setTimeout(function () {
		if (gameState === 'charging') {
			handleFail('TIME EXPIRED');
		}
	}, levelParams.timeLimit);
};
game.up = function (x, y, obj) {
	if (gameState !== 'charging' || !isCharging) {
		return;
	}
	// Stop charging and check breach success
	isCharging = false;
	gameState = 'breaching';
	// Clear timeout
	if (gameTimer) {
		LK.clearTimeout(gameTimer);
		gameTimer = null;
	}
	// Check if breach was successful based on progress bar
	if (progressBar.currentValue > 0) {
		if (progressBar.isInTargetZone()) {
			// Perfect breach
			door.breach();
			handleSuccess();
		} else if (progressBar.currentValue > levelParams.targetMax * 100) {
			// Too much force
			handleFail('TOO MUCH FORCE');
		} else {
			// Not enough force
			handleFail('NOT ENOUGH FORCE');
		}
	} else {
		// No charge
		handleFail('NO CHARGE APPLIED');
	}
};
// Game update function
game.update = function () {
	// Update agent
	agent.update();
	// Update charging progress
	if (gameState === 'charging' && isCharging) {
		var newValue = progressBar.currentValue + levelParams.chargeSpeed;
		progressBar.updateProgress(newValue);
		// If progress exceeds max, auto-release
		if (progressBar.currentValue >= 100) {
			// Simulate releasing the charge
			game.up(0, 0, null);
		}
	}
};
// Initialize the game
initGame();