-- 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 function print(...) _G.print(...) end

local wstr=require("wetgenes.string")
local pack=require("wetgenes.pack")
local sod=require("wetgenes.sod")

--module
local M={ modname=(...) } ; package.loaded[M.modname]=M


M.bake=function(state,beep)

	beep=beep or {} 
	beep.modname=M.modname

	local cake=state.cake
	local sounds=cake.sounds
	local al=sounds.al
	
	
	beep.fadewait=0
	
	

	local ids={
	

		["bossmove"]={
			name="ogg/bossmove",
		},
		["warning"]={
			name="ogg/warning",
		},

		["ball_side"]={
			name="sfx/clear1",
		},
		["ball_land"]={
			name="sfx/clear1",
		},
		["score"]={
			name="sfx/slide",
		},
		["fall"]={
			name="sfx/land",
		},
		
		["bounce"]={
			name="ogg/bounce",
		},

		["boom"]={
			name="ogg/explode1",
			idx=4,
		},
		["fire"]={
			name="ogg/explode2",
--			idx=4,
		},
		
		["genicide"]={
			name="ogg/same",
		},

		["upturn"]={
			name="ogg/switch",
		},

		["skip"]={
			name="ogg/warp1",
		},
		["warp"]={
			name="ogg/warp2",
		},
		["reset"]={
			name="ogg/warp3",
		},

		["sponge"]={
			name="ogg/sponge1",
		},
		["shatter"]={
			name="ogg/shatter",
		},
		["squash"]={
			name="ogg/squash",
		},

		["dopple"]={
			name="ogg/dopple",
		},


		["button"]={
			name="ogg/button1",
		},
		["button1"]={
			name="ogg/button1",
		},
		["button2"]={
			name="ogg/button2",
		},
		["button3"]={
			name="ogg/button3",
		},
		
		["score4"]={
			name="ogg/victorious4",
		},

		["die"]={
			name="ogg/die",
		},

--		["shop"]={
--			name="ogg/shop",
--		},

		["scream"]={
			name="ogg/wilhelm_scream",
			idx=4,
		},
		["dead"]={
			name="ogg/dead",
			idx=4,
		},
	}

