setfenv(1, select(2, ...))
local Minimap, MinimapCluster, MinimapBackdrop = Minimap, MinimapCluster, MinimapBackdrop
local MiniMapMailFrame, MiniMapTracking = MiniMapMailFrame, MiniMapTracking
local MiniMapLFGFrame, MiniMapVoiceChatFrame, MiniMapBattlefieldFrame = MiniMapLFGFrame, MiniMapVoiceChatFrame, MiniMapBattlefieldFrame

-- Drag ability
MinimapCluster:SetPoint("TOPRIGHT", -10, -10)
MinimapCluster:SetClampedToScreen(true)
MinimapCluster:SetMovable(true)

MinimapZoneTextButton:SetScript("OnMouseDown", function(_, button)
	if button == "LeftButton" and IsAltKeyDown() then
		MinimapCluster:StartMoving()
	end
end)

MinimapZoneTextButton:SetScript("OnMouseUp", function()
	MinimapCluster:StopMovingOrSizing()
end)

-- Hide zoom buttons, mousewheel zooming
MinimapZoomIn:Hide()
MinimapZoomOut:Hide()

Minimap:SetScript("OnMouseWheel", function(self, delta)
	local zoom = Minimap:GetZoom()
	if delta == 1 and zoom < Minimap:GetZoomLevels() then
		if IsShiftKeyDown() then
			Minimap:SetZoom(Minimap:GetZoomLevels())
		else
			Minimap:SetZoom(zoom + 1)
		end
	elseif delta == -1 and zoom > 0 then
		if IsShiftKeyDown() then
			Minimap:SetZoom(0)
		else
			Minimap:SetZoom(zoom - 1)
		end
	end
end)

-- Hide map button
MiniMapWorldMapButton:Hide()

-- Hide compass
hooksecurefunc("Minimap_UpdateRotationSetting", function()
	MinimapNorthTag:Hide()
	MinimapCompassTexture:Hide()
end)

-- Hide calendar
GameTimeFrame:Hide()

-- Hide time manager
local dummy = CreateFrame("Frame")
dummy:RegisterEvent("ADDON_LOADED")
dummy:SetScript("OnEvent", function(_, event, ...)
	if event == "ADDON_LOADED" then
		if ... == "Blizzard_TimeManager" then
			TimeManagerClockButton:Hide()
		end
	end
end)

-- Hide LFG button
local showLFGMenu = MiniMapLFGFrame:IsShown()
hooksecurefunc("MiniMapLFG_UpdateIsShown", function()
	showLFGMenu = MiniMapLFGFrame:IsShown()
	MiniMapLFGFrame:Hide()
end)

-- Hide voice chat button
local showVoiceMenu = MiniMapVoiceChatFrame:IsShown()
hooksecurefunc("MiniMapVoiceChat_Update", function()
	showVoiceMenu = MiniMapVoiceChatFrame:IsShown()
	MiniMapVoiceChatFrame:Hide()
end)

-- Hide PvP button
local showPvPMenu = MiniMapBattlefieldFrame:IsShown()
hooksecurefunc("PVP_UpdateStatus", function()
	showPvPMenu = MiniMapBattlefieldFrame:IsShown()
	--MiniMapBattlefieldFrame:Hide()
end)

-- Skin minimap
Minimap:SetPoint("CENTER", MinimapCluster, 0, -10)
Minimap:SetMaskTexture(media.background["Flat"])
Minimap:SetFrameLevel(3)

MinimapBackdrop:SetFrameLevel(2)
MinimapBackdrop:SetPoint("TOPLEFT", Minimap, -11, 11)
MinimapBackdrop:SetPoint("BOTTOMRIGHT", Minimap, 11, -11)
MinimapBackdrop:SetBackdrop({
	bgFile = media.background["Flat"],
	edgeFile = media.border["hankui: Thin Glow"],
	edgeSize = 16,
	insets = { left = 4, right = 4, top = 4, bottom = 4 }
})
MinimapBackdrop:SetBackdropColor(unpack(colors["Background"].applyAlpha(1)))
MinimapBackdrop:SetBackdropBorderColor(unpack(colors["Background"].applyAlpha(0.8)))
MinimapBorder:Hide()

local glow = MinimapBackdrop:CreateTexture("MinimapGlow", "BACKGROUND", nil, -8)
glow:SetPoint("TOPLEFT", MinimapBackdrop, -110, 110)
glow:SetPoint("BOTTOMRIGHT", MinimapBackdrop, 110, -110)
glow:SetBlendMode("ADD")
glow:SetTexture(media.background["hankui: Minimap glow"])
glow:SetVertexColor(unpack(colors["Signature color"].applyAlpha(1)))

