local overlord = CreateFrame("Button", (...).."Overlord", UIParent, "SecureHandlerClickTemplate")
local IRF3 = CreateFrame("Frame", ..., overlord, "SecureHandlerAttributeTemplate")
IRF3:SetScript("OnEvent", function(self, event, ...) self[event](self, ...) end)
IRF3:RegisterEvent("PLAYER_LOGIN")
IRF3:SetFrameStrata("MEDIUM")
IRF3:SetFrameLevel(2)
IRF3:SetMovable(true)
IRF3:SetClampedToScreen(true)

local _G = _G
local type = _G.type
local pairs = _G.pairs
local unpack = _G.unpack
local GetSpellInfo = _G.GetSpellInfo
local IsPartyLeader = _G.IsPartyLeader
local IsRaidLeader = _G.IsRaidLeader
local IsRaidOfficer = _G.IsRaidOfficer
local LBDB = LibStub("LibBlueDB-1.0")

function IRF3:PLAYER_LOGIN()
	self.PLAYER_LOGIN = nil
	self.playerClass = select(2, UnitClass("player"))
	self:InitDB()
	self.version = GetAddOnMetadata(self:GetName(), "Version")
	self.website = GetAddOnMetadata(self:GetName(), "X-Website")
	self:ApplyPorfile()
	self:SelectClickCastingDB()
	self:RegisterEvent("READY_CHECK")
	self:RegisterEvent("PLAYER_REGEN_ENABLED")
	self:RegisterEvent("PLAYER_REGEN_DISABLED")
	self.PLAYER_REGEN_ENABLED = self.UpdateTooltipState
	self.PLAYER_REGEN_DISABLED = self.UpdateTooltipState
	LibStub("LibMapButton-1.1"):CreateButton(self, "InvenRaidFrames3MapButton", "Interface\\AddOns\\InvenRaidFrames3\\Texture\\Icon.tga", 190, InvenRaidFrames3DB.minimapButton)
	self.mapButtonMenu:SetParent(InvenRaidFrames3MapButton)
	self.mapButtonMenu:SetPoint("CENTER", 0, 0)
	LibStub("LibDataBroker-1.1"):NewDataObject("InvenRaidFrames3", {
		type = "launcher",
		text = "IRF3",
		OnClick = function(_, button) IRF3:OnClick(button) end,
		icon = "Interface\\AddOns\\InvenRaidFrames3\\Texture\\Icon.tga",
		OnTooltipShow = function(tooltip)
			if not tooltip or not tooltip.AddLine then return end
			IRF3:OnTooltip(tooltip)
		end,
		OnLeave = GameTooltip_Hide,
	})
	self:SetScript("OnHide", InvenRaidFrames3Member_OnDragStop)
end

function IRF3:LoadPosition()
	self:SetUserPlaced(nil)
	self:SetScale(self.db.scale)
	self:ClearAllPoints()
	if self.db.px then
		self:SetPoint(self.db.anchor, UIParent, self.db.px / self.db.scale, self.db.py / self.db.scale)
	else
		self:SetPoint(self.db.anchor, UIParent, "CENTER", 0, 0)
	end
	self.petHeader:SetUserPlaced(nil)
	self.petHeader:SetScale(self.db.petscale)
	self.petHeader:ClearAllPoints()
	if self.db.petpx then
		self.petHeader:SetPoint(self.db.petanchor, UIParent, self.db.petanchor, self.db.petpx / (self.db.petscale * self.db.scale), self.db.petpy / (self.db.petscale * self.db.scale))
	else
		self.petHeader:SetPoint(self.db.petanchor, UIParent, "CENTER", 0, 0)
	end
end

function IRF3:SavePosition()
	if self.db.anchor == "TOPLEFT" then
		self.db.px = self:GetLeft() * self.db.scale
		self.db.py = self:GetTop() * self.db.scale - UIParent:GetTop()
	elseif self.db.anchor == "TOPRIGHT" then
		self.db.px = self:GetRight() * self.db.scale - UIParent:GetRight()
		self.db.py = self:GetTop() * self.db.scale - UIParent:GetTop()
	elseif self.db.anchor == "BOTTOMLEFT" then
		self.db.px = self:GetLeft() * self.db.scale
		self.db.py = self:GetBottom() * self.db.scale
	elseif self.db.anchor == "BOTTOMRIGHT" then
		self.db.px = self:GetRight() * self.db.scale - UIParent:GetRight()
		self.db.py = self:GetBottom() * self.db.scale
	end
	if self.db.petanchor == "TOPLEFT" then
		self.db.petpx = self.petHeader:GetLeft() * (self.db.petscale * self.db.scale)
		self.db.petpy = self.petHeader:GetTop() * (self.db.petscale * self.db.scale) - UIParent:GetTop()
	elseif self.db.petanchor == "TOPRIGHT" then
		self.db.petpx = self.petHeader:GetRight() * (self.db.petscale * self.db.scale) - UIParent:GetRight()
		self.db.petpy = self.petHeader:GetTop() * (self.db.petscale * self.db.scale) - UIParent:GetTop()
	elseif self.db.petanchor == "BOTTOMLEFT" then
		self.db.petpx = self.petHeader:GetLeft() * (self.db.petscale * self.db.scale)
		self.db.petpy = self.petHeader:GetBottom() * (self.db.petscale * self.db.scale)
	elseif self.db.petanchor == "BOTTOMRIGHT" then
		self.db.petpx = self.petHeader:GetRight() * (self.db.petscale * self.db.scale) - UIParent:GetRight()
		self.db.petpy = self.petHeader:GetBottom() * (self.db.petscale * self.db.scale)
	end
