Quantcast

Armory Update (CharacterFrame Changes from KnightFrame being pulled in)

Repooc [10-28-16 - 21:15]
Armory Update (CharacterFrame Changes from KnightFrame being pulled in)
Filename
ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua
diff --git a/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua b/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua
index cfdce20..2dcbb6b 100644
--- a/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua
+++ b/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua
@@ -1,9 +1,12 @@
 if select(2, GetAddOnInfo('ElvUI_KnightFrame')) and IsAddOnLoaded('ElvUI_KnightFrame') then return end

+local _G = _G
 local SLE, T, E, L, V, P, G = unpack(select(2, ...))
 local KF, Info, Timer = unpack(ElvUI_KnightFrame)
+local ElvUI_BagModule = E:GetModule('Bags')
+local Lib_Search = LibStub('LibItemSearch-1.2-ElvUI')
 --GLOBALS: CreateFrame, UIParent, SLE_ArmoryDB, hooksecurefunc, GetInventoryItemGems
-local _G = _G
+
 local _
 local IsShiftKeyDown = IsShiftKeyDown
 local SetItemRef = SetItemRef
@@ -28,6 +31,7 @@ local C_Transmog_GetSlotInfo = C_Transmog.GetSlotInfo
 local C_TransmogCollection_GetAppearanceSourceInfo = C_TransmogCollection.GetAppearanceSourceInfo
 local C_Transmog_GetSlotVisualInfo = C_Transmog.GetSlotVisualInfo
 local C_TransmogCollection_GetIllusionSourceInfo = C_TransmogCollection.GetIllusionSourceInfo
+local AnimatedNumericFontStringMixin = AnimatedNumericFontStringMixin

 local format = format

@@ -38,7 +42,12 @@ local CA = CharacterArmory or CreateFrame('Frame', 'CharacterArmory', _G["PaperD

 local IsGemType = LE_ITEM_CLASS_GEM
 local SlotIDList = {}
-local InsetDefaultPoint = { _G["CharacterFrameInsetRight"]:GetPoint() }
+local DefaultPosition = {
+	InsetDefaultPoint = { _G["CharacterFrameInsetRight"]:GetPoint() },
+	CharacterMainHandSlot = { _G["CharacterMainHandSlot"]:GetPoint() }
+}
+local Legion_ArtifactData = {}
+local COLORSTRING_ARTIFACT = E:RGBToHex(BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].r, BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].g, BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].b)

 local linkCache = {};

@@ -87,41 +96,12 @@ do --<< Button Script >>--
 			end)
 		end
 	end
-
-
+
 	function CA:OnLeave()
 		self:SetScript('OnUpdate', nil)
 		_G["GameTooltip"]:Hide()
 	end
-
-
-	function CA:GemSocket_OnEnter()
-		_G["GameTooltip"]:SetOwner(self, 'ANCHOR_RIGHT')
-
-		local Parent = self:GetParent()
-
-		if Parent.GemItemID then
-			if T.type(Parent.GemItemID) == 'number' then
-				if T.GetItemInfo(Parent.GemItemID) then
-					_G["GameTooltip"]:SetHyperlink(T.select(2, T.GetItemInfo(Parent.GemItemID)))
-					self:SetScript('OnUpdate', nil)
-				else
-					self:SetScript('OnUpdate', CA.GemSocket_OnEnter)
-					return
-				end
-			else
-				_G["GameTooltip"]:ClearLines()
-				_G["GameTooltip"]:AddLine("|cffffffff"..Parent.GemItemID)
-			end
-		elseif Parent.GemType then
-			_G["GameTooltip"]:ClearLines()
-			_G["GameTooltip"]:AddLine("|cffffffff".._G["EMPTY_SOCKET_"..Parent.GemType])
-		end
-
-		_G["GameTooltip"]:Show()
-	end
-
-
+
 	function CA:GemSocket_OnClick(Button)
 		if CursorHasItem() then
 			CA.GemSocket_OnRecieveDrag(self)
@@ -132,12 +112,15 @@ do --<< Button Script >>--

 		if self.GemItemID then
 			local ItemName, ItemLink = T.GetItemInfo(self.GemItemID)
-
-			if not IsShiftKeyDown() then
+			if self.Socket and self.Socket.Link then
+				ItemLink = self.Socket.Link
+			end
+			if Button == 'LeftButton' and not IsShiftKeyDown() then
 				SetItemRef(ItemLink, ItemLink, 'LeftButton')
-			else
+			elseif IsShiftKeyDown() then
 				if Button == 'RightButton' then
-					SocketInventoryItem(T.GetInventorySlotInfo(self.SlotName))
+					ShowUIPanel(SocketInventoryItem(self.SlotID))
+					--SocketInventoryItem(T.GetInventorySlotInfo(self.SlotName))
 				elseif HandleModifiedItemClick(ItemLink) then
 				elseif _G["BrowseName"] and _G["BrowseName"]:IsVisible() then
 					AuctionFrameBrowse_Reset(_G["BrowseResetButton"])
@@ -147,22 +130,27 @@ do --<< Button Script >>--
 			end
 		end
 	end
-
-
+
+	local INVTYPE_ARTIFACT_RELIC = GetItemSubClassInfo(LE_ITEM_CLASS_GEM, 11)
 	function CA:GemSocket_OnRecieveDrag()
 		self = self:GetParent()

 		if CursorHasItem() then
 			local CursorType, _, ItemLink = GetCursorInfo()
-
-			if CursorType == 'item' and T.select(6, T.GetItemInfo(ItemLink)) == IsGemType then
-				SocketInventoryItem(T.GetInventorySlotInfo(self.SlotName))
-				ClickSocketButton(self.SocketNumber)
+			local _, _, _, _, _, ItemType, ItemSubType = GetItemInfo(ItemLink)
+
+			if CursorType == 'item' and T.select(6, T.GetItemInfo(ItemLink)) == AUCTION_CATEGORY_GEMS then
+				ShowUIPanel(SocketInventoryItem(self.SlotID))
+
+				if ItemSubType == INVTYPE_ARTIFACT_RELIC then
+					ArtifactFrame.PerksTab.TitleContainer:OnRelicSlotClicked(ArtifactFrame.PerksTab.TitleContainer['RelicSlot'..self.SocketNumber])
+				else
+					ClickSocketButton(self.SocketNumber)
+				end
 			end
 		end
 	end
-
-
+
 	function CA:Transmogrify_OnEnter()
 		self.Texture:SetVertexColor(1, .8, 1)

@@ -170,8 +158,7 @@ do --<< Button Script >>--
 		_G["GameTooltip"]:SetHyperlink(self.Link)
 		_G["GameTooltip"]:Show()
 	end
-
-
+
 	function CA:Transmogrify_OnLeave()
 		self.Texture:SetVertexColor(1, .5, 1)

@@ -208,10 +195,38 @@ do --<< Button Script >>--
 			HandleModifiedItemClick(self.Link)
 		end
 	end
+
+	-- function CA:GemSocket_OnEnter()
+	-- 	_G["GameTooltip"]:SetOwner(self, 'ANCHOR_RIGHT')
+
+	-- 	local Parent = self:GetParent()
+
+	-- 	if Parent.GemItemID then
+	-- 		if T.type(Parent.GemItemID) == 'number' then
+	-- 			if T.GetItemInfo(Parent.GemItemID) then
+	-- 				_G["GameTooltip"]:SetHyperlink(T.select(2, T.GetItemInfo(Parent.GemItemID)))
+	-- 				self:SetScript('OnUpdate', nil)
+	-- 			else
+	-- 				self:SetScript('OnUpdate', CA.GemSocket_OnEnter)
+	-- 				return
+	-- 			end
+	-- 		else
+	-- 			_G["GameTooltip"]:ClearLines()
+	-- 			_G["GameTooltip"]:AddLine("|cffffffff"..Parent.GemItemID)
+	-- 		end
+	-- 	elseif Parent.GemType then
+	-- 		_G["GameTooltip"]:ClearLines()
+	-- 		_G["GameTooltip"]:AddLine("|cffffffff".._G["EMPTY_SOCKET_"..Parent.GemType])
+	-- 	end
+
+	-- 	_G["GameTooltip"]:Show()
+	-- end
+
 end


 function CA:Setup_CharacterArmory()