MinimapBorderTop:Hide()
fonts.overrides["hMinimapZone"] = {"Tahoma Bold", 14, "OUTLINE"}
MinimapZoneText:SetFontObject("hMinimapZone")

-- Skin buttons
local MiniMapBin = CreateFrame("Button", "MiniMapBin", Minimap)
local MiniMapBinIcon = MiniMapBin:CreateTexture("MiniMapBinIcon", "ARTWORK")
local MiniMapBinBorder =  MiniMapBin:CreateTexture("MiniMapBinBorder", "BORDER")

for i, v in ipairs({ "MiniMapMail", "MiniMapTracking", "MiniMapBin" }) do
	local frame = _G[v .. "Frame"] or _G[v]
	local btn = _G[v .. "Button"]
	local ico = _G[v .. "Icon"]
	local bd = _G[v .. "Border"] or _G[v .. "ButtonBorder"]
	
	frame:SetSize(32, 32)
	frame:ClearAllPoints()
	frame:SetAlpha(0)
	
	if btn then
		btn:SetAllPoints()
		btn:SetHighlightTexture(nil)
		btn:SetScript("OnMouseDown", nil)
		btn:SetScript("OnMouseUp", nil)
	end
	
	local scriptRef = btn or frame
	scriptRef:HookScript("OnEnter", function(_, motion)
		ico:SetVertexColor(unpack(colors["Signature color"].applyAlpha(1)))
		bd:SetVertexColor(unpack(colors["Signature color"].applyAlpha(1)))
	end)
	scriptRef:HookScript("OnLeave", function(_, motion)
		ico:SetVertexColor(unpack(colors["Background light"].applyAlpha(1)))
		bd:SetVertexColor(unpack(colors["Background"].applyAlpha(1)))
	end)
	
	ico:SetAllPoints()
	ico:SetTexture(media.button["Minimap"])
	ico:SetTexCoord((i - 1) * 0.25, i * 0.25, 0, 0.5)
	ico:SetVertexColor(unpack(colors["Background light"].applyAlpha(1)))
	
	bd:SetAllPoints()
	bd:SetTexture(media.button["Minimap"])
	bd:SetTexCoord((i - 1) * 0.25, i * 0.25, 0.5, 1)
	bd:SetVertexColor(unpack(colors["Background"].applyAlpha(1)))
end

MiniMapTracking:SetPoint("BOTTOM", 0, 10)
MiniMapMailFrame:SetPoint("RIGHT", MiniMapTracking, "LEFT", -5, 0)
MiniMapBin:SetPoint("LEFT", MiniMapTracking, "RIGHT", 5, 0)

-- Show buttons on mouseover
local function showBtns()
	MiniMapBin:SetAlpha(1)
	MiniMapTracking:SetAlpha(1)
	MiniMapMailFrame:SetAlpha(1)
end

local function hideBtns()
	if not Minimap:IsMouseOver() then
		MiniMapBin:SetAlpha(0)
		MiniMapTracking:SetAlpha(0)
		MiniMapMailFrame:SetAlpha(0)
	end
end

for _, v in ipairs({ "Minimap", "MiniMapBin", "MiniMapTrackingButton", "MiniMapMailFrame" }) do
	_G[v]:HookScript("OnEnter", showBtns)
	_G[v]:HookScript("OnLeave", hideBtns)
end

hideBtns()

-- Button bin: Try to get all external addon buttons off the map
local external = {
	frames = {},
	factoryFrames = {
		"MinimapZoneTextButton",
		"MiniMapBattlefieldFrame",
		"GameTimeFrame",
		"MiniMapVoiceChatFrame",
		"MiniMapBin",
		"TimeManagerClockButton",
		"MiniMapWorldMapButton",
		"MiniMapLFGFrame",
		"MinimapZoomIn",
		"MinimapZoomOut",
		"MiniMapRecordingButton"
	},
	filteredStrings = {
		"Minimap",
		"Icon",
		"Button",
		"Frame",
		"LibDB[%d]*",
		"_"
	}
}

Minimap:RegisterEvent("PLAYER_LOGIN")
Minimap:HookScript("OnEvent", function(_, event)
	if event == "PLAYER_LOGIN" then
		local externalButtons = {}
		for _, frame in ipairs({ "MinimapCluster", "Minimap", "MinimapBackdrop" }) do
			if _G[frame]:GetChildren() then
				for i = 1, select("#", _G[frame]:GetChildren()) do
					local child = select(i, _G[frame]:GetChildren())
					if child:GetObjectType() == "Button" and not tContains(external.factoryFrames, child:GetName()) then
						table.insert(external.frames, child)
						child:Hide()
					end
				end
			end
		end
	end
end)

