local _G = _G
local pairs = _G.pairs
local ipairs = _G.ipairs
local unpack = _G.unpack
local tinsert = _G.table.insert
local GetItemInfo = _G.GetItemInfo
local GetItemIcon = _G.GetItemIcon

local itemIndex, name, rariry, level, subType, equipLoc, idx
local nameTable, rariryTable, levelTable, subTypeTable, iconTable = {}, {}, {}, {}, {}
local sortOrder = { ["모두"] = 0, ["판금"] = 1, ["사슬"] = 2, ["가죽"] = 3, ["천"] = 4, ["양손 도검류"] = 5, ["양손 둔기류"] = 6, ["양손 도끼류"] = 7, ["장창류"] = 8, ["지팡이류"] = 9, ["한손 도검류"] = 10, ["한손 둔기류"] = 11, ["한손 도끼류"] = 12, ["단검류"] = 13, ["장착 무기류"] = 14, ["방패"] = 15, ["총기류"] = 16, ["활류"] = 17, ["석궁류"] = 18, ["투척 무기류"] = 19, ["마법봉류"] = 20, ["우상"] = 21, ["토템"] = 22, ["성서"] = 23, ["인장"] = 24, ["기타"] = 25, ["퀘스트"] = 26 }
local sortOrderStat = { ["모두"] = 0, ["힘"] = 1, ["민첩성"] = 2, ["체력"] = 3, ["지능"] = 4, ["정신력"] = 5, ["생명력"] = 6, ["마나"] = 7, ["전투력"] = 10, ["근접 전투력"] = 11, ["원거리 전투력"] = 12, ["변신 상태 전투력"] = 13, ["주문력"] = 14, ["공격력 증가"] = 15, ["치유량 증가"] = 16, ["치명타 및 주문 극대화 적중도"] = 20, ["원거리 치명타 적중도"] = 21, ["근접 치명타 적중도"] = 22, ["주문 극대화 적중도"] = 23, ["가속도"] = 24, ["근접 가속도"] = 25, ["원거리 가속도"] = 26, ["주문 가속도"] = 27, ["적중도"] = 28, ["근접 적중도"] = 29, ["원거리 적중도"] = 30, ["주문 적중도"] = 31, ["숙련도"] = 32, ["방어구 관통력"] = 33, ["주문 관통력"] = 34, ["방어도"] = 35, ["탄력도"] = 36, ["회피 숙련도"] = 37, ["공격 회피 숙련도"] = 38, ["근접 공격 회피 숙련도"] = 39, ["원거리 공격 회피 숙련도"] = 40, ["주문 공격 회피 숙련도"] = 41, ["무기 막기 숙련도"] = 42, ["방어 숙련도"] = 43, ["방패 막기 숙련도"] = 44, ["방패 피해 방어량"] = 45, ["치명타 회피 숙련도"] = 46, ["근접 치명타 회피 숙련도"] = 47, ["원거리 치명타 회피 숙련도"] = 48, ["주문 치명타 회피 숙련도"] = 49, ["생명력 회복량"] = 50, ["마나 회복량"] = 51, ["5초당 생명력 회복량"] = 52, ["5초당 마나 회복량"] = 53, ["5초당 분노 회복량"] = 54, ["5초당 기력 회복량"] = 55, ["5초당 룬 회복량"] = 56, ["5초당 룬 마력 회복량"] = 57, ["5초당 집중 회복량"] = 58, ["5초당 만족도 회복량"] = 59, ["비전 저항력"] = 60, ["화염 저항력"] = 61, ["자연 저항력"] = 62, ["냉기 저항력"] = 63, ["암흑 저항력"] = 64, ["신성 저항력"] = 65, ["비전"] = 66, ["화염"] = 67, ["자연"] = 68, ["냉기"] = 69, ["암흑"] = 70, ["신성"] = 71, ["얼개 보석 홈"] = 80, ["붉은색 보석 홈"] = 81, ["노란색 보석 홈"] = 82, ["푸른색 보석 홈"] = 83, ["다색 보석 홈"] = 84 }
local faction = UnitFactionGroup("player") == "Horde" and 1 or 2

