local panel

local function drawTabTitle(tab)
	local dark = tab.selected and 0.6 or 0.25
	dark = dark * (tab.empty and 0.5 or 1)
	gfx.setColor(0, 0, 0, dark * (tab.hovered and 1.5 or 1))
	gfx.rectangle("fill", mf(tab.x), tab.y, tab.width, tab.height, 2)
	gfx.setLineWidth(2)
	if tab.selected then
		gfx.setColor(1, 1, 1, 0.5)
		gfx.rectangle("line", mf(tab.x), mf(tab.y), mf(tab.width), mf(tab.height), 1)
	end
	gfx.setColor(1, 1, 1, tab.empty and 0.2 or 1)
	gfx.printf(tab.t == 1 and "File" or tab.name, mf(tab.x + 4), mf(tab.y + 1), tab.width - 8, "center")
end

local function drawGalleryBack()
	gfx.setScissor(panel.bounds.x, panel.bounds.y, panel.bounds.w, panel.bounds.h)
end

local function drawGalleryItem(item)
	local rounding = 3 + (panel.thumbSize / editor.thumbSize) * 3
	gfx.setColor(1, 1, 1, panel.alpha)
	gfx.draw(
		load_imageTex("checkersRounded"),
		mf(item.x),
		mf(item.y),
		0,
		panel.thumbSize / editor.thumbSize,
		panel.thumbSize / editor.thumbSize
	)

	local backCol = (item.selected > 0) and 0.7 or (item.hovered and 0.4 or 0)
	gfx.setColor(1, 1, 1, backCol)
	gfx.rectangle("fill", mf(item.x), mf(item.y), item.width, item.height, rounding)

	if load_imageThumb(item.key) ~= nil then
		gfx.setColor(1, 1, 1, 1)
		gfx.setBlendMode("alpha", "premultiplied")
		if load_imageThumb(item.key) ~= load_imageTex("checkers") then
			local w, h = load_imageThumb(item.key):getWidth(), load_imageThumb(item.key):getHeight()
			gfx.draw(load_imageThumb(item.key), mf(item.x), mf(item.y), 0, panel.thumbSize / w, panel.thumbSize / h)
		end
		gfx.setBlendMode("alpha")
	end
	local lineCol = 1
	-- if (panel.searchTerm and panel.searchTerm~="") or (namer.enabled and namer.type == "Gallery Search") then
	gfx.setColor(1, 1, 1, 1)
	gfx.printf(ellipses(item.name, item.width - 4), mf(item.x), mf(item.y + item.height) + 1, item.width - 4, "center")
	-- end
	if item.selected > 0 then
		gfx.setColor(1, 1, 1, lineCol) -- OVER OUTLINE ITEM (WHITE)
		gfx.rectangle("line", mf(item.x), mf(item.y), item.width, item.height, rounding)
		gfx.setColor(0, 0, 0, lineCol) -- OVER OUTLINE ITEM (WHITE)
		gfx.rectangle("line", mf(item.x) - 1, mf(item.y) - 1, item.width + 2, item.height + 2, rounding)
	end
end

