@@ -8,6 +8,10 @@ MINIMAP_EXPANDER_MAXSIZE = 28;
 HUNTER_TRACKING = 1;
 TOWNSFOLK = 2;
 
+GARRISON_ALERT_CONTEXT_BUILDING = 1;
+GARRISON_ALERT_CONTEXT_MISSION = 2;
+GARRISON_ALERT_CONTEXT_INVASION = 3;
+
 LFG_EYE_TEXTURES = { };
 LFG_EYE_TEXTURES["default"] = { file = "Interface\\LFGFrame\\LFG-Eye", width = 512, height = 256, frames = 29, iconSize = 64, delay = 0.1 };
 LFG_EYE_TEXTURES["raid"] = { file = "Interface\\LFGFrame\\LFR-Anim", width = 256, height = 256, frames = 16, iconSize = 64, delay = 0.05 };
@@ -387,7 +391,7 @@ end
 
 function MiniMapInstanceDifficulty_Update()
 	local _, instanceType, difficulty, _, maxPlayers, playerDifficulty, isDynamicInstance, _, instanceGroupSize = GetInstanceInfo();
-	local _, _, isHeroic, isChallengeMode = GetDifficultyInfo(difficulty);
+	local _, _, isHeroic, isChallengeMode, displayHeroic, displayMythic = GetDifficultyInfo(difficulty);
 
 	if ( IS_GUILD_GROUP ) then
 		if ( instanceGroupSize == 0 ) then
@@ -400,14 +404,20 @@ function MiniMapInstanceDifficulty_Updat
 			GuildInstanceDifficulty.emblem:SetPoint("TOPLEFT", 12, -10);
 		end
 		GuildInstanceDifficultyText:ClearAllPoints();
-		if ( isHeroic or isChallengeMode ) then
+		if ( isHeroic or isChallengeMode or displayMythic or displayHeroic ) then
 			local symbolTexture;
 			if ( isChallengeMode ) then
 				symbolTexture = GuildInstanceDifficultyChallengeModeTexture;
 				GuildInstanceDifficultyHeroicTexture:Hide();
+				GuildInstanceDifficultyMythicTexture:Hide();
+			elseif ( displayMythic ) then
+				symbolTexture = GuildInstanceDifficultyMythicTexture;
+				GuildInstanceDifficultyHeroicTexture:Hide();
+				GuildInstanceDifficultyChallengeModeTexture:Hide();
 			else
 				symbolTexture = GuildInstanceDifficultyHeroicTexture;
 				GuildInstanceDifficultyChallengeModeTexture:Hide();
+				GuildInstanceDifficultyMythicTexture:Hide();
 			end
 			-- the 1 looks a little off when text is centered
 			if ( instanceGroupSize < 10 ) then
@@ -424,6 +434,7 @@ function MiniMapInstanceDifficulty_Updat
 		else
 			GuildInstanceDifficultyHeroicTexture:Hide();
 			GuildInstanceDifficultyChallengeModeTexture:Hide();
+			GuildInstanceDifficultyMythicTexture:Hide();
 			GuildInstanceDifficultyText:SetPoint("BOTTOM", 2, 8);
 		end
 		MiniMapInstanceDifficulty:Hide();
@@ -434,18 +445,21 @@ function MiniMapInstanceDifficulty_Updat
 		MiniMapChallengeMode:Show();
 		MiniMapInstanceDifficulty:Hide();
 		GuildInstanceDifficulty:Hide();
-	elseif ( instanceType == "raid" or isHeroic ) then
+	elseif ( instanceType == "raid" or isHeroic or displayMythic or displayHeroic ) then
 		MiniMapInstanceDifficultyText:SetText(instanceGroupSize);
 		-- the 1 looks a little off when text is centered
 		local xOffset = 0;
 		if ( instanceGroupSize >= 10 and instanceGroupSize <= 19 ) then
 			xOffset = -1;
 		end
-		if ( isHeroic ) then
-			MiniMapInstanceDifficultyTexture:SetTexCoord(0, 0.25, 0.0703125, 0.4140625);
+		if ( displayMythic ) then
+			MiniMapInstanceDifficultyTexture:SetTexCoord(0.25, 0.5, 0.0703125, 0.4296875);
+			MiniMapInstanceDifficultyText:SetPoint("CENTER", xOffset, -9);
+		elseif ( isHeroic or displayHeroic ) then
+			MiniMapInstanceDifficultyTexture:SetTexCoord(0, 0.25, 0.0703125, 0.4296875);
 			MiniMapInstanceDifficultyText:SetPoint("CENTER", xOffset, -9);
 		else