function InvenSimulatorUI:OpenItemList(id)
	self:ScanItemCache()
	if self.itemDB[id] then
		self:CreateItemListFrame()
		self:ShowTop(self.itemListFrame)
		self.itemListFrame.openSlotID = id
		SetPortraitToTexture(self.itemListFrame.icon, self.slots[id].backgroundTextureName:gsub(".blp", ""))
		self.itemListFrame.editBox:SetText(SEARCH)
		self.itemListFrame.editBox.search = nil
		self:FirstMakeItemList()
		UIDropDownMenu_Initialize(self.itemListFrame.filterDropdown, self.itemListFrame.filterDropdown.Initialize)
		self:MakeItemList()
	elseif self.itemListFrame then
		self.itemListFrame:Hide()
	end
end

function InvenSimulatorUI:ClearItemListData()
	for p in pairs(self.itemListFrame.data) do
		self.itemListFrame.data[p] = nil
		self.itemListFrame.list[p] = nil
	end
	for p in pairs(nameTable) do
		nameTable[p] = nil
		rariryTable[p] = nil
		levelTable[p] = nil
		subTypeTable[p] = nil
		iconTable[p] = nil
	end
	for p in pairs(self.itemListFrame.subTypes) do
		self.itemListFrame.subTypes[p] = nil
	end
	for p in pairs(self.itemListFrame.hasStats) do
		self.itemListFrame.hasStats[p] = nil
	end
	self.itemListFrame.scroll.bar:SetMinMaxValues(0, 0)
	self.itemListFrame.scroll.bar:SetValue(0)
	self.itemListFrame.scroll.offset = 0
end

function InvenSimulatorUI:FirstMakeItemList()
	self:ClearItemListData()
	idx = self.itemListFrame.openSlotID
	for _, item in ipairs(self.itemDB[idx]) do
		if self:HasTradeSkill(self:IsTradeSkillOnly(item)) then
			name, _, rariry, level, _, _, subType, _, equipLoc = GetItemInfo(item)
			if name and self.slotsEquipLoc[idx] and self.slotsEquipLoc[idx][equipLoc] then
				nameTable[item], rariryTable[item], levelTable[item], subTypeTable[item], iconTable[item] = name, rariry, level, subType, GetItemIcon(item)
				self.itemListFrame.subTypes[subType] = true
				for p, v in pairs(self.itemDataByStat) do
					if v[item] then
						self.itemListFrame.hasStats[p] = true
					end
				end
				tinsert(self.itemListFrame.data, item)
			end
		end
	end
	sort(self.itemListFrame.data, function(a, b)
		if rariryTable[a] > rariryTable[b] then
			return true
		elseif rariryTable[a] == rariryTable[b] then
			if levelTable[a] > levelTable[b] then
				return true
			elseif levelTable[a] == levelTable[b] then
				return nameTable[a] < nameTable[b]
			end
		end
		return false
	end)
	self.itemListFrame.filterDropdown.filter = nil
	for p in pairs(self.itemListFrame.filterDropdown.list) do
		self.itemListFrame.filterDropdown.list[p] = nil
	end
	for s in pairs(self.itemListFrame.subTypes) do
		tinsert(self.itemListFrame.filterDropdown.list, s)
	end
	if #self.itemListFrame.filterDropdown.list > 1 then
		sort(self.itemListFrame.filterDropdown.list, function(a, b)
			if sortOrder[a] and sortOrder[b] then
				return sortOrder[a] < sortOrder[b]
			elseif sortOrder[a] then
				return false
			elseif sortOrder[b] then
				return true
			else
				return a < b
			end
		end)
		tinsert(self.itemListFrame.filterDropdown.list, 1, "모두")
		if self.itemListFrame.subTypes[self.maxArmor] then
			self.itemListFrame.filterDropdown.filter = self.maxArmor
		else
			self.itemListFrame.filterDropdown.filter = "모두"
		end
	else
		self.itemListFrame.filterDropdown.filter = self.itemListFrame.filterDropdown.list[1]
	end
	UIDropDownMenu_Initialize(self.itemListFrame.filterDropdown, self.itemListFrame.filterDropdown.Initialize)
	UIDropDownMenu_SetSelectedValue(self.itemListFrame.filterDropdown, self.itemListFrame.filterDropdown.filter)
	for p in pairs(self.itemListFrame.statDropdown.list) do
		self.itemListFrame.statDropdown.list[p] = nil
	end
	for s in pairs(self.itemListFrame.hasStats) do
		tinsert(self.itemListFrame.statDropdown.list, s)
	end
	sort(self.itemListFrame.statDropdown.list, function(a, b)
		if sortOrderStat[a] and sortOrderStat[b] then
			return sortOrderStat[a] < sortOrderStat[b]
		elseif sortOrderStat[a] then
			return false
		elseif sortOrderStat[a] then
			return true
		else
			return a < b
		end
	end)
	tinsert(self.itemListFrame.statDropdown.list, 1, "모두")
	self.itemListFrame.statDropdown.filter = "모두"
	UIDropDownMenu_Initialize(self.itemListFrame.statDropdown, self.itemListFrame.statDropdown.Initialize)
	UIDropDownMenu_SetSelectedValue(self.itemListFrame.statDropdown, self.itemListFrame.statDropdown.filter)
