-- ************************************ PigRace ************************************ --
PigRace = deriveLuaClass("PigRace", "DialogCare")

dialogs = dialogs or {}
dialogs.pig_race = {
	class="PigRace",
	background="BACKGROUND:easter",
	autoCenter=true,
	movable=false,
	components = {
		{class="Button", x=114, y=382, name="BET", image="BUTTON_BET:easter", anchor="top"},
		{class="Button", x=270, y=382, name="GO", image="BUTTON_GO:easter", anchor="top"},
		{class="Button", x=690, y=382, name="BACK", image="BUTTON_BACK:easter", anchor="top"},

		{class="Label", x=367, y=374, textId="PIGRACE_CREDITS", font="FONT_WELCOME:default", pivot="center"},
		{class="Label", x=444, y=374, name="CREDITS", font="FONT_GUI_SCORE:default", pivot="center"},

		{class="Label", x=367, y=402, textId="PIGRACE_BET", font="FONT_WELCOME:default", pivot="center"},
		{class="Label", x=444, y=402, name="WAGER", font="FONT_GUI_SCORE:default", pivot="center"},

		{class="Label", x=496, y=402, textId="PIGRACE_RETURN", font="FONT_WELCOME:default", pivot="center"},
		{class="Label", x=573, y=402, name="RETURNS", font="FONT_GUI_SCORE:default", pivot="center"},
	}
}

PigRace.initShift = function(level)
	if (level:getSpriteExt("guineapig_top_upgrade")) then
		local pig = level:getSpriteExt("guineapig")
		if (pig) then
			pig.clickable = true
			pig.drawOutline = false
			pig.clickTimer = 0
			pig.clickedTimes = 0
			pig.onTick = function(_, time)
				pig:tick(time)
				if (pig.clickTimer > 0) then
					pig.clickTimer = pig.clickTimer - time
					if (pig.clickTimer <= 0) then
						pig.clickedTimes = 0
					end
				end
			end
			pig.onClick = function()
				pig.clickTimer = 1000
				pig.clickedTimes = pig.clickedTimes + 1
				if (player and pig.clickedTimes >= 3) then
					pig.clickedTimes = 0
					scene:openDialog(scene:createDialog("pig_race"))
					level:incPaused()
				end
			end
		end
	end
end

function PigRace:showStatus(statusText)
	if (self.dummyObject) then
		self.dummyObject:removeMessageDialog("STATUS")
	else
		self.dummyObject = self:newChild({class="Object", x=436, y=40})
	end
	local dlg = self.dummyObject:showMessageDialog({dialogId="STATUS", text=statusText, labelWidth=240})
	self.dummyObject:addChild(dlg)
	dlg.x = 0
	dlg.y = -dlg.height
end

function PigRace:removeStatus()
	if (self.dummyObject) then
		self.dummyObject:removeMessageDialog("STATUS")
	end
end

PigRace.jumpDist = 14

function PigRace:getTrackY(idx)
	return 94 + (idx-1)*52 + (5-self.numPigs)*20
end

function PigRace:getRandomStartX(idx)
	return 74 + math.Random(6)
end

function PigRace:getRandomStartY(idx)
	return self:getTrackY(idx) + 44 + math.Random(4)
end

function PigRace:animateBanner(textId)
	local banner = self:newChild({class="Label", font="FONT_MINIGAME_HEADING:default",
		y=60, x=1024, anchor="top", alpha=0, textId=textId})
	banner.x = 1024 + banner.width/2 - self.x - 150
	banner:animate(
		{alpha=1, x=self.width/2, duration=400, style="easeOut"},
		{delay=1000},
		{alpha=0, x=-banner.width/2 - self.x + 150, duration=400, style="easeIn"},
		{remove=true}
	)
	return banner
end

