-----------------------------------------------------------
-- SCRIPTS PANEL
-----------------------------------------------------------
function editor.defineScriptsPanel()
	scriptsPanel = 
	{	
	
		name 	= "Scripts",
		height 	= sidebar.titleH,
		hide 	= true,
		open 	= true,
		docked  = true,
		y 		= 0,
		remove 	= 0,
		alpha 	= 1,
		fontSize= config.fontSize or 8,
		minFontSize = 8,
		maxFontSize = 16,

		currentB= 1,
		id 		= "NONE",
		object 	= {},
		events 	= {},
		selected= {},
		delete 	= {},
		spacing = 3,

		row 	= sidebar.row,

		oldY	= 0,
		
		update 		= function(x) editor.scriptsPanelUpdate(x) end
	}

end

function editor.scriptsPanelUpdate(panel)

	panel.hide = (animationPanel.open or pathsPanel.open or anySelectedSimple or (not editor.editingCode) or  not room)

	if panel.hide then   panel.focused=false return end  

	editor.togglePanelWithSelected(panel,true)
	
	--trace(panel.buffer.x,panel.buffer.y,panel.focused)

	if not panel.open then  panel.focused=false editor.editingCode=false return end 

	if not panel.focused then 
		--shaders.alpha:send 		("alpha",panel.alpha/2) 
	end

	if editor.editingCode then 
		panel.drag=true
		gfx.fontSize(panel.fontSize)
		if not panel.docked then 
			panel.x = mc(16,panel.x,screenWidth-panel.width-16)
		end
		panel.width 				= easeTo(panel.width,panel.buffer and panel.buffer.maxw or panel.width,2)
		panel.y  						= mc(16,panel.y,screenHeight-panel.height)
		panel.height 				= mc(128,easeTo(panel.height, (panel.setHeight or 0)+panel.fontSize*1.7,2),screenHeight-32)
		panel.buffer 				= panel.buffer or {x=panel.x,y=panel.y,w=panel.width,h=8,c=gfx.getFont():getWidth('a'),d=13}
		
		panel.scroll  				= panel.scroll and mc(-panel.setHeight+panel.height, panel.scroll+(mouseIn(panel) and mouseScroll.y or 0)*10, 0) or 0
		scrolledMouse  				= mouse.y-panel.scroll-(panel.buffer.d or 12)/2
		panel.buffer.em 			= gfx.getFont():getWidth('a')
		panel.buffer.x 				= panel.x+4
		panel.buffer.y 				= panel.y+panel.fontSize*1.7-6 
		panel.buffer.w 				= panel.width-16
		panel.buffer.h 				= panel.height
		panel.buffer.gutterWidth 	= #panel.b.lines<10 and panel.fontSize or (#panel.b.lines<100 and panel.fontSize*2 or panel.fontSize*3)
		local alpha  				= panel.focused and 1 or 0
		local buffer  				= panel.buffer
		panel.border 				= {x=buffer.x,y=buffer.y-panel.fontSize*1.7+6,w=buffer.w+16,h=buffer.h}
		buffer.alpha 				= alpha
		buffer.gutterColor 			= {90,90,90,75}
		buffer.cursorColor 			= {190,190,255,(math.sin(time*5)+1.2)*120*alpha}
		buffer.markColor 	 		= {255,190,190,(math.sin(time*5)+1.2)*120*alpha}
		buffer.outlineColor 		= {190,190,255,(math.sin(time*5)+2)*5*alpha}
		buffer.fillColor 			= {33*2,39*2,51*2,(math.sin(time*5)+3)*20*alpha}

		if panel.focused then 
			gfx.draw(
				getImage("ContextShadow")
				, buffer.x+buffer.w/2
				, buffer.y+buffer.h/1.8
				, 0
				, (buffer.w/512)*1.3
				, (buffer.h/512)*1.2
				, 512/2
				, 512/2
			)     
		end 

		--gfx.setColor255(panel.focused and 33-5 or room.sky.color.r,panel.focused and 39-5 or room.sky.color.g,panel.focused and 51-5 or room.sky.color.b,255)
		gfx.setColor(0.1,0.13,0.18)
		gfx.rectangle("fill",panel.border.x-buffer.gutterWidth,panel.border.y,panel.border.w+buffer.gutterWidth,panel.border.h,4)

		if panel.b.needs_save then
			gfx.setColor255(150,150,50,100)
			gfx.circle("line",buffer.x-buffer.gutterWidth/3,panel.y+12,2+math.abs(math.sin(time)^2),16)
		end

		gfx.setColor255(190,190,190,255)
		gfx.printf(panel.title,buffer.x,panel.y+6,buffer.w-buffer.gutterWidth*2,"center")
		gfx.push()
		--gfx.setScissor(0,0,1,1)
		gfx.setScissor(panel.buffer.x-32,panel.buffer.y+8,panel.buffer.w,panel.buffer.h-panel.buffer.d*2)
		gfx.translate(0, panel.scroll)
		polywell.draw()
		gfx.setScissor()
		gfx.pop()
		panel.setHeight = math.clamp(0,9999,(#buffer.lines+4 or 2)-2)*buffer.d

		if panel.alpha == 0 then
			editor.editingCode=false
		end

		
		if mouseIn(panel) then
			stageHovered=false
			if not panel.focused then 
				mouse.pushClick(function()
					panel.focused=true
				end)
			end
		end
	

		if panel.focused then 
			if mouseIn(lume.merge(panel.border,{y=panel.buffer.y+12,h=panel.buffer.h-24})) and panel.b then
				lmouse.setCursor(lmouse.getSystemCursor("ibeam"))
				stageHovered=false
				mouse.set(function()
					if not shiftDown then
						editor.deselectCode()
					end
					buffer.preselect = true
					local line 	= mc(1,mf((scrolledMouse+sidebar.titleH-8-buffer.y-buffer.d)/buffer.d),#panel.b.lines)
					local char 	= mc(0,mf((mouse.x-buffer.x-buffer.c*1.5)/buffer.c),#panel.b.lines[line])
					if shiftDown then
						if not panel.b.mark then 
							panel.b.mark_line  	= panel.b.point_line  
							panel.b.mark  		= panel.b.point  	
						end
						panel.b.point_line  = line
						panel.b.point  		= char	
						
						buffer.preselect 	= false
						buffer.selecting 	= true
						buffer.ends = {
							math.min(panel.b.point_line,panel.b.mark_line),
							dir==1 and panel.b.point or (dir==2 and panel.b.mark  or math.min(panel.b.point,panel.b.mark )),
							math.max(panel.b.point_line,panel.b.mark_line),
							dir==1 and  panel.b.mark or (dir==2 and panel.b.point or math.max(panel.b.point,panel.b.mark ))
						}
					else	
						panel.b.point_line  = line
						panel.b.point  		= char
						if mouse.double then
							polywell.backward_word()
							polywell.forceMark = true
							polywell.forward_word()
							polywell.forceMark = false
						end
						if mouse.triple then
							polywell.beginning_of_line()
							polywell.forceMark = true
							polywell.end_of_line()
							polywell.forceMark = false
						end
					end
				end)
			end
			local newLine  	= mc(1,mf((scrolledMouse+sidebar.titleH-8-buffer.y-buffer.d)/buffer.d),#panel.b.lines)
			local newPoint  = mc(0,mf((mouse.x-buffer.x-buffer.c*1.5)/buffer.c),#panel.b.lines[newLine])
			if not lmouse.isDown(1)  then 
				buffer.preselect = false
				buffer.selecting = false
			end
			if buffer.preselect then
				if math.dist(mouse.x,scrolledMouse,mouseStored.x,mouseStored.y-panel.scroll)>8 and (newPoint~=panel.b.point or newLine~=panel.b.point_line) then
					buffer.preselect = false
					buffer.selecting = true
					panel.b.mark 		= panel.b.point   
					panel.b.mark_line 	= panel.b.point_line 	
				end
				mouse.pushRelease(function()
					buffer.preselect 	= false
					buffer.ends 		= nil
				end)
			end

			if buffer.selecting then
				panel.b.point_line  = newLine
				panel.b.point  		= newPoint
				local dir = panel.b.point_line<panel.b.mark_line and 1 or panel.b.point_line>panel.b.mark_line and 2 or 0
				buffer.ends = {
					math.min(panel.b.point_line,panel.b.mark_line),
					dir==1 and panel.b.point or (dir==2 and panel.b.mark  or math.min(panel.b.point,panel.b.mark )),
					math.max(panel.b.point_line,panel.b.mark_line),
					dir==1 and  panel.b.mark or (dir==2 and panel.b.point or math.max(panel.b.point,panel.b.mark ))
				}

				mouse.pushRelease(function()
					if buffer.ends and buffer.ends[1]==buffer.ends[3] and buffer.ends[2]==buffer.ends[4] then
						editor.deselectCode()
					end
					buffer.preselect = false
					buffer.selecting = false
				end)
			end

			if not buffer.selecting and not (panel.b.mark == nil or panel.b.mark_line == nil) then 
				local dir = panel.b.point_line<panel.b.mark_line and 1 or panel.b.point_line>panel.b.mark_line and 2 or 0
				buffer.ends = {
					math.min(panel.b.point_line,panel.b.mark_line),
					dir==1 and panel.b.point or (dir==2 and panel.b.mark  or math.min(panel.b.point,panel.b.mark )),
					math.max(panel.b.point_line,panel.b.mark_line),
					dir==1 and  panel.b.mark or (dir==2 and panel.b.point or math.max(panel.b.point,panel.b.mark ))
				}
				if buffer.ends and buffer.ends[1]==buffer.ends[3] and buffer.ends[2]==buffer.ends[4] then
					editor.deselectCode()
				end
			end
		end
		
	else
		panel.height  				= sidebar.titleH
		panel.name 					= "Scripts"
		lkeyboard.setKeyRepeat  (false)
		editor.updateScriptsPanel 	(panel)
		editor.newScriptButton 		(panel)
	end

end

function editor.deselectCode()
	local panel 			= scriptsPanel
	panel.buffer.ends 		= nil
	panel.buffer.selecting 	= false
	panel.b.mark 			= nil
	panel.b.mark_line 		= nil
end
	
function editor.openScript(key,external)
	
	local path = PROJ_DIR.."scripts".."/"..key
	local file = path..".lua"

	scripts[key].dateModified = os.time()

	if external then 
		os.execute 				("open \""..file.."\"")
	else
		gfx.fontSize(10)
		editor.editingCode 		= true
		scriptsPanel.script 	= scripts[key]
		scriptsPanel.editing 	= true
		scriptsPanel.name 		= ""
		scriptsPanel.title 		= scripts[key].name
		scriptsPanel.file  		= file 
		scriptsPanel.key   		= key
		scriptsPanel.height 	= mc(128,(scriptsPanel.b and #scriptsPanel.b.lines+4 or 8)*gfx.getFont():getHeight(),screenHeight-16)
		polywell.open 			(polywell.fs,file)

		scriptsPanel.drawBack 	= false
		scriptsPanel.focused 	= true
		scriptsPanel.stayFloat 	= true
		scriptsPanel.x 			= contextMenu.x
		scriptsPanel.y 			= mc(16,contextMenu.y,screenHeight-scriptsPanel.height-16)

		editor.floatPanel 		(scriptsPanel,scriptsPanel)
		lkeyboard.setKeyRepeat(true)
	end

end

function countLines(file)
	local file = lfs.newFile(file)
	file:open("r")
	local l = 1
	for c in file:lines(1) do l=l+1 end
	file:close()
	return l
end


function editor.removeScript(target,script)
	local v,i = lume.match(target.scripts,function(x) return x.key == script.key end)
	table.remove(target.scripts,i)
end

function editor.updateScriptsPanel(panel)
	gfx.fontSize(10)	
	panel.scripts 		= selectedEntities[1].scripts
	local xoffset 	 	= panel.x


	for i,script in lume.ripairs(panel.scripts) do
		if script.delete or not scripts[script.key] then  
			editor.removeScript(selectedEntities[1],script)
			panel.selected={}
			table.remove(panel.scripts,i)
		end
	end

	for i,script in ipairs(panel.scripts) do
		local b = scripts[script.key]
		-- script
		-----------------------------------------------------------
		local scriptItem = { 
			w 		= panel.row+panel.spacing+gfx.currentFont:getWidth(b.name)+4,
			h 		= panel.row,
			x 		= xoffset,
			y 		= panel.y+panel.height,
			name 	= b.name,
			col  	= b.public and {r=255,g=255,b=255,a=255} or {a=100},
			tcol  	= b.public and {r=0,g=0,b=0,a=255} or nil,
			align 	= "left",
			selected= multicheckOR(script.key,panel.selected)
		}
		script.selected = scriptItem.selected 
		if scriptItem.x+scriptItem.w+panel.spacing>panel.x+panel.width then
			xoffset  		= panel.x + scriptItem.w
			scriptItem.x = panel.x
			panel.height 	= panel.height + panel.row + panel.spacing
			scriptItem.y = panel.y+panel.height
		else
			xoffset = xoffset + scriptItem.w + panel.spacing
		end
		scriptItem.hovered = mouseIn(scriptItem)
		editor.drawEventTools( scriptItem ) 

		if scriptItem.hovered then
			editor.setToolTip((b.lines and tostring(b.lines) or "no").." lines")
			mouse.set(
				function() 
					if cmdDown then 
						if scriptItem.selected and #panel.selected>1 then
							lume.remove(panel.selected,script.key)
						else
							table.insert(panel.selected,script.key)
						end
					else
						panel.selected 		= {script.key}
					end
				end
			)
			mouse.setR(function() 
				if #panel.selected<=1 then 
					panel.selected = {script.key}
				else 
					table.insert(panel.selected,script.key)
				end

				local allAbled = 		lume.all(panel.scripts, function(x) return (not x.selected or x.enabled) end)
									or 	lume.all(panel.scripts, function(x) return (not x.selected or x.enabled==false) end)

				local allPublic = 		lume.all(panel.selected, function(x) return (scripts[x].public) end)
									or 	lume.all(panel.selected, function(x) return (scripts[x].public==false) end)

				editor.openContextMenu({
					{
						name = "Open",
						func = function (x) editor.processScripts(function (x)
							editor.openScript(x.key)
						end) end
					},
					allAbled and {
							name = script.enabled and "Disable" or "Enable",
							func = function (x) editor.processScripts( function(x)
								x.enabled = not x.enabled
							end) end
						}
						or {
						 	{ 
								name = "Enable",
								col  = {r=1,g=0.9,b=0.4 , a=0.2},
								func = function (x) editor.processScripts( function(x)
									x.enabled = true
								end) end
							},
							{
								name = "Disable",
								col  = {r=0.3,g=0.5,b=0.8 , a=0.2},
								func = function (x) editor.processScripts( function(x)
									x.enabled = false
								end) end
							}
						}
						or 1,
					allPublic and {
							name = b.public and "Make Private" or "Make Public",
							func = function (x) editor.processScripts( function(x)
								scripts[x.key].public = not scripts[x.key].public
							end) end
						} 
						or {
							{ 
								name = "Private",
								col  = {r=0.5,g=0.6,b=1 , a=0.2},
								func = function (x) editor.processScripts( function(x)
									scripts[x.key].public = false
								end) end
							},
							{
								name = "Public",
								col  = {r=0.8,g=0.5,b=0.7 , a=0.2},
								func = function (x) editor.processScripts( function(x)
									scripts[x.key].public = true
								end) end
							}
						}
						or 1,
					#panel.selected==1 and {
						name = "Rename",
						func = function() namer:typeString(
							"script name", 
							b.name, 
							{x=scriptItem.x+scriptItem.w/2,y=scriptItem.y}, 
							function(x) 
								b.name = x
							end
						)end
					} or 1,
					{
						name = "Delete",
						col  = {r=0.8,g=0.2,b=0.2,a=0.4},
						func = function (x) editor.processScripts( function (x)
							x.delete = true
						end) end
					}
				})
			end,true)
		end

		-- CHECKBOX
		-----------------------------------------------------------
		local checkButton = { 
			x	= scriptItem.x+scriptItem.w-panel.row,
			y	= scriptItem.y+2,
			w	= panel.row*0.8,
			h	= panel.row*0.8,
			col  = 	{r=0,b=0,g=0,a=0.8},
			text= script.enabled and "ticked" or "unticked", -- untickedticked,
			func = function () script.enabled = not script.enabled end
		}
		editor.drawButton(checkButton) 
	end

	panel.height 	= panel.height + (#panel.scripts>0 and panel.row+panel.spacing or 0)

end

function editor.processScripts(func)
	for i,b in ipairs(scriptsPanel.scripts) do
		if b.selected  then 
			func(b)
		end
	end
end

function editor.contextScripts(target)
	local settings = not noSettings
	return {	
		name 	 = "Scripts",  
		subWidth = 220, 
		subHeight= 220,
		sameY  	 = true,
		sub 	 = "Current", 
		items 	 = lume.concat({{
			currentRoom and {	
				name 		= "Current", 	
				subitems 	= editor.contextScriptsList(target,true)	, 
				scroll 		= 0,
				align 		= "center" , 
				func  		= returnTrue,
			} or nil,
			{	
				name 		= "Library", 		
				subitems	= editor.contextScriptsList(target,false)	, 
				scroll 		= 0,
				align 		= "center" , 
				func  		= returnTrue,
			},
		}
	})}
end

function editor.contextScriptsList(target,current) 
	local subitems = {}
	for s,script in lume.ripairs(current and target.scripts or sortBy(scripts,"public","dateUsed")) do
		if scripts[script.key] then--and (current or scripts[script.key].public) then 
			local scriptAdded = lume.match(target.scripts,function(x) return x.key == script.key end)
			local items = {
				{	
					name = current and "-" or "×", align="center",size=1, col = {r=0.8,g=0.4,b=0.25,a=0.4}, 
					warning="open",
					func = function() 
						(current and editor.removeScript or editor.deleteScript)(target,script)
						return "remove"
					end 
				},
				{	
					name = "", 	size=(current or not scriptAdded) and 6 or 7, 
					func = function() 
						editor.openScript(script.key)
					end ,
					update 	= function(x)
						x.name = scripts[script.key].name
						x.tcol = (script.enabled==false) and {a=0.5} or nil
					end
				},
				{	
					name = "»", align="center",size=1,col = {r=0,g=0,b=0,a=0.5},
					func = function() 
						editor.openScript(script.key,true)
					end
				},
				{	
					name = "···", align="center",size=1,col = {r=0,g=0,b=0,a=0.5},
					func = function() 
						namer:typeString(
							"script name", 
							scripts[script.key].name, 
							getMouse(), 
							function(x) 
								scripts[script.key].name = x
							end
						)
						return "rename"
					end
				},
				{	
					name = "", align="center",size=1, col = {r=0,g=0,b=0,a=0.5},
					func = function() 
						scripts[script.key].public=not scripts[script.key].public
						return "toggle"
					end,
					update 	= function(x)
						x.name = scripts[script.key].public and "↑" or "↓"
						x.col = scripts[script.key].public and {r=0.5,g=0.5,b=1 , a=0.2} or {r=0.8,g=0.5,b=0.7 , a=0.2}
					end
				},
				current and {	
					name = "", align="center",size=1, col = {r=0,g=0,b=0,a=0.5},
					func = function() 
						script.enabled=not script.enabled
						return "toggle"
					end,
					update 	= function(x)
						x.name = script.enabled and "ticked" or "unticked"
					end
				} or nil,
			}
			if not scriptAdded then 
				table.insert(items,3,{	
					name = "", align="center",size=1, col = colors.green,
					func = function() 
						table.insert(target.scripts,{ 	key = script.key, enabled = true })
						return "toggle"
					end,
					update 	= function(x)
						x.name = "+"
					end
				})
			end
			table.insert(subitems, items)
		else
			table.remove(target.scripts,s)
		end
	end
	table.insert(subitems, {name="New Script", col=colors.green,func = function()
		editor.newScript(target,true)
		return "new"
	end})
	return subitems
end


function editor.deleteScript(target,script)
	lfs.remove("scripts/"..script.key..".lua")
	scripts[script.key]=nil
end

-----------------------------------------------------------
-- OTHER SCRIPT PANEL FUNCTIONS  	 
-----------------------------------------------------------

function editor.newScript(target,open)
	namer:typeString(
		"script Name", 
		"new script", 
		getMouse(), 
		function(x) 
			editor.closeContextMenu()
			local default = { 	key 	= uuid(),enabled = true }
			scripts[default.key] = {key=default.key,public=false,name=x,filename="scripts/"..default.key}

			local entityScript 	= "-- Entity Script\nlocal public={}\nlocal self={} \nlocal entity \n\nfunction self.load()\n  entity = self.target \n  public = entity.public\n\nend\n\nfunction self.loop()\n  \nend \nreturn self,public"
			local roomScript 	= "-- Room Script\nlocal public={}\nlocal self={} \nlocal room \n\nfunction self.load()\n  room = self.target \n  public = room.public\n\nend\n\nfunction self.loop()\n  \nend \nreturn self,public"
			
			loader:writeFile(PROJ_DIR..scripts[default.key].filename..".lua",target.sky and roomScript or entityScript)

			table.insert 				( target.scripts, default)

			scripts[default.key].dateCreated = os.time()
			scripts[default.key].dateModified = os.time()
			scripts[default.key].dateUsed = os.time()

			if open then 
				editor.openScript(default.key)
			end

			editor.save()

		end
	)
end

function editor.openSavescriptMenu()

end

function editor.openLoadscriptMenu(panel)
	local contextItems = {}
	for k,b in pairs(scripts) do
		table.insert(contextItems, 
			{	
				name = b.name, 
				func = function() 
					table.insert( panel.scripts, b )
					editor.openscriptsPanel(panel) 
				end 
			}
		)
	end
	editor.openContextMenu (contextItems)
end

function editor.newScriptButton(panel)
	local button = { 
		x	=	panel.x+(panel.width-panel.row*1.1),
		y	=	panel.y,
		w	=	panel.row,
		h	=	panel.row,
		text=   "+" ,
		func= 	function() editor.newScript(panel) end,
	}
	editor.drawButton(button)  
end

-----------------------------------------------------------
-- DRAW CALLS
-----------------------------------------------------------

function editor.drawEventTools(button)
	local col 	= lume.merge({r=0,g=0,b=0,a=0},button.col)
	local tcol 	= lume.merge({r=255,g=255,b=255,a=255},button.tcol or {})

	if button.hovered then 
		lmouse.setCursor(hand)
	end

	gfx.setColor255	(col.r,col.g,col.b, (button.hovered and 255 or 120)*col.a/255)  
	gfx.rectangle	("fill",mf(button.x+1),mf(button.y+1),mf(button.w-2),mf(button.h)-2,2)

	buttonImages 	(button)

	if button.selected then 
		gfx.setLineWidth(1) 
		gfx.setColor255	(tcol.r,tcol.g,tcol.b,500-mean(tcol))
		gfx.rectangle	("line",mf(button.x+1),mf(button.y+1),mf(button.w-2),mf(button.h)-2,2)
	end
	gfx.setColor255	(tcol.r,tcol.g,tcol.b,tcol.a+(255-mean(tcol)))
	gfx.printf		(button.name, mf(button.x+4), mf(button.y+button.h/6), button.w-4, button.align or "center")
end

function editor.drawPlus(plus,type)
	gfx.setColor255(170,170,170,255)
	gfx.draw(getImage("PlusSign"),		plus.x, 	plus.y+6, 0, 0.8,0.8)
	gfx.printf(string.upper("add "..type), plus.x+16, plus.y+5, sidebar.width, "left")
end

function editor.drawCross(plus)
	
		gfx.setColor255(255,255,255,plus.hovered and 255 or 200)
		gfx.draw(getImage("CrossSign"),		plus.x+4, 	plus.y+4)
	
end


