-----------------------------------------------------------
-- OVERVIEW PANELS
-----------------------------------------------------------
local panel
function editor.defineOverviewPanel()
	overviewPanel = {
		update 	= function(x) editor.overviewPanelUpdate(x) end,
		name 		= "Overview",
		open 		= false,
		docked  = false,
		drag 		= false,
		panning = false,
		showTitles= false,
		winW 		= editor.roomPreview.w,
		winH 		= editor.roomPreview.h,
		titleHeight = 8,
		detailFade = 1,
		loose = 0,
		connectionFade= 0,
		connection={{x=0,y=0},{x=0,y=0},{}},
		sidebar = {x=screenWidth+500,y=0,w=350,h=0,scroll=0},
		connections={},
		selected = {},
		lines 	={},
		charW = 10,
		charH = 10,
		lineCount = 1,
		lineBox = {x=0,y=0,w=0,h=0},
		row 		= 20,
		resize=2,
		transform = {
			x 			= 0,
			y 			= 0,
			scale 	= 1
		},
		full 		= false,
		level 	= {},
		windows = {},
		edge 	= 32,
		alpha = 0,
		min 		= {
			x 		= 0,
			y 		= 0,
			scale = 0.5
		},
		max 		= {
			x 		= 0,
			y 		= 0,
			scale = 4		},
	}
	panel = overviewPanel
	-- for i=5, 30, 1 do 
	-- 	setFont(fonts.mplus,i)
	-- end
	editor.sizeOverviewPanel(overviewPanel)
end

function editor.sizeOverviewPanel(panel)
	panel.docked  = false
	panel.edge 		= -2
	panel.width  	= screenWidth--panel.edge-zero(tracer.x+tracer.width+10)
	panel.height 	= screenHeight
	panel.h 			= panel.height
	panel.x 		 	= 0--panel.edge/2+zero(tracer.x+tracer.width+10)
 	panel.y 			= panel.edge/2
end


function editor.overviewPanelUpdate(panel)
	
	panel.color = {r=0.2,g=0.2,b=0.2,a=0.5}
	panel.hide = panel.alpha<0.05
	editor.slowDraw = editor.resized==0 and panel.alpha==1

	suppressTrace = false--panel.open
	panel.alpha = easeTo(panel.alpha,panel.open and 1 or 0,4)

	panel.lineCount = 0

	if panel.alpha==0 and #panel.lines>0 then 
		panel.lines={}	
		panel.windows={}
		panel.sidebar = {}
		collectgarbage()
	end
	if not panel.open  then return 0 end 

	
	panel.height =  sidebar.titleH

	editor.sizeOverviewPanel(panel)
	editor.overviewUpdate(panel)
	editor.overviewPreMouse(panel)
	editor.updateRoomWindows(panel)
	editor.overviewContext(panel)
	editor.overviewConnections(panel)
	editor.overviewSidebar(panel)
	editor.overviewDialogue(panel)
	editor.drawOverviewPanel(panel)
	editor.overviewPostMouse(panel)



	level.overview = {x=panel.transform.x,y=panel.transform.y,scale=panel.transform.scale}

	panel.redraw = false
end

function editor.overviewDialogue(panel)
	for l=1,panel.lineCount,1 do 
		if panel.lines[l] then 
			editor.overviewDrag(panel,panel.lines[l])
			if panel.lines[l].hovered then mouse.set(function() editor.overviewSelect(panel,panel.lines[l]) end)end
		end
	end
end

function editor.overviewContext(panel)
	if not (panel.somethingHovered or panel.somethingDragging) then 
		local items = {}
		if #panel.selected>0 and not lume.match(panel.selected,function(x) return x.isRoom==false end) then 
			table.insert(items, {	name="New Set From Selected Rooms", 	func = function() editor.newSetFromRooms() end, items={
				{  name = "grid"  },
				{{ name = "strip H" },{ name = "strip V" }}
			}})
		else
			table.insert(items, {	name="New Room", 	func = function() editor.newRoom() end 	})
			table.insert(items, {	name="New Set", 	func = function() editor.newSet() end 	})
		end
		mouse.setR(function()editor.openContextMenu ({
		},{dark=true,color={r=0,g=0,b=0,a=1}} )end)
	end
end

function editor.overviewUpdate(panel)
	local pscale = panel.transform.scale
	panel.titleHeight 			= panel.showTitles and 8 or 0
	panel.somethingHovered 	= false 
	panel.somethingDragging = false 
	panel.detailFade 				= easeTo(panel.detailFade,panel.transform.scale<0.7 and 0 or 1,8)
	panel.winR 							= panel.transform.scale*panel.winW
	panel.scaleSpeed 				= panel.sidebar.hovered and 0 or mouseScroll.y
	panel.transform.scale 	=  mc(0,mc(panel.min.scale,panel.transform.scale+lume.sign(panel.scaleSpeed) * (panel.scaleSpeed^2)*0.01*mc(0.5,panel.transform.scale,1),panel.max.scale),15)
	panel.transform.scaleN  = utils.map(panel.transform.scale,panel.min.scale,panel.max.scale,0,1)
	panel.shifted 					= false
	panel.resize 					 = (round(pscale,2) ~= round(panel.transform.scale,2)) and 2 or panel.resize-1