+	local CharacterFrame_Level = CharacterModelFrame:GetFrameLevel()
 	--<< Core >>--
 	self:Point('TOPLEFT', _G["CharacterFrameInset"], 10, 20)
 	self:Point('BOTTOMRIGHT', _G["CharacterFrameInsetRight"], 'BOTTOMLEFT', -10, 5)
@@ -219,7 +234,8 @@ function CA:Setup_CharacterArmory()
 	--<< Updater >>--
 	local args
 	self:SetScript('OnEvent', function(self, Event, ...)
-		if Event == 'SOCKET_INFO_SUCCESS' or Event == 'ITEM_UPGRADE_MASTER_UPDATE' or Event == 'TRANSMOGRIFY_SUCCESS' or Event == 'PLAYER_ENTERING_WORLD' or Event == 'PLAYER_EQUIPMENT_CHANGED' then
+		if Event == 'SOCKET_INFO_SUCCESS' or Event == 'ITEM_UPGRADE_MASTER_UPDATE' or Event == 'TRANSMOGRIFY_SUCCESS' or Event == 'PLAYER_ENTERING_WORLD' then
+
 			self.GearUpdated = nil
 			self:SetScript('OnUpdate', self.ScanData)
 		elseif Event == 'UNIT_INVENTORY_CHANGED' then
@@ -229,6 +245,14 @@ function CA:Setup_CharacterArmory()
 				self.GearUpdated = nil
 				self:SetScript('OnUpdate', self.ScanData)
 			end
+		elseif Event == 'PLAYER_EQUIPMENT_CHANGED' then
+			args = ...
+			args = SlotIDList[args]
+
+			self.GearUpdated = type(self.GearUpdated) == 'table' and self.GearUpdated or {}
+			table.insert(self.GearUpdated, args)
+
+			self:SetScript('OnUpdate', self.ScanData)
 		elseif Event == 'COMBAT_LOG_EVENT_UNFILTERED' then
 			_, Event, _, _, _, _, _, _, args = ...

@@ -250,7 +274,7 @@ function CA:Setup_CharacterArmory()
 		elseif Info.CharacterArmory_Activate and frameType == "PaperDollFrame" then
 			_G["CharacterFrameInsetRight"]:SetPoint('TOPLEFT', _G["CharacterFrameInset"], 'TOPRIGHT', 110, 0)
 		else
-			_G["CharacterFrameInsetRight"]:SetPoint(T.unpack(InsetDefaultPoint))
+			_G["CharacterFrameInsetRight"]:SetPoint(T.unpack(DefaultPosition.InsetDefaultPoint))
 		end
 	end)
 	hooksecurefunc('PaperDollFrame_SetLevel', function()
@@ -278,6 +302,13 @@ function CA:Setup_CharacterArmory()

 	--<< Change Model Frame's frameLevel >>--
 	_G["CharacterModelFrame"]:SetFrameLevel(self:GetFrameLevel() + 2)
+
+	--<< Average Item Level >>--
+	-- KF:TextSetting(self, nil, { Tag = 'AverageItemLevel', FontSize = 12 }, 'BOTTOM', CharacterModelFrame, 'TOP', 0, 14)
+	-- local function ValueColorUpdate()
+	-- 	self.AverageItemLevel:SetText(KF:Color_Value(STAT_AVERAGE_ITEM_LEVEL)..' : '..format('%.2f', select(2, GetAverageItemLevel())))
+	-- end
+	-- E.valueColorUpdateFuncs[ValueColorUpdate] = true

 	-- Create each equipment slots gradation, text, gem socket icon.
 	local Slot
@@ -363,7 +394,7 @@ function CA:Setup_CharacterArmory()
 				Slot["Socket"..i]:SetBackdropBorderColor(0, 0, 0)
 				Slot["Socket"..i]:SetFrameLevel(_G["CharacterModelFrame"]:GetFrameLevel() + 1)

-				Slot["Socket"..i].SlotName = SlotName
+				Slot["Socket"..i].SlotID = Slot.ID
 				Slot["Socket"..i].SocketNumber = i

 				Slot["Socket"..i].Socket = CreateFrame('Button', nil, Slot["Socket"..i])
@@ -459,16 +490,205 @@ function CA:Setup_CharacterArmory()
 		_G["PawnUI_InventoryPawnButton"]:SetFrameLevel(_G["CharacterModelFrame"]:GetFrameLevel() + 1)
 	end

+	do -- Legion : Artifact Weapon Monitor
+		self.ArtifactMonitor = CreateFrame('Frame', nil, self)
+		self.ArtifactMonitor:SetFrameLevel(CharacterFrame_Level + 2)
+		self.ArtifactMonitor:Height(41)
+		self.ArtifactMonitor:Point('RIGHT', CharacterTrinket1Slot)
+		self.ArtifactMonitor:SetScript('OnShow', function() CA:LegionArtifactMonitor_SearchPowerItem() end)
+		self.ArtifactMonitor:SetScript('OnUpdate', function(_, Elapsed)
+			self.ArtifactMonitor.CurrentPower:UpdateAnimatedValue(Elapsed)
+
+			if not self.ArtifactMonitor.UpdateData then
+				CA:LegionArtifactMonitor_UpdateData()
+			end
+
+			if not self.ArtifactMonitor.SearchPowerItem then
+				CA:LegionArtifactMonitor_SearchPowerItem()
+			end
+		end)
+		self.ArtifactMonitor:SetScript('OnEvent', function(_, Event)
+			if Event == 'ARTIFACT_UPDATE' or Event == 'ARTIFACT_XP_UPDATE' then
+				self.ArtifactMonitor.UpdateData = nil
+			elseif Event == 'BAG_UPDATE' or Event == 'PLAYER_ENTERING_WORLD' then
+				self.ArtifactMonitor.SearchPowerItem = nil
+			end
+		end)
+
+		-- Gradation
+		self.ArtifactMonitor.Gradation = self.ArtifactMonitor:CreateTexture(nil, 'OVERLAY')
+		self.ArtifactMonitor.Gradation:Width(130)
+		self.ArtifactMonitor.Gradation:Point('TOPLEFT', E.Border, -E.Border)
+		self.ArtifactMonitor.Gradation:Point('BOTTOMLEFT', E.Border, E.Border)
+		self.ArtifactMonitor.Gradation:SetTexture('Interface\\AddOns\\ElvUI_KnightFrame\\Modules\\Armory\\Media\\Graphics\\Gradation')
+		self.ArtifactMonitor.Gradation:SetTexCoord(0, 1, 0, 1)
+
+		-- Power StatusBar
+		self.ArtifactMonitor.BarBorder = CreateFrame('Frame', nil, self.ArtifactMonitor)
+		self.ArtifactMonitor.BarBorder:Height(5)
+		self.ArtifactMonitor.BarBorder:Point('BOTTOMLEFT', 40, 4 + E.Border)
+		self.ArtifactMonitor.BarBorder:Point('RIGHT')
+		self.ArtifactMonitor.BarBorder:SetBackdrop({
+			bgFile = E.media.normTex,
+			edgeFile = E.media.blankTex,
+			tile = false, tileSize = 0, edgeSize = E.mult,
+			insets = { left = 0, right = 0, top = 0, bottom = 0}
+		})
+		self.ArtifactMonitor.BarBorder:SetBackdropColor(.25, .25, .25)
+		self.ArtifactMonitor.BarBorder:SetBackdropBorderColor(0, 0, 0)
+
+		self.ArtifactMonitor.Bar = CreateFrame('StatusBar', nil, self.ArtifactMonitor.BarBorder, 'AnimatedStatusBarTemplate')
+		self.ArtifactMonitor.Bar:SetFrameLevel(CharacterFrame_Level + 4)
+		self.ArtifactMonitor.Bar:SetStatusBarTexture(E.media.blankTex)
+		self.ArtifactMonitor.Bar:SetStatusBarColor(BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].r, BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].g, BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].b)
+		self.ArtifactMonitor.Bar:SetInside()
+		self.ArtifactMonitor.Bar:EnableMouse(false)
+		self.ArtifactMonitor.Bar.SparkBurstMove:Height(3)
+		self.ArtifactMonitor.BarExpected = CreateFrame('StatusBar', nil, self.ArtifactMonitor.BarBorder)
+		self.ArtifactMonitor.BarExpected:SetFrameLevel(CharacterFrame_Level + 3)
+		self.ArtifactMonitor.BarExpected:SetStatusBarTexture(E.media.blankTex)
+		self.ArtifactMonitor.BarExpected:SetStatusBarColor(unpack(E.media.rgbvaluecolor))
+		self.ArtifactMonitor.BarExpected:SetInside()
+		self.ArtifactMonitor.BarExpected:EnableMouse(false)
+		E:Flash(self.ArtifactMonitor.BarExpected, 1, true)
+
+		-- Gem Socket
+		for i = 1, C_ArtifactUI.GetEquippedArtifactNumRelicSlots() or 3 do
+			self.ArtifactMonitor['Socket'..i] = CreateFrame('Frame', nil, self.ArtifactMonitor)
+			self.ArtifactMonitor['Socket'..i]:Size(E.db.sle.Armory.Character.Gem.SocketSize)
+			self.ArtifactMonitor['Socket'..i]:SetBackdrop({
+				bgFile = E.media.blankTex,
+				edgeFile = E.media.blankTex,
+				tile = false, tileSize = 0, edgeSize = E.mult,
+				insets = { left = 0, right = 0, top = 0, bottom = 0}
+			})
+			self.ArtifactMonitor['Socket'..i]:SetBackdropColor(0, 0, 0, 1)
+			self.ArtifactMonitor['Socket'..i]:SetBackdropBorderColor(0, 0, 0)
+			self.ArtifactMonitor['Socket'..i]:SetFrameLevel(CharacterFrame_Level + 4)
+
+			self.ArtifactMonitor['Socket'..i].SlotID = 16
+			self.ArtifactMonitor['Socket'..i].SocketNumber = i
+
+			self.ArtifactMonitor['Socket'..i].Socket = CreateFrame('Button', nil, self.ArtifactMonitor['Socket'..i])
+			self.ArtifactMonitor['Socket'..i].Socket:SetBackdrop({
+				bgFile = E.media.blankTex,
+				edgeFile = E.media.blankTex,
+				tile = false, tileSize = 0, edgeSize = E.mult,
+				insets = { left = 0, right = 0, top = 0, bottom = 0}
+			})
+			self.ArtifactMonitor['Socket'..i].Socket:SetInside()
+			self.ArtifactMonitor['Socket'..i].Socket:SetFrameLevel(CharacterFrame_Level + 4)
+			self.ArtifactMonitor['Socket'..i].Socket:RegisterForClicks('AnyUp', 'RightButtonDown')
+			self.ArtifactMonitor['Socket'..i].Socket:SetScript('OnEnter', self.OnEnter)
+			self.ArtifactMonitor['Socket'..i].Socket:SetScript('OnLeave', self.OnLeave)
+			self.ArtifactMonitor['Socket'..i].Socket:SetScript('OnClick', self.GemSocket_OnClick)
+			self.ArtifactMonitor['Socket'..i].Socket:SetScript('OnReceiveDrag', self.GemSocket_OnRecieveDrag)
+
+			self.ArtifactMonitor['Socket'..i].Texture = self.ArtifactMonitor['Socket'..i].Socket:CreateTexture(nil, 'OVERLAY')
+			self.ArtifactMonitor['Socket'..i].Texture:SetTexCoord(.1, .9, .1, .9)
+			self.ArtifactMonitor['Socket'..i].Texture:SetInside()
+
+			self.ArtifactMonitor['Socket'..i]:Point('CENTER', self.MainHandSlot['Socket'..i])
+		end
+		self.ArtifactMonitor.SocketWarning = CreateFrame('Button', nil, self.ArtifactMonitor)
+		self.ArtifactMonitor.SocketWarning:Size(E.db.sle.Armory.Character.Enchant.WarningSize)
+		self.ArtifactMonitor.SocketWarning:RegisterForClicks('AnyUp')
+		self.ArtifactMonitor.SocketWarning.Texture = self.ArtifactMonitor.SocketWarning:CreateTexture(nil, 'OVERLAY')
+		self.ArtifactMonitor.SocketWarning.Texture:SetInside()
+		self.ArtifactMonitor.SocketWarning.Texture:SetTexture('Interface\\AddOns\\ElvUI_KnightFrame\\Modules\\Armory\\Media\\Graphics\\Warning-Small')
+		self.ArtifactMonitor.SocketWarning:SetScript('OnEnter', self.OnEnter)
+		self.ArtifactMonitor.SocketWarning:SetScript('OnLeave', self.OnLeave)
+		self.ArtifactMonitor.SocketWarning:Point('RIGHT', self.ArtifactMonitor.Socket3, 'LEFT', -3, 0)
+
+		-- Current Artifact Power
+		KF:TextSetting(self.ArtifactMonitor, ARTIFACT_POWER..' : ', { Tag = 'PowerTitle',
+			Font = E.db.sle.Armory.Character.Enchant.Font,
+			FontSize = 9,
+			FontStyle = E.db.sle.Armory.Character.Enchant.FontStyle,
+			directionH = 'LEFT'
+		}, 'BOTTOMLEFT', self.ArtifactMonitor.BarBorder, 'TOPLEFT', 0, 4 + E.Border)
+
+		KF:TextSetting(self.ArtifactMonitor, nil, { Tag = 'CurrentPower',
+			Font = E.db.sle.Armory.Character.Enchant.Font,
+			FontSize = 9,
+			FontStyle = E.db.sle.Armory.Character.Enchant.FontStyle,
+			directionH = 'LEFT'
+		}, 'LEFT', self.ArtifactMonitor.PowerTitle, 'RIGHT', 0, 0)
+		Mixin(self.ArtifactMonitor.CurrentPower, AnimatedNumericFontStringMixin)
+		self.ArtifactMonitor.CurrentPower:SetTextColor(BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].r, BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].g, BAG_ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT].b)
+
+		-- Available Artifact Power
+		KF:TextSetting(self.ArtifactMonitor.BarExpected, nil, { Tag = 'AvailablePower',
+			Font = E.db.sle.Armory.Character.Enchant.Font,
+			FontSize = 9,
+			FontStyle = E.db.sle.Armory.Character.Enchant.FontStyle,
+			directionH = 'LEFT'
+		}, 'TOPRIGHT', self.ArtifactMonitor.BarBorder, 'BOTTOMRIGHT', 0, -1)
+
+		-- Artifact Traits Rank
+		KF:TextSetting(self.ArtifactMonitor, nil, { Tag = 'TraitRank',
+			Font = E.db.sle.Armory.Character.Level.Font,
+			FontSize = 9,
+			FontStyle = E.db.sle.Armory.Character.Level.FontStyle,
+			directionH = 'LEFT'
+		}, 'BOTTOMLEFT', self.ArtifactMonitor.PowerTitle, 'TOPLEFT', 0, 3)
+
+		-- Require Artifact Power
+		KF:TextSetting(self.ArtifactMonitor, nil, { Tag = 'RequirePower',
+			Font = E.db.sle.Armory.Character.Enchant.Font,
+			FontSize = 9,
+			FontStyle = E.db.sle.Armory.Character.Enchant.FontStyle,
+			directionH = 'RIGHT'
+		}, 'BOTTOM', self.ArtifactMonitor.BarBorder, 'TOP', 0, 4 + E.Border)
+		self.ArtifactMonitor.RequirePower:Point('RIGHT', self.ArtifactMonitor)
+		self.ArtifactMonitor.CurrentPower:Point('RIGHT', self.ArtifactMonitor.RequirePower, 'LEFT', -4, 0)
+
+		-- Message
+		KF:TextSetting(self.ArtifactMonitor.BarExpected, nil, { Tag = 'Message',
+			Font = E.db.sle.Armory.Character.Level.Font,
+			FontSize = 11,
+			FontStyle = E.db.sle.Armory.Character.Level.FontStyle,
+			directionH = 'RIGHT'
+		}, 'BOTTOMRIGHT', self.ArtifactMonitor.RequirePower, 'TOPRIGHT', 0, 2)
+
+		self.ArtifactMonitor.AddPower = CreateFrame('Frame', nil, self.ArtifactMonitor)
+		self.ArtifactMonitor.AddPower:Point('BOTTOMLEFT', 39, 0)
+		self.ArtifactMonitor.AddPower:Point('TOPRIGHT')
+
+		self.ArtifactMonitor.AddPower.Texture = self.ArtifactMonitor.AddPower:CreateTexture(nil, 'OVERLAY')
+		self.ArtifactMonitor.AddPower.Texture:Size(15)
+		self.ArtifactMonitor.AddPower.Texture:SetTexture('Interface\\GLUES\\CharacterSelect\\Glue-Char-Up')
+		self.ArtifactMonitor.AddPower.Texture:Point('LEFT', self.ArtifactMonitor.TraitRank, 'RIGHT', 1, 0)
+		self.ArtifactMonitor.AddPower.Texture:Hide()
+
+		self.ArtifactMonitor.AddPower.Button = CreateFrame('Button', nil, self.ArtifactMonitor.AddPower)
+		self.ArtifactMonitor.AddPower.Button:SetInside()
+		self.ArtifactMonitor.AddPower.Button:SetFrameLevel(CharacterFrame_Level + 6)
+		self.ArtifactMonitor.AddPower.Button:SetScript('OnEnter', self.OnEnter)
+		self.ArtifactMonitor.AddPower.Button:SetScript('OnLeave', self.OnLeave)
+		self.ArtifactMonitor.AddPower.Button:SetScript('OnClick', function()
+			if E.private.bags.enable then
+				OpenAllBags()
+				ElvUI_ContainerFrameEditBox:SetText('POWER')
+				self.ArtifactMonitor.NowSearchingPowerItem = true
+			end
+		end)
+
+		self.ArtifactMonitor.ScanTT = CreateFrame('GameTooltip', 'Knight_CharacterArmory_ArtifactScanTT', nil, 'GameTooltipTemplate')
+		self.ArtifactMonitor.ScanTT:SetOwner(UIParent, 'ANCHOR_NONE')
+
+		self.ArtifactMonitor:Hide()
+
+		if E.private.bags.enable then
+			hooksecurefunc(ElvUI_BagModule, 'CloseBags', function() self:LegionArtifactMonitor_ClearPowerItemSearching() end)
+			ElvUI_ContainerFrame:HookScript('OnHide', function() self:LegionArtifactMonitor_ClearPowerItemSearching() end)
+		end
+	end
+
 	self.Setup_CharacterArmory = nil
 end

