Micromalist = LibStub("AceAddon-3.0"):NewAddon("Micromalist", "AceEvent-3.0", "AceHook-3.0", "AceConsole-3.0", "AceTimer-3.0")

local questtags, tags = {}, {Elite = "+", Group = "G", Dungeon = "D", Raid = "R", PvP = "P", Daily = "!", Heroic = "H", Repeatable = "?"}
local TRIVIAL, NORMAL = "|cff%02x%02x%02x[%d%s%s]|r "..TRIVIAL_QUEST_DISPLAY, "|cff%02x%02x%02x[%d%s%s]|r ".. NORMAL_QUEST_DISPLAY

local mod = Micromalist

function Micromalist:OnInitialize()
	self.abacus = LibStub("LibAbacus-3.0")

	--# register custom events
	mod:RegisterEvent("DUEL_REQUESTED")
	mod:RegisterEvent("MERCHANT_SHOW")
	mod:RegisterEvent("RESURRECT_REQUEST")
	mod:RegisterEvent("GOSSIP_SHOW")

	mod:SecureHook('QuestLog_Update')
	mod:SecureHook('WatchFrame_Update')
	mod:RegisterEvent("QUEST_GREETING")
	mod:RegisterEvent("GOSSIP_SHOW")

	ORIG_ERR_QUEST_ACCEPTED_S = ERR_QUEST_ACCEPTED_S
	mod:SecureHook('AcceptQuest')
	mod:RegisterEvent("QUEST_DETAIL")
	mod:RegisterEvent("QUEST_ACCEPT_CONFIRM")
	mod:RegisterEvent("QUEST_PROGRESS")
	mod:RegisterEvent("QUEST_COMPLETE")

	
	--# Initialize Chat
	for i = 1, NUM_CHAT_WINDOWS do
		--Allow resizing chatframes to whatever size you wish!
		local cf = _G[format("%s%d", "ChatFrame", i)]
		cf:SetMinResize(0,0)
		cf:SetMaxResize(0,0)

		--Allow the chat frame to move to the end of the screen
		cf:SetClampRectInsets(0,0,0,0)

		--Clamp the toast frame to screen to prevent it cutting out
		BNToastFrame:SetClampedToScreen(true)
	end
	
	--# Slash Commands
	--# /min or /minimlalist: Open Options Panel
	SlashCmdList["Micromalist"] = function() InterfaceOptionsFrame_OpenToCategory("Micromalist") end
	SLASH_Micromalist1 = "/Micromalist"
	SLASH_Micromalist2 = "/mic"

	--# /rl: Reload UI
	SlashCmdList["RELOADUI"] = function() ReloadUI() end
	SLASH_RELOADUI1 = "/rl"

	--# /rg: Restart GFX Subsystem
	SlashCmdList["RESTARTGX"] = function() RestartGx() end
	SLASH_RESTARTGX1 = "/rg"
end

function Micromalist:OnEnable()

	self:ChatButtonsOff()
	--self:ChatMoveEditBox()
	self:ChatArrowsOff()
	
	MainMenuBarLeftEndCap:Hide()
	MainMenuBarRightEndCap:Hide()

	self:MinMapHide()

	
end

function Micromalist:MinMapHide()
	MinimapZoomIn:Hide()
	MinimapZoomOut:Hide()
	GameTimeFrame:Hide()
	MinimapZoneTextButton:Hide()
	MinimapBorderTop:Hide()
	MiniMapTracking:Hide()
	MiniMapWorldMapButton:Hide()

end


function Micromalist:AcceptQuest()
	ERR_QUEST_ACCEPTED_S = "|cFF33FF99Micromalist:|cFFFFFFFF Accepted:           |Hquest:"..quest_link..":"..UnitLevel("player").."|h[%s]|h|r"
end

