-- NAME: Memory Match
-- DESC: Find matching pairs

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

-- Game constants
local GRID_COLS = 4
local GRID_ROWS = 4
local CARD_SIZE = 28
local CARD_SPACING = 4
local FLIP_DURATION = 15  -- Frames to show flip animation

function init()
    game.vars.state = STATE_MENU
    game.vars.score = 0
    game.vars.moves = 0
    
    -- Card grid
    game.vars.cards = {}  -- {id, face_up, matched}
    game.vars.selected = {}  -- Indices of selected cards
    game.vars.flip_frame = 0
    game.vars.waiting = false  -- Waiting to flip back incorrect pair
    
    -- Enable continuous updates
    game.set_frame_updates(true)
    
    print("Memory Match 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 card selection
        if event.type == INPUT.TOUCH_DOWN and not game.vars.waiting then
            local card_idx = get_card_at(event.x, event.y)
            if card_idx and not game.vars.cards[card_idx].matched and not game.vars.cards[card_idx].face_up then
                -- Select card
                game.vars.cards[card_idx].face_up = true
                table.insert(game.vars.selected, card_idx)
                
                if #game.vars.selected == 2 then
                    game.vars.moves = game.vars.moves + 1
                    
                    -- Check for match
                    if game.vars.cards[game.vars.selected[1]].id == game.vars.cards[game.vars.selected[2]].id then
                        -- Match!
                        game.vars.cards[game.vars.selected[1]].matched = true
                        game.vars.cards[game.vars.selected[2]].matched = true
                        game.vars.score = game.vars.score + 1
                        game.vars.selected = {}
                        
                        -- Check win
                        if game.vars.score == (GRID_COLS * GRID_ROWS) / 2 then
                            game.vars.state = STATE_GAME_OVER
                        end
                    else
                        -- No match, wait then flip back
                        game.vars.waiting = true
                        game.vars.flip_frame = 0
                    end
                end
                
                return true
            end
        end
        
        -- Handle flip-back animation
        if game.vars.waiting and event.type == INPUT.FRAME_TICK then
            game.vars.flip_frame = game.vars.flip_frame + 1
            
            if game.vars.flip_frame >= FLIP_DURATION then
                -- Flip cards back
                game.vars.cards[game.vars.selected[1]].face_up = false
                game.vars.cards[game.vars.selected[2]].face_up = false
                game.vars.selected = {}
                game.vars.waiting = false
                game.vars.flip_frame = 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(game.width() / 2 - 40, game.height() / 2 - 40, "MEMORY MATCH", true)
        renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Find all pairs", true)
        renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true)
    
    elseif state == STATE_PLAYING or state == STATE_GAME_OVER then
        -- Draw grid
        local start_x = (game.width() - (GRID_COLS * (CARD_SIZE + CARD_SPACING))) / 2
        local start_y = 30
        
        for row = 0, GRID_ROWS - 1 do
            for col = 0, GRID_COLS - 1 do
                local idx = row * GRID_COLS + col + 1
                local card = game.vars.cards[idx]
                local x = start_x + col * (CARD_SIZE + CARD_SPACING)
                local y = start_y + row * (CARD_SIZE + CARD_SPACING)
                
                if card.face_up or card.matched then
                    -- Show card value
                    renderer.rect(x, y, CARD_SIZE, CARD_SIZE, true, true)
                    local text = tostring(card.id)
                    renderer.text(x + CARD_SIZE / 2 - 2, y + CARD_SIZE / 2 - 2, text, false)
                else
                    -- Face down (outline)
                    renderer.rect(x, y, CARD_SIZE, CARD_SIZE, true, false)
                end
            end
        end
        
        -- Draw stats
        renderer.text(10, 10, "Pairs: " .. tostring(game.vars.score) .. "/" .. tostring((GRID_COLS * GRID_ROWS) / 2), true)
        renderer.text(10, 20, "Moves: " .. tostring(game.vars.moves), true)
        
        if state == STATE_GAME_OVER then
            renderer.text(game.width() / 2 - 40, 5, "YOU WIN!", true)
            renderer.text(game.width() / 2 - 50, game.height() - 20, "Tap to Menu", true)
        end
    end
end

function get_card_at(x, y)
    local start_x = (game.width() - (GRID_COLS * (CARD_SIZE + CARD_SPACING))) / 2
    local start_y = 30
    
    for row = 0, GRID_ROWS - 1 do
        for col = 0, GRID_COLS - 1 do
            local card_x = start_x + col * (CARD_SIZE + CARD_SPACING)
            local card_y = start_y + row * (CARD_SIZE + CARD_SPACING)
            
            if x >= card_x and x < card_x + CARD_SIZE and
               y >= card_y and y < card_y + CARD_SIZE then
                return row * GRID_COLS + col + 1
            end
        end
    end
    
    return nil
end

function reset_game()
    game.vars.score = 0
    game.vars.moves = 0
    game.vars.selected = {}
    game.vars.flip_frame = 0
    game.vars.waiting = false
    
    -- Create shuffled card pairs
    local card_ids = {}
    local num_pairs = (GRID_COLS * GRID_ROWS) / 2
    for i = 1, num_pairs do
        table.insert(card_ids, i)
        table.insert(card_ids, i)
    end
    
    -- Shuffle
    for i = #card_ids, 2, -1 do
        local j = math.random(1, i)
        card_ids[i], card_ids[j] = card_ids[j], card_ids[i]
    end
    
    -- Create card objects
    game.vars.cards = {}
    for i = 1, #card_ids do
        game.vars.cards[i] = {
            id = card_ids[i],
            face_up = false,
            matched = false
        }
    end
end
