-- NAME: Asteroids
-- DESC: Destroy asteroids, avoid collisions

-- Game states
local STATE_MENU = 0
local STATE_PLAYING = 1
local STATE_GAME_OVER = 2

-- Game constants
local SHIP_SPEED = 2
local SHIP_ROTATION_SPEED = 8
local BULLET_SPEED = 5
local ASTEROID_SPAWN_RATE = 120
local ASTEROID_SPEEDS = {1.5, 2, 2.5, 3}

function init()
    game.vars.state = STATE_MENU
    game.vars.score = 0
    game.vars.level = 1
    
    -- Ship
    game.vars.ship_x = game.width() / 2
    game.vars.ship_y = game.height() / 2
    game.vars.ship_angle = 0  -- Radians
    game.vars.ship_vel_x = 0
    game.vars.ship_vel_y = 0
    game.vars.thrusting = false
    
    -- Bullets
    game.vars.bullets = {}
    game.vars.bullet_cooldown = 0
    
    -- Asteroids
    game.vars.asteroids = {}
    game.vars.frame_count = 0
    
    -- Enable continuous updates
    game.set_frame_updates(true)
    
    print("Asteroids initialized")
end

function update(event)
    local state = game.vars.state
    
    if state == STATE_MENU then
        if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
            reset_game()
            game.vars.state = STATE_PLAYING
            return true
        end
    
    elseif state == STATE_PLAYING then
        -- Handle input
        if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.TOUCH_MOVE then
            if event.x < game.width() / 2 then
                -- Left side: rotate counter-clockwise
                game.vars.ship_angle = game.vars.ship_angle - SHIP_ROTATION_SPEED * 0.017
            else
                -- Right side: rotate clockwise
                game.vars.ship_angle = game.vars.ship_angle + SHIP_ROTATION_SPEED * 0.017
            end
            
            -- Thrust
            game.vars.thrusting = true
        else
            game.vars.thrusting = false
        end
        
        -- Update physics on frame tick
        if event.type == INPUT.FRAME_TICK then
            update_ship()
            update_bullets()
            update_asteroids()
            check_collisions()
            
            -- Spawn asteroids
            game.vars.frame_count = game.vars.frame_count + 1
            if game.vars.frame_count >= ASTEROID_SPAWN_RATE then
                spawn_asteroid(game.width() / 2, game.height() / 2, 3)
                game.vars.frame_count = 0
            end
            
            return true
        end
    
    elseif state == STATE_GAME_OVER then
        if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
            game.vars.state = STATE_MENU
            return true
        end
    end
    
    return false
end

