-- Addon:	ChiBar: functional part
-- Author:	Fushui(EU-Azshara)

if select(2, UnitClass("player")) ~= "MONK" then
    return
end


------------------------------------------
--		Functions						--
------------------------------------------

-- Function for hiding/showing the Addon
function ChiBar:enable()
	if ChiBarDB.enable then
		ChiBar.mainFrame:Hide()
		ChiBarDB.enable = false
		print(ChiBarLocalization.HIDE:format())
		ChiBar:unregisterEvents()
	else
		ChiBar:showMainFrame()
		ChiBarDB.enable = true
		print(ChiBarLocalization.SHOW:format())
		ChiBar:registerEvents()
	end
end

-- Funcion for the Colorpicker to
function ChiBar:enableSeperateOpacity()
	if ChiBarDB.seperate then
		ChiBarDB.seperate = false
		ChiBar.Widgets.opacitySubTitle1:SetText(ChiBarLocalization.OP_OPACITYSUBTITLE1_1)
		ChiBar.Widgets.opacitySubTitle2:Hide()
		ChiBar.Widgets.opacitySlider2:Hide()
		ChiBar.Widgets.currOpacityText2:Hide()
	else
		ChiBarDB.seperate = true
		ChiBar.Widgets.opacitySubTitle1:SetText(ChiBarLocalization.OP_OPACITYSUBTITLE1_2)
		ChiBar.Widgets.opacitySubTitle2:Show()
		ChiBar.Widgets.opacitySlider2:Show()
		ChiBar.Widgets.currOpacityText2:Show()
	end
	ChiBar:adjustOpacity(ChiBarDB.alpha1, ChiBarDB.alpha2)
end

-- Function for changing the texture
function ChiBar:changeTexture(newTextureID)
	local index
	for index = 1, 5 do
		ChiBar.Textures0[index]:SetTexture(ChiBar.textures[((ChiBarDB.savedTexture*2)-1)])
		ChiBar.Textures1[index]:SetTexture(ChiBar.textures[(ChiBarDB.savedTexture*2)])
	end
end

-- Function for showing mainFrame under conditions of autohide
function ChiBar:showMainFrame()
	if (ChiBarDB.autohide and not UnitAffectingCombat("player")) or UnitHasVehicleUI("player") then
		ChiBar.mainFrame:Hide()
	else
		ChiBar.mainFrame:Show()
	end
end

-- Function for setting the default parameters
function ChiBar:defaultParameters()
	ChiBarDB = {}
	
	ChiBarDB.x = 0
	ChiBarDB.y = 0
	ChiBarDB.from = "CENTER"
	ChiBarDB.to = "CENTER"
	ChiBarDB.scale = 1
	ChiBarDB.alpha1 = 1
	ChiBarDB.alpha2 = 1
	ChiBarDB.seperate = false
	ChiBarDB.enable = true
	ChiBarDB.autohide = false
	ChiBarDB.savedTexture = 11
	ChiBarDB.grow1 = true
	ChiBarDB.grow2 = true
	ChiBarDB.color = {1, 1, 1}
	ChiBarDB.hideStandard = false
	ChiBarDB.mainLayer = 3
	ChiBarDB.strata = 2
	ChiBarDB.offset = 0
end

-- Function for adding new saved Variables, if you're updating from a lower version of ChiBar
function ChiBar:versionUpdate()
	if ChiBarDB.x == nil 				then ChiBarDB.x = 0 				end
	if ChiBarDB.y == nil 				then ChiBarDB.y = 0 				end
	if ChiBarDB.from == nil				then ChiBarDB.from = "CENTER" 		end
	if ChiBarDB.to == nil 				then ChiBarDB.to = "CENTER" 		end
	if ChiBarDB.scale == nil			then ChiBarDB.scale = 1 			end
	if ChiBarDB.alpha1 == nil 			then ChiBarDB.alpha1 = 1 			end
	if ChiBarDB.alpha2 == nil 			then ChiBarDB.alpha2 = 1 			end
	if ChiBarDB.seperate == nil 		then ChiBarDB.seperate = false 		end
	if ChiBarDB.enable == nil 			then ChiBarDB.enable = true 		end
	if ChiBarDB.autohide == nil 		then ChiBarDB.autohide = false 		end
	if ChiBarDB.savedTexture == nil 	then ChiBarDB.savedTexture = 11 	end
	if ChiBarDB.grow1 == nil 			then ChiBarDB.grow1 = true 			end
	if ChiBarDB.grow2 == nil 			then ChiBarDB.grow2 = true 			end
	if ChiBarDB.color == nil 			then ChiBarDB.color = {1, 1, 1} 	end
	if ChiBarDB.hideStandard == nil 	then ChiBarDB.hideStandard = false 	end
	if ChiBarDB.mainLayer == nil 		then ChiBarDB.mainLayer = 3 		end
	if ChiBarDB.strata == nil 			then ChiBarDB.strata = 2 			end
	if ChiBarDB.offset == nil 			then ChiBarDB.offset = 0 			end
