var canvas = document.getElementById("theCanvas");
var ctx = canvas.getContext("2d");

var Tween = createjs.Tween;
var Ease = createjs.Ease;
createjs.Ticker.timingMode = createjs.Ticker.RAF;

var font = "Montserrat";
var screenWidth = 1000;

var imagesToLoad = [
	"key",
	"monies",
	//coal
	"coalPile",
	"fire1",
	"fire2",
	"fire3",
	"fire4",
	"furnace",
	"shovel",
	//wind
	"windBase",
	"windBlades",
	"windArrow",
	//solar
	"solarPanel",
	"sun",
	//fission
	"tower",
	"nuke"
];
var images = {};

for (var i = 0; i < imagesToLoad.length; i++) {
	images[imagesToLoad[i]] = new Image();
	images[imagesToLoad[i]].src = imagesToLoad[i]+".png";
}

var soundsToLoad = [
	"windmill",
	"windmillCash",
	"fire",
	"fireWhoosh",
	"rumble",
	"drone",
	"warn"
];
var sounds = {};

for (var i = 0; i < soundsToLoad.length; i++) {
	sounds[soundsToLoad[i]] = new Audio(soundsToLoad[i]+".wav");
}
sounds["fireWhoosh"].volume = 0.6;

var upToSource = 0;
var energySources = [
	{
		"name": "coal",
		"draw": drawCoal,
		"logic": coalLogic,
		"price": 100,
		"costToBuy": 0,
		"nextCoalCounter": 0,
		"coalDrawOffset": -(screenWidth/2),
		"coalInAnim": -1,
		"fireAnim": 0,
		"firstFrame": true,
		"cashParticles": []
	},
	{
		"name": "wind",
		"draw": drawWind,
		"logic": windLogic,
		"price": 400,
		"costToBuy": 2400,
		"unlocked": false,
		"firstFrame": true,
		"alreadyHit": false,
		"canHit": true,
		"wheelPos": 0,
		"resetTimeout": null,
		"smokeParticles": [],
		"cashParticles": [],
		"priceDownInterval": null
	},
	{
		"name": "solar",
		"draw": drawSolar,
		"logic": solarLogic,
		"price": 460,
		"costToBuy": 8000,
		"unlocked": false,
		"firstFrame": true,
		"leftKey": false,
		"rightKey": false,
		"panelAngle": 0,
		"sunPosition": 0,
		"sunDirection": 1,
		"sunQuality": 0,
		"cashParticles": []
	},
	{
		"name": "fission",
		"draw": drawFission,
		"logic": fissionLogic,
		"price": 2200,
		"costToBuy": 18000,
		"unlocked": false,
		"firstFrame": true,
		"reactorHeat": 0.5,
		"disabled": false,
		"cashParticles": []
	}
];
var generalAnim = {
	"newEnergyReveal": 1
};
var playerScore = 0;
var currentYear = 0;

window.requestAnimationFrame(drawAll); //get this party started