end

function InvenSimulatorUI:MakeItemList(search, filter, statFilter)
	search = search or self.itemListFrame.editBox.search
	filter = filter or self.itemListFrame.filterDropdown.filter
	statFilter = statFilter or self.itemListFrame.statDropdown.filter
	if search == "" or search == SEARCH then search = nil end
	if filter == "모두" then filter = nil end
	if statFilter == "모두" then statFilter = nil end
	if self.itemListFrame.prevSearch ~= search or self.itemListFrame.prevFilter ~= filter or self.itemListFrame.prevStatFilter ~= statFilter then
		self.itemListFrame.prevSearch = search
		self.itemListFrame.prevFilter = filter
		self.itemListFrame.prevStatFilter = statFilter
		self.itemListFrame.scroll.bar:SetMinMaxValues(0, 0)
		self.itemListFrame.scroll.bar:SetValue(0)
		self.itemListFrame.scroll.offset = 0
	end
	for p in pairs(self.itemListFrame.list) do
		self.itemListFrame.list[p] = nil
	end
	for _, item in ipairs(self.itemListFrame.data) do
		if (search and nameTable[item]:find(search, 1, true)) or (not search) then
			if (filter and subTypeTable[item] == filter) or (not filter) then
				if (statFilter and self.itemDataByStat[statFilter] and self.itemDataByStat[statFilter][item]) or (not statFilter) then
					tinsert(self.itemListFrame.list, item)
				end
			end
		end
	end
	self.itemListFrame.title:SetFormattedText("%s (%d)", self.slots[self.itemListFrame.openSlotID].tooltipText, #self.itemListFrame.list)
	self:UpdateItemList()
end

function InvenSimulatorUI:UpdateItemList()
	self = InvenSimulatorUI
	FauxScrollFrame_Update(self.itemListFrame.scroll, #self.itemListFrame.list, 12, 20)
	for i, button in ipairs(self.itemListFrame.items) do
		itemIndex = i + self.itemListFrame.scroll.offset
		if self.itemListFrame.list[itemIndex] then
			button.itemID = self.itemListFrame.list[itemIndex]
			button:SetID(itemIndex)
			button:SetNormalTexture(iconTable[button.itemID])
			button:SetText(self.qualityColorHex[rariryTable[button.itemID]]..nameTable[button.itemID])
			button:Show()
		else
			button:Hide()
		end
	end
end

function InvenSimulatorUI:CreateItemListFrame()
	if not self.itemListFrame then
		local f = CreateFrame("Frame", "InvenSimulatorItemListFrame", UIParent)
		f.levelElements = {}
		f.data, f.list, f.subTypes, f.hasStats = {}, {}, {}, {}
		f:Hide()
		f:SetToplevel(true)
		f:EnableMouse(true)
		f:SetClampedToScreen(true)
		f:SetMovable(true)
		f:RegisterForDrag("LeftButton")
		f:SetScript("OnDragStart", f.StartMoving)
		f:SetScript("OnDragStop", function(self)
			self:StopMovingOrSizing()
			InvenSimulatorUI.db.itemListPos[1], _, _, InvenSimulatorUI.db.itemListPos[2], InvenSimulatorUI.db.itemListPos[3] = self:GetPoint()
		end)
		f:SetWidth(267)
		f:SetHeight(335)
		f:SetPoint(self.db.itemListPos[1], UIParent, self.db.itemListPos[1], self.db.itemListPos[2], self.db.itemListPos[3])
		f:SetScript("OnShow", function() PlaySound("igCharacterInfoOpen") end)
		f:SetScript("OnHide", function()
			PlaySound("igCharacterInfoClose")
			InvenSimulatorUI:ClearItemListData()
		end)
		f.icon = f:CreateTexture(nil, "BACKGROUND")
		f.icon:SetWidth(60)
		f.icon:SetHeight(60)
		f.icon:SetPoint("TOPLEFT", -3, 6)
		f.title = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
		f.title:SetHeight(14)
		f.title:SetPoint("TOP", 17, -4)
		local tl = f:CreateTexture(nil, "ARTWORK")
		tl:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopLeft")
		tl:SetWidth(256)
		tl:SetHeight(256)
		tl:SetPoint("TOPLEFT", f, "TOPLEFT", -11, 12)
		local tr = f:CreateTexture(nil, "ARTWORK")
		tr:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopRight")
		tr:SetWidth(128)
		tr:SetHeight(256)
		tr:SetPoint("LEFT", tl, "RIGHT", -70, 0)
		local bl = f:CreateTexture(nil, "ARTWORK")
		bl:SetTexture("Interface\\TaxiFrame\\UI-TaxiFrame-BotLeft")
		bl:SetWidth(256)
		bl:SetHeight(256)
		bl:SetPoint("TOP", tl, "BOTTOM", 0, 90)
		local br = f:CreateTexture(nil, "ARTWORK")
		br:SetTexture("Interface\\TaxiFrame\\UI-TaxiFrame-BotRight")
		br:SetWidth(128)
		br:SetHeight(256)
		br:SetPoint("LEFT", bl, "RIGHT", -70, 0)
		f.closeButton = CreateFrame("Button", nil, f, "UIPanelCloseButton")
		f.levelElements[f.closeButton] = 1
		f.closeButton:SetPoint("CENTER", f, "TOPRIGHT", -10, -12)
		f.scroll = CreateFrame("ScrollFrame", "InvenItemComapre2ItemListFrameScroll", f, "ClassTrainerListScrollFrameTemplate")
		f.levelElements[f.closeButton] = 1
		f.scroll:SetWidth(227)
		f.scroll:SetHeight(242)
		f.scroll:SetPoint("TOPLEFT", 10, -85)
		f.scroll.bar = InvenItemComapre2ItemListFrameScrollScrollBar
		f.scroll.center = f.scroll:CreateTexture(nil, "ARTWORK")
		f.scroll.center:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
		f.scroll.center:SetPoint("RIGHT", f.scroll, "RIGHT", 29, 0)
		f.scroll.center:SetWidth(31)
		f.scroll.center:SetHeight(130)
		f.scroll.center:SetTexCoord(0, 0.484375, 0.5, 1)
		f.items = {}
		local function buttonOnEnter(self)
			f.scroll.enter = self
			GameTooltip:SetOwner(self, "ANCHOR_RIGHT", 30, 0)
			GameTooltip:SetHyperlink("item:"..self.itemID)
			GameTooltip:Show()
		end
		local function buttonOnDoubleClick(self)
			ClearCursor()
			local link, _, _, _, _, _, _, equipLoc = select(2, GetItemInfo(self.itemID))
			InvenSimulatorUI:SlotHighlighUpdate(equipLoc, link)
			if InvenSimulatorUI:GetEquipableSlot(InvenSimulatorUI.itemListFrame.openSlotID) then
				InvenSimulatorUI:SetItem(InvenSimulatorUI.itemListFrame.openSlotID, link, nil, true)
				InvenSimulatorUI.itemListFrame:Hide()
				InvenSimulatorUI:ModelUpdate()
			end
			InvenSimulatorUI.isHighlightSlot = nil
			for i = 1, 19 do
				InvenSimulatorUI.slots[i]:UnlockHighlight()
			end
		end
		for i = 1, 12 do
			f.items[i] = CreateFrame("Button", "InvenSimulatorItemListFrameButton"..i, f)
			f.levelElements[f.items[i]] = 2
			f.items[i].buttonIndex = i
			f.items[i]:SetID(i)
			f.items[i]:SetWidth(225)
			f.items[i]:SetHeight(20)
			f.items[i]:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")
			f.items[i]:SetNormalTexture("Interface\\Icons\\Temp")
			f.items[i].normalTexture = f.items[i]:GetNormalTexture()
			f.items[i].normalTexture:SetTexCoord(0.07, 0.93, 0.07, 0.93)
			f.items[i].normalTexture:SetWidth(20)
			f.items[i].normalTexture:SetHeight(20)
			f.items[i].normalTexture:ClearAllPoints()
			f.items[i].normalTexture:SetPoint("LEFT", f.items[i], "LEFT")
			f.items[i]:SetNormalFontObject("GameFontNormalLeft")
			f.items[i]:SetText("아이템")
			f.items[i].text = f.items[i]:GetFontString()
			f.items[i].text:ClearAllPoints()
			f.items[i].text:SetPoint("TOPLEFT", f.items[i]:GetNormalTexture(), "TOPRIGHT", 2, 0)
			f.items[i].text:SetPoint("BOTTOMRIGHT", f.items[i], "BOTTOMRIGHT")
			f.items[i]:SetScript("OnEnter", buttonOnEnter)
			f.items[i]:SetScript("OnLeave", GameTooltip_Hide)
			f.items[i]:SetScript("OnDoubleClick", buttonOnDoubleClick)
			if i == 1 then
				f.items[i]:SetPoint("TOPLEFT", f.scroll, "TOPLEFT", 2, -2)
			else
				f.items[i]:SetPoint("TOP", f.items[i - 1], "BOTTOM")
			end
		end
		f.scroll:SetScript("OnVerticalScroll", function(self, scroll)
			FauxScrollFrame_OnVerticalScroll(self, scroll, 20, InvenSimulatorUI.UpdateItemList)
			if self.enter then
				buttonOnEnter(self.enter)
			end
		end)
		f.editBox = CreateFrame("EditBox", "InvenSimulatorItemListFrameSearch", f)
		f.levelElements[f.editBox] = 1
		f.editBox.GetCleanText = function(self) return (self:GetText() or ""):trim() end
		f.editBox:SetAutoFocus(false)
		f.editBox:SetWidth(80)
		f.editBox:SetHeight(20)
		f.editBox:SetWidth(80)
		f.editBox:SetPoint("TOPLEFT", f, "TOPLEFT", 70, -32)
		f.editBox.left = f.editBox:CreateTexture(nil, "BACKGROUND")
		f.editBox.left:SetTexture("Interface\\Common\\Common-Input-Border")
		f.editBox.left:SetWidth(8)
		f.editBox.left:SetHeight(20)
		f.editBox.left:SetPoint("TOPLEFT", -5, 0)
		f.editBox.left:SetTexCoord(0, 0.0625, 0, 0.625)
		f.editBox.right = f.editBox:CreateTexture(nil, "BACKGROUND")
		f.editBox.right:SetTexture("Interface\\Common\\Common-Input-Border")
		f.editBox.right:SetWidth(8)
		f.editBox.right:SetHeight(20)
		f.editBox.right:SetPoint("RIGHT")
		f.editBox.right:SetTexCoord(0.9375, 1, 0, 0.625)
		f.editBox.middle = f.editBox:CreateTexture(nil, "BACKGROUND")
		f.editBox.middle:SetTexture("Interface\\Common\\Common-Input-Border")
		f.editBox.middle:SetPoint("TOPLEFT", f.editBox.left, "TOPRIGHT")
		f.editBox.middle:SetPoint("BOTTOMRIGHT", f.editBox.right, "BOTTOMLEFT")
		f.editBox.middle:SetTexCoord(0.0625, 0.9375, 0, 0.625)
		f.editBox:SetFontObject("ChatFontSmall")
		f.editBox:SetText(SEARCH)
		f.editBox:SetScript("OnEnterPressed", f.editBox.ClearFocus)
		f.editBox:SetScript("OnEscapePressed", f.editBox.ClearFocus)
		f.editBox:SetScript("OnEditFocusLost", function(self)
			self:HighlightText(0, 0)
			self:SetText(self:GetCleanText())
			if self:GetText() == "" then
				self:SetText(SEARCH)
			end
		end)
		f.editBox:SetScript("OnEditFocusGained", function(self)
			self:HighlightText()
			if self:GetCleanText() == SEARCH then
				self:SetText("")
			end
		end)
		f.editBox:SetScript("OnTextChanged", function(self)
			self.value = self:GetCleanText()
			if self.value == "" or self.value == SEARCH then
				self.search = nil
			else
				self.search = self.value
			end
			InvenSimulatorUI:MakeItemList()
		end)
		local dropdownFunc = function(self)
			self.owner.filter = self.value
			UIDropDownMenu_SetSelectedValue(self.owner, self.value)
			InvenSimulatorUI:MakeItemList()
			InvenSimulatorItemListFrameSearch:ClearFocus()
		end
		local dropdownInitialize = function(self)
			local info = UIDropDownMenu_CreateInfo()
			for _, text in ipairs(self.list) do
				info.text = text
				info.value = self.value
				info.func = self.func
				info.owner = UIDROPDOWNMENU_OPEN_MENU
				info.checked = self.filter == text and 1 or nil
				UIDropDownMenu_AddButton(info)
			end
		end
		f.filterDropdown = CreateFrame("Frame", "InvenSimulatorItemListFrameFilter", f, "UIDropDownMenuTemplate")
		f.levelElements[f.filterDropdown] = 1
		InvenSimulatorItemListFrameFilterButton:HookScript("OnClick", function()
			InvenSimulatorItemListFrameSearch:ClearFocus()
		end)
		f.filterDropdown.list = {}
		f.filterDropdown:SetID(1)
		f.filterDropdown:EnableMouse(true)
		f.filterDropdown:SetPoint("LEFT", f.editBox, "RIGHT", -14, -2)
		UIDropDownMenu_SetWidth(f.filterDropdown, 92)
		UIDropDownMenu_JustifyText(f.filterDropdown, "LEFT")
		f.filterDropdown.func = dropdownFunc
		f.filterDropdown.Initialize = dropdownInitialize
		f.statDropdown = CreateFrame("Frame", "InvenSimulatorItemListFrameStatFilter", f, "UIDropDownMenuTemplate")
		f.levelElements[f.filterDropdown] = 2
		InvenSimulatorItemListFrameStatFilterButton:HookScript("OnClick", function()
			InvenSimulatorItemListFrameSearch:ClearFocus()
		end)
		f.statDropdown.list = {}
		f.statDropdown:SetID(2)
		f.statDropdown:EnableMouse(true)
		f.statDropdown:SetPoint("TOPRIGHT", f.filterDropdown, "BOTTOMRIGHT", 0, 7)
		UIDropDownMenu_SetWidth(f.statDropdown, 160)
		UIDropDownMenu_JustifyText(f.statDropdown, "LEFT")
		f.statDropdown.func = dropdownFunc
		f.statDropdown.Initialize = dropdownInitialize
		f.refreshButton = CreateFrame("Button", "InvenSimulatorItemListFrameRefreshButton", f, "UIPanelButtonTemplate")
		f.levelElements[f.filterDropdown] = 1
		f.refreshButton:SetWidth(70)
		f.refreshButton:SetHeight(20)
		f.refreshButton:SetText("아이템 갱신")
		f.refreshButton:SetPoint("RIGHT", f.statDropdown, "LEFT", 10, 0)
		f.refreshButton:SetScript("OnClick", function()
			InvenSimulatorUI.hasItemData = nil
			InvenSimulatorUI:OpenItemList(InvenSimulatorUI.itemListFrame.openSlotID)
		end)
		self.itemListFrame = f
		tinsert(UISpecialFrames, "InvenSimulatorItemListFrame")
	end
end