end

-- Funcion for confirming the data reset
function ChiBar:confirmReset()
	InterfaceOptionsFrame_Show()
	StaticPopup_Show("CHIBAR_RESETFRAME")
end

-- Funcion for the Colorpicker to open the ColorPicker
function ChiBar:openColorPicker()
	ColorPickerFrame:SetColorRGB(ChiBarDB.color[1], ChiBarDB.color[2], ChiBarDB.color[3], 1)
	ChiBar.oldColors = ChiBarDB.color
	ColorPickerFrame.hasOpacity = false
	ColorPickerFrame.previousValues = {ChiBarDB.color[1], ChiBarDB.color[2], ChiBarDB.color[3], 1}
	ColorPickerFrame.func, ColorPickerFrame.opacityFunc, ColorPickerFrame.cancelFunc = 
		ChiBar.ColorPickerSuccess, nil, ChiBar.ColorPickerCancel
	ColorPickerFrame:Hide()
	InterfaceOptionsFrame_Show()
	ColorPickerFrame:Show()
end

-- Funcion for the Colorpicker to save the chosen color
function ChiBar:ColorPickerSuccess()
	ChiBarDB.color[1], ChiBarDB.color[2], ChiBarDB.color[3] = ColorPickerFrame:GetColorRGB()
	ChiBar:changeColor()
	if not ColorPickerFrame:IsShown() then InterfaceOptionsFrame_OpenToCategory(ChiBar.opanel) end
end

-- Funcion for the Colorpicker to pick the color
function ChiBar:ColorPickerCancel()
	local _
	ChiBarDB.color[1], ChiBarDB.color[2], ChiBarDB.color[3], _ = unpack(ColorPickerFrame.previousValues)
	ChiBar:changeColor()
	InterfaceOptionsFrame_OpenToCategory(ChiBar.opanel)
end

--Funcion for the Colorpicker to change the color
function ChiBar:changeColor()
	local index
	for index = 1, 5 do
		ChiBar.Textures0[index]:SetVertexColor(ChiBarDB.color[1], ChiBarDB.color[2], ChiBarDB.color[3])
		ChiBar.Textures1[index]:SetVertexColor(ChiBarDB.color[1], ChiBarDB.color[2], ChiBarDB.color[3])
	end
end

-- Funcion for the Colorpicker to reset the color
function ChiBar:resetColor(sender)
	ChiBarDB.color = {1,1,1}
	ChiBar:changeColor()
	if sender then
		print(ChiBarLocalization.COLORRESET:format())
	end
end