end

function editor.overviewSidebar(panel)
	
	panel.sidebar = panel.sidebar or {}
	panel.sidebar.target = {dialogue = dialogue}
	panel.sidebar.lines = panel.sidebar.lines or {}
	panel.sidebar.lineBox = panel.sidebar.lineBox or {x=screenWidth,h=panel.sidebar.h}
	panel.sidebar.w = mc(200,screenWidth/6,350)
	panel.sidebar.h = panel.height-32
	if editor.resized>0 then panel.sidebar.x = panel.sidebar.active and screenWidth+10 or panel.sidebar.x end
	panel.sidebar.x = panel.sidebar.x and easeTo(panel.sidebar.x,panel.x+panel.width-(panel.sidebar.active and panel.sidebar.w+2 or -16),2) or screenWidth+500
	panel.sidebar.y = panel.y+16
	panel.sidebar.ox = panel.sidebar.x
	panel.sidebar.oy = panel.sidebar.y
	panel.sidebar.scrollSpeed = panel.sidebar.scrollSpeed and (panel.sidebar.hovered  and panel.sidebar.scrollSpeed+mouseScroll.y*2) or 0
	panel.sidebar.scrollSpeed = panel.sidebar.scrollSpeed*0.92
	panel.sidebar.scroll = panel.sidebar.scroll and mc(0,panel.sidebar.scroll-(hiSpec and panel.sidebar.scrollSpeed or (panel.sidebar.hovered and mouseScroll.y*6 or 0)),panel.sidebar.lineBox.h-screenHeight*1.9,4) or 0
	panel.sidebar.yoff = 16-panel.sidebar.scroll
	panel.sidebar.padding = 4
	panel.sidebar.lineBox = {x=panel.sidebar.x,y=panel.sidebar.y,w=panel.sidebar.w,h=panel.sidebar.h}
	panel.sidebar.color = {r=0.1,g=0.1,b=0.1,a=0.1}
	panel.sidebar.authCol = {r=0.1,g=0.1,b=0.1,a=0.9}
	panel.sidebar.sky = {color = panel.sidebar.color}
	panel.sidebar.sideAuths = panel.sidebar.sideAuths or {}
	panel.sidebar.hovered = mouseIn(panel.sidebar)

	if keypressed("tab")then 
		panel.sidebar.active = not panel.sidebar.active 
		panel.sidebar.resize = true
	end
	if panel.sidebar.x<screenWidth-10 and panel.sidebar.x>screenWidth-100 then 
		panel.sidebar.resize=true 
	end
	if panel.sidebar.x<screenWidth  then 
		editor.overviewFont(panel,true)
		editor.updateDialogueLines(panel,panel.sidebar)
	
		if panel.sidebar.hovered then 
			mouse.set(function() end)
		end
		
	end
	panel.sidebar.resize = false
end

function editor.overviewPreMouse(panel)
	if panel.preDrag and math.dist(mouse.x,mouse.y,panel.preDrag.x,panel.preDrag.y)>4 then 
		panel.dragging = true 
		panel.preDrag = nil
	end
	if panel.panning then 
		lmouse.setCursor(grabCursor)
		mouse.pushRelease(function() 
			panel.panning = false 
		end)
		mouse.pushReleaseM(function() 
			panel.panning = false 
		end)
		panel.mouse = {
			x = (mouse.x-panel.startTransform.x)/panel.startTransform.scale,
			y = (mouse.y-panel.startTransform.y)/panel.startTransform.scale
		}
		panel.transform.x = panel.startTransform.x + (   panel.mouse.x- panel.startMouse.x )
		panel.transform.y = panel.startTransform.y + (   panel.mouse.y- panel.startMouse.y )
	else 
		panel.mouse = {
			x = (mouse.x-panel.transform.x)/panel.transform.scale,
			y = (mouse.y-panel.transform.y)/panel.transform.scale
		}
		panel.moose = {
			x = ((mouse.x 									-screenWidth/2)/panel.transform.scale)-panel.transform.x-panel.winW/2,
			y = ((mouse.y+panel.titleHeight-screenHeight/2)/panel.transform.scale)-panel.transform.y-panel.winH/2
		}
	end
end

