local script = globalObject;
local god = nil;
local commandMap = {};

local BONUS_COUNT		= 24;
local BONUS_UPDATE_TIME	= 15;
local BONUS_SPAWN_D	= 8.0;

--~ bonus ratio in percents
local BONUS_AMMO_RATION		= 40.0;
local BONUS_ROCKET_RATION		= 15.0;
local BONUS_MINE_RATION		= 10.0;
local BONUS_NITRO_RATION		= 20.0;
local BONUS_LIFE_RATION		= 15.0;


local BONUS_SHIELD_RATION		= 10.0;



local Bonuses = 
{
	pBonuses		= nil;
	nCount		= BONUS_COUNT;
	
	pLoadBonuses	= nil;
	
	fDt			= 0.0;
	
	bGenerated		= false;
	
	Initialize		= nil;
	Update		= nil;
	Generate		= nil;
	UpdateList		= nil;
	Release		= nil;
	nLinesCount = 0;
	nLineStep = 0;
};

Bonuses.Initialize = function ()
	local pBonusAmmo		= LoadRenderObject("bonus_ammo.rdf", 20);
	local pBonusRocket		= LoadRenderObject("bonus_rocket.rdf", 20);
	local pBonusMine		= LoadRenderObject("bonus_mine.rdf", 20);
	local pBonusLife		= LoadRenderObject("bonus_life.rdf", 20);
	local pBonusNitro		= LoadRenderObject("bonus_nitro.rdf", 20);
	local pBonusShield		= LoadRenderObject("bonus_shield.rdf", 20);
	
	local nPercent = BONUS_COUNT / 100.0;
	
	Bonuses.nLinesCount = GetSplineLineCount();
	Bonuses.nLineStep	= ToInt(Bonuses.nLinesCount / BONUS_COUNT);

	Bonuses.pLoadBonuses = {};
	
	Bonuses.pLoadBonuses[1] = {};
	Bonuses.pLoadBonuses[1][1] = pBonusAmmo;
	Bonuses.pLoadBonuses[1][2] = 0.0;
	Bonuses.pLoadBonuses[1][3] = BONUS_AMMO_RATION;
	
	Bonuses.pLoadBonuses[2] = {};
	Bonuses.pLoadBonuses[2][1] = pBonusRocket;
	Bonuses.pLoadBonuses[2][2] = 0.0;
	Bonuses.pLoadBonuses[2][3] = BONUS_ROCKET_RATION;
	
	Bonuses.pLoadBonuses[3] = {};
	Bonuses.pLoadBonuses[3][1] = pBonusNitro;
	Bonuses.pLoadBonuses[3][2] = 0.0;
	Bonuses.pLoadBonuses[3][3] = BONUS_NITRO_RATION;
	
	Bonuses.pLoadBonuses[4] = {};
	Bonuses.pLoadBonuses[4][1] = pBonusMine;
	Bonuses.pLoadBonuses[4][2] = 0.0;
	Bonuses.pLoadBonuses[4][3] = BONUS_MINE_RATION;
	
	
	Bonuses.pLoadBonuses[5] = {};
	Bonuses.pLoadBonuses[5][1] = pBonusLife;
	Bonuses.pLoadBonuses[5][2] = 0.0;
	Bonuses.pLoadBonuses[5][3] = BONUS_LIFE_RATION;
	
	
--~ 	Bonuses.pLoadBonuses[6] = {};
--~ 	Bonuses.pLoadBonuses[6][1] = pBonusShield;
--~ 	Bonuses.pLoadBonuses[6][2] = 0.0;
--~ 	Bonuses.pLoadBonuses[6][3] = BONUS_SHIELD_RATION;
end

Bonuses.Update = function ()
	if(Bonuses.bGenerated)
	then
		for i = 1, Bonuses.nCount do
			if(CheckVisible(Bonuses.pBonuses[i][1]))
			then
				DrawDynamicObject(Bonuses.pBonuses[i][1]);
			end
		end
	end
--~ 	
--~ 	Bonuses.fDt = Bonuses.fDt + GetDeltaTime();
--~ 	if(Bonuses.fDt >= BONUS_UPDATE_TIME)
--~ 	then
--~ 		ClearBonuses();
--~ 		Bonuses.bGenerated = false;
--~ 		Bonuses.Generate();
--~ 		Bonuses.fDt = 0.0;
--~ 	end
end