local function drawGalleryShadow()
	gfx.setColor(1, 1, 1, 0.7)
	local shadowOffsetTop = 0
	shadowOffsetTop = mc(-128, panel.tab.scrollPos - 128, -64)
	-- gfx.draw(load_imageTex("panelShadowH"),panel.bounds.x-64,panel.bounds.y+shadowOffsetTop,0,1,1)

	local shadowOffsetBot = 0
	local rows = mu(#panel.items / panel.iconColumns)

	shadowOffsetBot = mc(32, (panel.tab.maxScroll - panel.tab.scrollPos), 64)
	-- gfx.draw(load_imageTex("panelShadowH"),panel.bounds.x-64,panel.bounds.y+panel.bounds.h-shadowOffsetBot,0,1,1)
end

local function drawGalleryBorder()
	gfx.setScissor()
	gfx.setColor(0.05, 0.05, 0.05, 0.1)
	gfx.setLineWidth(4)
	gfx.rectangle("line", panel.bounds.x + 2, panel.bounds.y, panel.bounds.w - 4, panel.bounds.h - 2, 1)
end

local function getSelectedTags()
	panel.selectedTags = {}
	for i, item in ipairs(panel.selected) do
		panel.selectedTags = mergeIndexed(panel.selectedTags, item.data.tags)
	end
end

local function editTags()
	local contextItems = {}
	for t, tag in ipairs(panel.selectedTags) do
		table.insert(contextItems, {
			{
				size = 1,
				align = "center",
				name = "-",
				col = { r = 200, g = 60, b = 40, a = 60 },
				func = function()
					for i, item in lume.ripairs(panel.selected) do
						if lume.remove(item.data.tags, tag) then
							lume.remove(ctx.tagged[tag], item.data.key)
							panel.items[item.id] = nil
						end
					end
				end,
			},
			{
				size = 5,
				name = ctx.tags[tag],
				func = function()
					panel.tags = { tag }
				end,
			},
			{
				size = 1,
				align = "center",
				name = "+",
				col = { r = 60, g = 200, b = 90, a = 40 },
				func = function()
					for i, item in ipairs(panel.selected) do
						table.add(item.data.tags, tag)
						table.add(ctx.tagged[tag], item.data.key)
					end
				end,
			},
		})
	end
	return contextItems
end

local function newTagTab(t)
	table.insert(panel.tabs, {
		name = ctx.tags[t],
		key = t,
		scrollPos = 0,
		hovered = false,
		selected = true,
	})
end

local function resetTagTabs()
	panel.tabs = {}
	for t, tag in ipairs(panel.defaultTags) do
		newTagTab(tag)
	end
	local sortedTags = lume.keys(ctx.tagged)
	table.sort(sortedTags, function(a, b)
		return a > b
	end)
	for t, tag in
		ipairs(lume.reject(sortedTags, function(x)
			return multicheckOR(x, panel.baseTags)
		end))
	do
		newTagTab(tag)
	end
end

local function addTags(obj)
	local addTags = {}
	for t, tag in pairs(tags) do
		if not multicheckOR(t, panel.baseTags) then
			table.insert(addTags, {
				name = tag,
				func = function()
					for i, item in ipairs(panel.selected) do
						table.add(item.data.tags, t)
						load_tagImage(item.data)
					end
				end,
			})
		end
	end
	table.insert(addTags, {
		name = "New Tag",
		func = function()
			namer_typeString("New tag", "", {
				x = panel.x + panel.width / 2,
				y = panel.bounds.y + panel.bounds.h / 2,
				notri = true,
				backing = panel.bounds,
			}, function(x)
				local id = uuid()
				ctx.tags[id] = x
				ctx.tagged[id] = {}
				newTagTab(id)
				for i, item in ipairs(panel.selected) do
					table.insert(item.data.tags, id)
					load_tagImage(item.data)
				end
				table.insert(panel.selectedTags, x)
			end)
		end,
		col = { r = 0.3, g = 0.8, b = 0.3, a = 0.2 },
	})
	return addTags
end

local function clearTags(key)
	if load_getSymbol(key) then
		for t, tag in ipairs(mergeIndexed(load_getSymbol(key).tags, { "Game" })) do
			if ctx.tagged[tag] then
				lume.remove(ctx.tagged[tag], load_getSymbol(key).key)
			end
		end
	end
end

local function processTab(tab, noSplit)
	tab.width = 8 + #tab.name * 10
	local over = (noSplit and noSplit.x + noSplit.width + tab.width + 4 > panel.x + panel.width)
	tab.height = 16
	tab.y = over and noSplit.y + tab.height + 2 or (noSplit and noSplit.y or panel.y + panel.height)
	tab.x = over and panel.x + 2
		or (noSplit and noSplit.x + noSplit.width + 4 or panel.x + 38 + (tab.t - 1) * (tab.width + 2))
	tab.hovered = mouse_in({ x = tab.x, y = tab.y, width = tab.width, height = tab.height })
	panel.height = over and panel.height + tab.height or panel.height
end

local function mergeTags(key)
	for t, tag in
		lume.ripairs(lume.reject(panel.tags, function(x)
			return multicheckOR(x, lume.concat(panel.defaultTags, { key }))
		end))
	do
		for i, item in lume.ripairs(ctx.tagged[tag]) do
			lume.remove(load_getSymbol(item).tags, tag)
			table.add(load_getSymbol(item).tags, key)
		end
		ctx.tagged[key] = mergeIndexed(ctx.tagged[key], ctx.tagged[tag])
		ctx.tagged[tag] = nil
		ctx.tags[tag] = nil
	end
	panel.tags = { key }
	resetTagTabs()
	load_tagImages()
end

local function setTab(tab)
	tab.selected = multicheckOR(tab.key, panel.tags)
	if tab.hovered then
		mouse_setCursor(cursors.hand)
		mouse_set(function()
			if cmdDown then
				if tab.selected and #panel.tags > 1 then
					lume.remove(panel.tags, tab.key)
				else
					table.insert(panel.tags, tab.key)
				end
			else
				panel.tags = { tab.key }
			end
		end)
		mouse_setR(function()
			editor_openContextMenu({
				multicheckOR(tab.key, panel.defaultTags) and 0 or {
					name = "Rename",
					func = function()
						namer_typeString("Rename tag", tab.name, { x = tab.x + tab.width / 2, y = tab.y }, function(x)
							tab.name = x
							ctx.tags[tab.key] = x
						end)
					end,
				},
				(#panel.tags == 1 or multicheckOR(tab.key, panel.defaultTags)) and 0 or {
					name = "Merge",
					func = function()
						mergeTags(tab.key)
					end,
				},
				multicheckOR(tab.key, panel.defaultTags) and 0 or {
					name = "Delete",
					func = function()
						panel.delete = tab.selected and "" or tab.key
					end,
					col = { r = 0.8, g = 0.25, b = 0.15, a = 0.4 },
				},
			})
		end)
	end
end

local function deleteTags()
	if not panel.delete then
		return
	end

	if panel.delete ~= "" then
		ctx.tagged[panel.delete] = nil
		ctx.tags[panel.delete] = nil
		for t, tab in ipairs(panel.tabs) do
			if tab.key == panel.delete and not multicheckOR(tab.key, panel.defaultTags) then
				panel.tabs[t] = nil
			end
		end
	else
		for t, tag in lume.ripairs(panel.tags) do
			if not multicheckOR(tag, panel.defaultTags) then
				ctx.tagged[tag] = nil
				ctx.tags[tag] = nil
			end
		end
		panel.tags = { "Game" }
		resetTagTabs()
	end
	panel.delete = false
	load_tagImages()
end

local function getSelectedTab()
	gfx.setLineWidth(1)
	gfx.print("Tags:", panel.x + 4, panel.y + 20)
	for t, tab in ipairs(panel.tabs) do
		if ctx.tagged[tab.key] then
			tab.t = t
			tab.empty = (lume.count(ctx.tagged[tab.key]) == 0)
			processTab(tab, panel.tabs[t - 1] or false)
			setTab(tab)
			drawTabTitle(tab)
		end
	end
	panel.height = panel.height + sidebar.titleHp
end

local function scrollGallery()
	if mouse_in(panel.bounds) then
		panel.scrollSpeed = panel.scrollSpeed - mouse.scroll.y * 2
	end

	panel.scrollSpeed = easeTo(panel.scrollSpeed, 0, 4)
	panel.tab.scrollPos = panel.tab.scrollPos + panel.scrollSpeed
	panel.tab.rows = mu(lume.count(panel.items) / panel.iconColumns)
	panel.tab.maxScroll = math.max(0, (panel.tab.rows - 1) * panel.fullThumbSize - panel.height - sidebar.titleH * 2)
	panel.tab.upperBound = (panel.tab.maxScroll < 0) and 0 or panel.tab.maxScroll
	panel.tab.scrollPos = math.sling(0, panel.tab.scrollPos, panel.tab.upperBound, 4)
end

local function setGalleryBounds()
	panel.bounds = (panel.sizeSlider and panel.sizeSlider.sliding) and panel.bounds
		or {
			x = panel.x + 4,
			y = panel.y + panel.height,
			w = panel.width - 8,
			h = math.min(
				screenH / 2.5,
				math.min(
					screenH - panel.y - panel.height - 32,
					easeTo(panel.bounds.h or 10, math.max(128, (panel.tab.rows + 1) * panel.fullThumbSize), 4)
				)
			),
		}
end

local function iconSizeSlider()
	panel.sizeSlider = panel.sizeSlider
		or {
			x = 0,
			y = 0,
			width = sidebar.minWidth / 3,
			height = config.row,
			text = "Icon Size",
			pct = (panel.thumbSize - 32) / 64,
			state = "non",
			opacity = 1,
			col = { r = 0.05, g = 0.05, b = 0.05, a = 1 },
			name = "icon size",
			hovered = false,
			sliding = false,
		}

	if panel.sizeSlider.hovered then
		mouse_set(function()
			panel.sizeSlider.sliding = true
		end)
	end

	mouse_pushRelease(function()
		panel.sizeSlider.sliding = false
	end, true)
	panel.sizeSlider.hovered = mouse_in(panel.sizeSlider)
	panel.sizeSlider.x = panel.x + panel.width - panel.sizeSlider.width - 2
	panel.sizeSlider.y = panel.y + panel.height - 5
	panel.sizeSlider.pct = panel.sizeSlider.sliding
			and mc(0.05, (mouse.x - panel.sizeSlider.x) / panel.sizeSlider.width, 1)
		or panel.sizeSlider.pct
	panel.thumbSize = 32 + panel.sizeSlider.pct * 64
	panel.height = panel.height + 12

	editor_updateButton(panel.sizeSlider)

end

local function galleryItemSortButtons()
	panel.sortPropButton = {
		w = sidebar.minWidth / 3 - panel.row,
		h = 18,
		x = panel.x,
		y = panel.y + panel.height - 18,
    box=true,
		text = "sort: "..panel.sort,
		col = { r = 0, g = 0, b = 0, a = 1 },
		tcol = { a = 1 },
		tip = "Sort by " .. panel.sort,
		func = function()
			local items = {}
			for s, sort in ipairs(panel.sorts) do
				table.insert(items, {
					name = sort,
					func = function()
						panel.sort = sort
					end,
				})
			end
			editor_openContextMenu(items, {
				x = panel.x,
				y = panel.y + panel.height + 8,
				width = sidebar.minWidth / 3 - panel.row,
			})
		end,
	}

	panel.sortDirButton = {
		w = panel.row,
		h = 18,
		x = panel.x + sidebar.minWidth / 3 - panel.row + 2,
		y = panel.y + panel.height - 18,
    box=true,

		text = panel.sortAsc and ">" or "<",
		col = { r = 0, g = 0, b = 0, a = 0.3 },
		tcol = { a = 0.8 },
		tip = panel.sortAsc and "Ascending Order" or "Descending Order",
		func = function()
			panel.sortAsc = not panel.sortAsc
		end,
	}
  editor_updateButton(panel.sortPropButton)
  editor_updateButton(panel.sortDirButton)
end

local function setIconColumns()
	panel.iconColumns = mf((panel.bounds.w - 8) / panel.fullThumbSize)
end

local function deleteItem(item)
	lume.remove(galleryPanel.items, item)
	gallery_deleteImage(item.key)
end

local function deleteItems()
	--namer_warning("Delete",function()
	for i, item in lume.ripairs(sortBy(panel.selected, "id")) do
		deleteItem(item)
		print(item.id)
	end
	panel.selected = {}
	save_project()
	--end)
end

local function showGalleryItem(item)
	editor_showInFinder(PROJ_DIR .. "symbols" .. "/" .. item.data.key .. ".png")
end

local function renameSymbol(item)
	namer_typeString(
		"Rename Object",
		load_getSymbol(item.key).name,
		{ x = item.x + item.width / 2, y = item.y },
		function(x)
			load_getSymbol(item.key).name = x
			item.name = x
		end
	)
end

local function openItemMenu(item)
	local obj = load_getSymbol(item.key)
	getSelectedTags()
	editor_openContextMenu({
			-- temp
			--{name="Approx. Def LQ", func = function() editor.approxDef(trueItem)  end},
		#panel.selected > 1 and 1
			or {
				name = "Show In Finder",
				func = function()
					showGalleryItem(item)
				end,
			},
		#panel.selected > 1 and 1 or {
			name = "Rename",
			func = function()
				renameSymbol(item)
			end,
		},
		(ctx.isAnim or #panel.selected > 1) and 1 or {
			name = "Set Background",
			items = {
				{
					name = "Level",
					func = function()
						ctx.page.sky.image.key = item.key
						ctx.page.sky.image.anim = load_getSymbol(item.key).default
						ctx.page.sky.image.color = { a = 1, r = 1, g = 1, b = 1 }
					end,
				},
				{
					name = "Room",
					func = function()
						room.sky.image.key = item.key
						room.sky.image.anim = load_getSymbol(item.key).default
						room.sky.image.color = { a = 1, r = 1, g = 1, b = 1 }
					end,
				},
			},
		},
			--{name="Duplicate",    func  = function() gallery_duplicateItems()  end },
		#panel.selectedTags == 0 and 1 or { name = "Edit Tags", items = editTags() },
		{ name = "Add Tags", items = addTags(obj), col = { r = 0.25, g = 0.8, b = 0.35, a = 0.2 } },
		{
			name = "Delete",
			func = function()
				deleteItems()
			end,
			warning = "close",
			col = { r = 0.8, g = 0.25, b = 0.2, a = 0.4 },
		},
	})