-- load all the sample referenced in the ids table
	function beep.loads()
		local t={}
		for n,v in pairs(ids) do
			t[v.name]=true
		end
		local tab={}
		for n,v in pairs(t) do
			tab[#tab+1]=n
		end
		cake.sounds.loads(tab)
	end

	function beep.lookup(id)
	
		while type(id)=="string" do -- allow recursive lookups
			id=ids[id]
		end
	
		return id
	end

	function beep.play(id)
		local t=beep.lookup(id)
		
		if t then
		
			sounds.beep_max=3 -- keep 4 available for long sounds
		
			local ss=sounds.get(t.name)
			
			if ss then
				ss.idx=t.idx -- temp setting
				ss.name=t.name
				
				sounds.beep(ss)
			end
		
		else
		
print("Missing sound FX for "..id)

		end
	
	end

	function beep.danger(f)
--		if f<0 then f=0 elseif f>1 then f=1 end
		if f<0.5 then f=0 else f=1 end
		local qq=cake.sounds.queues[1]
		qq.l2= 1.0 - (1.0*f)
		qq.r2=       (1.0*f)

	end

	function beep.stream_fx(id,n)
		local qq=cake.sounds.queues[2]


		if     id=="win" then
		
			local ns={
				"ogg/victorious1",
				"ogg/victorious2",
				"ogg/victorious3",
				"ogg/victorious4",
			}
			local name=ns[ 1 + (n%#ns) ]

			qq.ogg_loop=false
			
			qq.state="play_queue"
			qq.oggs={}
			qq.gain=1
			qq.pitch=1
			qq.oggs[1]=name

			local qq=cake.sounds.queues[1]
			qq.gain=0
			
			beep.mode="sfx_fadeoutin"
			beep.fadeinc=(1/(60*1))
			beep.fadewait=60*2.5
			
		elseif     id=="score" then
		
			qq.ogg_loop=false
			
			qq.state="play_queue"
			qq.oggs={}
			qq.gain=1
			qq.pitch=1
			qq.oggs[1]="ogg/arcadefired"

			local qq=cake.sounds.queues[1]
			qq.gain=0
			
			beep.mode="sfx_fadeoutin"
			beep.fadeinc=(1/(60*8))
		end
		
				
	end
	
	function beep.update()
		local q1=cake.sounds.queues[1]
		local q2=cake.sounds.queues[2]

		if	beep.mode=="sfx_playonce" then
		
			if not q2.og and not q2.oggs[1] then -- finished
				
				q1.gain=1
				q2.gain=0
			end
		
		elseif	beep.mode=="sfx_fadeoutin" then
		
			if beep.fadewait>0 then
				beep.fadewait=beep.fadewait-1
			else
				q1.gain=q1.gain+beep.fadeinc
				q2.gain=q2.gain-beep.fadeinc
				
				if q1.gain>1 or q2.gain<0 then
					q1.gain=1
					q2.gain=0
					beep.mode=nil
				end
			end
		elseif	beep.mode=="sfx_fadeout" then
		
			if beep.fadewait>0 then
				beep.fadewait=beep.fadewait-1
			else
				q2.gain=q2.gain-beep.fadeinc
				
				if q2.gain<0 then
					q1.gain=1
					q2.gain=0
					beep.mode=nil
				end
			end
		end
		
	end

	function beep.stream(id,idx)

--print("stream",id)

		local qq=cake.sounds.queues[1]
		local q2=cake.sounds.queues[2]

		local	BufferData=function(buf,fmt,dat,len,rate)
			if fmt==al.FORMAT_STEREO16 then
				local ud
				ud,qq.l1,qq.r1=sod.dynap_st16(dat,qq.l1,qq.l2,qq.r1,qq.r2,1/65536)
				al.BufferData(buf,al.FORMAT_MONO16,ud,len/2,rate)
			else
				al.BufferData(buf,fmt,dat,len,rate)
			end
		end

		qq.l1=qq.l1 or 0
		qq.r1=qq.r1 or 0


		if     id=="score" then

			qq.BufferData=nil
			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/arcadefired"}

			q2.ogg_loop=false
			q2.state="play_queue"
			q2.oggs={}
			q2.gain=1
			q2.pitch=1
			q2.oggs={"ogg/pulley"}

			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		elseif     id=="intro" then

			qq.BufferData=nil
			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/storytime"}
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		elseif     id=="shop" then

			beep.replay=beep.replay_next
			if beep.replay then qq:push() end

			qq.BufferData=nil
			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
--				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/shop"}
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		elseif id=="menu" then

			qq.BufferData=BufferData
			qq.l2=0.5
			qq.r2=0.0

			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/soft"}
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)
			
			
		elseif id=="play" and beep.replay then

			qq:pop()
			
			al.SourceStop(sounds.strs[1].source)
			qq.l2=0.0
			qq.r2=0.0
			
			beep.replay=nil
			
--			qq.BufferData=BufferData			
			
--			qq.l2=0.5
--			qq.r2=0.0

--			if not qq.oggs then
--				qq.ogg_loop=true
--				qq.state="play_queue"
--				qq.oggs={}
--				qq.gain=1
--				qq.pitch=1
--			end
--			qq.oggs[1]=beep.replay
--			beep.replay=nil
--			qq.og=nil -- force old ogg to stop
--			al.SourceStop(sounds.strs[1].source)

		elseif id=="play" then
		
			local ns={
				"baroquebeat",
				"retrobuzzkill",
				"therebeblooddragons",
			}
			local n=ns[ 1 + (idx%#ns) ]
			
			if idx>=100 then n="boss" end 

			qq.BufferData=BufferData			
			
			qq.l2=0.5
			qq.r2=0.0

			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/"..n}
			beep.replay_next=qq.oggs[1]
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		elseif     id=="bigwin" then

			qq.BufferData=nil
			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/bigwin"}
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		elseif     id=="about" then

			qq.BufferData=nil
			if not qq.oggs then
				qq.ogg_loop=true
				qq.state="play_queue"
				qq.oggs={}
				qq.gain=1
				qq.pitch=1
			end
			qq.oggs={"ogg/boss"}
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		else		
			qq.oggs={}
			qq.og=nil -- force old ogg to stop
			al.SourceStop(sounds.strs[1].source)

		end
		
	end
	
	
	return beep
end