-- Function for resetting the ChiBar
function ChiBar:reset()
	ChiBar:defaultParameters()
	ChiBar:registerEvents()
	ChiBar:changeTexture()
	ChiBar:settingUpOrientation()
	ChiBar.mainFrame:SetPoint(ChiBarDB.from, UIParent, ChiBarDB.to, ChiBarDB.x, ChiBarDB.y)
	ChiBar.mainFrame:SetScale(ChiBarDB.scale)
	ChiBar:adjustOpacity(ChiBarDB.alpha1, ChiBarDB.alpha2)
	ChiBar:updateLayerLevel()
	ChiBar:resetColor()
	ChiBar:showMainFrame()
	if ChiBarDB.hideStandard then
		MonkHarmonyBar:SetScript("OnShow", MonkHarmonyBar.Hide)
		MonkHarmonyBar:Hide()
	else
		MonkHarmonyBar:SetScript("OnShow", nil)
		MonkHarmonyBar:Show()
	end
	ChiBar.Widgets.enableBox.element:SetChecked(ChiBarDB.enable)
	ChiBar.Widgets.autohideBox.element:SetChecked(ChiBarDB.autohide)
	ChiBar.Widgets.hideStandardBox.element:SetChecked(ChiBarDB.hideStandard)
	ChiBar.Widgets.scaleSlider:SetValue(ChiBarDB.scale)
	ChiBar.Widgets.opacitySlider1:SetValue(ChiBarDB.alpha1)
	ChiBar.Widgets.opacitySlider2:SetValue(ChiBarDB.alpha2)
	ChiBar.Widgets.seperateBox.element:SetChecked(ChiBarDB.seperate)
	ChiBar.Widgets.verticalBox.element:SetChecked(ChiBarDB.grow1)
	ChiBar.Widgets.horizontalBox.element:SetChecked(not ChiBarDB.grow1)
	ChiBar.Widgets.leftbottomBox.element:SetChecked(ChiBarDB.grow1)
	ChiBar.Widgets.righttopBox.element:SetChecked(not ChiBarDB.grow1)
	ChiBar.Widgets.offsetSlider:SetValue(ChiBarDB.offset)
	
	if not ChiBarDB.seperate then
		ChiBar.Widgets.opacitySubTitle2:Hide()
		ChiBar.Widgets.opacitySlider2:Hide()
		ChiBar.Widgets.currOpacityText2:Hide()
	end

	UIDropDownMenu_SetSelectedID(ChiBar.Widgets.dropdownMenu.element, ChiBarDB.savedTexture)
	UIDropDownMenu_SetSelectedID(ChiBar.Widgets.mainLayerMenu.element, ChiBarDB.mainLayer)
	UIDropDownMenu_SetSelectedID(ChiBar.Widgets.strataMenu.element, ChiBarDB.strata)
	print(ChiBarLocalization.RESET:format())
	InterfaceOptionsFrame_OpenToCategory(ChiBar.opanel)
end

-- Function for scaling the ChiBar
function ChiBar:scaleUI()
	ChiBar.mainFrame:SetScale(ChiBarDB.scale)
	ChiBar.Widgets.scaleSlider:SetValue(ChiBarDB.scale)
	ChiBar.Widgets.currScaleText:SetText(ChiBarDB.scale)
end

-- Function for adjust the opacity of ChiBar
function ChiBar:adjustOpacity()
	local newalpha3 = 0
	local index
	if ChiBarDB.seperate then
		newalpha3 = ChiBarDB.alpha2
	else
		newalpha3 = ChiBarDB.alpha1
	end
	for index = 1, 5 do
		ChiBar.Textures0[index]:SetAlpha(newalpha3)
		ChiBar.Textures1[index]:SetAlpha(ChiBarDB.alpha1)
	end
	ChiBar.Widgets.opacitySlider1:SetValue(ChiBarDB.alpha1)
	ChiBar.Widgets.opacitySlider2:SetValue(ChiBarDB.alpha2)
	ChiBar.Widgets.currOpacityText1:SetText(ChiBarDB.alpha1)
	ChiBar.Widgets.currOpacityText2:SetText(ChiBarDB.alpha2)
end