end

local function clickItem(item)
	mouse_set(function()
		if cmdDown then
			if item.selected > 0 then
				table.remove(panel.selected, item.selected)
				item.selected = 0
			else
				table.insert(panel.selected, item)
				item.selected = #panel.selected
				editor.droppingItem = true
				editor.dropScale = 1
			end
		elseif shiftDown then
		else
			panel.selected = { item }
			item.selected = #panel.selected
			editor.droppingItem = true
			editor.dropScale = 1
		end
	end)

	mouse_setR(function()
		if item.selected == 0 then
			panel.selected = { item }
			item.selected = #panel.selected
		end
		openItemMenu(item)
	end, true)
end

local function updateItem(item)
	local row = mf((item.id - 1) / panel.iconColumns)
	local column = item.id - row * panel.iconColumns - 1
	local remainder = ((panel.bounds.w - 12) / panel.fullThumbSize - panel.iconColumns) * editor.thumbSize
	local gap = remainder / (panel.iconColumns + 1)

	item.x = panel.bounds.x + column * (panel.fullThumbSize + gap) + gap + 4
	item.y = panel.bounds.y
		+ row * (panel.fullThumbSize + panel.thumbSize / 6.5)
		+ (row + 1) * gap
		- panel.tab.scrollPos
		+ 4
	item.width = panel.thumbSize
	item.w = panel.thumbSize
	item.height = panel.thumbSize
	item.h = panel.thumbSize

	item.hovered = (mouse_in(panel.bounds) and mouse_in(item))

	if #panel.selected == 1 and panel.selected[1] ~= item then
		item.selected = 0
	end

	if item.hovered then
		editor_setToolTip(item.data.name)
		panel.anyHoveredItem = true
		clickItem(item)
	end

	if not load_imageThumb(item.key) then
		local symbol = load_getSymbol(item.key)
		local thumb = gfx.newCanvas(64, 64)
		gfx.push("all")
		gfx.setShader(shaders.forwardRender)
		gfx.setMeshCullMode("none")
		gfx.rectangle("fill", 0, 0, 0, 0)
		gfx.setCanvas(thumb)
		gfx.clear(0, 0, 0, 0)
		-- drawSymbol(
		--     ctx.viewport,
		--  symbol,
		--  mat4():scale(mat4():translate(mat4(),vec3(0,0,0)),vec3(1)),
		--  symbol.default,
		--  1
		-- )
		gfx.pop()
		load_setImageThumb(item.key, thumb)
	end
	
