-- NAME: Flappy Bird
-- DESC: Tap to flap, avoid pipes

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

-- Game constants
local BIRD_SIZE = 8
local BIRD_GRAVITY = 0.3
local BIRD_FLAP_POWER = -7
local PIPE_WIDTH = 20
local PIPE_GAP = 50
local PIPE_SPEED = 3
local SPAWN_RATE = 80  -- Frames between pipe spawns

function init()
    game.vars.state = STATE_MENU
    game.vars.score = 0
    game.vars.frame_count = 0
    
    -- Bird
    game.vars.bird_y = game.height() / 2
    game.vars.bird_vel = 0
    
    -- Pipes (array of {x, gap_y})
    game.vars.pipes = {}
    game.vars.last_pipe_frame = 0
    
    -- Enable continuous updates
    game.set_frame_updates(true)
    
    print("Flappy Bird 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 flap input
        if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
            game.vars.bird_vel = BIRD_FLAP_POWER
        end
        
        -- Update physics on frame tick
        if event.type == INPUT.FRAME_TICK then
            update_bird()
            update_pipes()
            check_collisions()
            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 - 40, game.height() / 2 - 30, "FLAPPY BIRD", true, 2)
        renderer.text_scaled(game.width() / 2 - 50, game.height() / 2, "Tap to Start", true, 2)
    
    elseif state == STATE_PLAYING then
        -- Draw bird (convert to integer)
        renderer.circle(20, math.floor(game.vars.bird_y + 0.5), BIRD_SIZE, true, true)
        
        -- Draw pipes
        for i = 1, #game.vars.pipes do
            local pipe = game.vars.pipes[i]
            
            -- Top pipe
            renderer.rect(pipe.x, 0, PIPE_WIDTH, pipe.gap_y, true, true)
            
            -- Bottom pipe
            local bottom_start = pipe.gap_y + PIPE_GAP
            renderer.rect(pipe.x, bottom_start, PIPE_WIDTH, game.height() - bottom_start, true, true)
        end
        
        -- Draw score
        renderer.text_scaled(10, 10, "Score: " .. tostring(game.vars.score), true, 2)
    
    elseif state == STATE_GAME_OVER then
        renderer.text_scaled(game.width() / 2 - 40, game.height() / 2 - 30, "GAME OVER", true, 2)
        renderer.text_scaled(game.width() / 2 - 30, game.height() / 2, "Score: " .. tostring(game.vars.score), true, 2)
        renderer.text_scaled(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Restart", true, 2)
    end
end

function update_bird()
    -- Apply gravity
    game.vars.bird_vel = game.vars.bird_vel + BIRD_GRAVITY
    game.vars.bird_y = game.vars.bird_y + game.vars.bird_vel
    
    -- Clamp to screen (game over if hit top/bottom)
    if game.vars.bird_y - BIRD_SIZE < 0 or game.vars.bird_y + BIRD_SIZE > game.height() then
        game.vars.state = STATE_GAME_OVER
    end
end

function update_pipes()
    game.vars.frame_count = game.vars.frame_count + 1
    
    -- Spawn new pipe
    if game.vars.frame_count - game.vars.last_pipe_frame >= SPAWN_RATE then
        local gap_y = math.random(30, game.height() - PIPE_GAP - 30)
        table.insert(game.vars.pipes, {x = game.width(), gap_y = gap_y})
        game.vars.last_pipe_frame = game.vars.frame_count
    end
    
    -- Move and remove off-screen pipes
    for i = #game.vars.pipes, 1, -1 do
        local pipe = game.vars.pipes[i]
        pipe.x = pipe.x - PIPE_SPEED
        
        -- Score when pipe passes bird
        if pipe.x == 20 then
            game.vars.score = game.vars.score + 1
        end
        
        -- Remove if off-screen
        if pipe.x < -PIPE_WIDTH then
            table.remove(game.vars.pipes, i)
        end
    end
end

function check_collisions()
    -- Check collision with pipes
    for i = 1, #game.vars.pipes do
        local pipe = game.vars.pipes[i]
        
        -- Bird hitbox: circle at (20, bird_y) with radius BIRD_SIZE
        -- Check if within pipe's X range
        if 20 + BIRD_SIZE > pipe.x and 20 - BIRD_SIZE < pipe.x + PIPE_WIDTH then
            -- Check Y collision
            if game.vars.bird_y - BIRD_SIZE < pipe.gap_y or 
               game.vars.bird_y + BIRD_SIZE > pipe.gap_y + PIPE_GAP then
                game.vars.state = STATE_GAME_OVER
            end
        end
    end
end

function reset_game()
    game.vars.score = 0
    game.vars.bird_y = game.height() / 2
    game.vars.bird_vel = 0
    game.vars.pipes = {}
    game.vars.frame_count = 0
    game.vars.last_pipe_frame = 0
end