function draw()
    renderer.clear(false)  -- Black background
    
    local state = game.vars.state
    
    if state == STATE_MENU then
        renderer.text_scaled(game.width() / 2 - 35, game.height() / 2 - 30, "ASTEROIDS", true, 2)
        renderer.text_scaled(game.width() / 2 - 50, game.height() / 2, "Tap to Start", true, 2)
    
    elseif state == STATE_PLAYING or state == STATE_GAME_OVER then
        -- Draw asteroids (convert to integers)
        for i = 1, #game.vars.asteroids do
            local ast = game.vars.asteroids[i]
            renderer.circle(math.floor(ast.x + 0.5), math.floor(ast.y + 0.5), ast.size, true, false)
        end
        
        -- Draw bullets
        for i = 1, #game.vars.bullets do
            local bullet = game.vars.bullets[i]
            renderer.pixel(bullet.x, bullet.y, true)
        end
        
        -- Draw ship
        local ship_size = 6
        local nose_x = game.vars.ship_x + math.cos(game.vars.ship_angle) * ship_size
        local nose_y = game.vars.ship_y + math.sin(game.vars.ship_angle) * ship_size
        local back_x = game.vars.ship_x - math.cos(game.vars.ship_angle) * (ship_size / 2)
        local back_y = game.vars.ship_y - math.sin(game.vars.ship_angle) * (ship_size / 2)
        
        renderer.line(game.vars.ship_x, game.vars.ship_y, nose_x, nose_y, true, 1)
        renderer.line(back_x, back_y, nose_x, nose_y, true, 1)
        
        -- Draw thrust indicator
        if game.vars.thrusting then
            local flame_x = game.vars.ship_x - math.cos(game.vars.ship_angle) * ship_size
            local flame_y = game.vars.ship_y - math.sin(game.vars.ship_angle) * ship_size
            renderer.line(game.vars.ship_x, game.vars.ship_y, flame_x, flame_y, true, 1)
        end
        
        -- Draw score
        renderer.text_scaled(10, 10, "Score: " .. tostring(game.vars.score), true, 2)
        renderer.text_scaled(10, 20, "Level: " .. tostring(game.vars.level), true, 2)
        
        if state == STATE_GAME_OVER then
            renderer.text_scaled(game.width() / 2 - 40, game.height() / 2, "GAME OVER", true, 2)
            renderer.text_scaled(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Menu", true, 2)
        end
    end
end

function update_ship()
    if game.vars.thrusting then
        game.vars.ship_vel_x = game.vars.ship_vel_x + math.cos(game.vars.ship_angle) * SHIP_SPEED
        game.vars.ship_vel_y = game.vars.ship_vel_y + math.sin(game.vars.ship_angle) * SHIP_SPEED
    end
    
    -- Friction
    game.vars.ship_vel_x = game.vars.ship_vel_x * 0.98
    game.vars.ship_vel_y = game.vars.ship_vel_y * 0.98
    
    -- Move ship
    game.vars.ship_x = game.vars.ship_x + game.vars.ship_vel_x
    game.vars.ship_y = game.vars.ship_y + game.vars.ship_vel_y
    
    -- Wrap around screen
    if game.vars.ship_x < 0 then game.vars.ship_x = game.width() end
    if game.vars.ship_x > game.width() then game.vars.ship_x = 0 end
    if game.vars.ship_y < 0 then game.vars.ship_y = game.height() end
    if game.vars.ship_y > game.height() then game.vars.ship_y = 0 end
end

function update_bullets()
    -- Update existing bullets
    for i = #game.vars.bullets, 1, -1 do
        local bullet = game.vars.bullets[i]
        bullet.x = bullet.x + bullet.vel_x
        bullet.y = bullet.y + bullet.vel_y
        
        -- Remove if off-screen
        if bullet.x < 0 or bullet.x > game.width() or bullet.y < 0 or bullet.y > game.height() then
            table.remove(game.vars.bullets, i)
        end
    end
    
    -- Fire bullet
    game.vars.bullet_cooldown = math.max(0, game.vars.bullet_cooldown - 1)
    if game.vars.thrusting and game.vars.bullet_cooldown == 0 then
        local bullet_x = game.vars.ship_x + math.cos(game.vars.ship_angle) * 8
        local bullet_y = game.vars.ship_y + math.sin(game.vars.ship_angle) * 8
        
        table.insert(game.vars.bullets, {
            x = bullet_x,
            y = bullet_y,
            vel_x = math.cos(game.vars.ship_angle) * BULLET_SPEED + game.vars.ship_vel_x,
            vel_y = math.sin(game.vars.ship_angle) * BULLET_SPEED + game.vars.ship_vel_y
        })
        
        game.vars.bullet_cooldown = 5
    end
end

function update_asteroids()
    for i = 1, #game.vars.asteroids do
        local ast = game.vars.asteroids[i]
        ast.x = ast.x + ast.vel_x
        ast.y = ast.y + ast.vel_y
        
        -- Wrap around screen
        if ast.x < -ast.size then ast.x = game.width() + ast.size end
        if ast.x > game.width() + ast.size then ast.x = -ast.size end
        if ast.y < -ast.size then ast.y = game.height() + ast.size end
        if ast.y > game.height() + ast.size then ast.y = -ast.size end
    end
end

function check_collisions()
    -- Bullet-asteroid collisions
    for b = #game.vars.bullets, 1, -1 do
        local bullet = game.vars.bullets[b]
        for a = #game.vars.asteroids, 1, -1 do
            local ast = game.vars.asteroids[a]
            
            local dx = bullet.x - ast.x
            local dy = bullet.y - ast.y
            local dist = math.sqrt(dx * dx + dy * dy)
            
            if dist < ast.size then
                -- Hit!
                table.remove(game.vars.bullets, b)
                table.remove(game.vars.asteroids, a)
                game.vars.score = game.vars.score + (4 - ast.size) * 50
                
                -- Spawn smaller asteroids
                if ast.size > 1 then
                    for _ = 1, 2 do
                        spawn_asteroid(ast.x, ast.y, ast.size - 1)
                    end
                end
                
                break
            end
        end
    end
    
    -- Ship-asteroid collisions
    for i = 1, #game.vars.asteroids do
        local ast = game.vars.asteroids[i]
        
        local dx = game.vars.ship_x - ast.x
        local dy = game.vars.ship_y - ast.y
        local dist = math.sqrt(dx * dx + dy * dy)
        
        if dist < ast.size + 6 then
            game.vars.state = STATE_GAME_OVER
        end
    end
end

function spawn_asteroid(x, y, size)
    if size < 1 then return end
    
    local speed = ASTEROID_SPEEDS[size]
    local angle = math.random() * math.pi * 2
    
    table.insert(game.vars.asteroids, {
        x = x,
        y = y,
        size = size,
        vel_x = math.cos(angle) * speed,
        vel_y = math.sin(angle) * speed
    })
end

function reset_game()
    game.vars.score = 0
    game.vars.level = 1
    game.vars.ship_x = game.width() / 2
    game.vars.ship_y = game.height() / 2
    game.vars.ship_angle = 0
    game.vars.ship_vel_x = 0
    game.vars.ship_vel_y = 0
    game.vars.bullets = {}
    game.vars.asteroids = {}
    game.vars.frame_count = 0
    
    spawn_asteroid(game.width() / 2 - 40, game.height() / 2 - 40, 3)
    spawn_asteroid(game.width() / 2 + 40, game.height() / 2 + 40, 3)
end