-local function DCS_Check()
-	if _G["DCS_ExpandCheck"] then
-		_G["DCS_ExpandCheck"]:SetFrameLevel(_G["CharacterModelFrame"]:GetFrameLevel() + 2)
-		DCS_Check = nil
-	end
-end
-function CA:ScanData(...)
+function CA:ScanData()
 	self.NeedUpdate = nil

 	if not self.DurabilityUpdated then
@@ -481,13 +701,38 @@ function CA:ScanData(...)

 	if not self.NeedUpdate and self:IsShown() then
 		self:SetScript('OnUpdate', nil)
+		self:Update_Display(true)
 	elseif self.NeedUpdate then
 		self:SetScript('OnUpdate', self.ScanData)
 	end
-
-	if DCS_Check then DCS_Check() end
 end

+-- function CA:ScanData(...)
+-- 	self.NeedUpdate = nil
+
+-- 	if not self.DurabilityUpdated then
+-- 		self.NeedUpdate = self:Update_Durability() or self.NeedUpdate
+-- 	end
+
+-- 	if self.GearUpdated ~= true then
+-- 		self.NeedUpdate = self:Update_Gear() or self.NeedUpdate
+-- 	end
+
+-- 	if not self.NeedUpdate and self:IsShown() then
+-- 		self:SetScript('OnUpdate', nil)
+-- 	elseif self.NeedUpdate then
+-- 		self:SetScript('OnUpdate', self.ScanData)
+-- 	end
+
+-- 	if DCS_Check then DCS_Check() end
+-- end
+
+-- local function DCS_Check()
+-- 	if _G["DCS_ExpandCheck"] then
+-- 		_G["DCS_ExpandCheck"]:SetFrameLevel(_G["CharacterModelFrame"]:GetFrameLevel() + 2)
+-- 		DCS_Check = nil
+-- 	end
+-- end

 function CA:Update_Durability()
 	local Slot, R, G, B, CurrentDurability, MaxDurability
