-- 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 wstr=require("wetgenes.string")
local function dprint(...) _G.print(wstr.dump(...)) end


module("bulb.game_edit")

function bake(oven,edit)
	local edit=edit or {}
	
	local cake=oven.cake
	local canvas=cake.canvas
	local flat=canvas.flat
	
	local gl=oven.gl
	
	local game=cake.game
	
	
	local sounds=cake.sounds
	local al=sounds.al

	local levels=oven.rebake("bulb.levels")

	local level_idx=0
	local bag={}
	local map={}

	function edit.load_level(idx)
		level_idx=idx or level_idx
		map=levels.rawmap(level_idx)
		bag=levels.rawbag(level_idx)
	end
	function edit.save_level(idx)
		level_idx=idx or level_idx
		levels.setmapbag(level_idx,map,bag)
	end
	function edit.change_level(idx)
		if idx<1 then idx=1 end
		if idx>100 then idx=100 end
		edit.save_level(level_idx)
		edit.load_level(idx)
		
		print("LEVEL:"..level_idx)
	end

	edit.load_level(1)

	function edit.loads()
		cake.fonts.loads({"Vera","Chunk"})
				
	end
	
	local palsiz=480/24
	local bagsiz=16
	
	function edit.setup()

		edit.x=0
		edit.y=0

		edit.cw=6
		edit.ch=14
		
		edit.unit=32
		
		edit.px=edit.unit
		edit.py=480-edit.unit

		edit.brush=1
		
		edit.butt=nil
	
		edit.loads()

	end

	function edit.clean()


	end
	

	function edit.msg(m)
--dprint(m)

		if m.class=="key" then
			if m.action==-1 then
				local a=string.byte(m.ascii)
				local a0=string.byte("0")
				local a9=string.byte("9")
				if a and a>=a0 and a<=a9 then
					local s= level_idx .. m.ascii
					if #s>2 then s=string.sub(s,-2,-1) end
					if string.sub(s,1,1)=="0" then s=string.sub(s,-1,-1) end
					edit.change_level( tonumber(s) or 1 )
				else
					if     m.ascii=="-" then
						edit.change_level(level_idx-1)
					elseif m.ascii=="=" then
						edit.change_level(level_idx+1)
					elseif m.ascii=="e" then
						game.next=oven.rebake("bulb.game_menu")
					elseif m.ascii=="p" then
						game.next=oven.rebake("bulb.game_play").setup_mode{level=level_idx,mode="puzzle"}
					end
				end
			end
		end
		
		if m.class=="mouse" then
		
			if m.action==1  then edit.butt=m.keycode end
			if m.action==-1 then edit.butt=nil end
		
			edit.x=m.x
			edit.y=m.y

			if edit.mapzone(edit.x,edit.y) then
			
				local cx,cy=edit.pxpy_to_cxcy(edit.x,edit.y)
				local idx=edit.cxcy_to_idx(cx,cy)
				

				if edit.butt==1 then -- draw
					map[idx]=edit.brush
				end
				if edit.butt==2 then -- pickup
					local p=map[idx]
					if p>=1 and p<=64 then
						edit.brush=p
					end
				end
				if edit.butt==3 then -- delete
					map[idx]=0
				end
				
			end

			if m.action==1 then -- click only
				local pidx=edit.palzone(edit.x,edit.y)
				if pidx then
					if edit.butt==1 then -- draw
						edit.brush=pidx
					end
				end
			end
			
			local bidx=edit.bagzone(edit.x,edit.y)
			if bidx then
				if edit.butt==1 then -- draw
					bag[bidx]=edit.brush
				end
				if edit.butt==2 then -- pickup
					local p=bag[bidx]
					if p>=1 and p<=64 then
						edit.brush=p
					end
				end
				if edit.butt==3 then -- delete
					bag[bidx]=0
				end
			end
		end
		
		if m.action==-1 then -- save on mouse up
			edit.save_level()
		end
	end

	function edit.update()

		
	end

	function edit.draw()

		gl.Color(4/16,0,0,1)
		flat.tristrip("xyz",{
			0,0,0,
			bagsiz*16,0,0,
			0,bagsiz*6,0,
			bagsiz*16,bagsiz*6,0,
		})

		gl.Color(0,4/16,0,1)
		flat.tristrip("xyz",{
			320 - palsiz*3	,480 - palsiz*24	,0,
			320				,480 - palsiz*24	,0,
			320 - palsiz*3	,480				,0,
			320				,480				,0,
		})

		gl.Color(0,0,4/16,1)
		flat.tristrip("xyz",{
			(0.5)*edit.unit				,480 - (1+edit.ch)*edit.unit*3/4		,0,
			(1.0+edit.cw)*edit.unit		,480 - (1+edit.ch)*edit.unit*3/4		,0,
			(0.5)*edit.unit				,480 - (0.5)*edit.unit*3/4				,0,
			(1.0+edit.cw)*edit.unit		,480 - (0.5)*edit.unit*3/4				,0,
		})

		gl.Color(1,1,1,1)
		
		local bulbs=cake.sheets.get("bulbs")
		
		local px=0
		local py=0
		local idx=1
		
		for y=1,edit.ch do -- bottom to top
		
			for x=1,edit.cw do
			
				px = ( (x-1) + ( (y%2)==1 and 0 or 0.5 ) ) * edit.unit
				py = (y-1) * 3/4 * -edit.unit

				local id=map[idx]
