SWEP.GrenadeDownKey = IN_GRENADE1
SWEP.GrenadeMenuKey = IN_GRENADE2

function SWEP:IsQuickNadeAllowed()
    return TacRP.ConVars["quicknade"]:GetBool() and self:GetValue("CanQuickNade")
end

function SWEP:PrimeGrenade()
    self.Primary.Automatic = true

    if !self:IsQuickNadeAllowed() and !self:GetValue("PrimaryGrenade") then return end
    if self:StillWaiting(nil, true) then return end
    if self:GetPrimedGrenade() then return end

    if engine.ActiveGamemode() == "terrortown" and GetRoundState() == ROUND_PREP and ((TTT2 and !GetConVar("ttt_nade_throw_during_prep"):GetBool()) or (!TTT2 and GetConVar("ttt_no_nade_throw_during_prep"):GetBool())) then
        return
    end

    if !self:GetValue("PrimaryGrenade") and !self:CheckGrenade(nil, true) then
        self:SelectGrenade(nil, true)
    end

    -- if self:SprintLock() then return end

    self:CancelReload()

    local nade = self:GetValue("PrimaryGrenade") and TacRP.QuickNades[self:GetValue("PrimaryGrenade")] or self:GetGrenade()

    if nade.Singleton then
        if !self:GetOwner():HasWeapon(nade.GrenadeWep) then return end
    elseif !TacRP.IsGrenadeInfiniteAmmo(nade) then
        local ammo = self:GetOwner():GetAmmoCount(nade.Ammo)
        if ammo < 1 then return end

        -- self:GetOwner():SetAmmo(ammo - 1, nade.Ammo)
    end

    local rate = self:GetValue("QuickNadeTimeMult") / (nade.ThrowSpeed or 1)
    if self:GetValue("QuickNadeTryImpact") and nade.CanSetImpact then
        rate = rate * 1.5
    end

    local t = self:PlayAnimation("prime_grenade", rate, true)

    self:SetPrimedGrenade(true)
    self:ToggleBlindFire(TacRP.BLINDFIRE_NONE)
    self:ScopeToggle(0)

    local ct = CurTime()

    self:SetStartPrimedGrenadeTime(ct)
    self:SetAnimLockTime(ct + (t * 0.75))
    self:SetNextPrimaryFire(ct + (t * 1.1))

    self:GetOwner():DoCustomAnimEvent(PLAYERANIMEVENT_ATTACK_SECONDARY, t * 1000)

    if !nade.NoSounds then
        self:EmitSound(nade.PullSound or ("TacRP/weapons/grenade/pullpin-" .. math.random(1, 2) .. ".wav"), 65)
    end

    if CLIENT then return end

    self.CurrentGrenade = self:GetGrenade()
end

