local addonName, addon = ...

local GUI_VolumeBar = CreateFrame("Frame", "GUI_VolumeBar", UIParent)

GUI_VolumeBar:SetSize(20, 100)
function addon:GUI_VolumeBarSetPoint()
	GUI_VolumeBar:ClearAllPoints()
	GUI_VolumeBar:SetPoint("RIGHT", UIParent, "RIGHT", -45, 0)
	GUI_VolumeBar:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 300)
end

addon:GUI_VolumeBarSetPoint()

do
	local SIMPLE_BACKDROP = { bgFile = [[Interface\BUTTONS\WHITE8X8]] }
	local audio = CreateFrame("Button", "Audio_UI_Control", GUI_VolumeBar)
	audio:SetPoint("LEFT")
	audio:SetSize(20, 100)
	audio:EnableMouse(true)
	audio:SetScript("OnDragStart", audio.StartMoving)
	audio:SetScript("OnDragStop", audio.StopMovingOrSizing)
	audio:SetScript("OnHide", audio.StopMovingOrSizing)
	audio:SetBackdrop({
		bgFile = [[Interface\TutorialFrame\TutorialFrameBackground]], tile = true, tileSize = 32,
		edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]], edgeSize = 16,
		insets = { left = 5, right = 5, top = 5, bottom = 5 }
	})
	GUI_VolumeBar.audio = audio
	
	local volume = CreateFrame("Button", "$parent_Volume", audio)
	volume:SetPoint("BOTTOMLEFT", 5, 5)
	volume:SetPoint("RIGHT", -5, -5)
	volume:SetBackdrop(SIMPLE_BACKDROP)
	volume:SetBackdropColor(0, 1, 1, 0.5)
	audio.volume = volume
	
	local mask = CreateFrame("Button", "$parent_VolumeMask", audio)
	mask:SetPoint("BOTTOMLEFT", 5, 5)
	mask:SetPoint("TOPRIGHT", -5, -5)
	mask:SetBackdrop(SIMPLE_BACKDROP)
	mask:SetBackdropColor(1, 0, 0, 0.2)
	audio.volumeMask = mask
end

do
	local mute = CreateFrame("CheckButton", "Audio_UI_Mute", GUI_VolumeBar)
	mute:SetPoint("TOPLEFT", GUI_VolumeBar, "BOTTOMLEFT")
	mute:SetPoint("TOPRIGHT", GUI_VolumeBar, "BOTTOMRIGHT")
	mute:SetHeight(20)
	mute:SetNormalTexture([[Interface\COMMON\VOICECHAT-SPEAKER]])
	mute:SetCheckedTexture([[Interface\COMMON\VOICECHAT-MUTED]])
	--audio.mute = mute
end

Audio_Local_VolumeBarMask_Scripts = {}
Audio_Local_DraggingVolumeBar = nil
Audio_Local_VolumeBars = {}

--Set up binding calls
function Audio_Hook_BindVolumeBar(bar,mask)
	mask:RegisterForClicks("AnyUp","AnyDown")
	Audio_SetupScripts(mask, Audio_Local_VolumeBarMask_Scripts)
	Audio_Local_VolumeBars[mask] = bar
end

--Handle the volume control being clicked
function Audio_Local_VolumeBarMask_Scripts:OnClick(self)
    local _,y = GetCursorPosition()
	y = y / self:GetEffectiveScale() - self:GetBottom()
	Audio_SetVolume(y/(self:GetHeight()))
end

function Audio_Local_VolumeBarMask_Scripts:OnMouseDown(self)
	Audio_OnDragStart(self)
end

function Audio_Local_VolumeBarMask_Scripts:OnMouseUp(self)
	Audio_OnDragEnd(self)
end

function Audio_Local_VolumeBarMask_Scripts:OnHide(self)
	Audio_OnDragEnd(self)
end

function Audio_Local_VolumeBarMask_Scripts:OnUpdate(self,elapsed)
	Audio_OnDragUpdate(self,elapsed)
end

--DRAG
function Audio_OnDragStart(self)
	Audio_Local_DraggingVolumeBar = self
end

function Audio_OnDragEnd(self)
	Audio_Local_DraggingVolumeBar = nil
end