function Micromalist:QUEST_DETAIL()
	if not IsShiftKeyDown() then
		quest_link = GetQuestID()
		if not QuestGetAutoAccept() then
			AcceptQuest()
		else
			quest_link = GetAutoQuestPopUp(GetNumAutoQuestPopUps())
			CloseQuest()
		end
	end
end

function Micromalist:QUEST_ACCEPT_CONFIRM()
	if not IsShiftKeyDown() then
		ERR_QUEST_ACCEPTED_S = "|cFF33FF99Micromalist:|cFFFFFFFF Accepted:         %s (Escort)"
		ConfirmAcceptQuest()
		StaticPopup_Hide("QUEST_ACCEPT_CONFIRM")
	end
end

function Micromalist:QUEST_PROGRESS()
	if not IsShiftKeyDown() then
		if IsQuestCompletable() then
			CompleteQuest()
		end
	end
end

function Micromalist:QUEST_COMPLETE()
	if not IsShiftKeyDown() then
		if GetNumQuestChoices() < 2 then
			GetQuestReward(GetNumQuestChoices())
		end
	end
end

function Micromalist:GOSSIP_SHOW()
	self:GossipQuestLevelShow()
	if not IsShiftKeyDown() then
		self:SkipGossip()
	end
end


function Micromalist:SkipGossip()
	local t = GetGossipText()
	local list = {GetGossipOptions()}
	for i = 2,getn(list),2 do
		if(list[i]=="taxi" or list[i]=="battlemaster" or list[i]=="banker") then SelectGossipOption(i/2) return end
	end
end

local function GetTaggedTitle(i)
	-- helper function for Quest Level display
	local name, level, tag, group, header, _, complete, daily = GetQuestLogTitle(i)
	if header or not name then return end
	if not group or group == 0 then group = nil end
	return string.format("[%s%s%s%s] %s", level, tag and tags[tag] or "", daily and tags.Daily or "",group or "", name), tag, daily, complete
end

function Micromalist:QuestLog_Update()
	-- Add Quest Level to the Questlog
	for i,butt in pairs(QuestLogScrollFrame.buttons) do
		local qi = butt:GetID()
		local title, tag, daily, complete = GetTaggedTitle(qi)
		if title then butt:SetText("  "..title) end
		if (tag or daily) and not complete then butt.tag:SetText("") end
		QuestLogTitleButton_Resize(butt)
	end
end

function Micromalist:WatchFrame_Update()
	-- Add Quest Level to the Quest Watch Frame
	local questWatchMaxWidth, watchTextIndex = 0, 1
	for i=1,GetNumQuestWatches() do
		local qi = GetQuestIndexForWatch(i)
		if qi then
			local numObjectives = GetNumQuestLeaderBoards(qi)
			if numObjectives > 0 then
				for bi,butt in pairs(WATCHFRAME_QUESTLINES) do
					if butt.text:GetText() == GetQuestLogTitle(qi) then butt.text:SetText(GetTaggedTitle(qi)) end
				end
			end
		end
	end
end

local function helper(isActive, ...)
	-- helper function for Quest Level in Gossip
	local num = select('#', ...)
	if num == 0 then return end
	local skip = isActive and 4 or 5
	for j=1,num,skip do
		local title, level, isTrivial, daily, repeatable = select(j, ...)
		if isActive then daily, repeatable = nil end
		if title and level and level ~= -1 then
			local color = GetQuestDifficultyColor(level)
			_G["GossipTitleButton"..i]:SetFormattedText(isActive and isTrivial and TRIVIAL or NORMAL, color.r*255, color.g*255, color.b*255, level, repeatable and tags.Repeatable or "", daily and tags.Daily or "", title)
		end
		i = i + 1
	end
	i = i + 1
end

function Micromalist:GossipQuestLevelShow()
	i = 1
	helper(false, GetGossipAvailableQuests()) -- name, level, trivial, daily, repeatable
	helper(true, GetGossipActiveQuests()) -- name, level, trivial, complete
end