-- Set the orientation of ChiBar
function ChiBar:settingUpOrientation()
	local index
	if ChiBarDB.grow1 then
		ChiBar.BGTexture:SetWidth(5*ChiBar.BUBBLEDIM+4*ChiBarDB.offset)
		ChiBar.BGTexture:SetHeight(ChiBar.BUBBLEDIM)
		ChiBar.orientation1 = 0
		if ChiBarDB.grow2 then
			ChiBar.orientation2 = 1
		else
			ChiBar.orientation2 = -1
		end
	else
		ChiBar.BGTexture:SetWidth(ChiBar.BUBBLEDIM)
		ChiBar.BGTexture:SetHeight(5*ChiBar.BUBBLEDIM+4*ChiBarDB.offset)
		ChiBar.orientation1 = 1
		if ChiBarDB.grow2 then	
			ChiBar.orientation2 = 1
		else
			ChiBar.orientation2 = -1
		end
	end
	
	local add = (5-UnitPowerMax("player", ChiBar.CLASSPOWERID))*ChiBar.BUBBLEDIM/2
	
	ChiBar.BGTexture:SetPoint("CENTER", ChiBar.Bubbles[3], "CENTER", (-add)*(1-ChiBar.orientation1)*ChiBar.orientation2, (-add)*ChiBar.orientation1*ChiBar.orientation2)
	for index = 0, 4 do
		local coord = (index*ChiBar.BUBBLEDIM+add+index*ChiBarDB.offset)*ChiBar.orientation2
		ChiBar.Bubbles[index+1]:SetPoint("CENTER", ChiBar.mainFrame, "CENTER", (coord)*(1-ChiBar.orientation1), (coord)*ChiBar.orientation1)
	end
end

-- Function for updating the layerlevel of ChiBar
function ChiBar:updateLayerLevel()
	local index
	local layernames = {"BACKGROUND", "BORDER", "ARTWORK", "OVERLAY"}
	local stratanames = {"LOW", "MEDIUM", "HIGH", "DIALOG"}
	for index = 1, 5 do
		ChiBar.Bubbles[index]:SetFrameStrata(stratanames[ChiBarDB.strata])
		ChiBar.Textures0[index]:SetDrawLayer(layernames[ChiBarDB.mainLayer], 5)
		ChiBar.Textures1[index]:SetDrawLayer(layernames[ChiBarDB.mainLayer], 6)
	end
	ChiBar.BGTexture:SetDrawLayer(layernames[ChiBarDB.mainLayer], 4)
	ChiBar.BGTexture2:SetDrawLayer(layernames[ChiBarDB.mainLayer], 7)
end

-- Function for updating the offsetspace between the Orbs of ChiBar
function ChiBar:updateOffset()
	ChiBar.Widgets.offsetSlider:SetValue(ChiBarDB.offset)
	ChiBar.Widgets.currOffsetText:SetText(ChiBarDB.offset)
	ChiBar:settingUpOrientation()
end

-- Function for update the GUI on Talentchange (Ascension)
function ChiBar:updateStructure()
	local maxindex = UnitPowerMax("player", ChiBar.CLASSPOWERID)
	local index
	for index = 1, maxindex do
		ChiBar.Bubbles[index]:Show()
	end
	for index = maxindex+1, 5 do
		ChiBar.Bubbles[index]:Hide()
	end
	ChiBar:settingUpOrientation()
end

-- Function for updating the horizontal/vertical orientation
function ChiBar:updateVertHor()
	if ChiBarDB.grow1 then
		ChiBarDB.grow1 = false
		ChiBar.Widgets.leftbottomBox.text:SetText(ChiBarLocalization.OP_GROW_TOP)
		ChiBar.Widgets.righttopBox.text:SetText(ChiBarLocalization.OP_GROW_BOTTOM)
		ChiBar.Widgets.verticalBox.element:SetChecked(ChiBarDB.grow1)
		ChiBar.Widgets.horizontalBox.element:SetChecked(not ChiBarDB.grow1)
	else
		ChiBarDB.grow1 = true
		ChiBar.Widgets.leftbottomBox.text:SetText(ChiBarLocalization.OP_GROW_RIGHT)
		ChiBar.Widgets.righttopBox.text:SetText(ChiBarLocalization.OP_GROW_LEFT)
		ChiBar.Widgets.verticalBox.element:SetChecked(ChiBarDB.grow1)
		ChiBar.Widgets.horizontalBox.element:SetChecked(not ChiBarDB.grow1)
	end
	ChiBar:settingUpOrientation()
end

-- Function for updating the grow direction
function ChiBar:updateGrowthDirec()
	if ChiBarDB.grow2 then
		ChiBarDB.grow2 = false
		ChiBar.Widgets.leftbottomBox.element:SetChecked(ChiBarDB.grow2)
		ChiBar.Widgets.righttopBox.element:SetChecked(not ChiBarDB.grow2)
	else
		ChiBarDB.grow2 = true
		ChiBar.Widgets.leftbottomBox.element:SetChecked(ChiBarDB.grow2)
		ChiBar.Widgets.righttopBox.element:SetChecked(not ChiBarDB.grow2)
	end
	ChiBar:settingUpOrientation()