end

local function getItem(t, item)
	local item = {
		x = 0,
		y = 0,
		width = panel.thumbSize,
		height = panel.thumbSize,
		data = load_getSymbol(item),
		hovered = false,
		selected = 0,
		key = item,
		name = load_getSymbol(item).name,
		size = load_getSymbol(item).size,
		--modified  = load_getSymbol(item).modified,
		--created   = load_getSymbol(item).created,
		folder = load_imageType(item),
		id = t,
	}

	log("fsize", item.size)

	table.insert(panel.items, item)

	updateItem(item)

	return item
end

local function processItems()
	local items = {}

	for t, tag in ipairs(panel.tags) do
		items = mergeIndexed(items, ctx.tagged[tag])
		local c = lume.find(items, "_controller")
		table.remove(items, c)
	end
	if #panel.items ~= #items or panel.prevTags ~= lume.serialize(panel.tags) then
		panel.items = {}
		gfx.fontSize(math.max(8, panel.thumbSize / 6.5))
		for k, key in ipairs(items) do
			getItem(k, key)
		end
	end
	panel.prevTags = lume.serialize(panel.tags)
end

local function sortItems()
	panel.sorts =
		lume.concat({ unpack(panel.sortModes) }, (panel.searchTerm and panel.searchTerm ~= "") and { "search" } or {})
	panel.items = lume.sort(panel.items, function(a, b)
		if a[panel.sort] == b[panel.sort] then
			return a.name > b.name
		else
			return (panel.sortAsc and a or b)[panel.sort] < (panel.sortAsc and b or a)[panel.sort]
		end
	end)
