local lang = SuR.Language
local vinMat = Material('surrounded/vin.png')
local anims_tab = {
    "sur_idles_m_armsback_",
    "sur_idles_m_armsfront_",
    "sur_idles_m_headache_",
    "sur_idles_m_hipleft_",
    "sur_idles_m_hipright_",
    "sur_idles_m_hips_",
    "sur_idles_m_neckache_",
}

local currentPointIndex = 1
local startTime = 0
local lastdatacam = {}
local modelcamtab = {}
local last_count_number = 0

local function CreateCamModels(data)
    for _, e in pairs(modelcamtab) do
        if !IsValid(e) then continue end
        e:Remove()
    end
    modelcamtab = {}
    
    local ply_tab, ply_index = player.GetAll(), 0
    for k, v in pairs(data.model) do
        ply_index = ply_index + 1
        local tar = ply_tab[ply_index]
        if !IsValid(tar) then continue end

        local anim = anims_tab[math.random(1,#anims_tab)]
        local model = ClientsideModel(tar:GetModel())
        modelcamtab[#modelcamtab+1] = model
        model.active_seq = anim.."loop"
        model.next_seq = anim.."toready"
        model.active_seq_noloop = false
        model.player = tar
        model:ResetSequence(anim.."loop")
        model:SetPos(v.pos)
        model:SetAngles(v.ang)
        model:SetEyeTarget(data.cam[#data.cam].pos)
        model:SetCycle(math.Rand(0,1))
    end
end

local function ready_up_anim()
    for k, v in pairs(modelcamtab) do
        v:SetCycle(0)
        v:ResetSequence(v.next_seq)
        v.active_seq = v.next_seq
        v.active_seq_noloop = true
    end
    timer.Simple(4, function()
        LocalPlayer():ScreenFade(SCREENFADE.OUT, color_black, 1, 2)
    end)
    timer.Simple(5, function()
        surface.PlaySound("surrounded/sfx/deploy_begin.mp3")
        SuR:StopDeployCutscene()
    end)
end

function SuR:StartDeployCutscene(cdata)
    local data = table.Copy(cdata)
    table.Shuffle(data.model)
    if !data.cam then return end

    SuR:PlayMusicOther(table.Random(SuR.Config.MusicWave["Deploy"]))
    SuR:StopDeployCutscene()
    table.insert(data.cam, 1, data.cam[1])
    LocalPlayer():ScreenFade(SCREENFADE.IN, color_black, 1, 1)
    CreateCamModels(data)

    local mode = "survival"
    if SuR.Config.Objective_Mode then
        mode = "objective"
    elseif SuR.Config.Versus_Mode then
        mode = "versus"
    end

    local team_ready = false
    hook.Add("HUDPaint", "SuR_DeployCutscene", function()
        surface.SetMaterial(vinMat)
        surface.SetDrawColor(0,0,0,200)
        surface.DrawTexturedRect(0, 0, ScrW(), ScrH())

        local ortime = SuR.Data["DeployTime"]-CurTime()
        local dtime = math.floor(ortime)
        if SuR.Data["Deploying"] and dtime >= 0 and SuR.Data["DrawHUD"] then
            if dtime > 5 then
                draw.SimpleText(lang["mode"]..lang["mode_"..mode], "SuR_SmallFont1", ScrW()/2, ScrH()-He(160), Color(200,200,50), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
                draw.SimpleText(string.format(lang["deploy_time"], dtime), "SuR_MediumFont1", ScrW()/2, ScrH()-He(130), color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
            else
                draw.SimpleText(dtime, "SuR_LargeFont1", ScrW()/2, ScrH()-He(200), color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
            end
            draw.SimpleText(lang["deploy_hint"], "SuR_SmallFont1", ScrW()/2, ScrH()-He(100), color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
            if player.GetCount() > #modelcamtab then
                draw.SimpleText(lang["deploy_big"], "SuR_SmallFont1", ScrW()/2, ScrH()-He(75), Color(255,255,255,200), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
            end
        end

        for k, v in pairs(modelcamtab) do
            if !IsValid(v.player) then continue end

            if v.player:GetModel() != v:GetModel() then
                local model = v.player:GetModel()
                v:SetModel(model)
                v:ResetSequence(v.active_seq)
            end

            local pos = v:GetBonePosition(v:LookupBone("ValveBiped.Bip01_Head1"))
            pos = (pos+Vector(0,0,16)):ToScreen()

            local icon = SuR.Config.ClassIcons[v.player:GetPlayerClass()]
            surface.SetMaterial(icon)
            surface.SetDrawColor(255,255,255,alpha)
            surface.DrawTexturedRect(pos.x-We(40), pos.y-He(16), We(32), He(32))
            draw.SimpleTextOutlined(v.player:Nick(), "SuR_SmallFont1", pos.x, pos.y-He(4), color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, 1, color_black)
            draw.SimpleTextOutlined(lang["class_lvl_"..v.player:GetLevel()], "SuR_PixelFont", pos.x, pos.y+He(8), color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, 1, color_black)
        end
    end)

    hook.Add("CalcView", "SuR_DeployCutscene", function(ply, pos, ang, fov)
        local tab = data.cam
        local currentTime = CurTime() - startTime
        local currentPoint = tab[currentPointIndex]
        local nextPoint = tab[currentPointIndex + 1]

        if player.GetCount() != #modelcamtab and #data.model >= player.GetCount() then
            surface.PlaySound("surrounded/sfx/deploy_new.mp3")
            CreateCamModels(data)
        end

        local ortime = SuR.Data["DeployTime"]-CurTime()
        local dtime = math.floor(ortime)
        if dtime <= 5 and last_count_number != dtime and dtime != 0 then
            surface.PlaySound("surrounded/sfx/deploy_tick.mp3")
            if not team_ready then 
                team_ready = true
                ready_up_anim() 
            end
        end
        last_count_number = dtime

        for k, v in pairs(modelcamtab) do
            if !v.active_seq then continue end
            local cycle = v:GetCycle()+FrameTime()/select(2, v:LookupSequence(v.active_seq))
            v:SetCycle(cycle)
            if cycle > 1 and not v.active_seq_noloop then
                v:SetCycle(0)
            end
            if !IsValid(v.player) then
                v:Remove()
            end
        end

        if nextPoint then
            local lerpedPos = LerpVector(currentTime / currentPoint.time, currentPoint.pos, nextPoint.pos)
            local lerpedAng = LerpAngle(currentTime / currentPoint.time, currentPoint.ang, nextPoint.ang)
            local lerpedFov = Lerp(currentTime / currentPoint.time, currentPoint.fov, nextPoint.fov)

            if currentTime >= currentPoint.time then
                currentPointIndex = currentPointIndex + 1
                startTime = CurTime()
            end

            lastdatacam = {lerpedPos, lerpedAng, lerpedFov}

            return {
                origin = lerpedPos,
                angles = lerpedAng,
                fov = lerpedFov,
                drawviewer = true,
            }
        else
            return {
                origin = lastdatacam[1],
                angles = lastdatacam[2],
                fov = lastdatacam[3],
                drawviewer = true,
            }
        end
    end)
end

function SuR:StopDeployCutscene()
    hook.Remove("CalcView", "SuR_DeployCutscene")
    hook.Remove("HUDPaint", "SuR_DeployCutscene")
    currentPointIndex = 1
    startTime = 0
    last_count_number = 0
    lastdatacam = {}
    for _, e in pairs(modelcamtab) do
        if !IsValid(e) then continue end
        e:Remove()
    end
    modelcamtab = {}
end

net.Receive("SuR.DeployCutscene", function()
    local bool = net.ReadBool()
    if bool then
        if !SuR.Config.Deploy_Cutscene then return end
        SuR:StartDeployCutscene(SuR.Config.Deploy_Cutscene)
    else
        SuR:StopDeployCutscene()
    end
end)

net.Receive("SuR.DeathView", function()
    local ent = net.ReadEntity()
    hook.Add("CalcView", "SuR_DeathView", function(ply, pos, angles, fov)
        if !IsValid(ent) or !ent:LookupAttachment('eyes') then
            hook.Remove("CalcView", "SuR_DeathView")
            return
        end
        local eye = ent:GetAttachment(ent:LookupAttachment('eyes'))
        if isvector(eye.Pos) then
            local view = {
                origin = eye.Pos,
                angles = eye.Ang,
                fov = fov,
                drawviewer = true,
                nearz = 1
            }
        
            return view
        end
    end)
    timer.Simple(2, function()
        LocalPlayer():ScreenFade(SCREENFADE.OUT, color_black, 1, 1)
    end)
    timer.Simple(3.5, function()
        hook.Remove("CalcView", "SuR_DeathView")
        LocalPlayer():ScreenFade(SCREENFADE.IN, color_black, 2, 1)
    end)
end)