function editor.overviewPostMouse(panel)
	if not panel.panning  then 
		if  keyDown("space") then 
			lmouse.setCursor(cursors.hand)
			mouse.set(editor.startOverviewPan)
		elseif panel.somethingHovered == false then
			mouse.setM(editor.startOverviewPan)
			mouse.pushClick(function() 
				editor.overviewDeselect(panel)
			end)
		end
	end

	mouse.pushRelease(function() 
		editor.dropDialogue(panel)
		panel.lineTarget = nil
		panel.preDrag 	= nil
		panel.dragging = false
		panel.loose = 1

	end)
end

function editor.overviewFont(panel,sidebar)
	panel.lineFontSize = sidebar and 10 or mf(mc(6,(5*panel.transform.scale)^1.1,11))
	panel.charW = fonts.mplus.sizes[panel.lineFontSize] and fonts.mplus.sizes[panel.lineFontSize]:getWidth("i") or panel.charW
	panel.charH = fonts.mplus.sizes[panel.lineFontSize] and fonts.mplus.sizes[panel.lineFontSize]:getHeight() or panel.charH
end

function editor.updateRoomWindows(panel)

	editor.overviewFont(panel,false)

	local lineTarget = false
	local i = 0 
	for w,window in pairs(panel.windows) do 
		i = i + 1
		local y = 0
		bench.push("1")

		window.x,window.y 	= panel.transform.scale*(window.target.ox+panel.transform.x)+screenWidth/2,
													panel.transform.scale*(window.target.oy+panel.transform.y)-panel.titleHeight+screenHeight/2
		window.w,window.h 	= panel.transform.scale*panel.winW+1,
													panel.transform.scale*(panel.winH+panel.titleHeight)
		window.cx,window.cy = window.x+window.w/2,window.y+window.h/2

		editor.overviewDrag(panel,window)
		
		window.hovered = mouseIn(window)

		if window.connecting then 
			mouse.pushReleaseM(function() 
				window.connecting = false 
				panel.somethingConnecting=false
			end)
		end

		if window.hovered then 
			panel.somethingHovered = true
			if panel.somethingConnecting and panel.connection[3]~=window then 
				panel.connection[2]={x=window.cx,y=window.cy}
				mouse.pushReleaseM(function()
					if not lume.any(level.connections,function(x) return (x[1]==window.key and x[2] ==panel.connection[3].key) or (x[2]==window.key and x[1] ==panel.connection[3].key) end) then 
						level.connections[uuid()]={{type="manual",room=window.key},{type="manual",room=panel.connection[3].key}}
						panel.connectionFade = 0
					end
				end)
			end

			mouse.setR(function() 
				local items = {}
				--table.insert(items, {	name="Color", 		items = editor.editBackground(currentSet) 	}) 
				table.insert(items, {{	name="Enter Room", 	func = function() 
					editor.closeOverviewPanel(panel)
					game.exitAllRooms()
					waitFor(function()
						if roomZoom<0.1 then 
							game.enterRoom(window.target,nil,nil,nil,true) 
							return true
						end
					end)
				end }, editor.contextRooms()})
				editor.openContextMenu(items)
			end,true)

			mouse.set(function() 
				editor.overviewSelect(panel,window) 
			end)

			mouse.pushClickM(function()
				panel.connection = {{x=window.cx,y=window.cy},{x=mouse.x,y=mouse.y},window}
				window.connecting = true
				panel.somethingConnecting=true
			end)
		end
		bench.pop("1")

		bench.push("2")
		y = window.y+window.h+3
		
		window.addLine.x = window.x+panel.winR+2
		window.addLine.w = panel.row*mc(0.5,panel.transform.scale/2,1)+3
		window.addLine.h = panel.row*mc(0.5,panel.transform.scale/2,1)
		window.addLine.y = window.y+window.h-window.addLine.h+1
		window.addLine.float=panel.transform.scale<1
		window.addLine.color 		 = {r=1,g=1,b=1,a=0.8}

		window.lineBox = window.lineBox or {x=0,y=0,w=0,h=0}
		window.lineBox.x = window.x 
		window.lineBox.y = y 
		window.lineBox.w = mc(150,window.w*3,500)
		window.lineBox.h = 0

		window.yoff = y
		bench.pop("2")

		bench.push("3")
		editor.updateDialogueLines(panel,window)
		bench.pop("3")

		bench.push("4")
		window.lineBox.h = window.lineBox.h+panel.row/2
		if panel.dragging then 
			if bboxCollide2(window.lineBox,panel.lineBox) then 
				lineTarget = true 
				-- gfx.print(inspect(panel.lineBox),0,0)
				-- gfx.print(inspect(window.lineBox),i*200,0)
				panel.lineTarget = window
			end
		end
		bench.pop("4")
	end
	
	if not lineTarget then 
		panel.lineTarget = nil 
	end

	if panel.selected[1] and panel.selected[1].isLine then 
		local dragY = 0
		for l,line in ipairs(panel.selected) do 
			line.dragY = dragY 
			dragY = dragY + line.h
		end
	end

	if panel.selected[1] then 
		panel.lineBox.x = panel.selected[1].x
		panel.lineBox.y = panel.selected[1].y
		panel.lineBox.w = panel.selected[1].w
	end
	

	bench.push("5")
	for w,window in pairs(panel.windows) do 
		if window.isSet then 
			local p1, p2, hovered, angle, offset
			local offsets = {}
			for v,view in pairs(window.target.views) do

				offsets[view.key] 	= offsets[view.key] and lume.sign(offsets[view.key])*-(math.abs(offsets[view.key])+((offsets[view.key]%2==1 or offsets[view.key]==0) and 10 or 0)) or 0
				offset 					= offsets[view.key]*panel.transform.scale
				p1 							= window
				p2 							= panel.windows[view.key]
				angle 					= math.angle(p1.cx,p1.cy,p2.cx,p2.cy)+pi/2
				p1,p2 					= {p1.cx+math.cos(angle)*offset,p1.cy+math.sin(angle)*offset},{p2.cx+math.cos(angle)*offset,p2.cy+math.sin(angle)*offset}
				hovered 				= false

				if not (panel.somethingHovered or panel.somethingDragging or panel.somethingConnecting ) and distPointToLineSegment({mouse.x,mouse.y},p1,p2) <5*panel.transform.scale then 
					panel.somethingHovered 	= true
					hovered 								= true
					mouse.setR(function()
						panel.selectedConnection = c
						editor.openContextMenu({
							{name="Remove Room from Set"},
						})
					end)
				end
				local highlight = hovered or (panel.selectedConnection and panel.selectedConnection ==c)
				table.insert(panel.connections,{p1,p2,(highlight and 8 or 4)*panel.transform.scale,{0,0,0,highlight and 1 or 0.7}})
			end
		end
	end
	bench.pop("5")