function drawAll() {
	ctx.fillStyle = "#000000";
	ctx.fillRect(0,0,screenWidth,600); //they shouldn't see this, but just in case
	//calculate bars
	var extraWidth = 0;
	var barWidth = 0;
	if (generalAnim["newEnergyReveal"] < 1) {
		extraWidth = (screenWidth/(upToSource+1))*generalAnim["newEnergyReveal"];
		barWidth = (screenWidth-extraWidth)/(upToSource);
	}
	else {
		barWidth = (screenWidth/(upToSource+1));
	}
	for (var i = 0; i < upToSource+1; i++) {
		ctx.save();
		if (generalAnim["newEnergyReveal"] < 1 && i === upToSource) { //the new bar
			ctx.translate(i * barWidth + extraWidth / 2, 300);
			ctx.beginPath();
			ctx.rect(-extraWidth / 2, -300, extraWidth, 600);
			ctx.clip();
			energySources[i]["draw"](extraWidth);
		}
		else { //the rest of the bars
			ctx.translate(i * barWidth + barWidth / 2, 300);
			ctx.beginPath();
			ctx.rect(-barWidth / 2, -300, barWidth, 600);
			ctx.clip();
			energySources[i]["draw"](barWidth);
		}
		ctx.restore();
	}
	//draw top bar
	ctx.fillStyle = "#ebebeb";
	ctx.fillRect(0,0,screenWidth,60);
	ctx.fillStyle = "#000000";
	ctx.font = "500 24px " + font;
	ctx.fillText("$"+Math.floor(playerScore), 20, 40);
	ctx.fillText("Year: "+Math.floor(currentYear+1970), 140, 40);

	window.requestAnimationFrame(drawAll);
}
function logicAll() {
	for (var i = 0; i < upToSource+1; i++) {
		energySources[i]["logic"]();
	}
	if (currentYear >= 10 && upToSource === 0 && generalAnim["newEnergyReveal"] === 1) {
		revealNext();
		energySources[1]["priceDownInterval"] = setInterval(function() {
			if (energySources[1]["costToBuy"] > 1200)
				energySources[1]["costToBuy"] -= 200;
			else if (energySources[1]["costToBuy"] > 600)
				energySources[1]["costToBuy"] -= 100;
		}, 1000);
	}
	if (currentYear >= 27 && upToSource === 1 && energySources[1]["unlocked"] && generalAnim["newEnergyReveal"] === 1) {
		revealNext();
		energySources[2]["priceDownInterval"] = setInterval(function() {
			if (energySources[2]["costToBuy"] > 4000)
				energySources[2]["costToBuy"] -= 100;
		}, 1000);
	}
	if (currentYear >= 35 && upToSource === 2 && energySources[2]["unlocked"] && generalAnim["newEnergyReveal"] === 1) {
		revealNext();
		energySources[3]["priceDownInterval"] = setInterval(function() {
			if (energySources[3]["costToBuy"] > 12000)
				energySources[3]["costToBuy"] -= 200;
		}, 1000);
	}
	if (currentYear >= 80) {
		clearInterval(logicInterval);
		document.getElementById("theCanvas").style.opacity = 0.5;
		for (var theSound in sounds) {
			sounds[theSound].pause();
		}
		if (playerScore > 50000) {
			document.getElementById("winAmount").innerHTML += Math.floor(playerScore);
			document.getElementById("winMessage").style.display = "block";
		}
		else {
			document.getElementById("loseAmount").innerHTML += Math.floor(playerScore);
			document.getElementById("loseMessage").style.display = "block";
		}
	}
	currentYear += 0.006;
}
var logicInterval;
function startGame() {
	document.getElementById("helloMessage").style.display = "none";
	document.getElementById("theCanvas").style.opacity = 1;
	logicInterval = setInterval(logicAll, 10);
}
function revealNext() {
	upToSource += 1;
	generalAnim["newEnergyReveal"] = 0;
	Tween.get(generalAnim).to({"newEnergyReveal":1}, 750, Ease.cubicInOut);
}