function SWEP:ThrowGrenade()
    local nade = self:GetValue("PrimaryGrenade") and TacRP.QuickNades[self:GetValue("PrimaryGrenade")] or self.CurrentGrenade or self:GetGrenade()

    local force = nade.ThrowForce
    local ent = nade.GrenadeEnt

    local src = self:GetOwner():EyePos()
    local ang = self:GetOwner():EyeAngles()
    local spread = 0

    local amount = 1

    local t = 0

    if !nade.OverhandOnly and (self.GrenadeThrowOverride == true or (self.GrenadeThrowOverride == nil and !self:GetOwner():KeyDown(self.GrenadeDownKey))) then
        t = self:PlayAnimation("throw_grenade_underhand", self:GetValue("QuickNadeTimeMult"), true, true)

        force = force / 2
        ang:RotateAroundAxis(ang:Right(), 20)
        if nade.UnderhandSpecial then
            force = force * 0.75
            ang:RotateAroundAxis(ang:Right(), -10)
            amount = math.random(2, 4)
            spread = 0.15
        end
    else
        ang:RotateAroundAxis(ang:Right(), 5)
        t = self:PlayAnimation("throw_grenade", self:GetValue("QuickNadeTimeMult"), true, true)
    end

    self.GrenadeThrowOverride = nil
    self.GrenadeDownKey = IN_GRENADE1

    if SERVER then
        if (self.GrenadeThrowCharge or 0) > 0 then
            force = force * (1 + self.GrenadeThrowCharge)
        end
        self.GrenadeThrowCharge = nil

        for i = 1, amount do

            local rocket = ents.Create(ent or "")

            if !IsValid(rocket) then return end

            local dispersion = Angle(math.Rand(-1, 1), math.Rand(-1, 1), 0)
            dispersion = dispersion * spread * 36

            rocket:SetPos(src)
            rocket:SetOwner(self:GetOwner())
            rocket:SetAngles(ang + dispersion)
            rocket:Spawn()
            rocket:SetPhysicsAttacker(self:GetOwner(), 10)

            if TacRP.IsGrenadeInfiniteAmmo(nade) then
                rocket.PickupAmmo = nil
                rocket.WeaponClass = nil -- dz ents
            end

            if self:GetValue("QuickNadeTryImpact") and nade.CanSetImpact then
                rocket.InstantFuse = false
                rocket.Delay = 0
                rocket.Armed = false
                rocket.ImpactFuse = true
            end

            if nade.TTTTimer then
                rocket:SetGravity(0.4)
                rocket:SetFriction(0.2)
                rocket:SetElasticity(0.45)
                rocket:SetDetonateExact(CurTime() + nade.TTTTimer)
                rocket:SetThrower(self:GetOwner())
            end

            local phys = rocket:GetPhysicsObject()

            if phys:IsValid() then
                phys:ApplyForceCenter((ang + dispersion):Forward() * force + self:GetOwner():GetVelocity())
                phys:AddAngleVelocity(VectorRand() * 1000)
            end

            if nade.Spoon and TacRP.ConVars["dropmagazinemodel"]:GetBool() then
                local mag = ents.Create("TacRP_droppedmag")

                if mag then
                    mag:SetPos(src)
                    mag:SetAngles(ang)
                    mag.Model = "models/weapons/tacint/flashbang_spoon.mdl"
                    mag.ImpactType = "spoon"
                    mag:SetOwner(self:GetOwner())
                    mag:Spawn()

                    local phys2 = mag:GetPhysicsObject()

                    if IsValid(phys2) then
                        phys2:ApplyForceCenter(ang:Forward() * force * 0.25 + VectorRand() * 25)
                        phys2:AddAngleVelocity(Vector(math.Rand(-300, 300), math.Rand(-300, 300), math.Rand(-300, 300)))
                    end
                end
            end
        end

        if !nade.NoSounds then
            self:EmitSound(nade.ThrowSound or ("tacrp/weapons/grenade/throw-" .. math.random(1, 2) .. ".wav"), 65)
        end

        if !nade.Singleton and !TacRP.IsGrenadeInfiniteAmmo(nade) then
            self:GetOwner():RemoveAmmo(1, nade.Ammo)
        end
    end

    if self:GetValue("PrimaryGrenade") then
        if !TacRP.IsGrenadeInfiniteAmmo(nade) and self:GetOwner():GetAmmoCount(nade.Ammo) == 0 then
            if SERVER then
                self:Remove()
            end
        else
            self:SetTimer(t, function()
                self:PlayAnimation("deploy", self:GetValue("DeployTimeMult"), true, true)
            end)
        end
    elseif nade.Singleton and self:GetOwner():HasWeapon(nade.GrenadeWep) then
        local nadewep = self:GetOwner():GetWeapon(nade.GrenadeWep)
        nadewep.OnRemove = nil -- TTT wants to switch to unarmed when the nade wep is removed - DON'T.
        if SERVER then
            nadewep:Remove()
        end
    elseif nade.GrenadeWep and self:GetOwner():HasWeapon(nade.GrenadeWep) and !TacRP.IsGrenadeInfiniteAmmo(nade) and self:GetOwner():GetAmmoCount(nade.Ammo) == 0 then
        if SERVER then
            self:GetOwner():GetWeapon(nade.GrenadeWep):Remove()
        end
    end
end

function SWEP:GetGrenade(index)
    index = index or self:GetGrenadeIndex()

    return TacRP.QuickNades[TacRP.QuickNades_Index[index]]
end

function SWEP:GetGrenadeIndex()
    return IsValid(self:GetOwner()) and self:GetOwner():GetNWInt("ti_nade", 1) or 1
end

function SWEP:GetNextGrenade(ind)
    ind = ind or self:GetGrenadeIndex()

    ind = ind + 1

    if ind > TacRP.QuickNades_Count then
        ind = 1
    elseif ind < 1 then
        ind = TacRP.QuickNades_Count
    end

    if !self:CheckGrenade(ind) then
        return self:GetNextGrenade(ind)
    end

    return self:GetGrenade(ind)