end

function editor.closeOverviewPanel(panel)
	panel.open=false 
end

function editor.overviewConnections(panel)
	local side,d,d2,col = nil,panel.transform.scale*64,999,{}
	for c,connection in pairs(level.connections) do 
		local p1 = panel.windows[connection[1].room]
		local p2 = panel.windows[connection[2].room]
		local hovered = false
		local spatial = connection[1].type~= "manual"
		local sideline 
		d2 = d/math.dist(p1.cx,p1.cy,p2.cx,p2.cy)
		if not (panel.somethingHovered or panel.somethingDragging or panel.somethingConnecting or panel.selectedConnection) and distPointToLineSegment({mouse.x,mouse.y},{p1.cx,p1.cy},{p2.cx,p2.cy}) <4*panel.transform.scale then 
			hovered = true
			panel.somethingHovered = true
			if connection[1].type~= "manual" then 
				side = math.dist(mouse.x,mouse.y,p1.cx,p1.cy)<d and p1 or (math.dist(mouse.x,mouse.y,p2.cx,p2.cy)<d and p2 or nil)
				if side then 
					col = side.target.sky.color
					sideline = {{lerp(p1.cx,p2.cx,side==p1 and d2 or 1-d2),lerp(p1.cy,p2.cy,side==p1 and d2 or 1-d2)},{side.cx,side.cy},15,{col.r,col.g,col.b,1}}
				end
			end
			mouse.setR(function()
				panel.selectedConnection = c
				editor.openContextMenu({
					{name="Remove Connection", func=function() level.connections[c]=nil end},
					{name="Insert New Room"}
				})
			end)
		end
		local highlight = hovered or (panel.selectedConnection and panel.selectedConnection ==c)
		table.insert(panel.connections,{{p1.cx,p1.cy},{p2.cx,p2.cy},panel.transform.scale*(spatial and 1.3 or 0.8)*(highlight and 5 or 2),{1,1,1,(spatial and 1 or (highlight and 0.3 or 0.05))}})
		if sideline then 
			table.insert(panel.connections,sideline)
		end
	end
end

function editor.dropDialogue(panel)
	if panel.selected[1] and panel.selected[1].isLine and panel.dragging and panel.lineTarget then 
		local drop = {}
		local k,v
		for l,line in ipairs(panel.selected) do 
			local win = panel.windows[line.window] or panel.sidebar
			lume.remove(win.lines,line)
			v,k = lume.match(win.target.dialogue,function(x) return x.key==line.dialogue.key end)
			line.drop = v 
			if win ~= panel.sidebar then 
				lume.remove(win.target.dialogue,v)
			end
		end
		for l,line in lume.ripairs(panel.selected) do 
			if #panel.lineTarget.lines > 0 then 
				table.insert(panel.lineTarget.lines, panel.lineInsert, line)
				table.insert(panel.lineTarget.target.dialogue,panel.lineInsert, line.drop)
			else
				table.insert(panel.lineTarget.lines,1,line)
				panel.lineTarget.target.dialogue = panel.lineTarget.target.dialogue or {}
				table.insert(panel.lineTarget.target.dialogue,1, line.drop)
			end
			
			line.window = panel.lineTarg
			line.resize = 2
		end
	end