end

function IRF3:UpdateTooltipState()
	if self.db.units.tooltip == 0 then
		self.tootipState = nil
	elseif self.db.units.tooltip == 1 then
		self.tootipState = true
	elseif InCombatLockdown() or UnitAffectingCombat("player") then
		self.tootipState = self.db.units.tooltip == 3
	elseif self.db.units.tooltip == 2 then
		self.tootipState = true
	else
		self.tootipState = nil
	end
	if not self.tootipState then
		UnitFrame_OnLeave(self.highlight)
	end
end

function IRF3:SetHighlight(frame)
	if frame then
		self.highlight:SetAlpha(self.db.highlightAlpha)
		self.highlight:SetParent(frame)
		self.highlight:SetAllPoints()
		self.highlight:Show()
		self.highlight:SetFrameLevel(frame:GetFrameLevel() + 2)
		if frame.displayedUnit and self.tootipState then
			self.highlight.unit = frame.displayedUnit
			UnitFrame_OnEnter(self.highlight)
		else
			UnitFrame_OnLeave(self.highlight)
		end
	else
		self.highlight:Hide()
	end
end

function IRF3:BorderUpdate(fast)
	if self.db.border then
		if fast then
			self.border.updater:GetScript("OnUpdate")(self.border.updater)
		else
			self.border.updater:Show()
		end
		self.petHeader.border:Show()
	else
		self.border.updater:Hide()
		self.border:SetAlpha(0)
		self.petHeader.border:Hide()
	end
end

function IRF3:OnClick(button)
	if button == "RightButton" then
		ToggleDropDownMenu(1, nil, IRF3.mapButtonMenu, "cursor")
	elseif InterfaceOptionsFramePanelContainer.displayedPanel == IRF3.optionFrame then
		InterfaceOptionsFrameOkay_OnClick()
	else
		InterfaceOptionsFrame_OpenToCategory(IRF3.optionFrame)
	end
end

function IRF3:OnTooltip(tooltip)
	tooltip = tooltip or GameTooltip
	tooltip:AddLine("인벤 레이드 프레임 3 v"..IRF3.version)
	tooltip:AddLine("http://wow.inven.co.kr", 1, 1, 1)
	tooltip:AddLine("좌클릭: 설정창 열기", 1, 1, 0)
	tooltip:AddLine("우클릭: 메뉴 열기", 1, 1, 0)
end

function IRF3:Message(msg)
	ChatFrame1:AddMessage("|cffffff00IRF3: |r"..msg, 1, 1, 1)
end

function IRF3:IsLeader()
	return IsPartyLeader() or IsRaidLeader() or IsRaidOfficer()
end

local function changeParent(frame, prevParent, newParent)
	if frame:GetParent() == prevParent then
		frame:SetParent(newParent)
	end
end

function IRF3:HideBlizzardPartyFrame(hide)
	self.db.hideBlizzardParty = hide
	if hide then
		for i = 1, MAX_PARTY_MEMBERS do
			changeParent(_G["PartyMemberFrame"..i], UIParent, self.dummyParent)
		end
		changeParent(PartyMemberBackground, UIParent, self.dummyParent)
		changeParent(CompactPartyFrame, UIParent, self.dummyParent)
	else
		for i = 1, MAX_PARTY_MEMBERS do
			changeParent(_G["PartyMemberFrame"..i], self.dummyParent, UIParent)
		end
		changeParent(PartyMemberBackground, self.dummyParent, UIParent)
		changeParent(CompactPartyFrame, self.dummyParent, UIParent)
	end
end

function IRF3:GetHeaderHeight(member)
	if member then
		if member > 0 then
			return self.db.height * member + ((self.db.usePet == 2 and self.db.petHeight or 0) + self.db.offset) * (member - 1)
		else
			return 0.1
		end
	else
		return (self.db.height + (self.db.usePet == 2 and self.db.petHeight or 0)) * 5 + self.db.offset * 4
	end
