-- This scales the scale amount non-linearly according to scaleWeight
function WeaponsGui:getWeightedScaleAmount(originalScaleAmount, newScreenDim, referenceScreenDim)
	return (1 - self.scaleWeight) * originalScaleAmount * referenceScreenDim / newScreenDim + self.scaleWeight * originalScaleAmount
end

function WeaponsGui:updateScale(guiObject, viewportSize)
	if guiObject:IsA("GuiObject") then
		local xScale = guiObject.Size.X.Scale
		local yScale = guiObject.Size.Y.Scale
		if xScale ~= 0 or yScale ~= 0 or self.originalScaleAmounts[guiObject] ~= nil then
			if self.originalScaleAmounts[guiObject] == nil then
				self.originalScaleAmounts[guiObject] = Vector2.new(xScale, yScale)
			end

			xScale = self:getWeightedScaleAmount(self.originalScaleAmounts[guiObject].X, viewportSize.X, self.referenceViewportSize.X)
			yScale = self:getWeightedScaleAmount(self.originalScaleAmounts[guiObject].Y, viewportSize.Y, self.referenceViewportSize.Y)
			guiObject.Size = UDim2.new(xScale, 0, yScale, 0)
		end
		return -- makes it so only the most outer container will be scaled
	end

	for _, child in ipairs(guiObject:GetChildren()) do
		self:updateScale(child, viewportSize)
	end
end

function WeaponsGui:setEnabled(enabled)
	if self.enabled == enabled then
		return
	end

	self.enabled = enabled
	if self.enabled then
		self.connections.renderStepped = RunService.RenderStepped:Connect(function(dt) self:onRenderStepped(dt) end)
	else
		self:setZoomed(false)

		for _, v in pairs(self.connections) do
			v:Disconnect()
		end
		self.connections = {}
	end

	if self.gui then
		self.gui.Enabled = self.enabled
	end
end

function WeaponsGui:setCrosshairEnabled(crosshairEnabled)
	if self.crosshairEnabled == crosshairEnabled then
		return
	end

	self.crosshairEnabled = crosshairEnabled
	if self.crosshairFrame then
		self.crosshairFrame.Visible = self.crosshairEnabled
	end
	if self.hitMarker then
		self.hitMarker.ImageTransparency = 1
		self.hitMarker.Visible = self.crosshairEnabled
	end
end

function WeaponsGui:setScopeEnabled(scopeEnabled)
	if self.scopeEnabled == scopeEnabled then
		return
	end

	self.scopeEnabled = scopeEnabled
	if self.scopeFrame then
		self.scopeFrame.Visible = self.scopeEnabled
	end

	local jumpButton = getJumpButton()

	if self.scopeEnabled then
		self.smallFireButton.Visible = true
		self.largeFireButton.Visible = true

		if jumpButton then
			jumpButton.Visible = false
		end
	else
		self.smallFireButton.Visible = false
		self.largeFireButton.Visible = false

		if jumpButton then
			jumpButton.Visible = true
		end
	end
end

function WeaponsGui:setCrosshairWeaponScale(scale)
	if self.crosshairWeaponScale == scale then
		return
	end

	self.crosshairWeaponScale = scale
end

function WeaponsGui:setCrosshairScaleTarget(target, dampingRatio, frequency)
	if typeof(dampingRatio) == "number" then
		self.crosshairDampingRatio = dampingRatio
	end
	if typeof(frequency) == "number" then
		self.crosshairFrequency = frequency
	end
	if self.crosshairScaleTarget == target then
		return
	end

	self.crosshairScaleTarget = target
	SpringService:Target(self, self.crosshairDampingRatio, self.crosshairFrequency, { crosshairScale = self.crosshairScaleTarget })
end

function WeaponsGui:setCrosshairScale(scale)
	if self.crosshairScale == scale then
		return
	end

	self.crosshairScale = scale
	SpringService:Target(self, self.crosshairDampingRatio, self.crosshairFrequency, { crosshairScale = self.crosshairScaleTarget })
end

function WeaponsGui:OnHitOtherPlayer(damage, humanoidHit) -- show hit indicator, then fade
	self.hitMarker.ImageTransparency = 0
	local tweenInfo = TweenInfo.new(0.8)
	local goal = {}
	goal.ImageTransparency = 1
	local tween = TweenService:Create(self.hitMarker, tweenInfo, goal)
	tween:Play()

	DamageBillboardHandler:ShowDamageBillboard(damage, humanoidHit.Parent:FindFirstChild("Head"))
end

function WeaponsGui:onRenderStepped(dt)
	if not self.enabled then
		return
	end
	if not self.gui then
		return
	end

	if self.crosshairFrame and self.crosshairEnabled then
		local crosshairSize = self.crosshairNormalSize * self.crosshairScale * self.crosshairWeaponScale
		self.crosshairFrame.Size = UDim2.new(0, crosshairSize.X, 0, crosshairSize.Y)
	end
end

function WeaponsGui:setZoomed(zoomed)
	if zoomed == self.isZoomed then
		return
	end

	self.isZoomed = zoomed
	local normalImage = self.isZoomed and AIM_OFF_NORMAL or AIM_ON_NORMAL
	local pressedImage = self.isZoomed and AIM_OFF_PRESSED or AIM_ON_PRESSED

	if self.smallAimButton then
		self.smallAimButton.Image = normalImage
		self.smallAimButton.PressedImage = pressedImage
	end
	if self.largeAimButton then
		self.largeAimButton.Image = normalImage
		self.largeAimButton.PressedImage = pressedImage
	end

	if self.weaponsSystem.camera then
		self.weaponsSystem.camera:setForceZoomed(self.isZoomed)
	end
end

function WeaponsGui:onTouchAimButtonActivated()
	self:setZoomed(not self.isZoomed)
end

function WeaponsGui:onTouchFireButton(inputObj, inputState)
	local currentWeapon = self.weaponsSystem.currentWeapon
	if currentWeapon and currentWeapon.instance and currentWeapon.instance:IsA("Tool") then
		if inputObj.UserInputState == Enum.UserInputState.Begin then
			currentWeapon.instance:Activate()
			if self.smallFireButton then
				self.smallFireButton.Image = FIRE_PRESSED
			end
			if self.largeFireButton then
				self.largeFireButton.Image = FIRE_PRESSED
			end

			inputObj:GetPropertyChangedSignal("UserInputState"):Connect(function()
				if inputObj.UserInputState == Enum.UserInputState.End then
					currentWeapon.instance:Deactivate()
					if self.smallFireButton then
						self.smallFireButton.Image = FIRE_NORMAL
					end
					if self.largeFireButton then
						self.largeFireButton.Image = FIRE_NORMAL
					end
				end
			end)
		end
	end
end

return WeaponsGui