end

function editor.updateDialogueLines(panel,window)
	
	bench.push("updateDialogueLines")

	local y = window.yoff or window.y
	local shift = panel.dragging and (panel.lineTarget == window)
	local lCount = 1

	local color = window.target.sky and window.target.sky.color or window.color
	local icolor = effects.getInverse(color)

	for l,line in ipairs(window.lines) do
		if not (line.selected and panel.dragging) then 
			if panel.loose>10 then 
				panel.loose=panel.loose-0.05
				line.x = easeTo(line.x, window.x,4)
				line.y = easeTo(line.y, y,4)
			elseif not panel.panning and not panel.redraw and (panel.sidebar~=window or window.active) then 
				line.x = easeTo(line.x, window.x,1.5)
				if shift and not panel.shifted then 
					if mouse.y-panel.row/2<y+line.h/2 then 
						y=y+panel.lineBox.h+panel.row/3
						panel.shifted = true
						panel.lineInsert = lCount
					elseif l == #window.lines then 
						panel.lineInsert = #window.lines
					end
				end
				line.y = easeTo(line.y, (shift and not panel.shifted) and y-panel.row/3 or y,1.5)
			else
				line.x = window.x
				line.y = y
			end
		end

		line.col  			=  dialogue[line.key].style and dialogue[line.key].style.backColor or color
		line.tcol  			=  dialogue[line.key].style and dialogue[line.key].style.textColor or icolor 
		line.window 		= window.key
		line.index 			= l


		if not line.w or mf(line.w)~=mf(window.lineBox.w) or (window~=panel.sidebar and panel.resize>0) or (window==panel.sidebar and window.resize)  or line.resize>0 then 
			line.resize = line.resize and line.resize>0 and line.resize-1 or 0
			line.text,line.lines 	= lume.wordwrap(line.dialogue.languages[game.lang] or "",(line.w-4)/panel.charW)
			line.text 						= lume.trim(line.text)
			line.w 					= window.lineBox.w
			line.h 					= panel.charH*line.lines+4
			line.refreshText = true
		end

		line.invert 		= panel.sidebar~=window
		line.full 			= true
		line.align 			= "left"
		line.alpha 			= panel.alpha^2
		line.col.a 			= panel.sidebar==window and 0.8 or 1--panel.detailFade
		line.infoTime 	= line.infoTime and easeTo(line.infoTime,line.hovered and 1 or 0,4) or 0

		if not panel.sidebar.hovered or panel.sidebar==window then 
			editor.hoverButton(line)
		end


			line.cacheText=true 


		if not line.selected then 
			window.lineBox.h = 	window.lineBox.h + line.h + (window == panel.sidebar and 1 or 1)
		end

		if window~= panel.sidebar and  line.infoTime>0.1 then 
			line.sideAuth = line.sideAuth or {}
			line.sideAuth.x=line.x-(line.w/3+2)*line.infoTime
			line.sideAuth.y=line.y
			line.sideAuth.w=line.w/3
			line.sideAuth.h=mc(9,line.h,panel.charH*2+4)
			line.sideAuth.text=line.dialogue.author
			line.sideAuth.align="left"
			line.sideAuth.full = true
		end

		if not (line.selected and panel.dragging ) then 
			y = y + line.h +1
			lCount=lCount+1
		end

		if line.hovered then 
			panel.somethingHovered = true
		end
		panel.lineCount = panel.lineCount+1
		panel.lines[panel.lineCount] = window.lines[l] 
	end
	
	--window.lineBox.h = window.lineBox.h+(panel.row*panel.transform.scale*0.2)
	bench.pop("updateDialogueLines")
end

function editor.startOverviewPan()
	local panel = overviewPanel
	panel.startTransform 	= lume.clone(panel.transform)
	panel.startMouse 			= lume.clone(panel.mouse)
	panel.panning  				= true
end

function editor.overviewDrag(panel,item)
	if item.selected then 
		if panel.dragging then 
			panel.somethingDragging = true 
			if item.isWindow then 
				item.target.ox = ((mouse.x-item.startDiff.x-screenWidth/2)/panel.transform.scale)-panel.transform.x
				item.target.oy = ((mouse.y-item.startDiff.y+panel.titleHeight-screenHeight/2)/panel.transform.scale)-panel.transform.y
			else 
				item.x=easeTo(item.x , mouse.x-item.w/2 , 2)
				item.y=easeTo(item.y , mouse.y-panel.row/2+item.dragY , 2)
			end
		end
	end
end