end

function SWEP:SelectGrenade(index, requireammo)
    if !self:IsQuickNadeAllowed() then return end
    if !IsFirstTimePredicted() then return end
    if self:GetPrimedGrenade() then return end

    local ind = self:GetOwner():GetNWInt("ti_nade", 1)

    if index then
        ind = index
    elseif !requireammo then
        if self:GetOwner():KeyDown(IN_WALK) then
            ind = ind - 1
        else
            ind = ind + 1
        end
    end

    if ind > TacRP.QuickNades_Count then
        ind = 1
    elseif ind < 1 then
        ind = TacRP.QuickNades_Count
    end

    if !self:CheckGrenade(ind, requireammo) then
        local nades = self:GetAvailableGrenades(requireammo)
        if #nades > 0 then
            ind = nades[1].Index
        end
    end

    self:GetOwner():SetNWInt("ti_nade", ind)
    self.Secondary.Ammo = self:GetGrenade().Ammo or "none"
end

function SWEP:CheckGrenade(index, checkammo)
    index = index or (self:GetValue("PrimaryGrenade") and TacRP.QuickNades_Index[self:GetValue("PrimaryGrenade")] or self:GetOwner():GetNWInt("ti_nade", 1))
    local nade = self:GetGrenade(index)
    if nade.Singleton then
        return self:GetOwner():HasWeapon(nade.GrenadeWep)
    end
    local hasammo = (nade.Ammo == nil or self:GetOwner():GetAmmoCount(nade.Ammo) > 0)
    if (nade.Secret and !hasammo and (!nade.SecretWeapon or !self:GetOwner():HasWeapon(nade.SecretWeapon))) or (nade.RequireStat and !self:GetValue(nade.RequireStat)) then
        return false
    end
    if checkammo and !TacRP.IsGrenadeInfiniteAmmo(index) and !hasammo then
        return false
    end
    return true
end

function SWEP:GetAvailableGrenades(checkammo)
    local nades = {}

    for i = 1, TacRP.QuickNades_Count do
        if self:CheckGrenade(i, checkammo) then
            table.insert(nades, self:GetGrenade(i))
        end
    end

    return nades
end

if CLIENT then

SWEP.QuickNadeModel = nil

end

function SWEP:ThinkGrenade()
    if !self:IsQuickNadeAllowed() then return end

    if CLIENT then
        if self:GetPrimedGrenade() and !IsValid(self.QuickNadeModel) and self:GetStartPrimedGrenadeTime() + 0.2 < CurTime() and self:GetGrenade().Model then
            local nade = self:GetGrenade()
            local vm = self:GetVM()

            local model = ClientsideModel(nade.Model or "models/weapons/tacint/v_quicknade_frag.mdl")

            if !IsValid(model) then return end

            model:SetParent(vm)
            model:AddEffects(EF_BONEMERGE)
            model:SetNoDraw(true)

            if nade.Material then
                model:SetMaterial(nade.Material)
            end

            self.QuickNadeModel = model

            local tbl = {
                Model = model,
                Weapon = self
            }

            table.insert(TacRP.CSModelPile, tbl)
        elseif !self:GetPrimedGrenade() and self.QuickNadeModel then
            SafeRemoveEntity(self.QuickNadeModel)
            self.QuickNadeModel = nil
        end
    end

    if self:GetOwner():KeyPressed(IN_GRENADE1) then
        self:PrimeGrenade()
    elseif !tobool(self:GetOwner():GetInfo("tacrp_nademenu")) and self:GetOwner():KeyPressed(self.GrenadeMenuKey) then
        self:SelectGrenade()
    elseif tobool(self:GetOwner():GetInfo("tacrp_nademenu")) and self.GrenadeMenuKey != IN_GRENADE2 and !self:GetOwner():KeyDown(self.GrenadeMenuKey) then
        self.GrenadeMenuKey = IN_GRENADE2
    end

    if CLIENT and self.GrenadeWaitSelect and self:GetOwner():HasWeapon(self.GrenadeWaitSelect) then
        input.SelectWeapon(self:GetOwner():GetWeapon(self.GrenadeWaitSelect))
        self.GrenadeWaitSelect = nil
    end

    if self:GetPrimedGrenade() and self:GetAnimLockTime() < CurTime() then
        self:ThrowGrenade()
        self:SetPrimedGrenade(false)
    end
end
