GermMatch = getClass("GermMatch")

GermMatch.minigameID = "GERMMATCH"
GermMatch.minigameIdx = 2

GermMatch.levels = {}
GermMatch.levels[1] =
{
	duration = 14000,
	minExtraGerms = 4,
	maxExtraGerms = 6,
	numMatchingFeatures = 2,
    penaltyTime = 1900,
}
GermMatch.levels[2] =
{
	duration = 10000,
	minExtraGerms = 7,
	maxExtraGerms = 10,
	numMatchingFeatures = 1,
    penaltyTime = 1800,
}
GermMatch.levels[3] =
{
	duration = 11000,
	minExtraGerms = 9,
	maxExtraGerms = 12,
	numMatchingFeatures = 1,
    penaltyTime = 1700,
}
GermMatch.levels[4] =
{
	duration = 16000,
	minExtraGerms = 11,
	maxExtraGerms = 14,
	numMatchingFeatures = 2,
    penaltyTime = 1600,
}
GermMatch.levels[5] =
{
	duration = 16000,
	minExtraGerms = 13,
	maxExtraGerms = 16,
	numMatchingFeatures = 2,
    penaltyTime = 1500,
}
GermMatch.layouts = {}
GermMatch.layouts[1] =
{ class="GermMatch", name="GermMatch MiniGame",
	gameSprites =
	{
		{class="Sprite", x=30, y=90, name="FLUID1", image="GERMMATCH_FLUID1:minigames"},
		{class="Sprite", x=30, y=90, name="FLUID2", image="GERMMATCH_FLUID2:minigames"},

		{class="Sprite", x=0, y=561, name="BOX", image="GERMMATCH_BOX:minigames"},
		{class="Label", x=88, y=597, anchor="topright", font="FONT_FLOATER_SCORE", textID="MINIGAME_GERM_CORES"},
		{class="Label", x=312, y=597, anchor="topright", font="FONT_FLOATER_SCORE", textID="MINIGAME_GERM_COLOR"},
		{class="Label", x=539, y=597, anchor="topright", font="FONT_FLOATER_SCORE", textID="MINIGAME_GERM_EDGE"},

		{class="Label", x=185, y=598, name="CORES", font="FONT_SCORE_NUMBERS:default", anchor="top"},
		{class="Sprite", x=412, y=595, name="COLOR", image="GERMMATCH_COLORS:minigames", anchor="top"},
		{class="Sprite", x=642, y=595, name="EDGE", image="GERMMATCH_EDGES:minigames", anchor="top"},
	},
}

function GermMatch:setupRotation(item, minDelay, maxDelay, minMaxSpeed, maxMaxSpeed, accInc, accDec)
	item.r = item.rotation * 2 * math.pi / 360
	item.rotSpeed = 0
	item.rotTarget = 0
	item.newRotTargetDelay = 0
	item.maxRotSpeed = 0.02
	return function(_, time)
		item.r, item.rotSpeed = math.calcNewSpeedAndPos(
			time, item.r, item.rotTarget, item.rotSpeed, item.maxRotSpeed, accInc, accDec)
		item.rotation = item.r * 360 / 2 * math.pi
		item.newRotTargetDelay = item.newRotTargetDelay - time
		if (item.newRotTargetDelay <= 0) then
			local diff = math.pi - math.Random(2 * math.pi)
			item.rotTarget = item.rotation + diff
			item.newRotTargetDelay = math.Random(minDelay, maxDelay) * (1 + math.abs(diff))
			item.maxRotSpeed = math.Random(minMaxSpeed, maxMaxSpeed)
		end
	end
end

function GermMatch:setupPosition(item, numPulls, newPosFunc, minDuration, maxDuration, relativeDuration)
	relativeDuration = (relativeDuration ~= false)
	item.pulls = {}
	return function(_, time)
		local toRemove = {}
		local totalFrac = 0
		local totalPos = {x=0,y=0}
		for k,v in pairs(item.pulls) do
			local ramp = v.duration * 0.3
			v.progress = (v.progress or 0) + time
			if (v.progress < ramp) then
				v.frac = math.rcurve(v.progress / ramp)
			elseif (v.progress < v.duration - ramp) then
				v.frac = 1
			elseif (v.progress < v.duration) then
				v.frac = math.jcurve((v.duration - v.progress) / ramp)
			else
				item.pulls[k] = nil
				v.frac = 0
			end
			assert(v.frac >= 0)
			assert(v.frac <= 1)
			totalFrac = totalFrac + v.frac
			totalPos.x = totalPos.x + v.pos.x * v.frac
			totalPos.y = totalPos.y + v.pos.y * v.frac
		end

		local numPullsNow = numPulls
		if (item.noBouncePull) then
			numPullsNow = numPullsNow + 1
		end
		if (table.count(item.pulls) < numPulls) then
			local newPull = self:getNewPull(item, newPosFunc, minDuration, maxDuration, relativeDuration)
			table.insert(item.pulls, newPull)
		end

		if (totalFrac > 0) then
			item.x = totalPos.x / totalFrac
			item.y = totalPos.y / totalFrac
		end
	end
end

function GermMatch:getNewPull(item, newPosFunc, minDuration, maxDuration, relativeDuration)
	local p = newPosFunc(self, item)
	local durationMul = 1
	if (relativeDuration) then
		local d = {x=p.x-item.x, y=p.y-item.y}
		durationMul = math.sqrt(d.x*d.x + d.y*d.y)
	end
	return {
		pos = p,
		duration = math.Random(minDuration, maxDuration) * durationMul,
	}
end

function GermMatch:setupGerm(item, newPosFunc)
	item.noBounceDelay = 0

	local rotFunc = self:setupRotation(item, 200, 4000, 0.008, 0.014, 0.005, 0.008)
	local posFunc = self:setupPosition(item, 2, self.getAGoodPositionFor, 200, 800)
	item.onTick = function(_, time)
		if (not self.active) then return end
		rotFunc(_, time)
		--posFunc(_, time)

		--if (item.noBouncePull) then
		--	if (not table.contains(item.pulls, item.noBouncePull)) then
		--		item.noBouncePull = nil
		--	end
		--elseif (item.noBounceDelay > 0)  then
		--	item.noBounceDelay = item.noBounceDelay - time
		--else
		--	local minDist = self:getMinDistanceToOthers(item)
		--	if (minDist < 40) then
		--		item.noBouncePull = self:getNewPull(item, self.getAGoodPositionOnTheBorder, 1400, 3000, false)
		--		table.insert(item.pulls, item.noBouncePull)
		--		item.noBounceDelay = math.Random(1000, 2000)
		--	end
		--end
	end
end

function GermMatch:setupCore(item)
	item.mx = item.x
	item.my = item.y

	local getNewPos = function()
		return {
			x = item.mx + math.Random(-4, 4),
			y = item.my + math.Random(-4, 4),
		}
	end

	local rotFunc = self:setupRotation(item, 1000, 4000, 0.020, 0.040, 0.01, 0.01)
	local posFunc = self:setupPosition(item, 3, getNewPos, 600, 800)
	item.onTick = function(_, time)
		rotFunc(_, time)
		posFunc(_, time)
	end
end