function Micromalist:QUEST_GREETING()
	local nact,navl = GetNumActiveQuests(), GetNumAvailableQuests()
	local title,level,button
	local o,GetTitle,GetLevel = 0,GetActiveTitle,GetActiveLevel
	for i = 1,nact+navl do
		if(i==nact+1) then
			o,GetTitle,GetLevel = nact,GetAvailableTitle,GetAvailableLevel
		end
		title,level = GetTitle(i-o), GetLevel(i-o)
		if level > 0 then
			button = getglobal("QuestTitleButton"..i)
			button:SetText(format('[%d] %s',level,title))
		end
	end
end


function Micromalist:DUEL_REQUESTED()
	if not IsShiftKeyDown() then
		HideUIPanel(StaticPopup1)
		CancelDuel()
	end
end

function Micromalist:MERCHANT_SHOW()
	if not IsShiftKeyDown() then
		self:MinSellJunk()
		if CanMerchantRepair() then self:RepairHandler() end
	end
end

function Micromalist:RepairHandler()
	local equipcost = GetRepairAllCost()
	local funds = GetMoney()

	if (funds < equipcost) then
		self:Print("Insufficient Funds to Repair")
	end

	if (equipcost > 0) then 
		RepairAllItems() 
		self:Print("Total repair Costs: "..self.abacus:FormatMoneyExtended(equipcost))
	end
end

function Micromalist:MinSellJunk()
	if not IsShiftKeyDown() then
		local bag, slot
		for bag = 0, 4 do
			if GetContainerNumSlots(bag) > 0 then
				for slot = 1, GetContainerNumSlots(bag) do
					local _, _, _, quality = GetContainerItemInfo(bag, slot)
					if (quality == 0 or quality == -1) then
						if (self:ProcessLink(GetContainerItemLink(bag, slot))) then
							UseContainerItem(bag, slot)
						end
					end
				end
			end
		end
	end
end

function Micromalist:ProcessLink(link)
	for color, name in string.gmatch(link, "(|c%x+)|Hitem:.+|h%[(.-)%]|h|r") do
	if color == ITEM_QUALITY_COLORS[0].hex then
		return true
	end
		return false
	end
end

function Micromalist:RESURRECT_REQUEST()
	if not IsShiftKeyDown() then
		if (arg1 == "Chained Spirit") then return end
		if (GetCorpseRecoveryDelay() ~= 0) then return end
		HideUIPanel(StaticPopup1)
		AcceptResurrect()
	end
end

function Micromalist:ChatButtonsOff()
	if (not ChatFrameMenuButton:IsVisible()) then return end
	local hideFunc = function(frame) frame:Hide() end

	ChatFrameMenuButton:SetScript("OnShow", hideFunc)
	ChatFrameMenuButton:Hide()
	FriendsMicroButton:SetScript("OnShow", hideFunc)
	FriendsMicroButton:Hide()

	for i = 1, NUM_CHAT_WINDOWS do
		local bf = _G[format("%s%d%s", "ChatFrame", i, "ButtonFrame")]
		bf:SetScript("OnShow", hideFunc)
		bf:Hide()
	end
end

function Micromalist:OnShow()
	this:Hide()
end

function Micromalist:ChatMoveEditBox()
	for i = 1, NUM_CHAT_WINDOWS do
		local eb =  _G[format("%s%d%s", "ChatFrame", i, "EditBox")]
		local cf = _G[format("%s%d", "ChatFrame", i)]
		eb:ClearAllPoints()
		eb:SetPoint("BOTTOMLEFT",  cf, "TOPLEFT",  -5, -5)
		eb:SetPoint("BOTTOMRIGHT", cf, "TOPRIGHT", 0, -5)
	end
end

function Micromalist:ChatArrowsOff()
	for i = 1, NUM_CHAT_WINDOWS do
		--Allow arrow keys editing in the edit box
		local eb =  _G[format("%s%d%s", "ChatFrame", i, "EditBox")]
		eb:SetAltArrowKeyMode(false)
	end
end
