
function editor.contextRooms(noSettings)
	local settings = not noSettings
	editor.roomContextMode = noSettings and "Settings" or editor.roomContextMode 
	return {	
		size 	 = -1,
		name 	 = settings and  "···" or "Rooms",  
		align 	 = settings and  "center" or "left", 	
		col 	 = {r=0,g=0,b=0,a=settings and 0.5 or 0}, 
		subWidth = 250, 
		subHeight = 300,
		sameY 	 = true,
		sub 	 = editor.roomContextMode, 
		items 	 = lume.concat({{
			(currentRoom and currentRoom.viewport and game.setContains(currentSet,currentRoom)) and {	
				name 		= "Settings", 	
				size 		= settings and 1 or 0, 
				subitems 	= settings and editor.roomSettings() or {} 	, 
				align 		= "center" , 
				static 		= noSettings ,
				func  		= function()return true end,
				rollOn  	= function(x) editor.roomContextMode=x.name end
			} or {name 		= "Settings",size=0 },
			(currentRoom and currentRoom.viewport and game.setContains(currentSet,currentRoom)) and {	
				name 		= "Camera", 	
				size 		= settings and 1 or 0, 
				subitems 	= settings and editor.cameraSettings() or {} 	, 
				align 		= "center" , 
				static 		= noSettings ,
				func  		= function()return true end,
				rollOn  	= function(x) 
					editor.roomContextMode=x.name 
					editor.preTempCam = currentRoom.camera 
					editor.preTempCam.index = currentRoom.cameraID 
				end
			} or {name 		= "Settings",size=0 },
			-- {	
			-- 	name 		= "Rooms", 		
			-- 	subitems	= editor.roomSelector() 		, 
			-- 	align 		= "center" , 
			-- 	func 		= function()return true end,
			-- 	rollOn 		= function(x) editor.roomContextMode=x.name end
			-- },
			-- {	
			-- 	name 		= "Sets", 		
			-- 	subitems	= editor.setSelector() 		, 
			-- 	align 		= "center" , 
			-- 	func  		= function()return true end,
			-- 	rollOn  	= function(x) editor.roomContextMode=x.name end
			-- },
		}
	})}
end