end

function IRF3.GetSpellName(id)
	return GetSpellInfo(id) or ""
end

IRF3.dummyParent = CreateFrame("Frame")
IRF3.dummyParent:Hide()

IRF3.highlight = CreateFrame("Frame", nil, IRF3)
IRF3.highlight:Hide()
IRF3.highlight:SetToplevel(true)
IRF3.highlight.texture = IRF3.highlight:CreateTexture(nil, "OVERLAY")
IRF3.highlight.texture:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
IRF3.highlight.texture:SetBlendMode("ADD")
IRF3.highlight.texture:SetAllPoints()
IRF3.highlight:SetScript("OnHide", UnitFrame_OnLeave)
IRF3.highlight:SetFrameLevel(4)

IRF3.border = CreateFrame("Frame", nil, IRF3)
IRF3.border:SetFrameLevel(1)
IRF3.border:SetBackdrop({
	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
	edgeFile = "Interface\\Addons\\InvenRaidFrames3\\Texture\\Border.tga",
	tile = true, tileSize = 16, edgeSize = 16,
	insets = { left = 2, right = 2, top = 2, bottom = 2 },
})
IRF3.border.updater = CreateFrame("Frame", nil, IRF3.border)
IRF3.border.updater:Hide()
IRF3.border.updater:SetScript("OnUpdate", function(self)
	self:Hide()
	self = self:GetParent()
	self.headers = self:GetParent().headers
	self.count, self.left, self.right, self.top, self.bottom = 0
	for i = 0, 8 do
		if self.headers[i]:IsVisible() then
			self.count = self.count + 1
			if self.headers[i].visible > 0 then
				if self.headers[i]:GetLeft() and self.headers[i]:GetRight() and self.headers[i]:GetTop() and self.headers[i]:GetBottom() then
					if not self.left or self.headers[i]:GetLeft() < self.left:GetLeft() then
						self.left = self.headers[i]
					end
					if not self.right or self.headers[i]:GetRight() > self.right:GetRight() then
						self.right = self.headers[i]
					end
					if IRF3.db.usePet == 2 and self.headers[i].members[self.headers[i].visible].petButton:IsShown() then
						if IRF3.db.anchor:find("TOP") then
							if not self.top or self.headers[i]:GetTop() > self.top:GetTop() then
								self.top = self.headers[i]
							end
							if not self.bottom or self.headers[i].members[self.headers[i].visible].petButton:GetBottom() < self.bottom:GetBottom() then
								self.bottom = self.headers[i].members[self.headers[i].visible].petButton
							end
						else
							if not self.top or self.headers[i].members[self.headers[i].visible].petButton:GetTop() > self.top:GetTop() then
								self.top = self.headers[i].members[self.headers[i].visible].petButton
							end
							if not self.bottom or self.headers[i]:GetBottom() < self.bottom:GetBottom() then
								self.bottom = self.headers[i]
							end
						end
					else
						if not self.top or self.headers[i]:GetTop() > self.top:GetTop() then
							self.top = self.headers[i]
						end
						if not self.bottom or self.headers[i]:GetBottom() < self.bottom:GetBottom() then
							self.bottom = self.headers[i]
						end
					end
				else
					self:SetAlpha(0)
					return self.updater:Show()
				end
			end
		end
	end
	if self.left then
		self:ClearAllPoints()
		if IRF3.db.anchor == "TOPLEFT" then
			self:SetPoint("TOPLEFT", -5, 5)
			self:SetPoint("RIGHT", self.right, 5, 0)
			self:SetPoint("BOTTOM", self.bottom, "BOTTOM", 0, -5)
		elseif IRF3.db.anchor == "TOPRIGHT" then
			self:SetPoint("TOPRIGHT", 5, 5)
			self:SetPoint("LEFT", self.left, -5, 0)
			self:SetPoint("BOTTOM", self.bottom, "BOTTOM", 0, -5)
		elseif IRF3.db.anchor == "BOTTOMLEFT" then
			self:SetPoint("BOTTOMLEFT", -5, -5)
			self:SetPoint("RIGHT", self.right, 5, 0)
			self:SetPoint("TOP", self.top, 0, 5)
		elseif IRF3.db.anchor == "BOTTOMRIGHT" then
			self:SetPoint("BOTTOMRIGHT", 5, -5)
			self:SetPoint("LEFT", self.left, -5, 0)
			self:SetPoint("TOP", self.top, 0, 5)
		end
		self:SetAlpha(1)
	else
		self:SetAlpha(0)
		if self.count > 0 then
			return self.updater:Show()
		end
	end
	self.headers, self.count, self.left, self.right, self.top, self.bottom, self.anchor = nil
end)