function PigRace:onShow()
	self.numPigs = math.Random(3, 5)
	self.bet = 1
	self.running = false
	self.selectedPig = -1
	self.canSelect = true
	self.canResetGame = false
	self.maxBet = 10
	self.finishX = 715

	self.colors = {
		{r=1, g=0, b=0},
		{r=0, g=1, b=0},
		{r=0, g=0, b=1},
		{r=1, g=1, b=0},
		{r=1, g=0, b=1},
		{r=0, g=1, b=1},
	}

	self.tracks = {}
	self.pigs = {}
	for i=1,self.numPigs do
		self.tracks[i] = self:newChild({
			class="Sprite",
			name="TRACK"..i,
			image="TRACK:easter",
			x=60, y=self:getTrackY(i),
			color = self.colors[i],
		})
	end
	for i=1,self.numPigs do
		local c = self.colors[i]
		self.pigs[i] = self:newChild({
			class="CareCharacter",
			name="PIG"..i,
			baseAnimation = "GUINEAPIG",
			x=self:getRandomStartX(i), y=self:getRandomStartY(i),
			clickable = true,
			onTick = PigRace.updatePig,
			runTimer = 0,
			--color = {r=math.min(1, c.r+0.7), g=math.min(1, c.g+0.7), b=math.min(1, c.b+0.7) },
		})
		self.pigs[i].__getters.shadowResource = function() return "" end
	end

	self:updateGUI()
	self:showStatus(ghf.getString("PIGRACE_PICK"))
end

function PigRace:updateGUI()
	if (self.bet > self.maxBet or self.bet > player.money) then
		self.bet = 1
	end
	self.returns = self.bet * (self.numPigs-1)
	self:getChild("WAGER").text = tostring(self.bet)
	self:getChild("RETURNS").text = tostring(self.returns)
	self:getChild("CREDITS").text = tostring(player.money)

	self:getChild("BET").enabled = not self.running and player.money > 1
	self:getChild("GO").enabled = not self.running and player.money > 0 and self.selectedPig > 0
	self:getChild("BACK").enabled = not self.running
end

function PigRace:handleCommand(command, sender)
	if (command == "BET") then
		self:pigsReturn()
		self.bet = self.bet + 1
		self:updateGUI()

	elseif (command == "GO") then
		self.pigs[1]:playSample("SND_GUINEAPIG_POPS_UP")
		self.pigs[1]:playSample("SND_GUINEAPIG_RUNS")
		for _,pig in ipairs(self.pigs) do
			pig:addTask({class="WalkToTask", target={x=800, y = pig.y}, straight=true})
			pig.walkSpeed = math.Random(100, 200)
			pig.scale = 1.0
			pig.runnning = true
			pig.runTimer = math.Random(200, 500)
		end
		self.canSelect = false
		self.running = true
		self.somePigFinished = false
		self.winner = -1
		self.prevMaxPig = -1
		self:updateGUI()
		self:animateBanner("PIGRACE_RUN")

	elseif (command == "BACK") then
		level:decPaused()
		self:close()
	end
end

function PigRace:onTick(time)
	self:tick(time)
	if (self.running) then
		if (not self.somePigFinished) then
			local maxPigX = -1
			local maxPigId = 1
			for i,pig in ipairs(self.pigs) do
				if (pig.x > maxPigX) then
					maxPigX = pig.x
					maxPigId = i
				end
				if (pig.x > self.finishX - PigRace.jumpDist*2) then
					self.somePigFinished = true
					self.winner = i
					self.winPig = pig
					self.hasWon = (self.winner == self.selectedPig)
					if (self.hasWon) then
						player:incMoney(self.returns)
					else
						player:decMoney(self.bet)
					end
					break;
				end
			end

			if (self.somePigFinished) then
				for i,pig in ipairs(self.pigs) do
					taskSystem:cancelAllTasksFor(pig)
					pig:playAnimation("IDLE")
					pig.runnning = false
				end

				self.selectedPig = -1
				self.running = false
				self.canResetGame = true

				if (self.hasWon) then
					self:animateBanner("PIGRACE_WINNER")
				else
					self:animateBanner("PIGRACE_TOOBAD")
				end

				self.winPig:playAnimation("WALK")
				local mod = self.winPig:animate(
					{x = self.winPig.x + PigRace.jumpDist, y = self.winPig.y - 18, duration=180, style="easeOut"},
					{x = self.winPig.x + PigRace.jumpDist*2, y = self.winPig.y, duration=180, style="easeIn"},
					{call=function()
						if (self.winPig) then
							self.winPig:playAnimation("IDLE")
							self.canResetGame = true
						end
					end}
				)
				
				self:updateGUI()
				self:removeStatus()
				self:showStatus(ghf.getString("PIGRACE_RESET"))
			else
				if (maxPigId ~= self.prevMaxPig) then
					self.prevMaxPig = maxPigId
					self:showStatus(string.format(ghf.getString("PIGRACE_RUNNING"), guineaNames[maxPigId]))
				end
			end
		end
	end