Audio_Local_UpdateInterval = 0.1; 
function Audio_OnDragUpdate(self,elapsed)
	if self.TimeSinceLastUpdate == nil then self.TimeSinceLastUpdate = 0 end
	self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed; 	
	  while (self.TimeSinceLastUpdate > Audio_Local_UpdateInterval) do
		 if Audio_Local_DraggingVolumeBar ~= nil then
			local _,y = GetCursorPosition()
			y = math.min((Audio_Local_DraggingVolumeBar:GetHeight()),math.max(0,y / Audio_UI_Control:GetEffectiveScale() - Audio_Local_DraggingVolumeBar:GetBottom()))
			Audio_SetVolume(y/(Audio_Local_DraggingVolumeBar:GetHeight()))
		end
		self.TimeSinceLastUpdate = self.TimeSinceLastUpdate - Audio_Local_UpdateInterval;
	 end
end

Audio_Local_MuteButton_Scripts = {}
Audio_Local_MuteButtons = {}

--Set up binding calls
function Audio_Hook_BindMuteButton(mute)
	mute:RegisterForClicks("AnyUp")
	Audio_SetupScripts(mute, Audio_Local_MuteButton_Scripts)
	Audio_Local_MuteButtons[mute] = mute
end

--Handle the volume control being clicked
function Audio_Local_MuteButton_Scripts:OnClick(self)
    Audio_ToggleMute()
end


--CODE
Audio_Local_Events = {}
Audio_Local_BindingBasedMute = false

--Make sure it looks tidy at the start
function Audio_Local_Events:VARIABLES_LOADED(...)
  Audio_RefreshAudio()
end

--Event for this function is terrble so hook it
--Have setting values go through triggers so that our UI matches whatever else messes w/ the volume
--Have to put this outside of SetVolume because it is a post hook :/
function Audio_SetCVar(name,val)
  if name == "Sound_MasterVolume" then
	if val ~= 0 then
		Audio_UnMute()
	else
		Audio_Mute()
	end
    Audio_RefreshAudio()
  end
end

--Set up and register functions and hooks
function Audio_OnLoad()
  Audio_Hook_BindVolumeBar(Audio_UI_Control_Volume, Audio_UI_Control_VolumeMask)
  Audio_Hook_BindMuteButton(Audio_UI_Mute)
  hooksecurefunc("SetCVar", Audio_SetCVar)
  Audio_SetupEvents(Audio_UI_Control, Audio_Local_Events)
end

function Audio_SetupEvents(frame,table,event)
  frame:SetScript("OnEvent", function(self, event, ...)
    table[event](self, ...); -- call one of the functions above
  end);
  for k, v in pairs(table) do
    frame:RegisterEvent(k); -- Register all events for which handlers have been defined
  end
end

function Audio_SetupScripts(frame,table)
  for k, v in pairs(table) do
	frame:SetScript(k, function(...)
		v(frame,...); -- call one of the functions above
	end);
  end
end

--Fixes up how the UI should be looking
function Audio_RefreshAudio()
  for mask,bar in pairs(Audio_Local_VolumeBars) do
	  local h = (mask:GetHeight())*GetCVar("Sound_MasterVolume")
	  --if you set height to 0 it goes to default height...
	  if h == 0 then
		bar:Hide()
	  else
		bar:SetHeight(h)
		bar:Show()
	  end
  end
  for _,mute in pairs(Audio_Local_MuteButtons) do
	  mute:SetChecked(addon.settings.Muted)
  end
end

--Toggles if audio is muted
function Audio_ToggleMute()
	if addon.settings.Muted then
		Audio_UnMute()
	else
		Audio_Mute()
	end
end

--Ground zero for messing with volume
function Audio_SetVolume(val)
	--Make it look muted if you set it to zero
	if val == 0 then
		addon.settings.Muted = true
		--Only save new volume if it is a different volume from current one (prevents multiple 0 sets)
		local checkVolume = GetCVar("Sound_MasterVolume")
		if checkVolume ~= addon.settings.MutedVolume then
			addon.settings.MutedVolume = checkVolume
		end
	else
		addon.settings.Muted = false
	end
	SetCVar("Sound_MasterVolume",val)
end

--Mutes audio if it is not already
function Audio_Mute()
	if not addon.settings.Muted then
		Audio_SetVolume(0)
	end
end

--Unmutes audio if it is not already
function Audio_UnMute()
	if addon.settings.Muted then
		Audio_SetVolume(addon.settings.MutedVolume)
	end
end

Audio_OnLoad()

function addon:GUI_ShowVolume()
	if addon.settings.showVolume then
		GUI_VolumeBar:Hide()
	else
		GUI_VolumeBar:Show()
		Audio_ToggleMute()-- needed twice over for
		Audio_ToggleMute()-- proper functionality
	end
end


addon.RegisterEvent("VolumeBar-Initialize", 'PLAYER_ENTERING_WORLD', function(self, event)
	addon.UnregisterEvent(self, event)
	addon:GUI_ShowVolume()
end)