-			MiniMapInstanceDifficultyTexture:SetTexCoord(0, 0.25, 0.5703125, 0.9140625);
+			MiniMapInstanceDifficultyTexture:SetTexCoord(0, 0.25, 0.5703125, 0.9296875);
 			MiniMapInstanceDifficultyText:SetPoint("CENTER", xOffset, 5);
 		end
 		MiniMapInstanceDifficulty:Show();
@@ -469,14 +483,148 @@ function GuildInstanceDifficulty_OnEnter
 	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", 8, 8);
 	GameTooltip:SetText(GUILD_GROUP, 1, 1, 1);
 	if ( xpMultiplier < 1 ) then
-		GameTooltip:AddLine(string.format(GUILD_ACHIEVEMENTS_ELIGIBLE_MINXP, numGuildRequired, maxPlayers, guildName, xpMultiplier * 100), nil, nil, nil, 1);
+		GameTooltip:AddLine(string.format(GUILD_ACHIEVEMENTS_ELIGIBLE_MINXP, numGuildRequired, maxPlayers, guildName, xpMultiplier * 100), nil, nil, nil, true);
 	elseif ( xpMultiplier > 1 ) then
-		GameTooltip:AddLine(string.format(GUILD_ACHIEVEMENTS_ELIGIBLE_MAXXP, guildName, xpMultiplier * 100), nil, nil, nil, 1);
+		GameTooltip:AddLine(string.format(GUILD_ACHIEVEMENTS_ELIGIBLE_MAXXP, guildName, xpMultiplier * 100), nil, nil, nil, true);
 	else
 		if ( instanceType == "party" and maxPlayers == 5 ) then
 			numGuildRequired = 4;
 		end
-		GameTooltip:AddLine(string.format(GUILD_ACHIEVEMENTS_ELIGIBLE, numGuildRequired, maxPlayers, guildName), nil, nil, nil, 1);
+		GameTooltip:AddLine(string.format(GUILD_ACHIEVEMENTS_ELIGIBLE, numGuildRequired, maxPlayers, guildName), nil, nil, nil, true);
 	end
 	GameTooltip:Show();
 end
