-- NAME: Tetris
-- DESC: Stack falling blocks, clear lines

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

-- Game constants
local GRID_WIDTH = 10
local GRID_HEIGHT = 20
local CELL_SIZE = 8
local SPAWN_RATE = 30  -- Frames before piece drops

-- Tetromino shapes (4 orientations each)
local TETROMINOS = {
    -- I piece
    {
        {{0, 0}, {1, 0}, {2, 0}, {3, 0}},
        {{0, 0}, {0, 1}, {0, 2}, {0, 3}},
        {{0, 0}, {1, 0}, {2, 0}, {3, 0}},
        {{0, 0}, {0, 1}, {0, 2}, {0, 3}}
    },
    -- O piece
    {
        {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
        {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
        {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
        {{0, 0}, {1, 0}, {0, 1}, {1, 1}}
    },
    -- T piece
    {
        {{1, 0}, {0, 1}, {1, 1}, {2, 1}},
        {{1, 0}, {0, 1}, {1, 1}, {1, 2}},
        {{0, 1}, {1, 1}, {2, 1}, {1, 2}},
        {{1, 0}, {1, 1}, {2, 1}, {1, 2}}
    },
    -- S piece
    {
        {{1, 0}, {2, 0}, {0, 1}, {1, 1}},
        {{0, 0}, {0, 1}, {1, 1}, {1, 2}},
        {{1, 0}, {2, 0}, {0, 1}, {1, 1}},
        {{0, 0}, {0, 1}, {1, 1}, {1, 2}}
    },
    -- Z piece
    {
        {{0, 0}, {1, 0}, {1, 1}, {2, 1}},
        {{1, 0}, {0, 1}, {1, 1}, {0, 2}},
        {{0, 0}, {1, 0}, {1, 1}, {2, 1}},
        {{1, 0}, {0, 1}, {1, 1}, {0, 2}}
    },
    -- J piece
    {
        {{0, 0}, {0, 1}, {1, 1}, {2, 1}},
        {{1, 0}, {2, 0}, {1, 1}, {1, 2}},
        {{0, 1}, {1, 1}, {2, 1}, {2, 0}},
        {{1, 0}, {1, 1}, {0, 2}, {1, 2}}
    },
    -- L piece
    {
        {{2, 0}, {0, 1}, {1, 1}, {2, 1}},
        {{1, 0}, {1, 1}, {1, 2}, {2, 2}},
        {{0, 1}, {1, 1}, {2, 1}, {0, 0}},
        {{0, 0}, {1, 0}, {1, 1}, {1, 2}}
    }
}

function init()
    game.vars.state = STATE_MENU
    game.vars.score = 0
    game.vars.level = 1
    game.vars.lines = 0
    
    -- Grid (0 = empty, 1 = filled)
    game.vars.grid = {}
    for y = 1, GRID_HEIGHT do
        game.vars.grid[y] = {}
        for x = 1, GRID_WIDTH do
            game.vars.grid[y][x] = 0
        end
    end
    
    -- Current piece
    game.vars.piece = nil
    game.vars.piece_x = 0
    game.vars.piece_y = 0
    game.vars.piece_type = 0
    game.vars.piece_rotation = 0
    
    -- Animation
    game.vars.frame_count = 0
    game.vars.clear_rows = {}
    game.vars.clearing = false
    
    -- Enable continuous updates
    game.set_frame_updates(true)
    
    print("Tetris 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 then
            if event.x < game.width() / 2 then
                -- Left side: move left
                if can_move(game.vars.piece, game.vars.piece_x - 1, game.vars.piece_y, game.vars.piece_rotation) then
                    game.vars.piece_x = game.vars.piece_x - 1
                end
            else
                -- Right side: move right
                if can_move(game.vars.piece, game.vars.piece_x + 1, game.vars.piece_y, game.vars.piece_rotation) then
                    game.vars.piece_x = game.vars.piece_x + 1
                end
            end
            return true
        end
        
        -- Update physics on frame tick
        if event.type == INPUT.FRAME_TICK then
            game.vars.frame_count = game.vars.frame_count + 1
            
            if game.vars.clearing then
                -- Clear animation
                if game.vars.frame_count % 10 == 0 then
                    clear_lines()
                    game.vars.clearing = false
                end
            else
                -- Drop piece
                if game.vars.frame_count >= SPAWN_RATE then
                    game.vars.frame_count = 0
                    
                    if can_move(game.vars.piece, game.vars.piece_x, game.vars.piece_y + 1, game.vars.piece_rotation) then
                        game.vars.piece_y = game.vars.piece_y + 1
                    else
                        -- Lock piece
                        lock_piece()
                        
                        -- Check for complete lines
                        local complete = check_complete_lines()
                        if #complete > 0 then
                            game.vars.clear_rows = complete
                            game.vars.clearing = true
                        else
                            spawn_piece()
                        end
                    end
                end
            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 - 20, game.height() / 2 - 30, "TETRIS", 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 grid
        local start_x = 20
        local start_y = 15
        
        for y = 1, GRID_HEIGHT do
            for x = 1, GRID_WIDTH do
                if game.vars.grid[y][x] == 1 then
                    renderer.rect(start_x + (x - 1) * CELL_SIZE, start_y + (y - 1) * CELL_SIZE, CELL_SIZE, CELL_SIZE, true, true)
                end
            end
        end
        
        -- Draw current piece
        if game.vars.piece then
            for _, block in ipairs(game.vars.piece) do
                local x = start_x + (game.vars.piece_x + block[1]) * CELL_SIZE
                local y = start_y + (game.vars.piece_y + block[2]) * CELL_SIZE
                renderer.rect(x, y, CELL_SIZE, CELL_SIZE, true, true)
            end
        end
        
        -- Draw score
        renderer.text_scaled(game.width() - 50, 10, "Score: " .. tostring(game.vars.score), true, 2)
        renderer.text_scaled(game.width() - 50, 20, "Lines: " .. tostring(game.vars.lines), 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 spawn_piece()
    game.vars.piece_type = math.random(1, #TETROMINOS)
    game.vars.piece_rotation = 1
    game.vars.piece = TETROMINOS[game.vars.piece_type][game.vars.piece_rotation]
    game.vars.piece_x = 3
    game.vars.piece_y = 0
    
    -- Check if game over
    if not can_move(game.vars.piece, game.vars.piece_x, game.vars.piece_y, game.vars.piece_rotation) then
        game.vars.state = STATE_GAME_OVER
    end
end

function lock_piece()
    if not game.vars.piece then return end
    
    for _, block in ipairs(game.vars.piece) do
        local x = game.vars.piece_x + block[1] + 1
        local y = game.vars.piece_y + block[2] + 1
        
        if y >= 1 and y <= GRID_HEIGHT and x >= 1 and x <= GRID_WIDTH then
            game.vars.grid[y][x] = 1
        end
    end
end

function can_move(piece, x, y, rotation)
    if not piece then return false end
    
    for _, block in ipairs(piece) do
        local grid_x = x + block[1] + 1
        local grid_y = y + block[2] + 1
        
        if grid_x < 1 or grid_x > GRID_WIDTH or grid_y < 1 or grid_y > GRID_HEIGHT then
            return false
        end
        
        if game.vars.grid[grid_y][grid_x] == 1 then
            return false
        end
    end
    
    return true
end

function check_complete_lines()
    local complete = {}
    
    for y = 1, GRID_HEIGHT do
        local full = true
        for x = 1, GRID_WIDTH do
            if game.vars.grid[y][x] == 0 then
                full = false
                break
            end
        end
        
        if full then
            table.insert(complete, y)
        end
    end
    
    return complete
end

function clear_lines()
    for _, y in ipairs(game.vars.clear_rows) do
        -- Remove line
        table.remove(game.vars.grid, y)
        -- Add empty line at top
        table.insert(game.vars.grid, 1, {})
        for x = 1, GRID_WIDTH do
            game.vars.grid[1][x] = 0
        end
    end
    
    game.vars.score = game.vars.score + (#game.vars.clear_rows * 100)
    game.vars.lines = game.vars.lines + #game.vars.clear_rows
    game.vars.clear_rows = {}
    
    spawn_piece()
end

function reset_game()
    game.vars.score = 0
    game.vars.level = 1
    game.vars.lines = 0
    game.vars.frame_count = 0
    game.vars.clearing = false
    
    -- Clear grid
    for y = 1, GRID_HEIGHT do
        for x = 1, GRID_WIDTH do
            game.vars.grid[y][x] = 0
        end
    end
    
    spawn_piece()
end