end

function PigRace:onMouseLeftDown(x, y)
	if (self.canSelect) then
		for i,pig in ipairs(self.pigs) do
			if (pig:isInside(x, y)) then
				for _,v in ipairs(self.pigs) do
					v.scale = 1.0
					v.selected = false
				end
				pig.scale = 1.2
				pig.selected = true
				self.selectedPig = i
				self:updateGUI()
				self:showStatus(string.format(ghf.getString("PIGRACE_CHOSEN"), guineaNames[self.selectedPig]))
				break;
			end
		end
	elseif (self.running) then
		for i,pig in ipairs(self.pigs) do
			if (pig:isInside(x, y)) then
				pig:playSample("SND_GUINEAPIG_POPS_UP")
				pig.runTimer = 50
				--pig.prevMove = nil
			end
		end
	elseif (self.canResetGame) then
		self:pigsReturn()
	end
end

function PigRace:pigsReturn()
	if (self.canResetGame) then
		for i,pig in ipairs(self.pigs) do
			taskSystem:cancelAllTasksFor(pig)
			pig.walkSpeed = 400
			pig:addTask({class="WalkToTask", target={x=self:getRandomStartX(i), y=self:getRandomStartY(i)}, straight=true})
			pig.selected = false
		end
		self.pigs[1]:playSample("SND_GUINEAPIG_RUNS")
		self.pigs[1]:playSample("SND_GUINEAPIG_POPS_UP")
		self.canSelect = true
		self.canResetGame = false
		self.winPig = nil
		self:showStatus(ghf.getString("PIGRACE_PICK"))
	end
end

function PigRace.updatePig(pig, time)
	pig:tick(time)
	if (pig.runnning) then
		pig.runTimer = pig.runTimer - time
		if (pig.runTimer <= 0) then
			pig.runTimer = math.Random(500, 2200)
			taskSystem:cancelAllTasksFor(pig)
			local r = math.Random(1000)
			pig.walkSpeed = math.Random(60, 180)
			if (r < 400 and pig.prevMove ~= "-x") then
				local newX = 1000
				newX = math.clamp(pig.x + newX, 55, 800)
				pig:addTask({class="WalkToTask", target={x=newX, y=pig.y}, straight=true})
				pig.prevMove = "+x"
				pig:playSample("SND_GUINEAPIG_RUNS")
			elseif (r < 420) then
				pig:playDefaultAnimation()
			elseif (r < 620 and pig.prevMove ~= "+x") then
				local newX = 1000
				newX = math.clamp(pig.x - newX, 55, 800)
				pig:addTask({class="WalkToTask", target={x=newX, y=pig.y}, straight=true})
				pig.prevMove = "+x"
			elseif (r < 640) then
				pig:playSample("SND_GUINEAPIG_POPS_UP")
				pig:playDefaultAnimation()
			elseif (r < 850) then
				local newY = math.Random(20, 40)
				if (math.Random(1000) < 500) then
					newY = -newY;
				end
				newY = math.clamp(pig.y + newY, 110, 360)
				pig:addTask({class="WalkToTask", target={x=pig.x, y=newY}, straight=true})
			else -- (r <= 1000)
				pig:playDefaultAnimation()
			end
		end
	end
end