//coal
function drawCoal(width) {
	var coal = energySources[0];
	ctx.fillStyle = "#f2efb1";
	ctx.fillRect(-500,-300,1000,600);
	processCash(coal["cashParticles"]);
	ctx.drawImage(images["furnace"],-110,-110);
	ctx.save();
	ctx.beginPath();
	ctx.rect(-61,-58,121,75);
	ctx.clip();
	coal["fireAnim"] += 0.05;
	if (coal["fireAnim"] > 3.1415*2) {
		coal["fireAnim"] -= 3.1415*2;
	}
	ctx.drawImage(images["fire4"],-56,-40+(Math.cos(coal["fireAnim"])*4));
	ctx.drawImage(images["fire3"],-56,-40+(Math.cos(coal["fireAnim"]+3.1415/2)*4));
	ctx.drawImage(images["fire2"],-56,-37+(Math.cos(coal["fireAnim"]+3.1415)*4));
	ctx.drawImage(images["fire1"],-60,-29+(Math.cos(coal["fireAnim"]+3.1415*(3/2))*3));
	ctx.restore();
	ctx.drawImage(images["shovel"],90,40);
	//slide up coal
	if (coal["nextCoalCounter"] > 500)
		ctx.drawImage(images["coalPile"], -70 + coal["coalDrawOffset"] ,180);
	//coal into fire
	if (coal["coalInAnim"] !== -1)
		if (coal["coalInAnim"] > 0.8)
			ctx.globalAlpha = scaleValue(coal["coalInAnim"], 0.8, 1, 1, 0);
		ctx.drawImage(images["coalPile"], -70 + coal["coalInAnim"]*40, 180 - coal["coalInAnim"]*210, 141-(coal["coalInAnim"]*80), 104-(coal["coalInAnim"]*60));
	//key
	ctx.globalAlpha = 1;
	ctx.drawImage(images["key"],-width/2,220);
	ctx.font = "500 40px " + font;
	ctx.fillStyle = "#000000";
	ctx.fillText("A",-width/2+25,275);
}
function coalLogic() {
	var coal = energySources[0];
	if (coal["firstFrame"]) {
		coal["firstFrame"] = false;
	}
	if (coal["nextCoalCounter"] === 500)
		Tween.get(coal).to({"coalDrawOffset": 0}, 500, Ease.cubicOut);
	if (coal["nextCoalCounter"] < 1000)
		coal["nextCoalCounter"] += 10;
}
function coalKey() {
	var coal = energySources[0];
	if (coal["nextCoalCounter"] > 900) {
		setTimeout(function() {
			playerScore += coal["price"];
			cashExplosion(coal["cashParticles"],coal["price"]/3,0,-60);
		}, 350); //wait a bit, looks better
		sounds["fireWhoosh"].currentTime = 0;
		sounds["fireWhoosh"].play();
		Tween.removeTweens(coal);
		coal["nextCoalCounter"] = 0;
		coal["coalDrawOffset"] = -(screenWidth/2);
		coal["coalInAnim"] = 0;
		Tween.get(coal)
			.to({"coalInAnim": 1}, 500, Ease.cubicInOut);
	}
}

//wind
function drawWind(width) {
	var wind = energySources[1];
	ctx.fillStyle = "#f2bfb1";
	ctx.fillRect(-500,-300,1000,600);
	if (!wind["unlocked"]) {
		ctx.fillStyle = "#FFFFFF";
		ctx.font = "500 40px " + font;
		ctx.textAlign = "center";
		ctx.fillText("Wind",0,-50);
		ctx.fillText("$"+Math.ceil(wind["costToBuy"]),0,0);
		if (playerScore < wind["costToBuy"])
			ctx.globalAlpha = 0.5;
		else
			ctx.globalAlpha = 1;
		ctx.font = "500 20px " + font;
		ctx.fillText("Buy",0,210);
		ctx.drawImage(images["key"],-40,120);
		ctx.font = "500 40px " + font;
		ctx.fillStyle = "#000000";
		ctx.fillText("S",0,175);
		return;
	}

	if (!wind["canHit"])
		ctx.translate((Math.random()-0.5)*5,(Math.random()-0.5)*5); //TURBULENT DISPLACE https://youtu.be/_gUc3wFrN1g?t=300

	processCash(wind["cashParticles"]);

	ctx.drawImage(images["windBase"], -91, 15);

	ctx.save();
	ctx.translate(0,10); //this means it also draws lower
	ctx.rotate(wind["wheelPos"]*3.1415*2);
	ctx.drawImage(images["windBlades"], -127, -127);
	ctx.restore();
	//arrow
	if (!wind["canHit"])
		ctx.globalAlpha = 0.3;
	ctx.drawImage(images["windArrow"], -12, -190 - Math.cos(wind["wheelPos"]*3.14115*2+3.1415)*20);
	ctx.globalAlpha = 1;
	//key
	ctx.drawImage(images["key"],-width/2,220);
	ctx.font = "500 40px " + font;
	ctx.fillStyle = "#000000";
	ctx.fillText("S",-width/2+28,275);
}
function windLogic() {
	var wind = energySources[1];
	if (!wind["unlocked"]) {
		return;
	}
	if (wind["firstFrame"]) {
		Tween.get(wind,{loop:true}).to({"wheelPos":1},2000);
		sounds["windmill"].addEventListener('ended', function() {
			this.currentTime = 0;
			this.play();
		}, false);
		sounds["windmill"].play();
		wind["firstFrame"] = false;
	}
	if (!(wind["wheelPos"] < 0.05 || wind["wheelPos"] > 0.95))
		wind["alreadyHit"] = false;
}
function windKey() {
	var wind = energySources[1];
	if (!wind["unlocked"]) {
		if (playerScore >= wind["costToBuy"]) {
			playerScore -= wind["costToBuy"];
			wind["unlocked"] = true;
		}
		return;
	}
	if ((wind["wheelPos"] < 0.05 || wind["wheelPos"] > 0.95)) {
		if (!wind["alreadyHit"] && wind["canHit"]) {
			playerScore += wind["price"];
			wind["alreadyHit"] = true;
			cashExplosion(wind["cashParticles"],wind["price"]/8,0,-10);
			sounds["windmillCash"].play();
		}
	}
	else {
		wind["canHit"] = false;
		clearTimeout(wind["resetTimeout"]);
		wind["resetTimeout"] = setTimeout(function() {wind["canHit"] = true;}, 2500);
	}
}

