local calc = require("#monocle.calc")
local draw = require("#monocle.draw")
local color = require("#microsoft.xna.framework.color")
local lua_helper = celeste.Mod.LuaCutscenes.LuaHelper
local ring = {}
local scene = getRoom()
local finishedRoutine = false
local lockPos = player.Center

local function damageRoutine()
    if player.DashAttacking then
        return
    end

    die()
end

local function makeCoroutine(func)
  return monocle.Coroutine(lua_helper.LuaCoroutineToIEnumerator(coroutine.create(func)))
end

local function makeDartRoutine(angle, entity)
    return function()
        local t = angle
        local lifetime = 2

        while lifetime > 0 do
            entity.Position = puppet.Center + calc.AngleToVector(t,32)
            
            if lifetime > 0.5 then
                t = t + 0.05
            else
                t = t + lifetime / 10
            end
            lifetime = lifetime - engine.deltaTime
            wait(0)
        end

        lifetime = 1
        local mult = 1

        while lifetime > 0 do
            entity.Position = entity.Position + calc.AngleToVector(t,4) * mult
            mult = mult + 0.01
            lifetime = lifetime - engine.deltaTime
            wait(0)
        end

        entity:RemoveSelf()
        finishedRoutine = true
    end
end

local function makeTrackingDartRoutine(entity)
    return function()
        
        wait(0.5)

        local lifetime = 5
        local target = calc.Toward(entity.Position, player.Center, 1)

        local t = 1.5

        while lifetime > 0 do
            
            entity.Position = entity.Position + target * t
            
            t = t + 0.1

            lifetime = lifetime - engine.deltaTime

            wait(0)
        end

        entity:RemoveSelf()
        finishedRoutine = true
    end
end

local function makePillarRoutine(entity)
    return function ()
        wait(3)

        local darts = {}

        for i = 1, 3, 1 do
            darts[#darts+1] = getNewBasicAttackEntity(vector2(entity.Position.X, entity.Position.Y + entity.Height * i / 3), getCircle(4), "badeline_projectile", true, damageRoutine)
            
            darts[#darts]:add(makeCoroutine(makeTrackingDartRoutine(darts[#darts])))

            scene:add(darts[#darts])
            
        end

        entity.Collidable = false

        wait(1)

        entity:RemoveSelf()
    end
end



function onBegin()

    finishedRoutine = false

    local pillars = {
        getNewBasicAttackActor(player.Center - vector2(150,128), getHitbox(1,128),"badeline_beam", 1, 90, true, true, damageRoutine),
        getNewBasicAttackActor(player.Center - vector2(-150,128), getHitbox(1,128),"badeline_beam", 1, 90, true, true, damageRoutine)
    }

    pillars[1].Sprite.Rotation = calc.Circle / 4

    pillars[1]:add(makeCoroutine(makePillarRoutine(pillars[1])))

    scene:add(pillars[1])

    pillars[2].Sprite.Rotation = calc.Circle / 4

    pillars[2]:add(makeCoroutine(makePillarRoutine(pillars[2])))

    scene:add(pillars[2])


    
    for i = 1, 14, 1 do
        local vec = calc.AngleToVector(calc.Circle * i / 14, 32)
        ring[#ring+1] = getNewBasicAttackEntity(puppet.Center + vec + vector2(0, -12), getCircle(2), "badeline_projectile", true, damageRoutine, 0.5, 0.5)
        
        ring[#ring]:add(makeCoroutine(makeDartRoutine(calc.Circle * i / 14, ring[#ring])))
        
        scene:add(ring[#ring])
    end

    wait(2)

end

function getXSpeed()
    return sign(-(puppet.Position.X - lockPos.X)) * 150
end

function getYSpeed()
    return sign((puppet.Position.X - lockPos.X + 16)) * 150
end

function sign(x)
    return (x<0 and -1) or 1
end  

function abs(x)
    return x * sign(x)
end