@@ -514,7 +759,6 @@ function CA:Update_Durability()
 	self.DurabilityUpdated = true
 end

-
 function CA:ClearTooltip(Tooltip)
 	local TooltipName = Tooltip:GetName()

@@ -526,7 +770,7 @@ function CA:ClearTooltip(Tooltip)
 	end
 end

-
+local Artifact_ItemID, Artifact_Power, Artifact_Rank, LockedReason
 function CA:Update_Gear()
 	--[[ Get Player Profession

@@ -540,8 +784,10 @@ function CA:Update_Gear()
 	if Prof2 and Info.Armory_Constants.ProfessionList[Prof2] then self.PlayerProfession[(Info.Armory_Constants.ProfessionList[Prof2].Key)] = Prof2_Level end
 	]]
 	local ErrorDetected, NeedUpdate, NeedUpdateList, R, G, B
-	local Slot, ItemLink, ItemData, ItemRarity, BasicItemLevel, TrueItemLevel, ItemUpgradeID, ItemType, ItemTexture, UsableEffect, CurrentLineText, GemID, GemCount_Default, GemCount_Enable, GemCount_Now, GemCount, IsTransmogrified
-
+	local Slot, ItemLink, ItemData, BasicItemLevel, TrueItemLevel, ItemUpgradeID, CurrentUpgrade, MaxUpgrade, ItemType, UsableEffect, CurrentLineText, GemID, GemLink, GemTexture, GemCount_Default, GemCount_Now, GemCount, IsTransmogrified
+
+	Artifact_ItemID, _, _, _, Artifact_Power, Artifact_Rank = C_ArtifactUI.GetEquippedArtifactInfo()
+
 	for _, SlotName in T.pairs(T.type(self.GearUpdated) == 'table' and self.GearUpdated or Info.Armory_Constants.GearList) do
 		Slot = self[SlotName]
 		ItemLink = T.GetInventoryItemLink('player', Slot.ID)
@@ -550,14 +796,18 @@ function CA:Update_Gear()

 		if not (SlotName == 'ShirtSlot' or SlotName == 'TabardSlot') then
 			do --<< Clear Setting >>--
-				NeedUpdate, TrueItemLevel, UsableEffect, ItemUpgradeID, ItemType, ItemTexture, IsTransmogrified = nil, nil, nil, nil, nil, nil, nil
+				NeedUpdate, TrueItemLevel, UsableEffect, ItemUpgradeID, CurrentUpgrade, MaxUpgrade, ItemType, ItemTexture, IsTransmogrified = nil, nil, nil, nil, nil, nil, nil, nil, nil

+				Slot.ItemRarity = nil
 				Slot.ItemLevel:SetText(nil)
 				Slot.IsEnchanted = nil
 				Slot.ItemEnchant:SetText(nil)
+				Slot.ItemEnchant.Message = nil
+				Slot.GemCount_Enable = nil
 				for i = 1, MAX_NUM_SOCKETS do
 					Slot["Socket"..i].Texture:SetTexture(nil)
 					Slot["Socket"..i].Socket.Link = nil
+					Slot["Socket"..i].Socket.Message = nil
 					Slot["Socket"..i].GemItemID = nil
 					Slot["Socket"..i].GemType = nil
 					Slot["Socket"..i]:Hide()
@@ -583,100 +833,184 @@ function CA:Update_Gear()

 			if ItemLink then
 				if not ItemLink:find('%[%]') then -- sometimes itemLink is malformed so we need to update when crashed
