c = require(_G.Modules.CharacterModule)
l = "Left Shoulder" 
r = "Right Shoulder"

local lastShot = tick()
local input = game:GetService("UserInputService")
local bulletModule = nil
if script.Parent:FindFirstChild("BulletModule") then bulletModule = require(_G.Modules.BulletModule) end
function init(gun)
	local fov = 60
	local returnTable = {}
	local la = {} -- states for the arm in different animations
	local ra = {}
	returnTable.la = la
	returnTable.ra = ra
	returnTable.maxRounds = 10
	returnTable.shouldRest = true
	returnTable.clock = 0.1
	returnTable.rounds = returnTable.maxRounds
	local aiming = false
	local shootEvent
	local cameraLast = game.Workspace.CurrentCamera.CFrame.Rotation

	ra.aiming = CFrame.new(0,-1,-2)
	ra.idling = CFrame.new(1,-1,-2) * CFrame.Angles(0,0,0.5)
	ra.recoil = CFrame.new(0,0,1.5)
	ra.sheath = CFrame.new(1.5,-4,0)*CFrame.Angles(-1.57,0,0)
	ra.reload = {}
	ra.reload.beforeSmashMagazine = CFrame.new(1,-0.5,-2)*CFrame.Angles(0.8,0.5,0)
	ra.reload.smashingMagazine = CFrame.new(0.7,-0.9,-2)*CFrame.Angles(0.4,0.3,0)
	ra.reload.beforeLoadingMagazine = CFrame.new(1,-0.5,-2)*CFrame.Angles(0.8,-0.5,0)
	ra.reload.loadingMagazine = CFrame.new(1,-0.5,-2)*CFrame.Angles(0.8,-0.5,0)
	ra.reload.beforePullBack = CFrame.new(2.2,-1,-2.5)*CFrame.Angles(-0.3,1.2,0.1)
	ra.reload.pullBack = CFrame.new(1.7,-1,-2.5)*CFrame.Angles(-0.3,1.2,0.1)

	la.idling = CFrame.new(-1.5,0,0)*CFrame.Angles(-1.57,0,0)
	la.resting = CFrame.new(-1.5,0,0)*CFrame.Angles(-1.57,0,0)
	la.aiming = CFrame.new(-0.5,-1.3,-2) * CFrame.Angles(0.3,-1,0)
	la.recoil = CFrame.new(0.5,0,0.75)
	la.sheath = CFrame.new(-1.5,-1.3,0)*CFrame.Angles(-1.57,0,0)
	la.reload = {}
	la.reload.beforeSmashMagazine = CFrame.new(-1.1,-1.5,0)*CFrame.Angles(-1.57,0,0)
	la.reload.smashingMagazine = CFrame.new(-1.1,-1.5,0)*CFrame.Angles(-1.57,0,0)
	la.reload.beforeLoadingMagazine = CFrame.new(0.3,-1.1,-2.5) * CFrame.Angles(0.4,-1,0)
	la.reload.loadingMagazine = CFrame.new(0.6,-0.7,-2)*CFrame.Angles(0.6,-1,0)
	la.reload.beforePullBack = CFrame.new(-1,-1,-2.6)*CFrame.Angles(0.4,0,0)
	la.reload.pullBack = CFrame.new(0.5,-1,-2.4)*CFrame.Angles(0.4,0,0)
	
	for name,cframe in pairs(la.reload) do
		la.reload[name] = cframe + Vector3.new(-0.4,0,0)
	end
	for name,cframe in pairs(ra.reload) do
		ra.reload[name] = cframe + Vector3.new(-0.4,0,0)
	end
	
	gun.Equipped:Connect(function()
		if c.humanoid.SeatPart then return end

		local rc = {} -- state for the arm
		local lc = {}
		
		local gc = {} -- state for gun pully thing
		
		c.disableMotors()
		
		rc.offset = CFrame.new(0,0,0)
		rc.target = ra.idling
		lc.offset = CFrame.new(0,0,0)
		lc.target = la.resting
		rc.janky = CFrame.new()
		lc.janky = CFrame.new()
		if not returnTable.shouldRest then lc.target = la.idling end
		gc.target = CFrame.new(0,0,0)
		c.cframes[r] = ra.sheath c.setArm(r)
		if not returnTable.shouldRest then c.setArm(l) c.cframes[l] = la.sheath c.setArm(l) 
		else c.restArm(l) c.cframes[l] = la.resting c.restArm(l) end
		
		c.run:UnbindFromRenderStep("GunMove")
		c.run:UnbindFromRenderStep("Transparency")
		
		local modes = {["idle"]=1,["reload"]=function()
			local scale = game.Workspace.Scale.Value
			rc.target = ra.reload.beforeSmashMagazine
			lc.target = la.reload.beforeSmashMagazine
			wait(0.3*scale)
			gun.MagOut:Play()
			rc.target = ra.reload.smashingMagazine
			lc.target = la.reload.smashingMagazine
			wait(0.4*scale)
			rc.target = ra.reload.beforeLoadingMagazine
			lc.target = la.reload.beforeLoadingMagazine
			wait(0.5*scale)
			rc.target = ra.reload.loadingMagazine
			lc.target = la.reload.loadingMagazine
			gun.MagIn:Play()
			wait(0.3*scale)
			rc.target = ra.reload.beforePullBack
			lc.target = la.reload.beforePullBack
			wait(0.4*scale)
			gun.Reload:Play()
			if gun:FindFirstChild("Slide") then gc.target = gun.Slide.Value end
			rc.target = ra.reload.pullBack
			lc.target = la.reload.pullBack
			wait(0.3*scale)
			gc.target = CFrame.new(0,0,0)
		end,}
		local mode = modes.idle
		local reloading = false
		
		if shootEvent then shootEvent:Disconnect() end
		shootEvent = gun.Activated:Connect(function()
			if not reloading and not c.running then
				if returnTable.rounds == 0 and returnTable.maxRounds > 0 then
					reloading = true
					modes.reload()
					reloading = false
					returnTable.rounds = returnTable.maxRounds
					return 
				end
				if tick()-lastShot < returnTable.clock then return end
				gun.Fired:Play()
				lastShot = tick()
				returnTable.rounds-=1
				local rot = Vector3.new(0,0,math.random(-10,10)/10)
				rc.offset = ra.recoil * CFrame.Angles(rot.x,rot.y,rot.z)
				if aiming or not returnTable.shouldRest then lc.offset = la.recoil end
				if gun.Gun:FindFirstChild("GunShot") then
					gun.Gun.GunShot.ParticleEmitter.Transparency = NumberSequence.new(0)
				end
				if gun:FindFirstChild("Slide") then gc.target = gun.Slide.Value end
				if bulletModule and gun.Gun:FindFirstChild("Barrel") then bulletModule.fire(gun.Gun.Barrel) end
				wait()
				if gun.Gun:FindFirstChild("GunShot") then
					gun.Gun.GunShot.ParticleEmitter.Transparency = NumberSequence.new(1)
				end
				rc.offset = CFrame.new(0,0,0)
				lc.offset = CFrame.new(0,0,0)
				wait(returnTable.clock/2)
				gc.target = CFrame.new(0,0,0)
			end
		end)
		c.run:BindToRenderStep("GunMove",Enum.RenderPriority.Last.Value,function(delta)
			if gun.Parent ~= c.model then c.enableMotors() return end
			--game.Players.LocalPlayer.CameraMode = Enum.CameraMode.LockFirstPerson
			if not reloading then
				if input:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) or input:IsKeyDown(Enum.KeyCode.Q) then
					aiming = true
					c.setRunning(false)
					rc.target = ra.aiming
					lc.target = la.aiming
					fov = (fov+60)/2
				else
					aiming = false
					fov = (fov+70)/2
					rc.target = ra.idling
					rc.janky = CFrame.new():Lerp(game.Workspace.CurrentCamera.CFrame.Rotation:ToObjectSpace(cameraLast),0.3)
					cameraLast = game.Workspace.CurrentCamera.CFrame.Rotation
					--if lc.target ~= la.resting then c.setArm(l) end
					if returnTable.shouldRest then lc.target = la.resting
					else lc.target = la.idling end
				end
				game.Workspace.CurrentCamera.FieldOfView = fov
				if c.running then
					rc.target = CFrame.new(1.5,-1,-1.5) * CFrame.Angles(1,0,0)
					lc.target = la.resting
				end
				if not reloading and input:IsKeyDown(Enum.KeyCode.R) then
					mode = modes.reload
					reloading = true
					modes.reload()
					mode = modes.idle
					reloading = false
					returnTable.rounds = returnTable.maxRounds
				end
			end
			if not c.humanoid.SeatPart then c.rotateCharacter() c.disableMotors() else --[[print("Enable")]] c.enableMotors() end
			c.targets[r] = rc.target * rc.offset * rc.janky
			c.targets[l] = lc.target * lc.offset * lc.janky
			if gun.Gun:FindFirstChild("Slide") and gun.Gun.Slide:FindFirstChild("Motor6D") then
				gun.Gun.Slide.Motor6D.C1 = gun.Gun.Slide.Motor6D.C1:Lerp(gc.target,0.5)
			end
			c.setArm(r,delta)
			if lc.target == la.resting then
				c.restArm(l,delta)
			else 
				c.setArm(l,delta)
			end
			c.motors[r].Part1.LocalTransparencyModifier = 0
			c.motors[l].Part1.LocalTransparencyModifier = 0
			c.motors[r].Part1.CastShadow = false
			c.motors[l].Part1.CastShadow = false
			if math.abs(game.Workspace.CurrentCamera.CFrame:ToObjectSpace(c.head.CFrame).Position.Z) > 1 then c.cameraOffset = Vector3.new(1,0,0) end
		end)
		c.run:BindToRenderStep("Transparency",2,function()
			--game.StarterPlayer.CameraMode = Enum.CameraMode.LockFirstPerson
		end)
	end)
	return returnTable
end
return getfenv()