+
+
+function GarrisonLandingPageMinimapButton_OnLoad(self)
+	self.pulseLocks = {};
+	self:RegisterEvent("GARRISON_SHOW_LANDING_PAGE");
+	self:RegisterEvent("GARRISON_HIDE_LANDING_PAGE");
+	self:RegisterEvent("GARRISON_BUILDING_ACTIVATABLE");
+	self:RegisterEvent("GARRISON_BUILDING_ACTIVATED");
+	self:RegisterEvent("GARRISON_ARCHITECT_OPENED");
+	self:RegisterEvent("GARRISON_MISSION_FINISHED");
+	self:RegisterEvent("GARRISON_MISSION_NPC_OPENED");
+	self:RegisterEvent("GARRISON_INVASION_AVAILABLE");
+	self:RegisterEvent("GARRISON_INVASION_UNAVAILABLE");
+	self:RegisterEvent("SHIPMENT_UPDATE");
+end
+
+function GarrisonLandingPageMinimapButton_OnEvent(self, event, ...)
+	if (event == "GARRISON_HIDE_LANDING_PAGE") then
+		self:Hide();
+	elseif (event == "GARRISON_SHOW_LANDING_PAGE") then
+		self:Show();
+	elseif ( event == "GARRISON_BUILDING_ACTIVATABLE" ) then
+		GarrisonMinimapBuilding_ShowPulse(self);
+	elseif ( event == "GARRISON_BUILDING_ACTIVATED" or event == "GARRISON_ARCHITECT_OPENED") then
+		GarrisonMinimap_HidePulse(self, GARRISON_ALERT_CONTEXT_BUILDING);
+	elseif ( event == "GARRISON_MISSION_FINISHED" ) then
+		GarrisonMinimapMission_ShowPulse(self);
+	elseif ( event == "GARRISON_MISSION_NPC_OPENED" ) then
+		GarrisonMinimap_HidePulse(self, GARRISON_ALERT_CONTEXT_MISSION);
+	elseif (event == "GARRISON_INVASION_AVAILABLE") then
+		GarrisonMinimapInvasion_ShowPulse(self);
+	elseif (event == "GARRISON_INVASION_UNAVAILABLE") then
+		GarrisonMinimap_HidePulse(self, GARRISON_ALERT_CONTEXT_INVASION);
+	elseif (event == "SHIPMENT_UPDATE") then
+		local shipmentStarted = ...;
+		if (shipmentStarted) then
+			GarrisonMinimapShipmentCreated_ShowPulse(self);
+		end
+	end
+end
+
+function GarrisonLandingPageMinimapButton_OnShow(self)
+	self.faction = UnitFactionGroup("player");
+	if ( self.faction == "Horde" ) then
+		self:GetNormalTexture():SetAtlas("GarrLanding-MinimapIcon-Horde-Up", true)
+		self:GetPushedTexture():SetAtlas("GarrLanding-MinimapIcon-Horde-Down", true)
+	else
+		self:GetNormalTexture():SetAtlas("GarrLanding-MinimapIcon-Alliance-Up", true)
+		self:GetPushedTexture():SetAtlas("GarrLanding-MinimapIcon-Alliance-Down", true)
+	end
+end
+
+function GarrisonLandingPageMinimapButton_OnClick()
+	GarrisonLandingPage_Toggle();
+end
+
+function GarrisonLandingPage_Toggle()
+	if (not GarrisonLandingPage) then
+		Garrison_LoadUI();
+	end
+	if (not GarrisonLandingPage:IsShown()) then
+		ShowUIPanel(GarrisonLandingPage);
+	else
+		HideUIPanel(GarrisonLandingPage);
+	end
+end
+
+function GarrisonMinimap_SetPulseLock(self, lock, enabled)
+	self.pulseLocks[lock] = enabled;
+end
+
+-- We play an animation on the garrison minimap icon for a number of reasons, but only want to turn the
+-- animation off if the user handles all actions related to that alert. For example if we play the animation
+-- because a building can be activated and then another because a garrison invasion has occurred,  we want to
+-- turn off the animation after they handle both the building and invasion, but not if they handle only one.
+-- We always stop the pulse when they click on the landing page icon.
+
+function GarrisonMinimap_HidePulse(self, lock)
+	GarrisonMinimap_SetPulseLock(self, lock, false);
+	local enabled = false;
+	for k, v in pairs(self.pulseLocks) do
+		if ( v ) then
+			enabled = true;
+			break;
+		end
+	end
+
+	-- If there are no other reasons to show the pulse, hide it
+	if (not enabled) then
+		GarrisonLandingPageMinimapButton.MinimapLoopPulseAnim:Stop();
+	end
+end
+
+function GarrisonMinimap_ClearPulse()
+	local self = GarrisonLandingPageMinimapButton;
+	for k, v in pairs(self.pulseLocks) do
+		self.pulseLocks[k] = false;
+	end
+	self.MinimapLoopPulseAnim:Stop();
+end
+
+function GarrisonMinimapBuilding_ShowPulse(self)
+	GarrisonMinimap_SetPulseLock(self, GARRISON_ALERT_CONTEXT_BUILDING, true);
+	self.MinimapLoopPulseAnim:Play();
+end
+
+function GarrisonMinimapMission_ShowPulse(self)
+	GarrisonMinimap_SetPulseLock(self, GARRISON_ALERT_CONTEXT_MISSION, true);
+	self.MinimapLoopPulseAnim:Play();
+end
+
+function GarrisonMinimap_Justify(text)
+	--Center justify if we're on more than one line
+	if ( text:GetNumLines() > 1 ) then
+		text:SetJustifyH("CENTER");
+	else
+		text:SetJustifyH("RIGHT");
+	end
+end
+
+function GarrisonMinimapInvasion_ShowPulse(self)
+	PlaySound("UI_Garrison_Toast_InvasionAlert");
+	self.AlertText:SetText(GARRISON_LANDING_INVASION_ALERT);
+	GarrisonMinimap_Justify(self.AlertText);
+	GarrisonMinimap_SetPulseLock(self, GARRISON_ALERT_CONTEXT_INVASION, true);
+	self.MinimapAlertAnim:Play();
+	self.MinimapLoopPulseAnim:Play();
+end
+
+function GarrisonMinimapShipmentCreated_ShowPulse(self)
+	self.AlertText:SetText(GARRISON_LANDING_SHIPMENT_STARTED_ALERT);
+	GarrisonMinimap_Justify(self.AlertText);
+	self.MinimapAlertAnim:Play();
+end