//solar
function drawSolar(width) {
	var solar = energySources[2];
	ctx.fillStyle = "#b1d8f2";
	ctx.fillRect(-500,-300,1000,600);
	if (!solar["unlocked"]) {
		ctx.fillStyle = "#FFFFFF";
		ctx.font = "500 40px " + font;
		ctx.textAlign = "center";
		ctx.fillText("Solar",0,-50);
		ctx.fillText("$"+solar["costToBuy"],0,0);
		ctx.font = "500 20px " + font;
		if (playerScore < solar["costToBuy"])
			ctx.globalAlpha = 0.5;
		else
			ctx.globalAlpha = 1;
		ctx.fillText("Buy",0,210);
		ctx.font = "500 40px " + font;
		ctx.fillStyle = "#000000";
		//left key
		ctx.drawImage(images["key"],-70,120);
		ctx.fillText("◄",-30,175);
		//right key
		ctx.drawImage(images["key"],-10,120);
		ctx.fillText("►",30,175);
		return;
	}
	processCash(solar["cashParticles"]);
	//panel
	ctx.fillStyle = "#909090";
	ctx.fillRect(-20,200,40,100);
	ctx.fillStyle = "#28b220";
	ctx.fillRect(-15,300-(solar["sunQuality"]*80),30,solar["sunQuality"]*80);
	ctx.save();
	ctx.translate(0,190);
	ctx.rotate(solar["panelAngle"]*0.55);
	ctx.drawImage(images["solarPanel"], -123, -20);
	ctx.restore();
	//sun
	ctx.drawImage(images["sun"], -104+(solar["sunPosition"]*180), -250);
	//keys
	ctx.drawImage(images["key"],-width/2,220);
	ctx.font = "500 40px " + font;
	ctx.fillStyle = "#000000";
	ctx.fillText("◄",-width/2+18,275);
	ctx.drawImage(images["key"],width/2-80,220);
	ctx.font = "500 40px " + font;
	ctx.fillStyle = "#000000";
	ctx.fillText("►",width/2-58,275);
}
function solarLogic() {
	var solar = energySources[2];
	if (!solar["unlocked"]) {
		return;
	}
	if (solar["firstFrame"]) {
		setInterval(function() {
			cashExplosion(solar["cashParticles"],(solar["price"]/100)*solar["sunQuality"]*3,0,200)
		}, 100);
		sounds["drone"].addEventListener('ended', function() {
			this.currentTime = 0;
			this.play();
		}, false);
		sounds["drone"].play();
		solar["firstFrame"] = false;
	}
	//panel movement
	if (solar["leftKey"])
		solar["panelAngle"] -= 0.02;
	if (solar["rightKey"])
		solar["panelAngle"] += 0.02;
	solar["panelAngle"] = limitTo(solar["panelAngle"],-1,1);
	//sun movement
	solar["sunPosition"] += solar["sunDirection"]*0.01;
	solar["sunPosition"] = limitTo(solar["sunPosition"],-1,1);
	if (solar["sunPosition"] === 1 || solar["sunPosition"] === -1 || Math.random() < 0.009) {
		solar["sunDirection"] = solar["sunDirection"]*-1;
	}
	//scoring
	solar["sunQuality"] = Ease.quadIn(
		limitTo(1-(Math.abs(solar["panelAngle"]-solar["sunPosition"])),0,1)
	);
	sounds["drone"].volume = solar["sunQuality"];
	playerScore += (solar["price"]/100)*solar["sunQuality"];
}
function solarKey(e) {
	var keyCode = e.charCode || e.keyCode || e.which;
	var solar = energySources[2];
	if (!solar["unlocked"]) {
		if (playerScore >= solar["costToBuy"]) {
			playerScore -= solar["costToBuy"];
			solar["unlocked"] = true;
		}
		return;
	}
	if (keyCode === 37) {
		solar["leftKey"] = (e.type === "keydown");
	}
	else if (keyCode === 39) {
		solar["rightKey"] = (e.type === "keydown");
	}
}