end

-- Function for update the GUI(amount of available Chi)
function ChiBar:updateChi()
	local i
	local currChi = UnitPower("player", ChiBar.CLASSPOWERID)
	local maxChi = UnitPowerMax("player", ChiBar.CLASSPOWERID)
	for i = 1, currChi do
		ChiBar.Textures1[i]:Show()
	end
	for i = (UnitPower("player", ChiBar.CLASSPOWERID)+1), maxChi do
		ChiBar.Textures1[i]:Hide()
	end
end

-- Function for toggle Autohide out of Combat
function ChiBar:autohide()
	if ChiBarDB.autohide then
		ChiBarDB.autohide = false
		ChiBar:showMainFrame()
		print(ChiBarLocalization.AUTOHIDE_OFF:format())
	else
		ChiBarDB.autohide = true
		ChiBar:showMainFrame()
		print(ChiBarLocalization.AUTOHIDE_ON:format())
	end
end

-- Function for enable Lock
function ChiBar:lockFrame()
	local _
	ChiBar.mainFrame:SetMovable(false)
	ChiBar.mainFrame:EnableMouse(false)
	ChiBarDB.from, _, ChiBarDB.to, ChiBarDB.x, ChiBarDB.y = ChiBar.mainFrame:GetPoint()
	ChiBar:showMainFrame()
	ChiBar.BGTexture:Hide()
	ChiBar.BGTexture2:Hide()
	print(ChiBarLocalization.LOCK:format())
end

-- Function for disable Lock
function ChiBar:unlockFrame()
	InterfaceOptionsFrame_Show() 
	ChiBar.mainFrame:SetMovable(true)
	ChiBar.mainFrame:EnableMouse(true)
	ChiBar.mainFrame:Show()
	StaticPopup_Show("CHIBAR_UNLOCKFRAME")
	ChiBar.BGTexture:Show()
	ChiBar.BGTexture2:Show()
	print(ChiBarLocalization.UNLOCK:format())
end

--Function for hiding the standard chibar
function ChiBar:hideStandard()
	if ChiBarDB.hideStandard then
		ChiBarDB.hideStandard = false
		MonkHarmonyBar:SetScript("OnShow", nil)
		MonkHarmonyBar:Show()
	else
		ChiBarDB.hideStandard = true
		MonkHarmonyBar:SetScript("OnShow", MonkHarmonyBar.Hide)
		MonkHarmonyBar:Hide()
	end
end

-- Function for starting up the Addon
function ChiBar:InitialStartUp()
	if ChiBarDB == nil then
			print("Creating ChiBarDB")
			ChiBar:defaultParameters()
		end
		ChiBar:versionUpdate()
		ChiBar:createOptionsUI()
		ChiBar:createUI()
		print(ChiBar.VERSIONTEXT_1:format())
		print(ChiBarLocalization.GREETINGS:format())
		ChiBar.mainFrame:UnregisterEvent("ADDON_LOADED")
		ChiBar:showMainFrame()
		if not ChiBarDB.enable then
			ChiBar.mainFrame:Hide()
			ChiBar.unregisterEvents()
		end
		if ChiBarDB.hideStandard then
			MonkHarmonyBar:Hide()
			MonkHarmonyBar:SetScript("OnShow", MonkHarmonyBar.Hide)
		end
end


------------------------------------------
--		EventHandling					--
------------------------------------------