Bonuses.Generate = function ()
	if(not Bonuses.bGenerated)
	then
		--math.randomseed(GetDeltaTime() * 1000.0);
		math.randomseed(os.clock());
		
		local iLine 		= 0;
		for i = 1, BONUS_COUNT do
			local pBonus	= {};
			pBonus[1] = nil;
			pBonus[2] = nil;
			pBonus[3] = nil;
			pBonus[4] = nil;
			pBonus[5] = nil;
			pBonus[6] = nil;
			local rnd = math.random(100);
			local sum = 0;
			local bcount = 5;
			if (IsDeathRace())
			then
				bcount = 3;
			end
			local bonus_number = -1;
			for j = 1,bcount
			do
				if (rnd >= sum and rnd < sum + Bonuses.pLoadBonuses[j][3])
				then
					if ((j == 2 and not IsWeaponMounted(GetCurrentCar(), 2)) or (j == 4 and not IsWeaponMounted(GetCurrentCar(), 3)))
					then
						bonus_number = 1;
						break;
					end
					for kk = 1,6
					do
						pBonus[kk] = Clone(Bonuses.pLoadBonuses[j][1]);
					end
					break;
				end
				sum = sum + Bonuses.pLoadBonuses[j][3];
			end
			if (bonus_number == -1)
			then
	--			while(not bFind)
	--			do
	--				local rnd = math.random(6);
					
	--				if(Bonuses.pLoadBonuses[rnd][2] < Bonuses.pLoadBonuses[rnd][3])
	--				then
	--					pBonus = Clone(Bonuses.pLoadBonuses[rnd][1]);
	--					Bonuses.pLoadBonuses[rnd][2] = Bonuses.pLoadBonuses[rnd][2] + 1;
	--					bFind = true;
	--				end
	--			end
				--local pBonus	= Clone(Bonuses.pLoadBonuses[math.random(6)]);
				iLine = math.random(Bonuses.nLinesCount);
				local x, y, z, dx, dy		= GetSplineLinePoint(iLine);
				
				for kk = 1,6
				do
					SetPosition(
						pBonus[kk],
						x  + dx * (- 4 * 3 + kk * 3), -- - BONUS_SPAWN_D / 3.0 + math.random() * BONUS_SPAWN_D,
						y  + dy * (- 4 * 3 + kk * 3), -- - BONUS_SPAWN_D / 3.0 + math.random() * BONUS_SPAWN_D,
						1
						);
					AddBonus(pBonus[kk], iLine);
				end
			end
			
--			iLine = iLine + Bonuses.nLineStep;
		end
		
		Bonuses.bGenerated = true;
		Bonuses.UpdateList();
	
	end
end

Bonuses.UpdateList = function ()
	local name = GetCurrentParams(script);
--~ 	
--~ 	if("axel" == name)
--~ 	then
--~ 		Bonuses.pLoadBonuses[1][2] = Bonuses.pLoadBonuses[1][2] - 1;
--~ 	elseif("brake" == name)
--~ 	then
--~ 		Bonuses.pLoadBonuses[2][2] = Bonuses.pLoadBonuses[2][2] - 1;
--~ 	elseif("minus" == name)
--~ 	then
--~ 		Bonuses.pLoadBonuses[3][2] = Bonuses.pLoadBonuses[3][2] - 1;
--~ 	elseif("plus" == name)
--~ 	then
--~ 		Bonuses.pLoadBonuses[4][2] = Bonuses.pLoadBonuses[4][2] - 1;
--~ 	elseif("gloom" == name)
--~ 	then
--~ 		Bonuses.pLoadBonuses[5][2] = Bonuses.pLoadBonuses[5][2] - 1;
--~ 	elseif("repair" == name)
--~ 	then
--~ 		Bonuses.pLoadBonuses[6][2] = Bonuses.pLoadBonuses[6][2] - 1;
--~ 	end
	
	Bonuses.pBonuses	= GetBonusList();
	Bonuses.nCount		= GetBonusesCount();
end

Bonuses.Release = function ()
	ClearBonuses();
	Release(pBonusAmmo);
	Release(pBonusRockets);
	Release(pBonusMines);
	Release(pBonusNitro);
	Release(pBonusShield);
	Release(pBonusLife);
--~ 	Release(pBonusBrake);
--~ 	Release(pBonusMinus);
--~ 	Release(pBonusPlus);
--~ 	Release(pBonusGloom);
--~ 	Release(pBonusRepair);
	Bonuses.bGenerated = false;
end

local function BonusGenerate()
	ClearBonuses();
	Bonuses.bGenerated = false;
	Bonuses.Generate();
end

local function ExecuteCommands()
	while(SetNextCommand(script))
	do
		local command = GetCurrentCommand(script);
		if (commandMap[command])
		then
			commandMap[command]();
		end
	end
end

local function AddObject()
	god = StringToPointer(GetCurrentParams(script));
	
	SetLightCoeff(1);	
	
	Bonuses.Initialize();
	Bonuses.Generate();
	
	ClearLevelTimers();
	
	SetMedalPoints(3, 35);
	SetMedalPoints(2, 25);
	SetMedalPoints(1, 15);
	
	SetLensFlare(82.801, -315.034, 99.029);
	
	if (IsDeathRace())
	then
		BONUS_AMMO_RATION		= 55.0;
		BONUS_ROCKET_RATION		= 20.0;
		BONUS_NITRO_RATION		= 25.0;
	else
		BONUS_AMMO_RATION		= 40.0;
		BONUS_ROCKET_RATION		= 15.0;
		BONUS_MINE_RATION		= 10.0;
		BONUS_NITRO_RATION		= 20.0;
		BONUS_LIFE_RATION		= 15.0;
	end
	
end

local function DeleteObject()
	Bonuses.Release();

	Release(god);
	god = nil;
--	Update();
	StopScript(script);
end

commandMap["release_all"]			= DeleteObject;
commandMap["add_object"]			= AddObject;
commandMap["delete_object"]		= DeleteObject;
commandMap["update_bonus_list"]	= Bonuses.UpdateList;
commandMap["bonus_generate"]	= BonusGenerate;

while(true)
do
	ExecuteCommands();
	
	if (god ~= nil and IsLevelStarted())
	then
		Bonuses.Update();
	end
	
	Update();
end