function editor.roomSettings()
	local items = {}
	local room = currentRoom.room

	table.insert(items,{
		{ size=8, name="",  	tip="key: "..room.key,update=function(x) x.name =room.name end},
		{ size=-1,name="···", 	func = function() editor.renameRoom(room) return "rename" end ,col={r=0,g=0,b=0,a=0.5}}
	})
	local l = room.lighting
	table.insert(items, editor.makeToggle(l,"enabled",{name="lighting"},{
		editor.makeToggle(l.ambient,{"amount","enabled","ambient light"},{colors={"color"}}),
		editor.makeToggle(l.static,"enabled",{name="static lighting"},{
			editor.makeToggle(l.render, "enabled",{name="prerender",click=function() 
					l.render.scale=l.render.scale or 1 
					l.render.exposure=l.render.exposure or 1
				end},{
				editor.makeToggle(l.render,"run",{name="run"}),
				editor.makeSlider(l.render,"scale",{min=1,max=4,round=1}),
				editor.makeSlider(l.render,"exposure",{min=0.1,max=2}),
				editor.makeToggle(l.render,{"blurSize","blurEnabled","blur"},{min=0,max=4}),
				editor.makeToggle(l.render,"lock",{name="lock view"}),
				-- editor.makeToggle(l.render,"gpu",{name="GPU mode"}),
				-- editor.makeToggle(l.render,"shuffle",{name="shuffle rays"}),
				-- editor.makeSlider(l.render,"depth",{min=2,max=32,round=1}),
				-- editor.makeSlider(l.render,"numrays",{min=8,max=256,round=2}),
				-- editor.makeToggle(l.render,{"atlasSize","showPreview","show atlas"},{max=2}),
			})
		}),
		editor.makeToggle(l.dynamic,"enabled",{name="dynamic lighting"},{
			editor.makeToggle(l.probes, "enabled",{name="light probes"},{
				editor.makeToggle(l.probes,{"blur","convolve","convolve"}),
				editor.makeToggle(l.probes,"showProbes",{name="show probes"},{
					editor.makeToggle(l.probes,"test",{name="test probes"}),
					editor.makeToggle(l.probes,{"atlasSize","showAtlas","show atlas"},{max=2}),
				}),
			}),
			editor.makeToggle(l.vct,"enabled",{name="voxel cone tracing"},{
				editor.makeSlider(l.vct,"resolution",{min=16,max=128,round=16}),
				-- editor.makeSlider(l.vct,"bounces",{min=1,max=3,round=1}),
				-- editor.makeToggle(l.vct,"useShadowmap",{name="mapped shadows"}),
				editor.makeToggle(l.vct,"showOcclusion",{name="show occlusion"}),
				editor.makeToggle(l.vct,"showTraced",{name="show traced"}),
				editor.makeToggle(l.vct,"showVoxels",{name="show voxels"},{
					editor.makeToggle(l.vct,"showAverage",{name="split faces"}),
					editor.makeSlider(l.vct,"lod",{min=0,max=6,round=1}),
					editor.makeModes(l.vct,"show",{"diffuse","normal","occlusion","light"})
				}),
			}),
		}),
		editor.makeToggle(l.toon,{"amount","enabled","toon stuff"}),
	}))

	if roomsView then 
		table.insert( items, { name="View Depth", 		      slider={target=currentRoom,  					prop="depth" ,	min=0,	max=1,	round=0.001} } )
		table.insert( items, { name="View Wobble Speed", 		slider={target=currentRoom.viewport.wobble, 	prop="speed" ,	min=0,	max=10,	round=0.001}} )
		table.insert( items, { name="View Wobble Strength",	slider={target=currentRoom.viewport.wobble, 	prop="dist" ,	min=0,	max=50,	round=0.001}  } )
		table.insert( items, { name="Duplicate View",func = function() game.duplicateRoom(currentRoom,{offset={x=20,y=20}}) end} )
		table.insert( items, { name="Remove View", 	 func = function() game.removeRoom(currentRoom) end, warning="close",col = {r=0.8,g=0.2,b=0.2,a=0.4} } )
	end

	return items
end

function editor.cameraSettings()
	local settings = {}
	local buttons = {}

	table.insert(settings,classicConcat({{name="switch to:",size=2.5,align="left",func=nothing}},lume.map(room.cameras,function(cam) 
		return { 
			name=tostring(cam.index), 
			func=function() 
				editor.resetCamera(cam.index) 
				editor.preTempCam = currentRoom.camera 
				editor.preTempCam.index = currentRoom.cameraID 
				return true 
			end, 
			hover=function() editor.tempCam = cam.index end,
			update=function(x) x.col=(editor.preTempCam.index==cam.index) and colors.black50 or nil end	
		}
	end)))
	table.insert(settings,classicConcat({{name="set to:",size=2.5,align="left",func=nothing}},lume.map(room.cameras,function(cam) 
		return { 
			name=tostring(cam.index)	, 
			func=function() editor.setCamera(cam.index) return true end
		}
	end)))
	--table.insert(settings, {name="Lock"})
	--table.insert(settings, {name="FOV"})
	--table.insert(settings, {name="Wobble"})
	--table.insert(settings, {name="Interest"})
	-- shaders n stuff idk
	return settings
end

