#include <genesis.h>
#include <resources.h>
#include <string.h>
#include "megarunner.h"

#define ANIM_RUN  0
#define ANIM_JUMP 1

// =======================================
// Module-local variables
// =======================================
static Sprite* player;
static Sprite* obstacle;

// Positions & physics
static int player_x;
static fix16 player_y;
static fix16 player_vel_y;
static int player_height;

static int obstacle_x;
static int obstacle_vel_x;

static int floor_height;
static fix16 gravity;
static bool jumping;

// Game state & messages
static bool game_on;
static char msg_start[22] = "Press START to Begin!";
static char msg_reset[22] = "Press START to Reset!";

// Scrolling
static int scrollspeed;
static s16 scrollValues[15];
static int i;

// Score
static int score;
static char label_score[6] = "SCORE";
static char str_score[3] = "0";
static bool score_added;

// Function declarations
static void showText(char s[]);
static void clearText();
static void startGame();
static void endGame();
static void myJoyHandler(u16 joy, u16 changed, u16 state);
static void updateScoreDisplay();

// =======================================
//   ENTRY POINT FOR MULTI-GAME MENU
// =======================================
void runMegarunner()
{
    // Reset module variables
    game_on = FALSE;
    jumping = FALSE;
    score = 0;
    score_added = FALSE;

    player_x      = 32;
    player_height = 16;
    floor_height  = 128;

    player_y     = FIX16(112);
    player_vel_y = FIX16(0);

    obstacle_x     = 320;
    obstacle_vel_x = 0;

    gravity     = FIX16(0.2);
    scrollspeed = 2;

    for(int n=0; n<15; n++) scrollValues[n] = 0;

    // Reset screen (safe for subgames)
    VDP_resetScreen();

    //-----------------------------------------
    // VDP Setup (same as your original)
    //-----------------------------------------
    VDP_setPlaneSize(32,32, TRUE);

    VDP_loadTileSet(floor.tileset,1,DMA);
    VDP_loadTileSet(wall.tileset, 2,DMA);
    VDP_loadTileSet(light.tileset,3,DMA);

    VDP_fillTileMapRect(BG_B, TILE_ATTR_FULL(PAL1,0,FALSE,FALSE,1), 0,16,32,1);
    VDP_fillTileMapRect(BG_B, TILE_ATTR_FULL(PAL1,0,FALSE,TRUE ,2), 0,17,32,2);

    VDP_fillTileMapRect(BG_B, TILE_ATTR_FULL(PAL1,0,FALSE,FALSE,1), 0,19,32,1);
    VDP_fillTileMapRect(BG_B, TILE_ATTR_FULL(PAL1,0,FALSE,TRUE ,2), 0,20,32,8);

    VDP_fillTileMapRectInc(BG_B, TILE_ATTR_FULL(PAL1,0,FALSE,FALSE,3), 15,13,2,3);

    VDP_setScrollingMode(HSCROLL_TILE, VSCROLL_PLANE);

    PAL_setColor(0, RGB24_TO_VDPCOLOR(0x6dc2ca));
    PAL_setPalette(PAL1, light.palette->data, DMA);
    PAL_setPalette(PAL2, runner.palette->data, DMA);

    //-----------------------------------------
    // Sprites
    //-----------------------------------------
    SPR_init();

    player = SPR_addSprite(&runner, player_x, fix16ToInt(player_y),
                           TILE_ATTR(PAL2, 0, FALSE, FALSE));
    obstacle = SPR_addSprite(&rock, obstacle_x, 128,
                             TILE_ATTR(PAL2,0,FALSE,FALSE));

    SPR_setAnim(player, ANIM_RUN);

    //-----------------------------------------
    // Input
    //-----------------------------------------
    JOY_setEventHandler(myJoyHandler);

    //-----------------------------------------
    // Start screen text
    //-----------------------------------------
    showText(msg_start);

    //-----------------------------------------
    // MAIN GAME LOOP
    //-----------------------------------------
    while(1)
    {
        if (game_on)
        {
            // Scroll background sections
            VDP_setHorizontalScrollTile(BG_B, 13, scrollValues, 15, CPU);

            for(i=0; i<15; i++)
            {
                if(i <= 5) scrollValues[i] -= scrollspeed;
                else        scrollValues[i] -= (scrollspeed+1);

                if(scrollValues[i] <= -256) scrollValues[i] = 0;
            }

            // Move obstacle
            obstacle_vel_x = -scrollspeed;
            obstacle_x += obstacle_vel_x;

            if(obstacle_x < -8)
            {
                obstacle_x = 320;
                score_added = FALSE;
            }

            // Collision / scoring
            if (player_x < obstacle_x + 8 &&
                player_x + 8 > obstacle_x)
            {
                if (!jumping)
                {
                    endGame();
                }
                else if (!score_added)
                {
                    score++;
                    updateScoreDisplay();
                    score_added = TRUE;
                }
            }
            else if (obstacle_x + 8 < player_x && !score_added)
            {
                score_added = TRUE;
            }

            // Physics
            player_y += player_vel_y;
            if(jumping) player_vel_y += gravity;

            // Land on floor
            if(jumping && fix16ToInt(player_y) + player_height >= floor_height)
            {
                jumping = FALSE;
                score_added = FALSE;
                player_vel_y = FIX16(0);
                player_y     = intToFix16(floor_height - player_height);
                SPR_setAnim(player, ANIM_RUN);
            }

            // Sprite positions
            SPR_setPosition(obstacle, obstacle_x, 120);
            SPR_setPosition(player, player_x, fix16ToInt(player_y));
        }

        SPR_update();
        SYS_doVBlankProcess();

        // ==== EXIT BACK TO MENU (PRESS B) ====
        if(JOY_readJoypad(JOY_1) & BUTTON_B)
            break;
    }

    // Cleanup before returning to main menu
    SPR_end();
    VDP_resetScreen();
}

// =======================================
// Support functions (unchanged logic)
// =======================================
static void showText(char s[]){
    VDP_drawText(s, 20 - strlen(s)/2 ,10);
}

static void clearText(){
    VDP_clearText(0,10,32);
}

static void startGame(){
    if(!game_on){
        game_on = TRUE;
        clearText();

        VDP_drawText(label_score,10,1);
        score = 0;
        updateScoreDisplay();
        obstacle_x = 320;

        VDP_setHorizontalScrollTile(BG_B, 13, scrollValues, 15, CPU);
    }
}

static void endGame(){
    if(game_on){
        showText(msg_reset);
        game_on = FALSE;
    }
}

static void myJoyHandler(u16 joy, u16 changed, u16 state)
{
    if(joy == JOY_1)
    {
        if(state & BUTTON_START)
        {
            if(!game_on) startGame();
        }

        if(state & BUTTON_C)
        {
            if(!jumping)
            {
                jumping = TRUE;
                player_vel_y = FIX16(-4);
                SPR_setAnim(player, ANIM_JUMP);
            }
        }
    }
}

static void updateScoreDisplay(){
    sprintf(str_score,"%d",score);
    VDP_clearText(10,2,5);
    VDP_drawText(str_score,10,2);
}