end

local function updateItems(draw)
  if draw then 
  	gfx.setLineWidth(2)
  	gfx.fontSize(utils.map(panel.thumbSize, 35, 96, 8, 13))
  end
  local proc = draw and drawGalleryItem or updateItem
	panel.anyHoveredItem = false
	local t = 1
	for i, item in ipairs(panel.items) do
		if not (panel.searchTerm and item.search == 0) then
			item.id = t
			t = t + 1
  		proc(item)
		end
	end
end

local function duplicateItem(item)
	-- local file         = lfs.newFile("symbols".."/"..item.folder.."/"..item.key..".png")
	-- local thumb      = load_imageThumb(item.key)
	-- local thumbFile    = lfs.newFileData("thumbnails".."/"..item.key..".png")
	-- local newkey       = editor_dropFile(file, item.key)

	-- log(item.key,"->",newkey)
	-- log(load_getSymbol(item.key).name)
	-- load_getSymbol(newkey)    = deepcopy(load_getSymbol(item.key))
	-- load_getSymbol(newkey).name   = item.data.name.." copy"
	-- load_getSymbol(newkey).key  = newkey
	-- load_getSymbol(newkey).thumb = thumb

	-- lfs.write("thumbnails".."/"..load_getSymbol(newkey).key..".png", thumbFile)