function ChiBar_OnEvent(self, event, arg1, arg2, ...)
	-- Player entered Vehicle
	if event == "UNIT_ENTERED_VEHICLE" and arg1 == "player" then
		ChiBar:showMainFrame()
		
	-- Player exit Vehicle
	elseif event == "UNIT_EXITED_VEHICLE" and arg1 == "player" then
		ChiBar:showMainFrame()
		
	-- Player enter Combat while Autohide is on
	elseif event == "PLAYER_REGEN_DISABLED" then
		ChiBar:showMainFrame()
		
	-- Player exit Combat while Autohide is on
	elseif event == "PLAYER_REGEN_ENABLED" then
		ChiBar:showMainFrame()
		
	-- Player changed Talents
	elseif event == "UNIT_MAXPOWER" then
		ChiBar:updateStructure()
		ChiBar:updateChi()
		
	-- Player's Chi changed
	elseif event == "UNIT_POWER_FREQUENT" and arg1 == "player" and arg2 == "CHI" then
		ChiBar:updateChi()
		
	-- Player's main resource changed (e.g. if you change stance)
	elseif event == "UNIT_DISPLAYPOWER" and arg1 == "player" then
		ChiBar:updateChi()
		
	-- Player enters PetBattle
	elseif event == "PET_BATTLE_OPENING_START" then
		ChiBar.mainFrame:Hide()
		
	-- Player exits PetBattle
	elseif event == "PET_BATTLE_CLOSE" then
		ChiBar:showMainFrame()
		
	-- Player logging in - only used because UnitPowerMax() returns 0 after ADDON_LOADED
	elseif event == "PLAYER_LOGIN" then
		ChiBar.mainFrame:UnregisterEvent("PLAYER_LOGIN")
		ChiBar:updateStructure()
		ChiBar:updateChi()
		
	-- initial loading of the addon'S settings after loading the scriptfiles
	elseif event == "ADDON_LOADED" and arg1 == "ChiBar" then
		ChiBar:InitialStartUp()
	end
end

-- Function for registering Events
function ChiBar:unregisterEvents()
	ChiBar.mainFrame:UnregisterEvent("UNIT_POWER_FREQUENT")
	ChiBar.mainFrame:UnregisterEvent("UNIT_ENTERED_VEHICLE")
	ChiBar.mainFrame:UnregisterEvent("UNIT_EXITED_VEHICLE")
	ChiBar.mainFrame:UnregisterEvent("UNIT_MAXPOWER")
	ChiBar.mainFrame:UnregisterEvent("PLAYER_REGEN_DISABLED")
	ChiBar.mainFrame:UnregisterEvent("PLAYER_REGEN_ENABLED")
	ChiBar.mainFrame:UnregisterEvent("PET_BATTLE_OPENING_START")
	ChiBar.mainFrame:UnregisterEvent("PET_BATTLE_CLOSE")
	ChiBar.mainFrame:UnregisterEvent("UNIT_DISPLAYPOWER")
end

-- Function for unregistering Events
function ChiBar:registerEvents()
	ChiBar.mainFrame:RegisterEvent("UNIT_POWER_FREQUENT")
	ChiBar.mainFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
	ChiBar.mainFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
	ChiBar.mainFrame:RegisterEvent("UNIT_MAXPOWER")
	ChiBar.mainFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
	ChiBar.mainFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
	ChiBar.mainFrame:RegisterEvent("PET_BATTLE_OPENING_START")
	ChiBar.mainFrame:RegisterEvent("PET_BATTLE_CLOSE")
	ChiBar.mainFrame:RegisterEvent("UNIT_DISPLAYPOWER")
end

-- Registring Events the UI should react to -- Actually the fist executed code of the Addon!
ChiBar.mainFrame:RegisterEvent("ADDON_LOADED")
ChiBar.mainFrame:RegisterEvent("PLAYER_LOGIN")
ChiBar:registerEvents()
ChiBar.mainFrame:SetScript("OnEvent", ChiBar_OnEvent)
ChiBar.mainFrame:SetScript("OnDragStart", ChiBar.mainFrame.StartMoving)
ChiBar.mainFrame:SetScript("OnDragStop", ChiBar.mainFrame.StopMovingOrSizing)


------------------------------------------
--		SlashCommand					--
------------------------------------------

SLASH_CHIBAR1 = "/cb"
SLASH_CHIBAR2 = "/chibar"
SlashCmdList["CHIBAR"] = function(msg)
	if ChiBar.FIRST_SLASH_START == 0 then
		ChiBar.FIRST_SLASH_START = 1
		InterfaceOptionsFrame_OpenToCategory(ChiBar.opanel)
	end
	InterfaceOptionsFrame_OpenToCategory(ChiBar.opanel)
end


------------------------------------------
--		End of Script					--
------------------------------------------