function editor.newUntitledRoom()
	local key 	 				= uuid()
	level.rooms[key]    		= deepcopy(defaultLevel.rooms.defaultRoom)
	level.rooms[key].name 	 	= "Untitled Room "..lume.count(level.rooms)
	level.rooms[key].sky.color  = room and deepcopy(room.sky.color) or level.rooms[key].sky.color
	local view 					= {key=key,cameraID=1,viewportID=1,depth=1,room=level.rooms[key],camera=deepcopy(level.rooms[key].cameras[1]),viewport=deepcopy(level.rooms[key].viewports[1])}
	if add then 
		table.insert 		(currentRooms,view)
	end
	scene.loadRoom 	(key)
	editor.setRoom 		(view)
	scene.setView 	(view)
	return view
end


function editor.roomSelector()
	local items = {}
	local row = {}
	editor.roomPreview 		= {w=70,h=48}
	local numRooms = lume.count(level.rooms)

	local refresh = function ()
		if contextMenu.open then
			local selected 			= contextMenu.selected
			contextMenu.items[1][2] = editor.contextRooms 	()
			contextMenu.selected 	= selected
			contextMenu.refresh 	= true
		end
	end

	local roomButton = function(targetRoom)
			table.insert(row, {name="",key=targetRoom and targetRoom.key or nil,name2=targetRoom and targetRoom.name or "new room", align="center",height=50,col=targetRoom and targetRoom.sky.color or nil,img=targetRoom and targetRoom.preview or nil, 
			draw = function(item)
				if item.img then  
					gfx.draw(item.img,item.x+2,item.y+2,0,0.5,0.5)
				end
				if not targetRoom then
					gfx.draw(getImage("bigPlus"),item.x+2,item.y-2)
				end
				local w = item.width-4
				if contextMenu.open and item.options and item.context.editing==item.key then 
					gfx.setColor(0,0,0,0.6)
					gfx.rectangle("fill",mf(item.x+item.width-17),mf(item.y+1),16,item.height-2)
					for b,button in pairs(item.options) do
						editor.drawButton(button)
					end
					w = w -17
				end
				local cut = currentRoom.key==item.key and w-4 or w
				if not targetRoom or item.hovered then
					gfx.fontSize(8)
					gfx.setColor(0,0,0,0.8)
					gfx.rectangle("fill",mf(item.x+2),mf(item.y+item.height-10),w<75 and w+2 or w-4,10)
					gfx.setColor(1,1,1,0.9)
					gfx.printf(ellipses(item.key and level.rooms[item.key].name or item.name2,cut),mf(item.x+2),mf(item.y+item.height-11),w,"center")
					gfx.fontSize(contextMenu.fontSize)
				end
				if currentRoom.key==item.key then 
					gfx.setLineWidth(1)
					gfx.setColor(1,1,1,0.4)
					gfx.rectangle("line",mf(item.x+2),mf(item.y+2),cut==w and w or w+1,mf(item.height-3),2)
				end
			end, 
			funcR = targetRoom and function(item)
				item.context.editing = item.key
				item.options = {
					{
						x = item.x+item.width-16,
						y = item.y+3,
						w = 14,
						h = 14,
						col = {r=0.8/1.3,g=0.4/1.3,b=0.2/1.3,a=0.8},
						func= function() editor.deleteRoom(item.key) refresh() end,
						text= "×"
					},
					roomsView and {
						x = item.x+item.width-16,
						y = item.y+19,
						w = 14,
						h = 14,
						col = {r=0.4/2,g=1/2,b=0.5/2,a=0.8},
						func= function() game.addRoom(item.key) end,
						text= "+"
					} or nil,
					{
						x = item.x+item.width-16,
						y = item.y+18+16,
						w = 14,
						h = 14,
						col = {r=0.1,g=0.1,b=0.1,a=0.9},
						func= function() editor.renameRoom(targetRoom) end,
						text= "…"
					}
				}
				return "options"
			end or nil,
			func=function(item) 
				if item.context.editing~=item.key or mouse.x<item.x+item.width-18 then 
					if not targetRoom then 
						editor.newRoom()
						waitFor(function()
							if numRooms~=lume.count(level.rooms) then 
								refresh()
								return  true
							end
						end)
					elseif currentRoom.key==targetRoom.key and roomsView then
						game.enterRoom()
					elseif currentRoom.key~=targetRoom.key then
						game.openRoom(targetRoom.key)
					end
					item.context.editing=""
				end
				return "new"
			end
		})
		if #row==3 then 
			row.height = 50
			table.insert(items,row) 
			row={}
		end
	end

	roomButton()
	for r,room in lume.ripairs(sortBy(level.rooms,"dateCreated","name","key")) do 
		roomButton(room)
	end
	
	if #row>0 and #row<3 then
		table.insert(items,{row[1],row[2] or {static=true},row[3] or {static=true},height=50}) 
	end
	return items