end

local function duplicateItems()
	for i, item in lume.ripairs(panel.selected) do
		duplicateItem(item)
	end
end

local function searchBox()
	local searchbox = {
		x = panel.x + panel.width - panel.width / 4,
		y = panel.y + sidebar.titleH / 2,
		w = panel.width / 2,
		h = 18,
		notri = true,
		noshadow = true,
		align = "right",
		alert = false,
	}

	if panel.searchTerm then
		--  panel.searchFade=easeTo(panel.searchFade, panel.searchTerm and 1 or 0,4)
		--  editor_drawTip(lume.merge(searchbox,{text=panel.searchTerm,a=panel.searchFade}))
	end

	local search = (panel.searchTerm and panel.searchTerm ~= "")
	local searchTyping = (ctx.namer.enabled and ctx.namer.type == "Gallery Search")
	panel.searchButton = {
		x = (search or searchTyping) and searchbox.x - searchbox.w / 2 or panel.x + (panel.width - panel.row * 1.1),
		y = (search or searchTyping) and searchbox.y - 11 or panel.y,
		w = (search or searchTyping) and searchbox.w or panel.row,
		h = panel.row,
		text = (search or searchTyping) and panel.searchTerm or "-search",
		col = { a = panel.searchTerm and (searchTyping and 1 or 0.2) or 0 },
		align = "right",
		func = not searchTyping and function()
			panel.psort = panel.sort
			panel.searchButton.text = ""
			namer_typeString(
				"Gallery Search",
				panel.searchTerm or "",
				{ limit = searchbox.w / 8, hidden = true },
				nil,
				function(x)
					panel.searchTerm = x
					panel.sort = "search"
					if input_keyPressed("escape") then
						panel.searchTerm = nil
					end
				end
			)
		end or nil,
	}
	editor_updateButton(panel.searchButton)
	if (ctx.namer.enabled and ctx.namer.type == "Gallery Search") and panel.searchTerm == "" then
		panel.searchTerm = nil
	end
  panel.searching = search or searchTyping
	if search or searchTyping then
		panel.closeSearch = {
			x = panel.searchButton.x - panel.row + 1,
			y = panel.searchButton.y + 1,
			h = panel.searchButton.h - 2,
			w = panel.row - 2,
			col = { r = 0.8, g = 0.2, b = 0.2, a = 0.8 },
			text = "-x",
			func = function()
				panel.searchTerm = nil
			end
		}
    editor_updateButton(panel.closeSearch)
	elseif panel.sort == "search" then
		panel.sort = panel.psort
	end