-- Button bin: Dropdown
local dropdown = CreateFrame("Frame", "MiniMapBinDropDown", MiniMapBin, "UIDropDownMenuTemplate")
local tblDropDown = {}

local function showDropDown(self, level)
	-- Root menu
	if level == 1 then
		-- Calendar
		tblDropDown = {
			text = "Calendar" .. (CalendarGetNumPendingInvites() > 0 and (" (" .. CalendarGetNumPendingInvites() .. " pending)") or ""),
			notCheckable = true,
			tooltipOnButton = true,
			func = function() GameTimeFrame_OnClick(GameTimeFrame) end
		}
		UIDropDownMenu_AddButton(tblDropDown)
		
		-- Voice chat
		if showVoiceMenu then
			tblDropDown = {
				text = "Voice chat",
				notCheckable = true,
				hasArrow = true,
				value = "Voice",
				func = function() ToggleFriendsFrame(3) end
			}
			UIDropDownMenu_AddButton(tblDropDown)
		end
		
		-- LFG root menu
		if showLFGMenu then
			tblDropDown = {
				text = "Dungeon finder",
				notCheckable = true,
				hasArrow = true,
				value = "LFG",
				func = function()
					mode, submode = GetLFGMode()
					if mode == "proposal" and not LFDDungeonReadyPopup:IsShown() then
						PlaySound("igCharacterInfoTab");
            			StaticPopupSpecial_Show(LFDDungeonReadyPopup)
					elseif mode == "queued" or mode == "rolecheck" then
						ToggleLFDParentFrame()
					elseif mode == "listed" then
						ToggleLFRParentFrame()
					end
				end
			}
			
			local mode, submode = GetLFGMode()
			
			if mode == "queued" then
				tblDropDown.tooltipTitle = LOOKING_FOR_DUNGEON
				tblDropDown.tooltipText = LFDSearchStatusStatistic:GetText()
				tblDropDown.tooltipOnButton = true
			elseif mode == "proposal" then
				tblDropDown.tooltipTitle = LOOKING_FOR_DUNGEON
				tblDropDown.tooltipText = DUNGEON_GROUP_FOUND_TOOLTIP
				tblDropDown.tooltipOnButton = true
			elseif mode == "rolecheck" then
				tblDropDown.tooltipTitle = LOOKING_FOR_DUNGEON
				tblDropDown.tooltipText = ROLE_CHECK_IN_PROGRESS_TOOLTIP
				tblDropDown.tooltipOnButton = true
			elseif mode == "listed" then
				tblDropDown.tooltipTitle = LOOKING_FOR_RAID
				tblDropDown.tooltipText = YOU_ARE_LISTED_IN_LFR
				tblDropDown.tooltipOnButton = true
			elseif mode == "lfgparty" then
				tblDropDown.tooltipTitle = LOOKING_FOR_DUNGEON
				tblDropDown.tooltipText = YOU_ARE_IN_DUNGEON_GROUP
				tblDropDown.tooltipOnButton = true
			end
			
			UIDropDownMenu_AddButton(tblDropDown)
		end
		
		-- PvP root menu
		if showPvPMenu then
			tblDropDown = {
				text = "PvP",
				notCheckable = true,
				hasArrow = true,
				value = "PvP",
				tooltipTitle = "lolol",
				tooltipText = string.gsub(MiniMapBattlefieldFrame.tooltip, RIGHT_CLICK_MESSAGE, ""),
				tooltipOnButton = true,
				func = function()
				end
			}
			UIDropDownMenu_AddButton(tblDropDown)
		end
		
		
		-- External addons
		if #external.frames > 0 then
			tblDropDown = { notCheckable = true, notClickable = true }
			UIDropDownMenu_AddButton(tblDropDown)
			tblDropDown = { isTitle = true, text = "Addons", notCheckable = true }
			UIDropDownMenu_AddButton(tblDropDown)
			
			for i = 1, #external.frames do
				local caption
				if external.frames[i]:GetName() then
					caption = external.frames[i]:GetName()
					-- Filter out all the crap
					for _, filter in ipairs(external.filteredStrings) do
						caption = string.gsub(caption, filter, "")
					end
				else
					caption = "Unknown addon"
				end
				tblDropDown = {
					text = caption,
					notCheckable = true,
					func = function()
						external.frames[i]:GetScript("OnClick")(external.frames[i], "LeftButton", true)
					end
				}
				UIDropDownMenu_AddButton(tblDropDown)
			end
		end
	end
	
	-- Voice submenu
	if level == 2 and UIDROPDOWNMENU_MENU_VALUE == "Voice" then
		for id = 1, GetNumVoiceSessions() do
			local name, active = GetVoiceSessionInfo(id);
			tblDropDown = {
				text = name,
				checked = active,
				func = function (self, id)
					SetActiveVoiceChannelBySessionID(id)
				end,
				arg1 = id
			}
			UIDropDownMenu_AddButton(tblDropDown, 2)
		end
	 
		tblDropDown = {
			text = NONE,
			checked = not GetVoiceCurrentSessionID() and 1 or nil,
			func = function (self, id)
				SetActiveVoiceChannelBySessionID(id)
			end,
			arg1 = 0
		}
		UIDropDownMenu_AddButton(tblDropDown, 2)
	end
	
	-- LFG submenu
	if level == 2 and UIDROPDOWNMENU_MENU_VALUE == "LFG" then
		local mode, submode = GetLFGMode()

		-- Teleport
		if IsPartyLFG() then
			local addButton = false
			if IsInLFGDungeon() then
				tblDropDown = {
					text = TELEPORT_OUT_OF_DUNGEON,
					notCheckable = true,
					func = function()
						MiniMapLFGFrame_TeleportOut()
						ToggleDropDownMenu(1, nil, dropdown)
					end
				}
				UIDropDownMenu_AddButton(tblDropDown, 2)
			elseif GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 then
				tblDropDown = {
					text = TELEPORT_TO_DUNGEON,
					notCheckable = true,
					func = function()
						MiniMapLFGFrame_TeleportIn()
						ToggleDropDownMenu(1, nil, dropdown)
					end
				}
				UIDropDownMenu_AddButton(tblDropDown, 2)
			end
		end
		
		-- Proposals, list grp / player
		if mode == "proposal" and submode == "unaccepted" then
			tblDropDown = {
				text = ENTER_DUNGEON,
				notCheckable = true,
				func = function()
					AcceptProposal()
					ToggleDropDownMenu(1, nil, dropdown)
				end
			}
			UIDropDownMenu_AddButton(tblDropDown, 2)
			tblDropDown = {
				text = LEAVE_QUEUE,
				notCheckable = true,
				func = function()
					RejectProposal()
					ToggleDropDownMenu(1, nil, dropdown)
				end
			}
			UIDropDownMenu_AddButton(tblDropDown, 2)
		elseif mode == "queued" then
			tblDropDown = {
				text = LEAVE_QUEUE,
				notCheckable = true, 
				func = function()
					LeaveLFG()
					ToggleDropDownMenu(1, nil, dropdown)
				end,
				disabled = submode == "unempowered"
			}
			UIDropDownMenu_AddButton(tblDropDown, 2)
		elseif mode == "listed" then
			tblDropDown = {
				text = (GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0) and UNLIST_MY_GROUP or UNLIST_ME,
				notCheckable = true, 
				func = function()
					LeaveLF()
					ToggleDropDownMenu(1, nil, dropdown)
				end,
				disabled = submode == "unempowered"
			}
			UIDropDownMenu_AddButton(tblDropDown, 2)
		end
	end
	
	-- PvP submenu
	if level == 2 and UIDROPDOWNMENU_MENU_VALUE == "PvP" then
		-- ##2DO##
		-- **************************************************************************
		-- * http://wowprogramming.com/utils/xmlbrowser/live/FrameXML/PVPFrame.lua  *
		-- * MiniMapBattlefieldDropDown_Initialize()								*
		-- **************************************************************************
		for i = 1, MAX_BATTLEFIELD_QUEUES do
			local status, mapName, instanceID, levelRangeMin, levelRangeMax, teamSize, registeredMatch = GetBattlefieldStatus(i)
			if status == "queued" or status == "confirm" then
				if teamSize ~= 0 then
					tblDropDown = {
						text = ARENA_RATED_MATCH .. " " .. format(PVP_TEAMSIZE, teamSize, teamSize),
						isTitle = 1,
						notCheckable = 1
					}
				else
					tblDropDown = {
						text = ARENA_RATED_MATCH .. " " .. format(PVP_TEAMSIZE, teamSize, teamSize),
						isTitle = 1,
						notCheckable = 1
					}
				end
				
				UIDropDownMenu_AddButton(tblDropDown)
			end
		end
	end
	
end

UIDropDownMenu_Initialize(dropdown, showDropDown, "MENU")
dropdown.noResize = true

MiniMapBin:SetScript("OnClick", function()
	PlaySound("igMainMenuOptionCheckBoxOn")
	ToggleDropDownMenu(1, nil, dropdown, "MiniMapBin", 0, -5)
end)