-					do --<< Gem Parts >>--
-						ItemData = { T.split(':', ItemLink) }

-						for i = 1, #ItemData do
-							if i == 4 or i == 5 or i ==6 or i ==7 then
-								ItemData.FixedLink = (ItemData.FixedLink and ItemData.FixedLink..':' or '')..0
-							else
-								ItemData.FixedLink = (ItemData.FixedLink and ItemData.FixedLink..':' or '')..ItemData[i]
-							end
+					ItemData = { T.split(':', ItemLink) }
+
+					_, _, Slot.ItemRarity, BasicItemLevel, _, _, _, _, ItemType = T.GetItemInfo(ItemLink)
+					R, G, B = T.GetItemQualityColor(Slot.ItemRarity)
+
+					--<< Legion - Artifact Weapon Detection >>--
+					if (SlotName == 'MainHandSlot' or SlotName == 'SecondaryHandSlot') then
+						if Artifact_ItemID and Artifact_ItemID == tonumber(ItemData[2]) then
+							Legion_ArtifactData.MajorSlot = SlotName
+							Legion_ArtifactData.ItemID = Artifact_ItemID
+							Legion_ArtifactData.Power = Artifact_Power
+							Legion_ArtifactData.Rank = Artifact_Rank
+						elseif not Artifact_ItemID then
+							wipe(Legion_ArtifactData)
 						end
-
-						self:ClearTooltip(self.ScanTT)
-						self.ScanTT:SetHyperlink(ItemData.FixedLink)
-
+
+						ArtifactMonitor_RequireUpdate = true
+					end
+
+					do --<< Gem Parts >>--
 						GemCount_Default, GemCount_Now, GemCount = 0, 0, 0
-
-						-- First, Counting default gem sockets
-						for i = 1, MAX_NUM_SOCKETS do
-							ItemTexture = _G["Knight_CharacterArmory_ScanTTTexture"..i]:GetTexture()