end

local function search(items, query, key)
	if not query then
		return
	end
	local results = {}
	local test
	for r, result in pairs(items) do
		test = key and result[key] or r
		print("test", test, "query", query)
		--table.insert(results,{
		--  search  =   fuzzy(test, query),
		--  text  =   test
		--})
		result.search = fuzzy(test, string.lower(query))
	end
	--results = lume.sort(results,"search")
	--trace (results )
	return results
end

local function updateGallery()
	if not panel.tabs then
		if ctx.isAnim then
			panel.defaultTags = { "Game" }
			panel.tags = { "Game" }
		end
		resetTagTabs()
		panel.tab = panel.tabs[1]
	end

  panel.visible = panel.open

	if not (panel.open and panel.visible) then
		return
	end

	panel.height = sidebar.titleH

	searchBox()
	deleteTags()
	getSelectedTab()
	getSelectedTags()

	-- print("panel.tabs2",inspect(panel.tabs))
	if panel.tab == nil then
		return
	end

	panel.fullThumbSize = (panel.thumbSize + panel.iconBorder)

	scrollGallery()
	setGalleryBounds()
	setIconColumns()
	processItems()
	search(panel.items, panel.searchTerm, "name")
	sortItems()
	updateItems()
	
  panel.height = panel.height + panel.bounds.h + 8

	iconSizeSlider()
	galleryItemSortButtons()

end

function gallery_draw()
  drawGalleryBack()
  updateItems(true)
  drawGalleryShadow()
  drawGalleryBorder()
  gfx.setFont(fonts.interfont, 12)
  editor_drawButton(panel.sortPropButton)
  editor_drawButton(panel.sortDirButton)
  editor_drawButton(panel.sizeSlider)
  editor_updateButton(panel.searchButton)
  if panel.searching then 
    editor_updateButton(panel.closeSearch)
  end
  gfx.setColor(1, 1, 1, 1)
  gfx.setFont(fonts.interfont, 13)
  gfx.printf(
    #panel.items == 0 and "no items" or (#panel.items .. " item" .. (#panel.items > 1 and "s" or "")),
    panel.x + (panel.width - 100) / 2,
    panel.sizeSlider.y + 2,
    100,
    "center"
  )
end

function gallery_setPanel(p)
	panel = p
end

function gallery_deleteImage(key)
	clearTags(key)
	local name = load_getSymbol(key).name
	os.execute(os.rm .. ' "' .. PROJ_DIR .. "symbols/" .. name .. '.png"')
	os.execute(os.rm .. ' "' .. PROJ_DIR .. "symbols/" .. name .. '"')
	print(os.rm .. " " .. PROJ_DIR .. "symbols/" .. name)
	lfs.remove("symbols/" .. name .. ".dds")
	lfs.remove("thumbnails/" .. name .. ".png")
	load_removeSymbol(key)
end

function gallery_define()
	local panel = {
		name = "Gallery",
		open = false,
    drawBack = true,
		docked = true,
		height = 500,
		y = 0,
		tags = { "Game" },
		prevTags = "",
		numTags = 0,
		keys = {},
		items = {},
		selected = {},
		canvas = nil,
		scrollSpeed = 0,
		bounds = { x = 1, y = 1, w = 1, h = 1 },
		hovered = false,
		anyHoveredItem = false,
		delete = false,
		searching = false,
		showNames = false,
		searchFade = 0,
		baseTags = { "Game", "Level", "Room" },
		defaultTags = { "Game", "Level", "Room" },
		sortModes = { "name", "modified", "created" },
		sort = "name",
		psort = "name",
		thumbSize = config.galleryThumb or 56,
		fullThumbSize = config.galleryThumb or 50,
		iconBorder = 4,
		iconColumns = 3,
		row = config.row,
		alpha = 1,
		update = updateGallery,
    draw = gallery_draw
	}

	return panel
end