--				id=2
				if id and id>0 and id<=64 then 

					bulbs:draw(id,edit.px + px, edit.py + py ,0 , edit.unit *5/4 * 1.25 )

				end
				
				idx=idx+1
			end
		end

		local idx=1
		for y=1,6 do -- bottom to top
		
			for x=1,16 do
			
				px = (x-0.5)*bagsiz
				py = (y-0.5)*bagsiz

				local id=bag[idx]
				
				if id and id>0 and id<=64 then 
					bulbs:draw(id,px,py ,0 , bagsiz *1.25 )
				end
				
				idx=idx+1
			end
		end

		for y=1,3 do
			for x=1,24 do
			
				local id= (y-1)*24 + x
				if id > 64 then break end
				
				bulbs:draw(id, 320 - palsiz*(y-0.5) , 480 - palsiz*(x-0.5) ,0 , palsiz*1.25)

			end
		end


		gl.Color(0.5,0.5,0.5,0.5)
		
		if edit.mapzone(edit.x,edit.y) then

			local cx,cy=edit.pxpy_to_cxcy(edit.x,edit.y)
			local px,py=edit.cxcy_to_pxpy(cx,cy)
			
			bulbs:draw(edit.brush, px , py ,0 , edit.unit*1.25 )
		
		else

			bulbs:draw(edit.brush, edit.x , edit.y ,0 , edit.unit*1.25 )
		
		end

		gl.Color(1,1,1,1)
		canvas.font.set(cake.fonts.get("Chunk"))
		canvas.font.set_size(16,0)

		canvas.font.set_xy(bagsiz*0,bagsiz*6)
		canvas.font.draw(" L:"..level_idx)

	end

	function edit.bagzone(x,y)
		if x<bagsiz*16 then
			if y<bagsiz*6 then
				local idx=1 + math.floor(x/bagsiz) + math.floor(y/bagsiz)*16
				if idx<1 then idx=1 end
				if idx>16*6 then idx=16*6 end
				return idx
			end
		end
		return false
	end
	
	function edit.palzone(x,y)
		
		if y > 480 - palsiz*24 then
			if x > 320 - palsiz*3 then
				x=320-x
				y=480-y
				local idx=1 + math.floor(y/palsiz) + math.floor(x/palsiz)*24
				if idx<1 then idx=1 end
				if idx>64 then idx=64 end
				return idx
			end
		end
		return false
	end
	
	function edit.mapzone(x,y)
		if x < (edit.cw+1) * edit.unit then
			if y > 480 - (edit.ch+1) * edit.unit * 3/4 then
				return true
			end
		end
		return false
	end
	
	function edit.pxpy_to_cxcy(x,y)
		local cx,cy=0,0
		cy= math.floor( 0.5 + ( ( edit.py - edit.y ) / (edit.unit*0.75) ) )
		if cy<0 then cy=0 end
		if cy>edit.ch-1 then cy=edit.ch-1 end

		local fx=0
		if (cy%2)==1 then fx=0.5 end

		cx= math.floor( 0.5 + ( ( edit.x - edit.px ) / (edit.unit) ) - fx )
		if cx<0 then cx=0 end
		if cx>edit.cw-1 then cx=edit.cw-1 end
		
		
		x=edit.px + (fx+cx)*edit.unit
		y=edit.py - cy*edit.unit*0.75
		return cx,cy
	end

	function edit.cxcy_to_idx(cx,cy)
		return 1+cx+(cy*edit.cw)
	end
	
	function edit.cxcy_to_pxpy(cx,cy)
		local x,y=0,0
		local fx=0
		if (cy%2)==1 then fx=0.5 end

		x=edit.px + (fx+cx)*edit.unit
		y=edit.py - cy*edit.unit*0.75

		return x,y
	end
	
	return edit
	
end
