-- NAME: Breakout
-- DESC: Break bricks with bouncing ball and paddle

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

-- Game constants
local PADDLE_WIDTH = 40
local PADDLE_HEIGHT = 6
local BALL_RADIUS = 4
local BRICK_WIDTH = 16
local BRICK_HEIGHT = 6
local BRICK_COLS = 16
local BRICK_ROWS = 5
local BRICK_START_Y = 20

function init()
    game.vars.state = STATE_MENU
    game.vars.score = 0
    game.vars.lives = 3
    
    -- Paddle
    game.vars.paddle_x = (game.width() / 2) - (PADDLE_WIDTH / 2)
    
    -- Ball
    game.vars.ball_x = game.width() / 2
    game.vars.ball_y = game.height() - 30
    game.vars.ball_vel_x = 2
    game.vars.ball_vel_y = -3
    
    -- Bricks (true = exists, false = broken)
    game.vars.bricks = {}
    game.vars.bricks_remaining = 0
    
    -- Enable continuous updates
    game.set_frame_updates(true)
    
    print("Breakout 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 paddle input
        if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.TOUCH_MOVE then
            game.vars.paddle_x = math.max(0, math.min(game.width() - PADDLE_WIDTH, event.x - PADDLE_WIDTH / 2))
        end
        
        -- Update physics on frame tick
        if event.type == INPUT.FRAME_TICK then
            update_ball()
            check_brick_collisions()
            
            -- Check win
            if game.vars.bricks_remaining <= 0 then
                game.vars.state = STATE_LEVEL_COMPLETE
            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
    
    elseif state == STATE_LEVEL_COMPLETE 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 - 30, game.height() / 2 - 30, "BREAKOUT", true, 2)
        renderer.text_scaled(game.width() / 2 - 50, game.height() / 2, "Tap to Start", true, 2)
    
    elseif state == STATE_PLAYING then
        -- Draw bricks
        for row = 1, BRICK_ROWS do
            for col = 1, BRICK_COLS do
                local idx = (row - 1) * BRICK_COLS + col
                if game.vars.bricks[idx] then
                    local x = (col - 1) * BRICK_WIDTH
                    local y = BRICK_START_Y + (row - 1) * BRICK_HEIGHT
                    renderer.rect(x, y, BRICK_WIDTH, BRICK_HEIGHT, true, true)
                end
            end
        end
        
        -- Draw paddle
        renderer.rect(game.vars.paddle_x, game.height() - PADDLE_HEIGHT - 2, PADDLE_WIDTH, PADDLE_HEIGHT, true, true)
        
        -- Draw ball (convert to integers)
        renderer.circle(math.floor(game.vars.ball_x + 0.5), math.floor(game.vars.ball_y + 0.5), BALL_RADIUS, true, true)
        
        -- Draw score and lives
        renderer.text_scaled(5, 5, "Score: " .. tostring(game.vars.score), true, 2)
        renderer.text_scaled(game.width() - 50, 5, "Lives: " .. tostring(game.vars.lives), true, 2)
    
    elseif state == STATE_GAME_OVER then
        renderer.text_scaled(game.width() / 2 - 40, game.height() / 2 - 20, "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 Menu", true, 2)
    
    elseif state == STATE_LEVEL_COMPLETE then
        renderer.text_scaled(game.width() / 2 - 50, game.height() / 2 - 20, "LEVEL COMPLETE!", 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 Menu", true, 2)
    end
end

function update_ball()
    -- Move ball
    game.vars.ball_x = game.vars.ball_x + game.vars.ball_vel_x
    game.vars.ball_y = game.vars.ball_y + game.vars.ball_vel_y
    
    -- Bounce off walls
    if game.vars.ball_x - BALL_RADIUS < 0 or game.vars.ball_x + BALL_RADIUS > game.width() then
        game.vars.ball_vel_x = -game.vars.ball_vel_x
        game.vars.ball_x = math.max(BALL_RADIUS, math.min(game.width() - BALL_RADIUS, game.vars.ball_x))
    end
    
    -- Bounce off top
    if game.vars.ball_y - BALL_RADIUS < 0 then
        game.vars.ball_vel_y = -game.vars.ball_vel_y
        game.vars.ball_y = BALL_RADIUS
    end
    
    -- Check paddle collision
    if game.vars.ball_y + BALL_RADIUS > game.height() - PADDLE_HEIGHT - 2 then
        if game.vars.ball_x > game.vars.paddle_x and game.vars.ball_x < game.vars.paddle_x + PADDLE_WIDTH then
            if game.vars.ball_vel_y > 0 then
                game.vars.ball_vel_y = -game.vars.ball_vel_y
                
                -- Add spin based on hit position
                local hit_pos = (game.vars.ball_x - game.vars.paddle_x) / PADDLE_WIDTH
                game.vars.ball_vel_x = (hit_pos - 0.5) * 4
            end
        end
    end
    
    -- Fall off bottom = lose life
    if game.vars.ball_y > game.height() then
        game.vars.lives = game.vars.lives - 1
        if game.vars.lives <= 0 then
            game.vars.state = STATE_GAME_OVER
        else
            reset_ball()
        end
    end
end

function check_brick_collisions()
    for row = 1, BRICK_ROWS do
        for col = 1, BRICK_COLS do
            local idx = (row - 1) * BRICK_COLS + col
            if game.vars.bricks[idx] then
                local brick_x = (col - 1) * BRICK_WIDTH
                local brick_y = BRICK_START_Y + (row - 1) * BRICK_HEIGHT
                
                -- Simple AABB collision with ball
                if game.vars.ball_x + BALL_RADIUS > brick_x and
                   game.vars.ball_x - BALL_RADIUS < brick_x + BRICK_WIDTH and
                   game.vars.ball_y + BALL_RADIUS > brick_y and
                   game.vars.ball_y - BALL_RADIUS < brick_y + BRICK_HEIGHT then
                    
                    -- Destroy brick
                    game.vars.bricks[idx] = false
                    game.vars.bricks_remaining = game.vars.bricks_remaining - 1
                    game.vars.score = game.vars.score + 10
                    
                    -- Bounce ball (simple: vertical bounce)
                    game.vars.ball_vel_y = -game.vars.ball_vel_y
                end
            end
        end
    end
end

function reset_ball()
    game.vars.ball_x = game.vars.paddle_x + PADDLE_WIDTH / 2
    game.vars.ball_y = game.height() - 30
    game.vars.ball_vel_x = 2
    game.vars.ball_vel_y = -3
end

function reset_game()
    game.vars.score = 0
    game.vars.lives = 3
    game.vars.paddle_x = (game.width() / 2) - (PADDLE_WIDTH / 2)
    
    -- Create brick grid
    game.vars.bricks = {}
    game.vars.bricks_remaining = BRICK_ROWS * BRICK_COLS
    for i = 1, BRICK_ROWS * BRICK_COLS do
        game.vars.bricks[i] = true
    end
    
    reset_ball()
end