end

function editor.setSelector()
	local items 		= {}
	local row 			= {}
	local numSets 		= lume.count(level.sets)

	local refresh = function ()
		local selected 			= contextMenu.selected
		contextMenu.items[1][2] = editor.contextRooms 	()
		contextMenu.selected 	= selected
	end

	local setButton 	= function(targetSet)
		table.insert(row, {name="",key=targetSet and targetSet.key or nil,name2=targetSet and targetSet.name or "new set", align="center",height=50,col=targetSet and (targetSet.color or currentSet.sky.color) or nil,img=targetSet and targetSet.preview or nil, 
			draw = function(item)

				if item.img then  
					gfx.draw(item.img,item.x+2,item.y+2,0,0.5,0.5)
				end
				if not targetSet then
					gfx.draw(getImage("bigPlus"),item.x+2,item.y-2)
				end
				local w = item.width-4
				if contextMenu.open and item.options and item.context.editing==item.key then 
					gfx.setColor(0,0,0,0.6)
					gfx.rectangle("fill",mf(item.x+item.width-17),mf(item.y+1),16,item.height-2)
					for b,button in pairs(item.options) do
						editor.drawButton(button)
					end
					w = w -17
				end
				local cut = currentSet.key==item.key and w-4 or w
				if not targetSet or item.hovered then
					gfx.fontSize(8)
					gfx.setColor(0,0,0,0.8)
					gfx.rectangle("fill",mf(item.x+2),mf(item.y+item.height-10),w<75 and w+2 or w-4,10)
					gfx.setColor(1,1,1,0.9)
					local txt = item.key and level.sets[item.key].name or item.name2 or ""
					gfx.printf(ellipses(txt,cut), mf(item.x+2), mf(item.y+item.height-11),
					w,"center")
					gfx.fontSize(contextMenu.fontSize)
				end
				if currentSet.key==item.key then 
					gfx.setLineWidth(1)
					gfx.setColor(1,1,1,0.4)
					gfx.rectangle("line",mf(item.x+2),mf(item.y+2),cut==w and w or w+1,mf(item.height-3),2)
				end
			end, 
			funcR = targetSet and function(item)
				item.context.editing = item.key
				item.options = {
					{
						x = item.x+item.width-16,
						y = item.y+3,
						w = 14,
						h = 14,
						col = {r=0.8/1.3,g=0.4/1.3,b=0.3/1.3,a=0.8},
						func= function() editor.deleteSet(item.key) refresh() end,
						text= "×"
					},
					{
						x = item.x+item.width-16,
						y = item.y+19,
						w = 14,
						h = 14,
						col = {r=0.1,g=0.2,b=0.4,a=0.9},
						func= function() editor.duplicateSet(item.key) refresh() end,
						text= "D"
					},
					{
						x = item.x+item.width-16,
						y = item.y+18+16,
						w = 14,
						h = 14,
						col = {r=0.1,g=0.1,b=0.1,a=0.9},
						func= function() editor.renameSet(targetSet) end,
						text= "…"
					}
				}
				return "options"
			end or nil,
			func=function(item) 
				if item.context.editing~=item.key or mouse.x<item.x+item.width-18 then 
					if not targetSet then 
						editor.newSet()
						waitFor(function()
							if numSets~=lume.count(level.sets) then 
								refresh()
								return  true
							end
						end)
					elseif targetSet.key then
						game.openSet(targetSet.key)
					end
					item.context.editing=""
				end
				return "new"
			end
		})
		if #row==3 then 
			row.height 		= 50
			table.insert	(items,row) 
			row 			= {}
		end
	end
	setButton()
	for s,set in lume.ripairs(sortBy(level.sets,"dateCreated","name","key")) do 
		setButton(set)
	end
	
	if #row>0 and #row<3 then
		table.insert(items,{row[1],row[2] or {static=true},row[3] or {static=true},height=50}) 
	end
	return items
