-- luacheck: globals Hook Keys LuaUserData PlayerInput Character Descriptors CLIENT
-- luacheck: max line length 420
if not CLIENT then return end

local isToggle = true     -- toggle or hold behaviour
local smoothZoom = false  -- smooth or step

local zStep = 0.5         -- step size for when smoothZoom=false
local zSpeed = 0.02       -- speed for when smoothZoom=true
local zMin = 0.35          -- minimum zoom modifier
local zMax = 2.5          -- maximum zoom modifier
local zStart = 0.35        -- default zoom level

local zKey = Keys.P       -- zoom key
local dKey = Keys.NumPad1 -- decrease zoom key
local iKey = Keys.NumPad2 -- increase zoom key
local rKey = Keys.Back    -- reset zoom key
-- customization end
--end

local zoomOn = false -- default zoom state
local gzsDefault = false
zStart = math.max(math.min(zMax, zStart), zMin)
local gzsNew = zStart
local gzsMin = zMin
local gzsMax = zMax
local gzsUpd = false

local dHeld = false
local iHeld = false
local zHeld = false

LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.Camera"], "globalZoomScale")
LuaUserData.MakeMethodAccessible(Descriptors["Barotrauma.Camera"], "CreateMatrices")

Hook.HookMethod("Barotrauma.Camera", "CreateMatrices", function(instance, _)
	gzsDefault = instance.globalZoomScale
	gzsMin = math.max(zMin, gzsDefault * zMin)
	gzsMax = math.min(zMax, gzsDefault * zMax)
	gzsNew = math.max(math.min(gzsMax, gzsDefault * zStart), gzsMin)
	gzsUpd = true
	instance.MinZoom = math.min(gzsMin / 2, instance.MinZoom)
	instance.MaxZoom = math.max(gzsMax * 2, instance.MaxZoom)
end, Hook.HookMethodType.After)

Hook.HookMethod("Barotrauma.Character", "ControlLocalPlayer", function(_, ptable)
	gzsUpd = false
	if not gzsDefault then
		ptable.cam.CreateMatrices()
	else
		if not Character.DisableControls and Character.Controlled then
			if zoomOn then
				if PlayerInput.KeyDown(dKey) then
					if smoothZoom then
						gzsNew = math.max(gzsMin, gzsNew * (1 - zSpeed))
						gzsUpd = true
					elseif not dHeld then
						gzsNew = math.max(gzsMin, gzsNew - zStep)
						dHeld = true
						gzsUpd = true
					end
				else
					dHeld = false
				end
				if PlayerInput.KeyDown(iKey) then
					if smoothZoom then
						gzsNew = math.min(gzsMax, gzsNew * (1 + zSpeed))
						gzsUpd = true
					elseif not iHeld then
						gzsNew = math.min(gzsMax, gzsNew + zStep)
						iHeld = true
						gzsUpd = true
					end
				else
					iHeld = false
				end
				if PlayerInput.KeyDown(rKey) then
					gzsNew = gzsDefault * zStart
					gzsUpd = true
				end
			end
			if PlayerInput.KeyDown(zKey) or PlayerInput.Mouse5ButtonClicked() then
				if isToggle then
					if not zHeld then
						zoomOn = not zoomOn
						zHeld = true
						gzsUpd = true
					end
				else
					zoomOn = true
					gzsUpd = true
				end
			elseif isToggle then
				zHeld = false
			elseif zoomOn then
				zoomOn = false
				gzsUpd = true
			end
		else
			zoomOn = false
		end
		if gzsUpd then
			ptable.cam.globalZoomScale = zoomOn and gzsNew or gzsDefault
		end
	end
end, Hook.HookMethodType.After)