function editor.overviewSelect(panel,item)
	panel.lineTarget = nil
	local i,v =  lume.find(panel.selected,item)
	local sameType = panel.selected[1] and ((item.isWindow and panel.selected[1].isWindow) or (item.isLine and panel.selected[1].isLine))
	if shiftDown and sameType then 
		if v then 
			table.remove(panel.selected, i)
			item.selected=false
		else
			table.insert(panel.selected, item)
			item.selected = true
			item.dragOrder = #panel.selected
		end
	else
		if item.isWindow then 
			panel.dragging=true
		else
			panel.preDrag = {x=mouse.x,y=mouse.y}
		end
		if not item.selected then 
			editor.overviewDeselect(panel)
			panel.selected =  {item}
			item.selected = true
			item.dragOrder = #panel.selected
		end
	end
	panel.startMouse = lume.clone(panel.mouse)
	local dragY=0
	for i,item in pairs(panel.selected) do 
		if item.selected then 
			if item.isWindow then 
				item.startDiff  = {x=mouse.x-item.x,y=mouse.y-item.y}
			else
				item.dragY = dragY 
				dragY=dragY+item.h
			end
		end
	end
	panel.lineBox = {x=item.x,y=mouse.y,w=item.w,h=dragY}
end


function editor.drawOverviewPanel(panel)

	gfx.setScissor(panel.x+2,panel.y,panel.width,panel.height)

	for _,c in ipairs(panel.connections) do 
		gfx.setLineWidth(c[3])
		gfx.setColor(c[4])
		gfx.line(c[1][1],c[1][2],c[2][1],c[2][2])
	end
	panel.connections = {}

	panel.connectionFade = easeTo(panel.connectionFade,panel.somethingConnecting and 1 or 0,4)
	if panel.connectionFade >0 then 
		gfx.setColor(1,1,1,0.4*panel.connectionFade)
		gfx.setLineWidth(1+panel.connectionFade*5)
		gfx.line(panel.connection[1].x,panel.connection[1].y,panel.connection[2].x,panel.connection[2].y)
	end
	panel.connection[2] = panel.somethingConnecting and {x=mouse.x,y=mouse.y} or panel.connection[2]


	for w,window in pairs(panel.windows) do 
		local target = window.target
		shaders.alpha:send 		("alpha",panel.alpha) 
		if window.isSet then 
			gfx.setColor(0,0,0,0.8)
			gfx.setLineWidth(12*panel.transform.scale)
			gfx.rectangle("line",window.x-2,window.y-2,window.w+2,window.h+2,3)
		end
		if window.selected then 
			gfx.setColor(1,1,1,0.7)
			gfx.setLineWidth(8)
			gfx.rectangle("line",window.x-2,window.y-2,window.w+2,window.h+2,3)
		end
		gfx.setColor(target.sky.color.r,target.sky.color.g,target.sky.color.b,window.hovered and 1 or 0.8)
		gfx.rectangle("fill",window.x-2,window.y-2,window.w+2,window.h+2,3)

		if panel.showTitles then 
			gfx.setColor(colorTable(effects.getInverse(rgb(target.sky.color))))
			gfx.setFont(fonts.inconsolata,mc(6,(5*panel.transform.scale)^1.2,20))
			gfx.printf(target.name,window.x,window.y+panel.titleHeight*0.5*panel.transform.scale-gfx.currentFontHeight/1.5,panel.winW*panel.transform.scale,"center")
		end

		gfx.setColor(1,1,1,1)

		if window.redraw or panel.redraw then 
			shaders.alpha:send 		("alpha",1) 
			window.redraw = false
			target.preview =  newCanvas(panel.winW,panel.winH)
			if window.isSet then 
				target.preview:renderTo(function() gfx.clear(target.sky.color.r,target.sky.color.g,target.sky.color.b,1) end)
				target.temp = newCanvas(panel.winW,panel.winH)
				for v,view in ipairs(target.views) do
					local mesh 	= updateViewport(view,true)
					if mesh then 
						mesh = mesh.viewMesh
						local room = view.room
						local preTex = gfx.getTexture(mesh)
						gfx.setColor(1,1,1,1)
						drawRoom 		({
							room 			= room,
							camera 		= room.cameras[view.cameraID],
							viewport 	= room.viewports[view.viewportID], 
							canvas 		= target.temp, 
							nolinks 	= true , 
							release 	= true,
							preview   = true ,
							bounds    = {
								w 			= panel.winW, 
								h 			= panel.winH, 
							}
						}) 
						gfx.setTexture(mesh,target.temp)
						gfx.push("all") 
							target.preview:renderTo(function() 	
								gfx.setColor(1,1,1,1)
								gfx.scale(panel.winW/renderWidth,panel.winH/renderHeight) 
								gfx.draw(mesh) 
							end)
						gfx.pop()
						gfx.setTexture(mesh,preTex)
					end
				end
				shaders.alpha:send 		("alpha",panel.alpha) 
			else
				drawRoom({
					room    = target,
					camera 	= target.cameras[1], 
					canvas 	= target.preview, 
					nolinks = true ,
					release = true , 
					preview = true ,
					bounds  = {
						w 			= panel.winW, 
						h 			= panel.winH, 
					}
				}) 
			end
		end

		if target.preview then 
			gfx.setColor(1,1,1,1)
			gfx.draw(target.preview,window.x-1,window.y+(panel.titleHeight-1)*panel.transform.scale,0,panel.transform.scale,panel.transform.scale)
		end

		if window.hovered then 
			if not window.selected then 
				gfx.setColor(0,0,0,0.7)
				gfx.setLineWidth(5)
				gfx.rectangle("line",window.x-4,window.y-4,window.w+6,window.h+6,3)
			end
		end

		gfx.setFont(fonts.inconsolata,mc(4,6*panel.transform.scale,30))
		editor.drawButton(window.addLine)
		gfx.setFont(fonts.inconsolata,mc(4,6*panel.transform.scale,30)*2)
		--gfx.print(round(window.target.ox,0)..","..round(window.target.oy,0),window.x,window.y-25)


		if panel.lineTarget == window then 
			gfx.setColor(0,0,0,0.8)
			gfx.rectangle("fill",window.lineBox.x-6,window.lineBox.y-6-panel.row/6,window.lineBox.w+6,window.lineBox.h+panel.lineBox.h,3)
		end
	end

	editor.drawOverviewLines(panel,true)

	editor.drawContextBack(panel.sidebar)

	gfx.intersectScissor(0,panel.sidebar.y+4,screenWidth,panel.sidebar.h-8)

	editor.drawOverviewLines(panel,false)
	
	gfx.setScissor()
