-- copy all globals into locals, some locals are prefixed with a G to reduce name clashes
local coroutine,package,string,table,math,io,os,debug,assert,dofile,error,_G,getfenv,getmetatable,ipairs,Gload,loadfile,loadstring,next,pairs,pcall,print,rawequal,rawget,rawset,select,setfenv,setmetatable,tonumber,tostring,type,unpack,_VERSION,xpcall,module,require=coroutine,package,string,table,math,io,os,debug,assert,dofile,error,_G,getfenv,getmetatable,ipairs,load,loadfile,loadstring,next,pairs,pcall,print,rawequal,rawget,rawset,select,setfenv,setmetatable,tonumber,tostring,type,unpack,_VERSION,xpcall,module,require

local apps=apps
local win=win


local function print(...) _G.print(...) end

local wstr=require("wetgenes.string")

module("bulb.score")

function bake(state,score)
	local score=score or {}

	local cake=state.cake
	local game=cake.game
	local field	=state.rebake("bulb.field")
	local cells	=state.rebake("bulb.cells")
	local ball	=state.rebake("bulb.ball")
	local play	=state.rebake("bulb.game_play")
	local gui	=state.rebake("bulb.gui")
	local coins =state.rebake("bulb.coins")
	local beep  =state.rebake("bulb.beep")
	local cuts	=state.rebake("bulb.cuts")

	
	local gl=state.gl
	local canvas=cake.canvas

	local sgui=state.rebake("wetgenes.gamecake.spew.gui")
	local sprofiles=state.rebake("wetgenes.gamecake.spew.profiles")

	local sscores=state.rebake("wetgenes.gamecake.spew.scores")
	sscores.setup(1) -- we only bake once, so this is only called once


	function score.loads()
	end
	
	score.num=0
	
	function score.setup()
		
		score.tab={}
		
		score.num=0
		score.disp=0
		score.count=0
		score.per=0
		
--		score.levelnum=1000 -- level resets at 1000,2000,4000,8000,16000 etc points
--		ball.maxball=5
		
		sscores.reset()
		
	end

-- just go to the next level
	function score.levelskip(add)

		coins.save()
		coins.level_spent=0
		
		cells.floor=0
		cells.state_next="fill"

		cuts.co=nil

		play.setup_mode{
			level=play.level+add
		}

	end

	function score.levelstr(s)
		local n=score.newstr(160,480-160,s)
		n.vy=-1
		n.red=1
		n.green=1
		n.blue=0
	end
	
-- win the level
	function score.levelup()
	
		beep.stream_fx("win",play.level)
	
		local w=sprofiles.get("won_"..play.level) or 0
		local prize=math.ceil( ( coins.level_price(play.level+1) - coins.level_price(play.level) ) / 2 )

		local win=1
		if coins.level_spent==0 then win=win+1 end -- did not spend on this level
		if coins.spent==0 then win=win+1 end -- did not spend anything, ever, kept it real and started on level 1

-- coin bonus for first complete ( so you may buy this level at the start )
		if w<win then
			sprofiles.set("won_"..play.level,win)
			coins.add( prize * (win-w) )
		end
		
-- score bonus for level complete is coins gained whilst playing this game * sqrt of level ( so level 100 is x10 )
		local bonus=math.ceil( (coins.gain+1) * (play.level) )

		score.newfloater(320-32,480-16, bonus )
		score.add(bonus)

		score.levelskip(1)

		score.levelstr("Level "..(play.level).."!")
	end

	function score.update()

		if cells.counts and cells.counts[0]==0 and (not cells.boss.active) then -- levelup on a full clear
			if cells.is_stable() then
				score.levelup()
			end
		end
	
--		if score.num > score.levelnum then
--print( cells.state , score.num , score.levelup )
--			if cells.is_stable() then
--				score.levelup()
--				while score.levelnum < score.num do -- next levelup takes twice as long
--					score.levelnum=score.levelnum*2
--				end
--			end
--		end
	
		
		for i=#score.tab,1,-1 do local v=score.tab[i]