end



function editor.duplicateSet(key)
	local new  			= uuid()
	level.sets[new] 	= deepcopy(level.sets[key])
	level.sets[new].key = new 
	level.sets[new].dateCreated = os.time() 
	level.sets[new].name= level.sets[key].name.." copy"
end

function editor.deleteRoom(key)
	local delete = function(key)
		for i,s in pairs(level.sets) do 
			for j,r in lume.ripairs(s.rooms) do 
				if r.key == key then
					table.remove(level.sets[i].rooms,j)
				end
			end
		end

		for j,r in lume.ripairs(currentRooms) do 
			if r.key == key then
				table.remove(currentRooms,j)
			end
		end

		level.rooms[key] = nil

		currentRoom = currentRooms[1]
	end

	if not roomsView and key==currentRoom.key then 
		game.enterStackRoom 	(-1)
		editor.closeContextMenu()
		currentRoom=nil
		waitFor(function() 
			if roomZoom==1 then
				editor.deleteRoom(key)
				return true
			end
		end)
	else
		delete(key)
	end
end

function editor.deleteSet(key)
	if not roomsView and key==currentSet.key then 
		game.enterStackRoom 	(-1)
		level.sets[key] 		= nil
		currentSet 				= level.sets[lume.last(lume.sort(level.sets, "dateCreated" )).key]
	else
		level.sets[key] = nil
	end
end

function editor.renameRoom(room)
	namer:typeString("Rename Room",room.name,getMouse(),function(x) room.name=x end)
end

function editor.renameSet(set)
	namer:typeString("Rename Set",set.name,getMouse(),function(x) set.name=x end)
end

function editor.newRoom(set,add)
	namer:typeString("New Room","Untitled Room "..tostring(lume.count(level.rooms)+1),{x=mouse.x,y=mouse.y},
		function(x) 	
			local key 	 				= uuid()
			level.rooms[key]    		= deepcopy(defaultLevel.rooms.defaultRoom)
			level.rooms[key].key 		= key
			level.rooms[key].name 	= x
			level.rooms[key].dateCreated= os.time()
			level.rooms[key].sky.color  = room and deepcopy(room.sky.color) or level.rooms[key].sky.color
			level.rooms[key].cameras  	= {camera.setup()}
			if overviewPanel.open then 
				level.rooms[key].ox = overviewPanel.moose.x
				level.rooms[key].oy = overviewPanel.moose.y 
				editor.newOverviewRoom(level.rooms[key])
			end
			local view 					= {key=key,cameraID=1,viewportID=1,depth=1,room=level.rooms[key],camera=deepcopy(level.rooms[key].cameras[1]),viewport=deepcopy(level.rooms[key].viewports[1])}
			if set then 
				table.insert 		(set,view)
			end
			scene.loadRoom 		(key)
			if add then 
				editor.setRoom 		(view)
				scene.setView 	(view)
			end
		end
	)
end

function editor.newSet()
	namer:typeString("New Set","Untitled Set "..tostring(lume.count(level.sets)+1),{x=mouse.x,y=mouse.y},
		function(x) 	
			local key 	 	= uuid()
			level.sets[key] = {key=key,name=x,rooms={},dateCreated=os.time()}
		end
	)
end