//fission
function drawFission(width) {
	var fission = energySources[3];
	ctx.fillStyle = "#b1f2b1";
	ctx.fillRect(-500,-300,1000,600);
	if (!fission["unlocked"]) {
		ctx.fillStyle = "#FFFFFF";
		ctx.font = "500 40px " + font;
		ctx.textAlign = "center";
		ctx.fillText("Fission",0,-50);
		ctx.fillText("$"+fission["costToBuy"],0,0);
		ctx.font = "500 20px " + font;
		if (playerScore < fission["costToBuy"])
			ctx.globalAlpha = 0.5;
		else
			ctx.globalAlpha = 1;
		ctx.fillText("Buy",0,210);
		ctx.drawImage(images["key"],-40,120);
		ctx.font = "500 40px " + font;
		ctx.fillStyle = "#000000";
		ctx.fillText("▲",0,175);
		return;
	}

	if (fission["disabled"]) {
		ctx.translate((Math.random()-0.5)*8,(Math.random()-0.5)*8);
	}
	else if (fission["reactorHeat"] >= 0.8 || fission["reactorHeat"] <= 0.2) {
		ctx.translate((Math.random()-0.5)*3,(Math.random()-0.5)*3);
	}

	ctx.fillStyle = "#d9d9d9";
	ctx.fillRect(-110,-70,220,260);
	if (fission["disabled"]) {
		ctx.fillStyle = "#990016";
	}
	else {
		ctx.fillStyle = "#FF0000";
	}
	ctx.fillRect(-110,-70+scaleValue(limitTo(fission["reactorHeat"],0,1),0,1,260,0),220,scaleValue(limitTo(fission["reactorHeat"],0,1),0,1,0,260));
	ctx.drawImage(images["tower"],-170,-80);
	if (fission["reactorHeat"] >= 0.8 || fission["reactorHeat"] <= 0.2) {
		ctx.fillStyle = "#FF0000";
	}
	else {
		ctx.fillStyle = "#fffa6e";
	}
	ctx.beginPath();
	ctx.arc(0, 33, 46, 0, 2 * Math.PI);
	ctx.fill();
	ctx.drawImage(images["nuke"],-39,0);

	processCash(fission["cashParticles"]);

	ctx.drawImage(images["key"],-width/2,220);
	ctx.font = "500 40px " + font;
	ctx.fillStyle = "#000000";
	ctx.fillText("▲",-width/2+21,273);
}
function fissionLogic() {
	var fission = energySources[3];
	if (!fission["unlocked"]) {
		return;
	}
	if (fission["firstFrame"]) {
		setInterval(function() {
			if (!fission["disabled"])
				cashStream(fission["cashParticles"],fission["reactorHeat"]*5,0,-78)
		}, 100);
		fission["firstFrame"] = false;
	}
	if (fission["reactorHeat"] > 1 || fission["reactorHeat"] < 0) {
		fission["disabled"] = true;
		fission["reactorHeat"] = limitTo(fission["reactorHeat"],0,1);
		sounds["warn"].play();
		Tween.get(fission)
			.wait(500)
			.to({"reactorHeat":0.5}, 3250)
			.call(function() {
				fission["disabled"] = false;
			});
	}
	if (!fission["disabled"]) {
		playerScore += Ease.quadIn(fission["reactorHeat"])*(fission["price"]/100);
		fission["reactorHeat"] -= 0.005;
	}
}
function fissionKey() {
	var fission = energySources[3];
	if (!fission["unlocked"]) {
		if (playerScore >= fission["costToBuy"]) {
			playerScore -= fission["costToBuy"];
			fission["unlocked"] = true;
		}
		return;
	}
	if (!fission["disabled"]) {
		fission["reactorHeat"] += 0.17;
	}
}

