-- 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 wwin=require("wetgenes.win")

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

local wstr=require("wetgenes.string")

module("bulb.game_play")

function bake(state,play)
	local play=play or {}
	
	local gl=state.gl
	local cake=state.cake
	local sheets=cake.sheets
	local game=cake.game
	
	local sounds=cake.sounds
	local al=sounds.al

	local beep=state.rebake("bulb.beep")
	local cells	=state.rebake("bulb.cells")
	local ball	=state.rebake("bulb.ball")
	local gui=state.rebake("bulb.gui")
	
	cake.game.play=play
	
--	play.mode="endurance"
--	play.level=1

--	play.mode="puzzle"
--	play.level=1

	play.devcount=0
	
	play.level=1
	
	play.setup_mode=function(t)
		t=t or {}
		play.mode=t.mode or play.mode or "endurance"
		play.level=t.level or play.level or 1
		if play.level>100 then play.level=100 end -- max level

		ball.resets()
		ball.setup_nexts()
		cells.setup_map()
		
		beep.stream("play",play.level)

		play.slomo=nil

		return play
	end
--	play.setup_mode()

	local mods={} for i,n in ipairs{
--		"bulb.input",
		"bulb.levels",
		"bulb.field",
		"bulb.cells",
		"bulb.ball",
		"bulb.cuts",
		"bulb.bag",
		"bulb.emits",
		"bulb.score",
		"bulb.coins",
	} do mods[i]=state.rebake(n) end
	
	function play.loads()
		cake.fonts.loads({"Vera","Chunk"})
		
		
		for i,v in ipairs(mods) do
			if v.loads then v.loads() end
		end
		
	end
	
	function play.setup()

		if wwin.hardcore.count_input_devices then
			play.dev_count=wwin.hardcore.count_input_devices()
		end
			
		play.butt_wait=10
	
		play.pause=false
	
		play.loads()
			
		play.setup_mode()

		for i,v in ipairs(mods) do
			if v.setup then v.setup() end
			
--			state.cake.images.loads({
--	})

		end


		play.butt=false
		play.butt_down=false
		play.butt_up=false

	end

	function play.clean()

		for i,v in ipairs(mods) do
			if v.clean then v.clean() end
		end

	end

	function play.msg(m)
	
		if play.slomo then return end
		
		if ( m.class=="joykey" and m.action==-1 and (m.keycode==103 --[[or m.keycode==108]]) ) or
		   ( m.class=="key" and m.action==-1 and ( m.keyname=="return" or m.keyname=="enter" or m.keyname=="right" ) ) then -- test coins menu
			if m.keyname=="right" and play.pause then -- not when paused
			else
				play.pause=not play.pause
				if play.pause then
					gui.page("shop_balls")
				else
					if beep.replay then beep.stream("play") end
				end
				return
			end
		end

		if ( m.class=="joykey" and m.action==-1 and (m.keycode==102 or m.keycode==108) ) then
--			if m.action==-1 then
--				local t=state.rebake("wetgenes.gamecake.mods.escmenu")
--				t.show=not t.show
				play.pause=not play.pause
				if play.pause then
					gui.page("game_menu")
				else
					if beep.replay then beep.stream("play") end
				end
				return
--			end
		end


		if play.pause then
			if gui.msg(m) then return end -- gui can eat msgs
		end

		if m.class=="mouse" then

			if m.action==1 and (m.x*m.x+m.y*m.y)<(64*64) then -- test exit menu
--				state.rebake("wetgenes.gamecake.mods.escmenu").show=true
				play.pause=not play.pause
				if play.pause then
					gui.page("game_menu")
				else
					if beep.replay then beep.stream("play") end
				end
				return
			end

			local dx=m.x-320
			local dy=m.y

			if m.action==1 and (dx*dx+dy*dy)<(64*64) then -- test coins menu
				play.pause=not play.pause
				if play.pause then
					gui.page("shop_balls")
				else
					if beep.replay then beep.stream("play") end
				end
				return
			end
			
		end

-- finally we take any other key or mouse input as a single button click

		if (not play.pause) and ( m.class=="key" or m.class=="joykey" or m.class=="mouse" ) and
			( not( m.keyname=="return" or m.keyname=="enter" or m.keyname=="right" or m.keycode==0 or m.keycode==102 or m.keycode==4 or m.keycode==103 or m.keycode==108 or m.keycode==97 ) )
		then
		
			if m.action==1 then

				if not play.butt_wait then
--print("BUTTDOWN")
					play.butt=true
					play.butt_down=true
				end
				
			elseif m.action==-1 then
			
--print("BUTTUP")
				play.butt=false
				play.butt_up=true

			end
			
		end

	end

	function play.update()
		if play.butt_wait then
			play.butt_wait=play.butt_wait-1
			if play.butt_wait<=0 then play.butt_wait=nil end
		end
		
		if play.slomo then
			play.slomo=play.slomo+1

			if play.slomo >= 64*3 then
				game.next=state.rebake("bulb.game_win")
				return
			end

			local f=2+math.floor(play.slomo/16)
			if play.slomo % f ~= 0 then
				return
			end
		end

		for i,v in ipairs(mods) do
			if v.update then v.update() end
		end
				
--		play.butt=false
		play.butt_down=false
		play.butt_up=false
		
		if state.opts.smell=="gamestick" and ((game.frame%64)==0) then
			if wwin.hardcore.count_input_devices then
				local dev_count=wwin.hardcore.count_input_devices()
				if play.dev_count > dev_count then
					if not play.pause then -- enter pause state menu
						play.pause=true
						gui.page("game_menu")
					end
				end
				play.dev_count = dev_count
			end
		end
	end

	function play.draw()
		
		for i,v in ipairs(mods) do
			if v.draw then v.draw() end
		end
		

		if play.pause then
			game.draw_crap(true,true,true)
		else
			game.draw_crap(false,true,false)
		end
		
		if play.slomo then
			local a=play.slomo/(64*3)
			if a>1 then a=1 end
			cake.canvas.flat.tristrip("xyzrgba",{
				-2048,-2048,0,				a,a,a,a,
				 2048,-2048,0,				a,a,a,a,
				-2048, 2048,0,				a,a,a,a,
				 2048, 2048,0,				a,a,a,a,
			})
			
		end
	end
	
	return play
	
end