IRF3.optionFrame = CreateFrame("Frame", IRF3:GetName().."OptionFrame", InterfaceOptionsFramePanelContainer)
IRF3.optionFrame:Hide()
IRF3.optionFrame.name = "인벤 레이드 프레임 3"
IRF3.optionFrame.addon = IRF3:GetName()
IRF3.optionFrame:SetScript("OnShow", function(self)
	self:SetScript("OnShow", nil)
	LoadAddOn(self.addon.."_Option")
end)
InterfaceOptions_AddCategory(IRF3.optionFrame)
SLASH_INVENRAIDFRAMES31 = "/irf"
SLASH_INVENRAIDFRAMES32 = "/irf3"
SLASH_INVENRAIDFRAMES33 = "/인벤레이드"
SLASH_INVENRAIDFRAMES34 = "/인벤레이드프레임"
SLASH_INVENRAIDFRAMES35 = "/invenraidframe"
SLASH_INVENRAIDFRAMES36 = "/invenraidframes"
SLASH_INVENRAIDFRAMES37 = "/ㅑㄱㄹ"
SLASH_INVENRAIDFRAMES38 = "/ㅑㄱㄹ3"
SlashCmdList["INVENRAIDFRAMES3"] = IRF3.OnClick

overlord:SetFrameRef("frame", IRF3)
overlord:Execute("IRF3 = self:GetFrameRef('frame')")
overlord:SetAttribute("_onclick", "IRF3:SetAttribute('run', not IRF3:GetAttribute('run'))")
overlord:SetScript("PostClick", function()
	if IRF3.db.run ~= IRF3:GetAttribute("run") then
		IRF3.db.run = IRF3:GetAttribute("run")
		if IRF3.db.run then
			IRF3:Message("공격대 창이 활성화 되었습니다.")
		else
			IRF3:Message("공격대 창이 비활성화 되었습니다.")
		end
		if IRF3.optionFrame:IsVisible() and IRF3.optionFrame.runMenu:IsVisible() then
			IRF3.optionFrame.runMenu:Update()
		end
		IRF3.manager.locked:Update()
	end
end)

BINDING_HEADER_INVENRAIDFRAMES3 = "인벤 레이드 프레임 3"
BINDING_NAME_INVENRAIDFRAMES3_OPTION = "옵션창 열기"
BINDING_NAME_INVENRAIDFRAMES3_DOREADYCHECK = "전투 준비 확인하기"
BINDING_NAME_INVENRAIDFRAMES3_INITIATEROLEPOLL = "역할 확인하기"
_G["BINDING_NAME_CLICK InvenRaidFrames3Overlord:LeftButton"] = "레이드 프레임 활성/비활성화 하기"

local function runFunc()
	if InCombatLockdown() then
		IRF3:Message("전투중에는 활성/비활성화 설정을 할 수 없습니다.")
	else
		IRF3:SetAttribute("run", not IRF3:GetAttribute("run"))
		overlord:GetScript("PostClick")(overlord)
	end
end

local function lockFunc()
	IRF3.db.lock = not IRF3.db.lock
end

local function initializeDropDown()
	local info = UIDropDownMenu_CreateInfo()
	info.notCheckable = true
	info.isNotRadio = true
	info.text = "설정창 열기"
	info.func = IRF3.OnClick
	UIDropDownMenu_AddButton(info)
	info.notCheckable = nil
	info.text = "사용하기"
	info.checked = IRF3.db and IRF3.db.run
	info.func = runFunc
	UIDropDownMenu_AddButton(info)
	info.text = "고정하기"
	info.checked = IRF3.db and IRF3.db.lock
	info.func = lockFunc
	UIDropDownMenu_AddButton(info)
	info.notCheckable = true
	info.checked = nil
	info.text = "전투 준비 확인"
	info.disabled = not IRF3:IsLeader()
	info.func = DoReadyCheck
	UIDropDownMenu_AddButton(info)
	info.text = "역할 확인"
	info.func = InitiateRolePoll
	UIDropDownMenu_AddButton(info)
	info.disabled = nil
	info.func = nil
	info.text = "닫기"
	UIDropDownMenu_AddButton(info)
end

IRF3.mapButtonMenu = CreateFrame("Frame", "InvenRaidFrames3MapButtonMenu", IRF3, "UIDropDownMenuTemplate")
IRF3.mapButtonMenu:SetID(1)
IRF3.mapButtonMenu:SetWidth(10)
IRF3.mapButtonMenu:SetHeight(10)
UIDropDownMenu_Initialize(IRF3.mapButtonMenu, initializeDropDown, "MENU")