//keys
document.addEventListener("keydown", function(e) {
	var keyCode = e.charCode || e.keyCode || e.which;
	if (keyCode === 65) {
		coalKey();
	}
	else if (keyCode === 83) {
		windKey();
	}
	else if (keyCode === 37 || keyCode === 39) {
		solarKey(e);
	}
	else if (keyCode === 38) {
		fissionKey();
	}
});

document.addEventListener("keyup", function(e) {
	var keyCode = e.charCode || e.keyCode || e.which;
	if (keyCode === 37 || keyCode === 39) {
		solarKey(e);
	}
});

//helpers
//this one is super cool, save this somewhere
function scaleValue(value, inRangeStart, inRangeEnd, outRangeStart, outRangeEnd, ease) {
	value -= inRangeStart;
	value /= inRangeEnd-inRangeStart;
	if (ease)
		value = ease(value);
	value *= outRangeEnd-outRangeStart;
	value += outRangeStart;
	return value;
}
function limitTo(value, min, max) {
	return Math.min(Math.max(value, min), max);
}
function cashExplosion(cash,amount,x,y) {
	for (var i = 0; i < amount; i++) {
		var accelStrength = (Math.random()-0.5)*12;
		var accelAngle = (Math.random()*3.1415*2);
		cash.push(
			{
				"xpos": x,
				"ypos": y,
				"xaccel": Math.cos(accelAngle)*accelStrength,
				"yaccel": Math.sin(accelAngle)*accelStrength,
				"angle": Math.random()*3.1415*2
			}
		);
	}
}
function cashStream(cash,amount,x,y) {
	for (var i = 0; i < amount; i++) {
		cash.push(
			{
				"xpos": x,
				"ypos": y,
				"xaccel": (Math.random()-0.5)*12,
				"yaccel": (Math.random()-0.5)*4-10,
				"angle": Math.random()*3.1415*2
			}
		);
	}
}
function moveCash(cash) {
	for (var i = 0; i < cash.length; i++) {
		cash[i]["xpos"] += cash[i]["xaccel"];
		cash[i]["ypos"] += cash[i]["yaccel"];
		cash[i]["yaccel"] += 0.2;
		if (cash[i]["ypos"] > 600 || cash[i]["ypos"] < -400) {
			cash.splice(i, 1); //remove it
		}
	}
}
function drawCash(cash) {
	for (var i = 0; i < cash.length; i++) {
		ctx.save();
		ctx.translate(cash[i]["xpos"],cash[i]["ypos"]);
		ctx.rotate(cash[i]["angle"]);
		ctx.drawImage(images["monies"],-19,-8);
		ctx.restore();
	}
}
function processCash(cash) {
	moveCash(cash);
	drawCash(cash);
}