-- NAME: Snake Game
-- DESC: Classic snake with state machine

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

-- Game constants
local CELL_SIZE = 10
local GRID_W = 40
local GRID_H = 28

-- Initialize game
function init()
    game.vars.state = STATE_MENU
    game.vars.score = 0
    game.vars.high_score = 0
    
    -- Snake as array of {x, y} positions
    game.vars.snake = {}
    game.vars.snake[1] = {x = 20, y = 14}
    game.vars.snake[2] = {x = 19, y = 14}
    game.vars.snake[3] = {x = 18, y = 14}
    
    game.vars.dir_x = 1
    game.vars.dir_y = 0
    
    game.vars.food_x = 30
    game.vars.food_y = 14
    
    game.vars.frame_count = 0
    game.vars.move_speed = 20  -- Frames between moves (doubled from 10 for half speed)
    
    -- Enable continuous frame updates
    game.set_frame_updates(true)
    
    print("Snake Game initialized")
end

-- Update game logic
function update(event)
    local state = game.vars.state
    
    -- State: MENU
    if state == STATE_MENU then
        if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
            game.vars.state = STATE_PLAYING
            game.vars.score = 0
            init_snake()
            spawn_food()
            return true
        end
    
    -- State: PLAYING
    elseif state == STATE_PLAYING then
        -- Handle input for direction change
        if event.type == INPUT.TOUCH_DOWN then
            local head = game.vars.snake[1]
            local head_screen_x = head.x * CELL_SIZE
            local head_screen_y = head.y * CELL_SIZE
            
            local dx = event.x - head_screen_x
            local dy = event.y - head_screen_y
            
            -- Change direction based on touch relative to head
            if math.abs(dx) > math.abs(dy) then
                if dx > 0 and game.vars.dir_x ~= -1 then
                    game.vars.dir_x = 1
                    game.vars.dir_y = 0
                elseif dx < 0 and game.vars.dir_x ~= 1 then
                    game.vars.dir_x = -1
                    game.vars.dir_y = 0
                end
            else
                if dy > 0 and game.vars.dir_y ~= -1 then
                    game.vars.dir_x = 0
                    game.vars.dir_y = 1
                elseif dy < 0 and game.vars.dir_y ~= 1 then
                    game.vars.dir_x = 0
                    game.vars.dir_y = -1
                end
            end
        end
        
        -- Move snake every N frames
        game.vars.frame_count = game.vars.frame_count + 1
        if game.vars.frame_count >= game.vars.move_speed then
            game.vars.frame_count = 0
            move_snake()
            return true
        end
    
    -- State: GAME_OVER
    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

-- Draw game
function draw()
    renderer.clear(false)
    
    local state = game.vars.state
    
    -- Draw: MENU
    if state == STATE_MENU then
        renderer.text(game.width() / 2 - 30, game.height() / 2 - 20, "SNAKE", true)
        renderer.text(game.width() / 2 - 50, game.height() / 2, "Tap to Start", true)
        
        if game.vars.high_score > 0 then
            local hs_text = "High: " .. tostring(game.vars.high_score)
            renderer.text(game.width() / 2 - 30, game.height() / 2 + 20, hs_text, true)
        end
    
    -- Draw: PLAYING
    elseif state == STATE_PLAYING then
        -- Draw snake
        for i = 1, #game.vars.snake do
            local seg = game.vars.snake[i]
            local filled = (i == 1)  -- Head filled, body outline
            renderer.rect(seg.x * CELL_SIZE, seg.y * CELL_SIZE, CELL_SIZE, CELL_SIZE, true, filled)
        end
        
        -- Draw food (convert center to integers)
        renderer.circle(math.floor(game.vars.food_x * CELL_SIZE + CELL_SIZE / 2 + 0.5), 
                       math.floor(game.vars.food_y * CELL_SIZE + CELL_SIZE / 2 + 0.5), 
                       CELL_SIZE / 2, true, true)
        
        -- Draw score
        local score_text = "Score: " .. tostring(game.vars.score)
        renderer.text(5, 5, score_text, true)
    
    -- Draw: GAME_OVER
    elseif state == STATE_GAME_OVER then
        renderer.text(game.width() / 2 - 40, game.height() / 2 - 20, "GAME OVER", true)
        
        local score_text = "Score: " .. tostring(game.vars.score)
        renderer.text(game.width() / 2 - 40, game.height() / 2, score_text, true)
        
        renderer.text(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Continue", true)
    end
end

-- Helper: Initialize snake
function init_snake()
    game.vars.snake = {}
    game.vars.snake[1] = {x = 20, y = 14}
    game.vars.snake[2] = {x = 19, y = 14}
    game.vars.snake[3] = {x = 18, y = 14}
    game.vars.dir_x = 1
    game.vars.dir_y = 0
end

-- Helper: Spawn food at random position
function spawn_food()
    game.vars.food_x = math.random(0, GRID_W - 1)
    game.vars.food_y = math.random(0, GRID_H - 1)
end

-- Helper: Move snake
function move_snake()
    local head = game.vars.snake[1]
    local new_head = {
        x = (head.x + game.vars.dir_x) % GRID_W,
        y = (head.y + game.vars.dir_y) % GRID_H
    }
    
    -- Wrap around negative values (Lua modulo behavior)
    if new_head.x < 0 then new_head.x = new_head.x + GRID_W end
    if new_head.y < 0 then new_head.y = new_head.y + GRID_H end
    
    -- Check self collision
    for i = 1, #game.vars.snake do
        local seg = game.vars.snake[i]
        if new_head.x == seg.x and new_head.y == seg.y then
            game_over()
            return
        end
    end
    
    -- Check food collision
    local ate_food = false
    if new_head.x == game.vars.food_x and new_head.y == game.vars.food_y then
        ate_food = true
        game.vars.score = game.vars.score + 10
        spawn_food()
        
        -- Increase speed slightly (but keep it slower overall)
        if game.vars.move_speed > 5 then
            game.vars.move_speed = game.vars.move_speed - 1
        end
    end
    
    -- Move snake
    table.insert(game.vars.snake, 1, new_head)
    
    if not ate_food then
        table.remove(game.vars.snake)  -- Remove tail
    end
end

-- Helper: Game over
function game_over()
    game.vars.state = STATE_GAME_OVER
    
    if game.vars.score > game.vars.high_score then
        game.vars.high_score = game.vars.score
    end
    
    print("Game Over! Score: " .. game.vars.score)
end