end

function editor.drawOverviewLines(panel,sidebar)
	bench.push("drawOverviewLines")
	editor.overviewFont(panel,not sidebar)
	panel.lineFont = gfx.setFont(fonts.mplus,sidebar and panel.lineFontSize or 10)
	local line
	for l=1,panel.lineCount,1 do 
		line = panel.lines[l]
		if line then 
			if (panel.windows[line.window]~=nil)==sidebar then  
				
				if line.infoTime>0.1 then 
					editor.drawButton(line.sideAuth)
				end

				if line.selected then 
					gfx.setLineWidth(2)
					gfx.setColor(1,1,1,0.7)
					gfx.rectangle("line",line.x,line.y,line.w-1,line.h-1,3)
					gfx.printf(line.dragOrder,line.x-panel.row,line.y+3,panel.row)
				end
				

				line.a = (sidebar and panel.dragging) and 1 or nil
				line.harsh = mean(line.tcol)<0.5
				line.invert = (sidebar)
				gfx.setColor(1,1,1,0.7)
				editor.drawButton(line)


				if not sidebar and l>1  then 
					if (not panel.sidebar.prevAuth or line.author~=panel.sidebar.prevAuth) and line.author~="" and panel.sidebar.hovered then 
						panel.sidebar.sideAuths[line.author]  				= panel.sidebar.sideAuths[line.author] or {}
						panel.sidebar.sideAuths[line.author].x 				= line.x-line.w/2
						panel.sidebar.sideAuths[line.author].y 				= line.y
						panel.sidebar.sideAuths[line.author].w 				= line.w/2
						panel.sidebar.sideAuths[line.author].h 				= panel.row
						if editor.buttonVisible(panel.sidebar.sideAuths[line.author]) then 
							panel.sidebar.sideAuths[line.author].color 		= panel.sidebar.authCol
							--panel.sidebar.sideAuths[line.author].blur 		= true
							panel.sidebar.sideAuths[line.author].full 		= true
							panel.sidebar.sideAuths[line.author].align 		= "left"
							panel.sidebar.sideAuths[line.author].noClick 	= true
							panel.sidebar.sideAuths[line.author].invert 	= true
							panel.sidebar.sideAuths[line.author].cacheText=true 
							panel.sidebar.sideAuths[line.author].text 		= panel.sidebar.sideAuths[line.author].text or panel.sidebar.sideAuths[line.author].text or ellipses(line.author,line.w/2-20)
							editor.drawButton(panel.sidebar.sideAuths[line.author])
						end
					end
					panel.sidebar.prevAuth = line.author
				end
			end
		end
	end
	bench.pop("drawOverviewLines")
end

function editor.overviewDeselect(panel)
	for i,v in ipairs(panel.selected) do 
		v.selected = false
	end
	panel.selected = {}
	panel.selectedConnection = nil
end