-							if ItemTexture and ItemTexture:find('Interface\\ItemSocketingFrame\\') then
-								GemCount_Default = GemCount_Default + 1
-								Slot["Socket"..GemCount_Default].GemType = T.upper(T.gsub(ItemTexture, 'Interface\\ItemSocketingFrame\\UI--EmptySocket--', ''))
+						-- First, Counting default gem sockets
+						if Legion_ArtifactData.ItemID and Legion_ArtifactData.MajorSlot == SlotName then
+							Slot.GemCount_Enable = C_ArtifactUI.GetEquippedArtifactNumRelicSlots()
+
+							self:ClearTooltip(self.ScanTT)
+							self.ScanTT:SetInventoryItem('player', Slot.ID)
+
+							for i = 1, Slot.GemCount_Enable do
+								LockedReason, _, GemTexture, GemLink = C_ArtifactUI.GetEquippedArtifactRelicInfo(i)
+								GemID = Info.Armory_Constants.ArtifactType[Legion_ArtifactData.ItemID][i]
+								R, G, B = unpack(Info.Armory_Constants.GemColor[GemID])
+
+								if not LockedReason then
+									GemCount_Now = GemCount_Now + 1
+
+									self.ArtifactMonitor['Socket'..i].Texture:SetTexture(GemTexture)
+									self.ArtifactMonitor['Socket'..i].Socket.Link = GemLink
+									self.ArtifactMonitor['Socket'..i].Socket.Message = nil
+									self.ArtifactMonitor['Socket'..i].GemItemID = ItemData[i + 3] ~= '' and tonumber(ItemData[i + 3]) or 0
+									self.ArtifactMonitor['Socket'..i].Socket:SetBackdropColor(R, G, B, .5)
+
+									Slot['Socket'..i].Texture:SetTexture(GemTexture)
+									Slot['Socket'..i].Socket.Link = GemLink
+									Slot['Socket'..i].Socket.Message = nil
+									Slot['Socket'..i].GemItemID = ItemData[i + 3] ~= '' and tonumber(ItemData[i + 3]) or 0
+									Slot['Socket'..i].Socket:SetBackdropColor(R, G, B, .5)
+
+									if GemTexture then
+										GemCount = GemCount + 1
+									else
+										self.ArtifactMonitor['Socket'..i].Socket.Message = format(RELIC_TOOLTIP_TYPE, E:RGBToHex(R, G, B).._G['RELIC_SLOT_TYPE_'..GemID])
+										Slot['Socket'..i].Socket.Message = format(RELIC_TOOLTIP_TYPE, E:RGBToHex(R, G, B).._G['RELIC_SLOT_TYPE_'..GemID])
+									end
+								else
+									Slot.GemCount_Enable = Slot.GemCount_Enable - 1
+									self.ArtifactMonitor['Socket'..i].Socket.Message = format(LOCKED_RELIC_TOOLTIP_TITLE, E:RGBToHex(R, G, B).._G['RELIC_SLOT_TYPE_'..GemID])..'|r|n'..LockedReason
+									self.ArtifactMonitor['Socket'..i].Socket:SetBackdropColor(0, 0, 0, .5)
+
+									Slot['Socket'..i].Socket.Message = format(LOCKED_RELIC_TOOLTIP_TITLE, E:RGBToHex(R, G, B).._G['RELIC_SLOT_TYPE_'..GemID])..'|r|n'..LockedReason
+									Slot['Socket'..i].Socket:SetBackdropColor(0, 0, 0, .5)
+								end
+
+								self.ArtifactMonitor['Socket'..i].Socket:SetBackdropBorderColor(R, G, B)
+								self.ArtifactMonitor['Socket'..i].GemType = GemID
+
+								Slot['Socket'..i].Socket:SetBackdropBorderColor(R, G, B)
+								Slot['Socket'..i].GemType = GemID
+								if E.db.sle.Armory.Character.Gem.Display == 'Always' or E.db.sle.Armory.Character.Gem.Display == 'MouseoverOnly' and Slot.Mouseovered or E.db.sle.Armory.Character.Gem.Display == 'MissingOnly' then
+									Slot['Socket'..i]:Show()
+									Slot.SocketWarning:Point(Slot.Direction, Slot['Socket'..i], (Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 0)
+								end
+
+								--<< Notice Missing >>--
+								if E.db.sle.Armory.Character.NoticeMissing ~= false and Slot.GemCount_Enable > GemCount_Now or Slot.GemCount_Enable > GemCount or GemCount_Now > GemCount then
+									self.ArtifactMonitor.SocketWarning.Message = '|cffff5678'..(GemCount_Now - GemCount)..'|r '..L['Empty Socket']
+									self.ArtifactMonitor.SocketWarning:Show()
+								else
+									self.ArtifactMonitor.SocketWarning.Message = nil
+									self.ArtifactMonitor.SocketWarning:Hide()
+								end
 							end
-						end
-
-						-- Second, Check if slot's item enable to adding a socket
-						GemCount_Enable = GemCount_Default
-						--[[
-						if (SlotName == 'WaistSlot' and UnitLevel('player') >= 70) or -- buckle
-							((SlotName == 'WristSlot' or SlotName == 'HandsSlot') and self.PlayerProfession.BlackSmithing and self.PlayerProfession.BlackSmithing >= 550) then -- BlackSmith
-
-							GemCount_Enable = GemCount_Enable + 1
-							Slot["Socket'..GemCount_Enable].GemType = 'PRISMATIC'
-						end
-						]]
+						else
+							ItemData.FixedLink = ItemData[1]

-						self:ClearTooltip(self.ScanTT)
-						self.ScanTT:SetInventoryItem('player', Slot.ID)
+							for i = 2, #ItemData do
+								if i == 4 or i == 5 or i == 6 or i == 7 then
+									ItemData.FixedLink = ItemData.FixedLink..':'..0
+								else
+									ItemData.FixedLink = ItemData.FixedLink..':'..ItemData[i]
+								end
+							end

-						-- Apply current item's gem setting
-						for i = 1, MAX_NUM_SOCKETS do
-							ItemTexture = _G["Knight_CharacterArmory_ScanTTTexture"..i]:GetTexture()
+							self:ClearTooltip(self.ScanTT)
+							self.ScanTT:SetHyperlink(ItemData.FixedLink)

-							local _, GemLink = GetItemGem(ItemLink, i)
-							GemID = ItemData[i + 3]
+							-- First, Counting default gem sockets
+							for i = 1, MAX_NUM_SOCKETS do
+								GemTexture = _G["Knight_CharacterArmory_ScanTTTexture"..i]:GetTexture()
+
+								if GemTexture and GemTexture:find('Interface\\ItemSocketingFrame\\') then
+									GemCount_Default = GemCount_Default + 1
+									Slot["Socket"..GemCount_Default].GemType = T.upper(T.gsub(GemTexture, 'Interface\\ItemSocketingFrame\\UI--EmptySocket--', ''))
+								end
+							end
+
+							-- Second, Check if slot's item enable to adding a socket
+							Slot.GemCount_Enable = GemCount_Default
+							--[[
+							if (SlotName == 'WaistSlot' and UnitLevel('player') >= 70) or -- buckle
+								((SlotName == 'WristSlot' or SlotName == 'HandsSlot') and self.PlayerProfession.BlackSmithing and self.PlayerProfession.BlackSmithing >= 550) then -- BlackSmith

-							if Slot["Socket"..i].GemType and Info.Armory_Constants.GemColor[Slot["Socket"..i].GemType] then
-								R, G, B = T.unpack(Info.Armory_Constants.GemColor[Slot["Socket"..i].GemType])
-								Slot["Socket"..i].Socket:SetBackdropColor(R, G, B, .5)
-								Slot["Socket"..i].Socket:SetBackdropBorderColor(R, G, B)
-							else
-								Slot["Socket"..i].Socket:SetBackdropColor(1, 1, 1, .5)
-								Slot["Socket"..i].Socket:SetBackdropBorderColor(1, 1, 1)
+								GemCount_Enable = GemCount_Enable + 1
+								Slot["Socket'..GemCount_Enable].GemType = 'PRISMATIC'
 							end
+							]]

-							if ItemTexture or GemLink then
-								if E.db.sle.Armory.Character.Gem.Display == 'Always' or E.db.sle.Armory.Character.Gem.Display == 'MouseoverOnly' and Slot.Mouseovered or E.db.sle.Armory.Character.Gem.Display == 'MissingOnly' then
-									Slot["Socket"..i]:Show()
-									Slot.SocketWarning:Point(Slot.Direction, Slot["Socket"..i], (Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 0)
+							self:ClearTooltip(self.ScanTT)
+							self.ScanTT:SetInventoryItem('player', Slot.ID)
+
+							-- Apply current item's gem setting
+							for i = 1, MAX_NUM_SOCKETS do
+								GemTexture = _G['Knight_CharacterArmory_ScanTTTexture'..i]:GetTexture()
+								GemID = ItemData[i + 3] ~= '' and tonumber(ItemData[i + 3]) or 0
+								_, GemLink = GetItemGem(ItemLink, i)
+
+								if Slot["Socket"..i].GemType and Info.Armory_Constants.GemColor[Slot["Socket"..i].GemType] then
+									R, G, B = T.unpack(Info.Armory_Constants.GemColor[Slot["Socket"..i].GemType])
+									Slot["Socket"..i].Socket:SetBackdropColor(R, G, B, .5)
+									Slot["Socket"..i].Socket:SetBackdropBorderColor(R, G, B)
+								else
+									Slot["Socket"..i].Socket:SetBackdropColor(1, 1, 1, .5)
+									Slot["Socket"..i].Socket:SetBackdropBorderColor(1, 1, 1)
 								end

-								GemCount_Now = GemCount_Now + 1
+								if GemTexture or GemLink then
+									if E.db.sle.Armory.Character.Gem.Display == 'Always' or E.db.sle.Armory.Character.Gem.Display == 'MouseoverOnly' and Slot.Mouseovered or E.db.sle.Armory.Character.Gem.Display == 'MissingOnly' then
+										Slot["Socket"..i]:Show()
+										Slot.SocketWarning:Point(Slot.Direction, Slot["Socket"..i], (Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 0)
+									end
+
+									GemCount_Now = GemCount_Now + 1

-								if GemID then
-									GemCount = GemCount + 1
-									Slot["Socket"..i].GemItemID = GemID
-									Slot["Socket"..i].Socket.Link = GemLink
+									if GemID ~= 0 then
+										GemCount = GemCount + 1
+										Slot["Socket"..i].GemItemID = GemID
+										Slot["Socket"..i].Socket.Link = GemLink

-									ItemTexture = T.select(10, T.GetItemInfo(GemID))
+										GemTexture = T.select(10, T.GetItemInfo(GemID))

-									if ItemTexture then
-										Slot["Socket"..i].Texture:SetTexture(ItemTexture)
+										if GemTexture then
+											Slot["Socket"..i].Texture:SetTexture(GemTexture)
+										else
+											NeedUpdate = true
+										end
 									else
-										NeedUpdate = true
+											Slot['Socket'..i].Socket.Message = '|cffffffff'.._G['EMPTY_SOCKET_'..Slot['Socket'..i].GemType]
 									end
 								end
 							end
-						end

-						--print(SlotName..' : ', GemCount_Default, GemCount_Enable, GemCount_Now, GemCount)
-						if GemCount_Now < GemCount_Default then -- ItemInfo not loaded
-							NeedUpdate = true
+							--print(SlotName..' : ', GemCount_Default, GemCount_Enable, GemCount_Now, GemCount)
+							if GemCount_Now < GemCount_Default then -- ItemInfo not loaded
+								NeedUpdate = true
+							end
 						end
 					end
-
-					_, _, ItemRarity, _, _, _, _, _, ItemType, ItemTexture = T.GetItemInfo(ItemLink)
-					TrueItemLevel, _, BasicItemLevel = T.GetDetailedItemLevelInfo(ItemLink)
-					R, G, B = T.GetItemQualityColor(ItemRarity)

 					--<< Enchant Parts >>--
 					for i = 1, self.ScanTT:NumLines() do
 						CurrentLineText = _G["Knight_CharacterArmory_ScanTTTextLeft"..i]:GetText()
-						if CurrentLineText:find(Info.Armory_Constants.EnchantKey) then
+						if CurrentLineText:find(Info.Armory_Constants.ItemLevelKey_Alt) then
+								TrueItemLevel = T.tonumber(CurrentLineText:match(Info.Armory_Constants.ItemLevelKey_Alt))
+						elseif CurrentLineText:find(Info.Armory_Constants.ItemLevelKey) then
+							TrueItemLevel = T.tonumber(CurrentLineText:match(Info.Armory_Constants.ItemLevelKey))
+						elseif CurrentLineText:find(Info.Armory_Constants.EnchantKey) then
 							if E.db.sle.Armory.Character.Enchant.Display ~= 'Hide' then
 								CurrentLineText = CurrentLineText:match(Info.Armory_Constants.EnchantKey) -- Get enchant string
 								CurrentLineText = T.gsub(CurrentLineText, ITEM_MOD_AGILITY_SHORT, AGI)
@@ -714,8 +1048,10 @@ function CA:Update_Gear()
 						if ItemUpgradeID then
 							if ItemUpgradeID == '' or not E.db.sle.Armory.Character.Level.ShowUpgradeLevel and ItemRarity == 7 then
 								ItemUpgradeID = nil
-							else
+							elseif CurrentUpgrade or MaxUpgrade then
 								ItemUpgradeID = TrueItemLevel - BasicItemLevel
+							else
+								ItemUpgradeID = nil
 							end
 						end

@@ -729,25 +1065,20 @@ function CA:Update_Gear()
 					end

 					if E.db.sle.Armory.Character.NoticeMissing ~= false then
-						if not Slot.IsEnchanted and Info.Armory_Constants.EnchantableSlots[SlotName] then
-							local isValid = false
-							local isWeapon = Info.Armory_Constants.WeaponTypes[ItemType]
-							local isArtifact = (ItemRarity == 6)
-							-- print(isArtifact, ItemRarity)
-							if (isWeapon and not isArtifact) or (SlotName ~= 'SecondaryHandSlot' and not isWeapon) then
-								isValid = true
-							end
-							if isValid then
-								ErrorDetected = true
-								Slot.EnchantWarning:Show()
-
-								if not E.db.sle.Armory.Character.Enchant.WarningIconOnly then
-									Slot.ItemEnchant:SetText('|cffff0000'..L["Not Enchanted"])
-								end
+						if not Slot.IsEnchanted and
+							(Info.Armory_Constants.EnchantableSlots[SlotName] or (E.myclass == 'DEATHKNIGHT' and (SlotName == 'MainHandSlot' or SlotName == 'SecondaryHandSlot'))) and
+							not (SlotName == 'SecondaryHandSlot' and ItemType ~= 'INVTYPE_WEAPON' and ItemType ~= 'INVTYPE_WEAPONOFFHAND' and ItemType ~= 'INVTYPE_RANGEDRIGHT') then
+
+							ErrorDetected = true
+							Slot.IsEnchanted = false
+							Slot.EnchantWarning:Show()
+
+							if not E.db.sle.Armory.Character.Enchant.WarningIconOnly then
+								Slot.ItemEnchant:SetText('|cffff0000'..L["Not Enchanted"])
 							end
 						end

-						if GemCount_Enable > GemCount_Now or GemCount_Enable > GemCount or GemCount_Now > GemCount then
+						if Slot.GemCount_Enable > GemCount_Now or Slot.GemCount_Enable > GemCount or GemCount_Now > GemCount then
 							ErrorDetected = true

 							Slot.SocketWarning:Show()
@@ -761,7 +1092,7 @@ function CA:Update_Gear()
 							Slot.SocketWarning.Texture:Hide()
 						end
 					end
-
+
 					--<< Transmogrify Parts >>--
 					if Slot.TransmogrifyAnchor and C_Transmog_GetSlotInfo(Slot.ID, LE_TRANSMOG_TYPE_APPEARANCE) then
 						Slot.TransmogrifyAnchor.Link = T.select(6, C_TransmogCollection_GetAppearanceSourceInfo(T.select(3, C_Transmog_GetSlotVisualInfo(Slot.ID, LE_TRANSMOG_TYPE_APPEARANCE))));
@@ -785,7 +1116,8 @@ function CA:Update_Gear()

 			if NeedUpdate then
 				NeedUpdateList = NeedUpdateList or {}
-				NeedUpdateList[#NeedUpdateList + 1] = SlotName
+				table.insert(NeedUpdateList, SlotName)
+				--NeedUpdateList[#NeedUpdateList + 1] = SlotName
 			end
 		end

@@ -809,8 +1141,234 @@ function CA:Update_Gear()
 	end

 	self.GearUpdated = true
+
+	if ArtifactMonitor_RequireUpdate then
+		CA:LegionArtifactMonitor_UpdateLayout()
+	end
 end

+do --<< Artifact Monitor >>
+	local EnchantError, EnchantError_MainHand, EnchantError_SecondaryHand
+	function CA:LegionArtifactMonitor_UpdateLayout()
+		if Legion_ArtifactData.ItemID then
+			self.SecondaryHandSlot.Gradation:SetAlpha(0)
+			self.SecondaryHandSlot.ItemLevel:SetAlpha(0)
+			self.SecondaryHandSlot.EnchantWarning:SetAlpha(0)
+			self.SecondaryHandSlot.EnchantWarning:Disable()
+			self.SecondaryHandSlot.SocketWarning:SetAlpha(0)
+			self.SecondaryHandSlot.SocketWarning:Disable()
+			for i = 1, MAX_NUM_SOCKETS do
+				self.MainHandSlot['Socket'..i]:SetAlpha(0)
+				self.MainHandSlot['Socket'..i].Socket:Disable()
+				self.SecondaryHandSlot['Socket'..i]:SetAlpha(0)
+				self.SecondaryHandSlot['Socket'..i].Socket:Disable()
+			end
+
+			self.ArtifactMonitor:Show()
+			CA:LegionArtifactMonitor_UpdateData()
+
+			--if KF.db.Modules.Armory.Character.Gradation.Display then
+			--	self.ArtifactMonitor.Gradation:SetVertexColor(unpack(KF.db.Modules.Armory.Character.Gradation.Color))
+			--	self.ArtifactMonitor.Gradation:Show()
+			--else
+				self.ArtifactMonitor.Gradation:Hide()
+			--end
+
+			if Legion_ArtifactData.MajorSlot == 'SecondaryHandSlot' or self.SecondaryHandSlot.ItemRarity == 6 then
+				-- << Case : Artifact's core in SecondaryHandSlot (ex: Protection Paladin's Artifact) >>
+				-- << Case : Artifacts that using both of Hand slot >>
+
+				do	-- Notice Missing
+					EnchantError = nil
+					EnchantError_MainHand = self.MainHandSlot.ItemEnchant:GetText()
+					EnchantError_SecondaryHand = self.SecondaryHandSlot.ItemEnchant:GetText()
+
+					if self.MainHandSlot.IsEnchanted == false and EnchantError_MainHand ~= nil then
+						EnchantError = EnchantError_MainHand..'|r ('..INVTYPE_WEAPONMAINHAND..')'
+					elseif self.SecondaryHandSlot.IsEnchanted == false and EnchantError_SecondaryHand ~= nil then
+						EnchantError = EnchantError_SecondaryHand..'|r ('..INVTYPE_WEAPONOFFHAND..')'
+					end
+
+					self.MainHandSlot.ItemEnchant:SetText(EnchantError)
+
+					if E.db.sle.Armory.Character.NoticeMissing then
+						if EnchantError then
+							self.MainHandSlot.EnchantWarning:Show()
+						end
+						if self.ArtifactMonitor.SocketWarning:IsShown() then
+							EnchantError= true
+						end
+
+						if EnchantError then
+							self.MainHandSlot.Gradation:SetVertexColor(1, 0, 0)
+						end
+					end
+				end
+
+				self.ArtifactMonitor:Point('LEFT', CharacterSecondaryHandSlot, 1, 0)
+				--self.ArtifactMonitor:Width(210)
+			else
+				-- << Case : Mainhand only artifact >>
+				-- Hide SecondaryHandSlot and move MainHandSlot to center.
+
+				CharacterMainHandSlot:SetPoint('BOTTOMLEFT', PaperDollItemsFrame, 'BOTTOMLEFT', 205, 14)
+				CharacterSecondaryHandSlot:Hide()
+
+				self.ArtifactMonitor:Point('LEFT', CharacterMainHandSlot, 1, 0)
+				--self.ArtifactMonitor:Width(232)
+				return
+			end
+		else
+			self.SecondaryHandSlot.Gradation:SetAlpha(1)
+			self.SecondaryHandSlot.ItemLevel:SetAlpha(1)
+			self.SecondaryHandSlot.EnchantWarning:SetAlpha(1)
+			self.SecondaryHandSlot.EnchantWarning:Enable()
+			self.SecondaryHandSlot.SocketWarning:SetAlpha(1)
+			self.SecondaryHandSlot.SocketWarning:Enable()
+			for i = 1, MAX_NUM_SOCKETS do
+				self.MainHandSlot['Socket'..i]:SetAlpha(1)
+				self.MainHandSlot['Socket'..i].Socket:Enable()
+				self.SecondaryHandSlot['Socket'..i]:SetAlpha(1)
+				self.SecondaryHandSlot['Socket'..i].Socket:Enable()
+			end
+
+			self.ArtifactMonitor:Hide()
+		end
+
+		-- Restore Original Layout
+		CharacterMainHandSlot:SetPoint('BOTTOMLEFT', PaperDollItemsFrame, 'BOTTOMLEFT', 185, 14)
+
+		CharacterSecondaryHandSlot:Show()
+	end
+
+
+	function CA:LegionArtifactMonitor_UpdateData()
+		Artifact_ItemID, _, _, _, Artifact_Power, Artifact_Rank = C_ArtifactUI.GetEquippedArtifactInfo()
+
+		if Artifact_ItemID then
+			Legion_ArtifactData.ItemID = Artifact_ItemID
+			Legion_ArtifactData.Rank = Artifact_Rank
+			Legion_ArtifactData.Power = Artifact_Power
+			Legion_ArtifactData.AvailablePoint, Legion_ArtifactData.XP, Legion_ArtifactData.XPForNextPoint = MainMenuBar_GetNumArtifactTraitsPurchasableFromXP(Artifact_Rank, Artifact_Power)
+			Legion_ArtifactData.RemainXP = Legion_ArtifactData.XPForNextPoint - Legion_ArtifactData.XP
+
+			self.ArtifactMonitor.TraitRank:SetText(RANK..' : '..COLORSTRING_ARTIFACT..Artifact_Rank)
+			self.ArtifactMonitor.CurrentPower:SetAnimatedValue(Legion_ArtifactData.Power)
+			self.ArtifactMonitor.RequirePower:SetText(BreakUpLargeNumbers(Legion_ArtifactData.XPForNextPoint))
+
+			if Legion_ArtifactData.AvailablePoint > 0 then
+				self.ArtifactMonitor.BarExpected.Message:SetText(format(L['%s Points Available!!'], KF:Color_Value(Legion_ArtifactData.AvailablePoint)))
+			else
+				self.ArtifactMonitor.BarExpected.Message:SetText()
+			end
+
+			self.ArtifactMonitor.Bar:SetAnimatedValues(Legion_ArtifactData.XP, 0, Legion_ArtifactData.XPForNextPoint, Legion_ArtifactData.Rank + Legion_ArtifactData.AvailablePoint)
+			self.ArtifactMonitor.BarExpected:SetMinMaxValues(0, Legion_ArtifactData.XPForNextPoint)
+		end
+
+		self.ArtifactMonitor.UpdateData = true
+	end
+
+
+	local escapes = {
+		['|c%x%x%x%x%x%x%x%x'] = '', -- color start
+		['|r'] = '', -- color end
+	}
+	local function CleanString(str)
+		for k, v in pairs(escapes) do
+			str = str:gsub(k, v)
+		end
+		return str
+	end
+	local PowerItemLink, SearchingText, SearchingPhase, CurrentItemPower, TotalPower, LowestPower, LowestPower_BagID, LowestPower_SlotID, LowestPower_Link
+	function CA:LegionArtifactMonitor_SearchPowerItem()
+		if not self.ArtifactMonitor.UpdateData then
+			CA:LegionArtifactMonitor_UpdateData()
+		end
+
+		LowestPower = nil
+		TotalPower = 0
+
+		if Legion_ArtifactData.ItemID then
+			for BagID = 0, NUM_BAG_SLOTS do
+				for SlotID = 1, GetContainerNumSlots(BagID) do
+					_, _, _, _, _, _, PowerItemLink = GetContainerItemInfo(BagID, SlotID)
+
+					if PowerItemLink then
+						self:ClearTooltip(self.ArtifactMonitor.ScanTT)
+						self.ArtifactMonitor.ScanTT:SetHyperlink(PowerItemLink)
+						SearchingPhase = 1
+						CurrentItemPower = 0
+
+						for i = 1, self.ArtifactMonitor.ScanTT:NumLines() do
+							SearchingText = CleanString(_G['Knight_CharacterArmory_ArtifactScanTTTextLeft' .. i]:GetText())
+
+							if SearchingPhase == 1 and SearchingText == ARTIFACT_POWER then
+								SearchingPhase = 2
+							elseif SearchingPhase == 2 and SearchingText:find(ITEM_SPELL_TRIGGER_ONUSE) then
+								CurrentItemPower = tonumber(SearchingText:gsub(',', ''):match('%d+'))
+								TotalPower = TotalPower + CurrentItemPower
+
+								if not LowestPower or LowestPower > CurrentItemPower then
+									LowestPower = CurrentItemPower
+									LowestPower_BagID = BagID
+									LowestPower_SlotID = SlotID
+									LowestPower_Link = PowerItemLink
+								end
+
+								break
+							end
+						end
+
+						if SearchingPhase == 2 and not (LowestPower and LowestPower > 0) then
+							LowestPower = CurrentItemPower
+							LowestPower_BagID = BagID
+							LowestPower_SlotID = SlotID
+							LowestPower_Link = PowerItemLink
+						end
+					end
+				end
+			end
+
+			if LowestPower then
+				self.ArtifactMonitor.AddPower.Texture:Show()
+				self.ArtifactMonitor.AddPower.Button:Show()
+				self.ArtifactMonitor.AddPower.Button.Link = LowestPower_Link
+
+				if LowestPower > 0 then
+					self.ArtifactMonitor.BarExpected.AvailablePower:SetText(KF:Color_Value('+'..BreakUpLargeNumbers(TotalPower)))
+				else
+					self.ArtifactMonitor.BarExpected.AvailablePower:SetText()
+				end
+			else
+				self.ArtifactMonitor.AddPower.Texture:Hide()
+				self.ArtifactMonitor.AddPower.Button:Hide()
+				self.ArtifactMonitor.AddPower.Button.Link = nil
+
+				self.ArtifactMonitor.BarExpected.AvailablePower:SetText()
+				self:LegionArtifactMonitor_ClearPowerItemSearching()
+			end
+
+			if TotalPower + Legion_ArtifactData.XP > Legion_ArtifactData.XPForNextPoint then
+				TotalPower = Legion_ArtifactData.XPForNextPoint
+			else
+				TotalPower = TotalPower + Legion_ArtifactData.XP
+			end
+
+			self.ArtifactMonitor.BarExpected:SetValue(TotalPower)
+		end
+
+		self.ArtifactMonitor.SearchPowerItem = true
+	end
+
+
+	function CA:LegionArtifactMonitor_ClearPowerItemSearching()
+		if self.ArtifactMonitor.NowSearchingPowerItem and E.private.bags.enable and ElvUI_ContainerFrameEditBox and ElvUI_ContainerFrameEditBox:GetText() == 'POWER' then
+			ElvUI_BagModule.ResetAndClear(ElvUI_ContainerFrameEditBox)
+			self.ArtifactMonitor.NowSearchingPowerItem = nil
+		end
+	end
+end

 function CA:Update_BG()
 	if E.db.sle.Armory.Character.Backdrop.SelectedBG == 'HIDE' then
@@ -1020,6 +1578,10 @@ KF.Modules.CharacterArmory = function()
 		CA:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
 		CA:RegisterEvent('UPDATE_INVENTORY_DURABILITY')
 		CA:RegisterEvent('PLAYER_ENTERING_WORLD')
+		CA.ArtifactMonitor:RegisterEvent('ARTIFACT_UPDATE')
+		CA.ArtifactMonitor:RegisterEvent('ARTIFACT_XP_UPDATE')
+		CA.ArtifactMonitor:RegisterEvent('BAG_UPDATE')
+		CA.ArtifactMonitor:RegisterEvent('PLAYER_ENTERING_WORLD')

 		--[[
 		KF_KnightArmory.CheckButton:Show()
@@ -1033,7 +1595,8 @@ KF.Modules.CharacterArmory = function()
 		-- Setting frame to default
 		_G["CharacterFrame"]:SetHeight(424)
 		_G["CharacterFrame"]:SetWidth(_G["PaperDollFrame"]:IsShown() and _G["CharacterFrame"].Expanded and CHARACTERFRAME_EXPANDED_WIDTH or PANEL_DEFAULT_WIDTH)
-		_G["CharacterFrameInsetRight"]:SetPoint(T.unpack(InsetDefaultPoint))
+		--print(_G["CharacterFrame"]:GetWidth())
+		_G["CharacterFrameInsetRight"]:SetPoint(T.unpack(DefaultPosition.InsetDefaultPoint))

 		-- Move rightside equipment slots to default position
 		_G["CharacterHandsSlot"]:SetPoint('TOPRIGHT', _G["CharacterFrameInset"], 'TOPRIGHT', -4, -2)
@@ -1053,6 +1616,7 @@ KF.Modules.CharacterArmory = function()
 		-- Turn off ArmoryFrame
 		CA:Hide()
 		CA:UnregisterAllEvents()
+		CA.ArtifactMonitor:UnregisterAllEvents()

 		--[[
 		KF_KnightArmory.CheckButton:Hide()