--			ball.fizix(v)
			v.px=v.px+v.vx
			v.py=v.py+v.vy
			v.vy=v.vy*(33/32)
			v.alpha=v.alpha-(1/100)
			if v.alpha <= 0 then
				table.remove(score.tab,i)
			end
		end
		
		score.num=sscores.get(1)

		for i,v in ipairs{1000000,100000,10000,1000,100,10,1} do
			if score.disp+v<=score.num then
				score.disp=score.disp+v
				break
			end
		end
		
		sscores.update()
		
	end

	function score.draw()
	
		if play.pause then return end


		canvas.font.set(cake.fonts.get("Chunk"))
		canvas.font.set_size(32,0)
		if score.count>0 then
			score.per=math.floor(score.num/score.count)
		end
--		local s=string.format("%d / %d = %d",score.num,score.count,score.per)
--		local s=string.format("%d",score.disp)
		local s=wstr.str_insert_number_commas(score.disp)
		local sw=canvas.font.width(s)

		gl.Color(0,0,0,1)	
		canvas.font.set_xy(160-(sw/2)+2,24+2)
		canvas.font.draw(s)
		
		gl.Color(1,1,1,1)	
		canvas.font.set_xy(160-(sw/2),24)
		canvas.font.draw(s)
		

		canvas.font.set_size(128,0)
		canvas.font.set_xy(0,0)

		for i,v in ipairs(score.tab) do
			gl.PushMatrix()
			local a=v.alpha*v.alpha
			gl.Translate(v.px,v.py,0)
			local s=a--1+(1-a)*16
			gl.Scale(s,s,1)
			gl.Translate(-(canvas.font.width(v.str)/2),-64,0)
			gl.Color(0,0,0,a)
			canvas.font.draw(v.str)
			gl.Translate(-1,-1,0)
			gl.Color(v.red*a+a,v.green*a+a,v.blue*a+a,a+a)
			canvas.font.draw(v.str)
			gl.PopMatrix()
		end

--		sscores.draw("arcade2")

		canvas.font.set(cake.fonts.get("ostrich-black"))
		canvas.font.set_size(16,0)
		local s=string.format("L%02d",play.level)
--		local sw=canvas.font.width(s)

		gl.Color(0,0,0,1)	
		canvas.font.set_xy(0+2+4,480-20+2)
		canvas.font.draw(s)
		
		gl.Color(1,1,1,1)	
		canvas.font.set_xy(0+4,480-20)
		canvas.font.draw(s)
		
	end

	function score.add(num)
		coins.addscore( sscores.get(1) , num )

--		score.num=score.num+num
		sscores.add(num,1)
		
	end
	
	local color_ids=
	{
		{1,0,1},
		{0,1,1},
		{0,1,0},
		{1,1,0},
		{1,0,0},
		{1,0.5,0},
	}
	function color_from_id(id)
		if not id then return 1,1,1 end
		local v=color_ids[id]
		if not v then return 1,1,1 end
		return v[1],v[2],v[3]
	end
	
	function score.newfloater(x,y,num,id)

		local v={}
		
		v.px=x
		v.py=y
		
		v.num=num
--		v.str=string.format("%d",num)
		v.str=wstr.str_insert_number_commas(num)
		
		v.vx=0
		v.vy=-2
		
		v.red,v.green,v.blue=color_from_id(id)

		v.alpha=1

		score.tab[#score.tab+1]=v
		
		return v
	end

	function score.newstr(x,y,str)

		local v={}
		
		v.px=x
		v.py=y
		
		v.str=str
		
		v.vx=0
		v.vy=1
		
		v.red=1
		v.green=1
		v.blue=1
		
		v.alpha=1

		score.tab[#score.tab+1]=v
		
		return v
	end

	function score.final()
	
		local scr=sscores.final_score({})

		sgui.offset=scr.idx or 1
		
		game.next=state.rebake("bulb.game_menu")			
		game.next.next_page="score"
--		gui.page("score")

		
	end
	
	return score
end