function editor.newOverviewRoom(room)
	overviewPanel.windows[room.key]={
		key = room.key,
		target = room,
		isRoom = true,
		lines = {},
		lineBox = {x=0,y=0,w=0,h=0},
		redraw = true,
		addLine = {x=0,y=0,w=overviewPanel.row,h=overviewPanel.row,text="+",color={a=0.6},textColor={r=0,b=0,g=0,a=1},tip="Add Dialogue"},
		w =  editor.roomPreview.w+1,
		h =  editor.roomPreview.h,
		hovered = false,
		isWindow=true
	}
	overviewPanel.windows[room.key].addLine.func = function() editor.addDialogueLine(overviewPanel.windows[room.key]) end
end


function editor.openOverview(panel)
	if panel.full then 

	else

		panel.shadowless = true
		panel.padding = 4
		panel.width = screenWidth
		panel.height = screenHeight
		editor.sizeOverviewPanel(panel)
		panel.backTex = newCanvas(screenWidth,screenHeight)
		editor.drawContextBack(panel)
		panel.drawBack=false
		panel.redraw = true
		level.overview = level.overview or lume.clone(panel.transform)
		panel.transform = level.overview
		lmouse.setRelativeMode(false)
		panel.windows={}
		panel.sidebar = {x=screenWidth+50,active=false,resize=true,lines={}}
		panel.resize = 4
		for l,line in pairs(dialogue) do 
			editor.newOverviewLine(panel,line.key,panel.sidebar)
		end
		panel.sidebar.lines =sortBy(panel.sidebar.lines, "author")
		editor.overviewSidebar(panel)
		editor.updateDialogueLines(panel,panel.sidebar)

		for r,room in pairs(level.rooms) do
			editor.newOverviewRoom(room)
			for l,line in ipairs(room.dialogue) do 
				editor.newOverviewLine(panel,line.key,panel.windows[r])
			end
		end

		for s,set in pairs(level.sets) do
			panel.windows[s]={
				key = s,
				target = set,
				isSet = true,
				lines = {},
				redraw = true,
				addLine = {x=0,y=0,w=panel.row,h=panel.row,text="+",color={a=0.6},textColor={r=0,b=0,g=0,a=1},tip="Add Dialogue"},
				w =  editor.roomPreview.w+1,
				h =  editor.roomPreview.h,
				hovered = false,
				isWindow=true
			}
		end
	end
end

function editor.overviewBounds(panel,room)
	panel.min.x,panel.max.x = math.min(room.x,panel.min.x),math.max(room.x,panel.max.x)
	panel.min.y,panel.max.y = math.min(room.y,panel.min.y),math.max(room.y,panel.max.y)
end

function editor.addDialogue(target,window)
	local panel = overviewPanel
	namer:typeString("new dialogue","Untitled",{x=mouse.x,y=mouse.y},function(x)
		local key 	 			= uuid()
		dialogue[key] 		= {
			key 		= key,
			speaker = "",
			author  = "",
			languages={
				en=x
			},
		-- style=effects.defaultCardStyle()
		}
		table.insert(target.dialogue,{key=key})
		if window then 
			editor.newOverviewLine(panel,key,window)
		end
	end)
end

function editor.newOverviewLine(panel,key,target)
	if not dialogue[key] then print (inspect(key)) return end
	table.insert(panel.lines,{
		key = key,
		dialogue = dialogue[key],
		author = dialogue[key].author,
		hovered= false,
		noClick = true,
		isLine=true,
		col = dialogue[key].style and dialogue[key].style.backColor or room.sky.color,
		tcol= dialogue[key].style and dialogue[key].style.textColor or lume.merge(effects.getInverse(room.sky.color),{a=1}),
		releaseR= function() editor.editDialogue(key) end,
		w = panel.winW,
		h = panel.row,
		x=0,
		y=0
	})
	table.insert(target.lines,panel.lines[#panel.lines])
end

function editor.editDialogue(key)
	namer:typeString("new dialogue",dialogue[key].languages[game.lang],{x=mouse.x,y=mouse.y},function(x)
		dialogue[key].languages[game.lang] = x
	end)
end

function editor.addDialogueLine(target)
	editor.addDialogue(target.target,target)
end

function editor.startRoomLink(point)
	editor.roomLink = {cameraID=currentRoom.cameraID,point=point,room = currentRoom.room}
	cacheLinkPreview()
	editor.closePathsPanel()
	editor.tempTip("Started Link")
	editor.roomLinkPreview.active = true
end

function editor.stopRoomLink(point)
	level.connections[uuid()] = {lume.clone(editor.roomLink.point),lume.merge(lume.clone(point),{cameraID=currentRoom.cameraID})}
	editor.tempTip("Linked Paths")
	editor.roomLink = false
	editor.updateLinks = true
	editor.roomLinkPreview.active = false
end

function editor.cancelLink() 
	editor.roomLinkPreview.active = false
end

function editor.removeLink(link)
	level.connections[link.connection] = nil 
	rooms[link.linkRoom].links[link.connection] = nil
	rooms[link.room].links[link.connection] = nil
end