ISpyPrices = {
	["submersion"] = {5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15},
	["collector"] = {5, 5, 5, 10, 10, 15, 20, 25, 30, 35},
	["diver"] = {5, 5, 5, 10, 10, 15, 20, 25, 30, 35},
	["goldrush"] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}
}

ZCoeff = {
	["submersion"] = {
		["hint"] = 0.2 / 0.6,
		["time"] = 0.2 / 0.6
	},
	["collector"] = {
		["hint"] = 0.2 / 0.6,
		["time"] = 0.2 / 0.6
	},
	["diver"] = {
		["hint"] = 0.25 / 0.6,
	},
	["goldrush"] = {
		["hint"] = 0.25 / 0.6,
	}
}

--
-- Вернуть эталонный базовый множитель
--
function GetEtalonBaseMultiplier()
	local currentN = PermanentStorage.GetLocalIntOrDef("CurrentN", 0) + 1
	return math.sqrt(currentN)
end

--
-- Вернуть множитель базы.
-- Свойства множителя:
-- 1) по умолчанию множитель равен эталонному (квадратный корень из количества пройденных уровней)
-- 2) если пользователь не добирает до "эталонного" количества суммарных денег, множитель увеличивается;
-- 3) множитель никогда не уменьшается.
-- Детали реализации:
-- 1) эталонное количество денег - количество денег за предметы, без учетов всех бонусов
--    (предполагаем, что бонусы зарабатываются редко);
-- 2) множитель увеличивается в 1/среднее(1, max(p, 0.333)) раз, где p - процент заработанных денег (относительно эталона)
--
function GetBaseMultiplier()
	local mult = GetEtalonBaseMultiplier()
	local allMoney = PermanentStorage.GetLocalIntOrDef("All money from start", 0)
	local idealMoney = PermanentStorage.GetLocalIntOrDef("Ideal money", 0)
	if allMoney < idealMoney then
		local moneyPercent = allMoney / idealMoney
		if moneyPercent < 0.33 then
			moneyPercent = 0.33
		end
		moneyPercent = lerp(moneyPercent, 1, 0.5) -- перетягиваем ближе к 1
		mult = mult / moneyPercent
	end
	local oldMult = PermanentStorage.GetLocalFloatOrDef("MaxBaseMultiplier", 0)
	if mult < oldMult then
		mult = oldMult
	else
		PermanentStorage.SetLocalFloat("MaxBaseMultiplier", mult)
	end
	return mult
end

--
-- Вернуть неокругленную базовую стоимость всех предметов (Bn)
--
function GetBasePrice()
	local currentMode = PermanentStorage.GetLocalString("CurrentMode")
	local Bn = 0
	for i = 1, GetTableSize(ISpyPrices[currentMode]), 1 do
		Bn = Bn + ISpyPrices[currentMode][i]
	end
	Bn = Bn
	return Bn
end

--
-- Вернуть стоимость очередного найденного предмета
-- n начинается с 1
--
function GetNextPrice(n)
	local currentMode = PermanentStorage.GetLocalString("CurrentMode")
	local curTableSize = GetTableSize(ISpyPrices[currentMode])
	if n > curTableSize then
		n = curTableSize
	end
	local price = ISpyPrices[currentMode][n]
	assert(price ~= nil)
	price = GetBaseMultiplier() * price
	if currentMode ~= "goldrush" then
		return math.ceil( price / 5) * 5
	else
		if Clicks.isExpensive then
			price = price * 3
		end
		return price
	end
end

--
-- Вернуть бонус за хинты
--
function GetHintBonus()
	local currentMode = PermanentStorage.GetLocalString("CurrentMode")
	local Bn = GetBaseMultiplier() * GetBasePrice()
	local kh = PermanentStorage.GetLocalInt("nHints") / GameplayConst.GetInt("MaxHints");
	local result = Bn * kh * ZCoeff[currentMode]["hint"]
	return math.ceil(result / 5) * 5
end

--
-- Вернуть бонус за время
--
function GetTimeBonus()
	if PermanentStorage.GetLocalStringOrDef("temp:Exit type", "give up") ~= "win" then
		return 0; -- если нашли не все предметы, возвращаем 0
	end
	local currentMode = PermanentStorage.GetLocalString("CurrentMode");
	local Bn = GetBaseMultiplier() * GetBasePrice()
	local kt = 1 - PermanentStorage.GetLocalFloat("temp:level finish time") / GameplayConst.GetFloat("TimeToLevelSubmersion")
	local result = Bn * kt * ZCoeff[currentMode]["time"]
	return math.ceil(result / 5) * 5
end

--
-- Вернуть мегабонус
--
function GetMegaBonus()
	if PermanentStorage.GetLocalStringOrDef("temp:Exit type", "give up") ~= "win" then
		return 0; -- если нашли не все предметы, возвращаем 0
	end
	local result = GetBaseMultiplier() * GetBasePrice() * 0.5
	return math.ceil(result / 5) * 5
end

--
-- Округляет заработанные (за предметы) на уровне деньги
-- Нужно в основном в режиме Золотая Лихорадка, когда сумма заработанных денег не кратна 5
--
function RoundLevelMoney()
	local levelMoney = PermanentStorage.GetLocalInt("temp:Level money");
	levelMoney = math.ceil(levelMoney / 5) * 5
		-- округляем обязательно в бОльшую сторону
	PermanentStorage.SetLocalInt("temp:Level money", levelMoney)
end

--
-- Возвращает бонус за точность
--
function GetAccuracyBonus()
	if Clicks.n == 0 then
		return 0
	else 
		local accuracy = Clicks.nHits / Clicks.n;
		local Bn = GetBaseMultiplier() * GetBasePrice()
		local currentMode = PermanentStorage.GetLocalString("CurrentMode")
		local result = Bn * accuracy * ZCoeff[currentMode]["time"]
			-- бонус за точность у нас заместо времени, поэтому берем понижающий коэффициент для времени
		return math.ceil(result / 5) * 5
	end
end

--
-- Возвращает 1, если нашли дорогую вещь
-- 0, если недорогую
--
function IsExpensive()
	if Clicks.isExpensive then
		return 1
	else
		return 0
	end
end
