local SML = LibStub("LibSharedMedia-3.0");
local switches, _ = {}
local switchValues = {}
local switchButtons = {}

local function GetSwitchButton(i)
	if not switchButtons[i] then
		local button = CreateFrame("Button", "WhatsNext_UserSwitchFrame"..i, nil, "WhatsNext_UserSwitchFrame")
		button.index = i
		if i ~= 1 then
			button:SetPoint("TOP",GetSwitchButton(i-1),"BOTTOM",0,-2)
		end
		button:Hide()
		switchButtons[i] = button
	end
	return switchButtons[i]
end

local function SetSwitchValue(self,value)
	local frameSettings = WhatsNext.db.profile.switchFrame
	switchValues[self.name:GetText()] = value
	self:RegisterForDrag("LeftButton");
	local textColor, bgColor, borderColor
	if value then
		textColor = frameSettings.textColorOn
		bgColor = frameSettings.bgColorOn
		borderColor = frameSettings.borderColorOn
	else
		textColor = frameSettings.textColorOff
		bgColor = frameSettings.bgColorOff
		borderColor = frameSettings.borderColorOff
	end
	
	self:SetMovable(true)
	self:SetScale(frameSettings.scale)
	self.name:SetFont(SML:Fetch('font', frameSettings.font), 16, frameSettings.outline)
	self.name:SetTextColor(textColor.r, textColor.g, textColor.b, textColor.a)
	self.bg:SetColorTexture(bgColor.r,bgColor.g,bgColor.b,bgColor.a)
	self.borderFrame:SetBackdropBorderColor(borderColor.r,borderColor.g,borderColor.b,borderColor.a)
	
	if self.index == 1 then
		local scale = self:GetEffectiveScale()
		local pos = frameSettings.pos
		self:SetPoint(pos.p1, nil, pos.p2, pos.x / scale, pos.y / scale)
	end
	self:SetWidth(self.name:GetStringWidth())
end

local function SetSwitch(self,switchName)
	self.name:SetText(switchName)
	SetSwitchValue(self,switchValues[self.name:GetText()])
	self:Show()
end

function WhatsNext_UserSwitch_Click(index)
	WhatsNext_UserSwitch_OnClick(GetSwitchButton(index))
end

function WhatsNext_UserSwitch_OnClick(self)
	if self:IsVisible() then
		SetSwitchValue(self, not switchValues[self.name:GetText()])
	end
end

function WhatsNext_UserSwitch_DragStart(self)
	if not WhatsNext.db.profile.switchFrame.locked then
		GetSwitchButton(1):StartMoving()
	end
end

function WhatsNext_UserSwitch_DragStop(self)
	local frame = GetSwitchButton(1)
	frame:StopMovingOrSizing()
	local scale = frame:GetEffectiveScale()
	local pos = WhatsNext.db.profile.switchFrame.pos
	pos.x = frame:GetLeft() * scale
	pos.y = frame:GetTop() * scale
	pos.p2 = "BOTTOMLEFT";
end

WhatsNext:AddDisplaySettingsListener(function()
	
	for _,button in ipairs(switchButtons) do
		SetSwitchValue(button,switchValues[button.name:GetText()])
	end
end)

WhatsNext:AddLogicSetUpdateListener(function(logicSet)
	wipe(switches)
	for _,block in ipairs(logicSet) do
		for _,check in ipairs(block.checks) do
			if check.type == "User Switch" and not tContains(switches, check.switchName) then
				tinsert(switches,check.switchName)
			end
		end
	end
	sort(switches)
	
	for _,button in ipairs(switchButtons) do
		button:Hide()
	end
	
	for i,switch in pairs(switches) do
		SetSwitch(GetSwitchButton(i),switch)
	end
end)

WhatsNext:AddConditionalStatement("User Switch",{
	category = "User Switches",
	test = function(checkTable)
		return switchValues[checkTable.switchName]
	end,
	text = "{switchName} is ON.",
	arguments = {
		switchName = {label = "Switch Name", type = "text", default = "Switch 1"}
	}
})

WhatsNext:AddConditionalStatement("User Switch Or",{
	category = "User Switches",
	test = function(checkTable)
		return switchValues[checkTable.switchName1] or switchValues[checkTable.switchName2]
	end,
	text = "{switchName1} OR {switchName2} is ON.",
	arguments = {
		switchName1 = {label = "Switch 1", type = "text", default = "Switch 1"},
		switchName2 = {label = "Switch 2", type = "text", default = "Switch 2"}
	}
})