#include <akgltest.h>
#include <akgl/game.h>

akerr_ErrorContext AKERR_NOIGNORE *akgltest_set_gamemode_menu(akgl_Actor *appstate, SDL_Event *event)
{
    PREPARE_ERROR(e);
    AKGL_BITMASK_DEL(game.state.flags, AKGLTEST_STATE_WAITFORINPUT);
    AKGL_BITMASK_DEL(game.state.flags, AKGLTEST_STATE_RUNNING);
    PASS(e, akgl_tilemap_release(gamemap));
    physics = &_akgl_physics;
    PASS(e, akgl_registry_init_actor());
    PASS(e, akgl_heap_init_actor());
    PASS(e, akgltest_init_menupointer());
    akgl_Actor *menupointer = SDL_GetPointerProperty(AKGL_REGISTRY_ACTOR, "menupointer", NULL);
    GAME_ControlMaps[AKGLTEST_CONTROLMAP_INGAMEACTOR].target = NULL;
    GAME_ControlMaps[AKGLTEST_CONTROLMAP_MENU].target = menupointer;
    menupointer->visible = true;

    PASS(e, aksl_memset((void *)GAME_ControlMaps, 0x00, (sizeof(akgl_ControlMap) * AKGL_MAX_CONTROL_MAPS)));
    PASS(e, akgltest_controller_bind_universal("menupointer", AKGLTEST_CONTROLMAP_MENU, kbid, jsid));
    PASS(e, aksl_memset(gamemap, 0x00, sizeof(akgl_Tilemap)));
    AKGL_BITMASK_ADD(game.state.flags, AKGLTEST_STATE_MAPMENU);
    SUCCEED_RETURN(e);
}    

akerr_ErrorContext AKERR_NOIGNORE *akgltest_set_gamemode_running(akgl_Actor *appstate, SDL_Event *event)
{
    PREPARE_ERROR(e);
    AKGL_BITMASK_DEL(game.state.flags, AKGLTEST_STATE_WAITFORINPUT);
    AKGL_BITMASK_DEL(game.state.flags, AKGLTEST_STATE_MAPMENU);
    PASS(e, akgl_registry_init_actor());
    PASS(e, akgl_heap_init_actor());
    PASS(e, akgltest_init_player());
    //PASS(e, akgl_physics_init_arcade(physics));
    PASS(e, aksl_memset((void *)GAME_ControlMaps, 0x00, (sizeof(akgl_ControlMap) * AKGL_MAX_CONTROL_MAPS)));
    PASS(e, akgltest_controller_bind_universal("player", AKGLTEST_CONTROLMAP_INGAMEACTOR, kbid, jsid));
    akgl_Actor *actorptr = SDL_GetPointerProperty(AKGL_REGISTRY_ACTOR, "player", NULL);
    GAME_ControlMaps[AKGLTEST_CONTROLMAP_INGAMEACTOR].target = actorptr;
    GAME_ControlMaps[AKGLTEST_CONTROLMAP_MENU].target = NULL;
    actorptr->visible = true;

    if ( menuselection == 0 ) {
	strcpy((char *)&dirnamebuf, "assets/imagemap.tmj");
	PASS(e, akgl_tilemap_load((char *)&dirnamebuf, gamemap));
    } else if ( menuselection == 1 ) {
	strcpy((char *)&dirnamebuf, "assets/tilemap.tmj");
	PASS(e, akgl_tilemap_load((char *)&dirnamebuf, gamemap));
    } else if ( menuselection == 2 ) {
	strcpy((char *)&dirnamebuf, "assets/sidescroller.tmj");
	PASS(e, akgl_tilemap_load((char *)&dirnamebuf, gamemap));
    } else if ( menuselection == 3 ) {
	AKGL_BITMASK_DEL(game.state.flags, AKGLTEST_STATE_RUNNING);
	AKGL_BITMASK_ADD(game.state.flags, AKGLTEST_STATE_QUIT);
    }
    if ( gamemap->use_own_physics == true ) {
	SDL_Log("Using game map physics engine");
	physics = &gamemap->physics;
    }
    AKGL_BITMASK_ADD(game.state.flags, AKGLTEST_STATE_RUNNING);
    SUCCEED_RETURN(e);
}    

akerr_ErrorContext AKERR_NOIGNORE *akgltest_iterate_mapmenu(void)
{
    akgl_Actor *menupointer = NULL;
    akgl_Iterator opflags = {
	.flags = 0,
	.layerid = 0
    };
    PREPARE_ERROR(e);
    ATTEMPT {
	CATCH(e, renderer->frame_start(renderer))
	    
	SDL_SetRenderDrawColor(renderer->sdl_renderer, 0, 0, 0, 255);
	SDL_RenderClear(renderer->sdl_renderer);
	PASS(e, akgl_text_rendertextat(
		 SDL_GetPointerProperty(
		     AKGL_REGISTRY_FONT,
		     "C64Pro",
		     NULL),
		 "IMAGE MAP DEMO",
		 (SDL_Color){255, 255, 255, 255},
		 0,
		 150,
		 100)
	    );
	PASS(e, akgl_text_rendertextat(
		 SDL_GetPointerProperty(
		     AKGL_REGISTRY_FONT,
		     "C64Pro",
		     NULL),
		 "TILE MAP DEMO",
		 (SDL_Color){255, 255, 255, 255},
		 0,
		 150,
		 200)
	    );
	PASS(e, akgl_text_rendertextat(
		 SDL_GetPointerProperty(
		     AKGL_REGISTRY_FONT,
		     "C64Pro",
		     NULL),
		 "SIDESCROLLER MAP DEMO",
		 (SDL_Color){255, 255, 255, 255},
		 0,
		 150,
		 300)
	    );
	PASS(e, akgl_text_rendertextat(
		 SDL_GetPointerProperty(
		     AKGL_REGISTRY_FONT,
		     "C64Pro",
		     NULL),
		 "QUIT GAME",
		 (SDL_Color){255, 255, 255, 255},
		 0,
		 150,
		 400)
	    );
	menupointer = SDL_GetPointerProperty(AKGL_REGISTRY_ACTOR, "menupointer", NULL);
	FAIL_ZERO_BREAK(e, menupointer, AKERR_NULLPOINTER, "actor missing from registry");
	menupointer->visible = true;
	CATCH(e, akgl_game_update(&opflags));
	CATCH(e, renderer->frame_end(renderer))
    } CLEANUP {
    } PROCESS(e) {
    } FINISH(e, true);

    SUCCEED_RETURN(e);
}

akerr_ErrorContext AKERR_NOIGNORE *akgltest_iterate_waitforinput(void)
{

    PREPARE_ERROR(e);

    akgl_game_updateFPS();
    
    PASS(e, akgl_text_rendertextat(
	     SDL_GetPointerProperty(
		 AKGL_REGISTRY_FONT,
		 "C64Pro",
		 NULL),
	     "PRESS ANY KEY OR JOYSTICK BUTTON",
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     40,
	     120)
	);
    PASS(e, renderer->frame_end(renderer));
    SUCCEED_RETURN(e);
}

akerr_ErrorContext AKERR_NOIGNORE *akgltest_iterate_running(void)
{
    int i = 0;
    akgl_Iterator opflags;
    akgl_Actor *player;
    TTF_Font *gamefont;
    char screenText[128];
    int count;

    PREPARE_ERROR(e);
    PASS(e, renderer->frame_start(renderer));
    player = SDL_GetPointerProperty(AKGL_REGISTRY_ACTOR, "player", NULL);
    FAIL_ZERO_RETURN(e, player, AKERR_NULLPOINTER, "player not in registry");
    gamefont = SDL_GetPointerProperty(AKGL_REGISTRY_FONT, "C64Pro", NULL);
    FAIL_ZERO_RETURN(e, player, AKERR_NULLPOINTER, "font not in registry");

    PASS(e, akgl_game_update(NULL));

    memset((char *)&screenText, 0x00, 32);
    snprintf((char *)&screenText, 127, "FPS : %d", game.fps);
    PASS(e, akgl_text_rendertextat(
	     gamefont,
	     (char *)&screenText,
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     450,
	     10)
	);

    memset((char *)&screenText, 0x00, 128);
    snprintf((char *)&screenText, 127, "VX: %f", player->vx);
    PASS(e, akgl_text_rendertextat(
	     gamefont,
	     (char *)&screenText,
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     10,
	     10)
	);
    memset((char *)&screenText, 0x00, 128);
    snprintf((char *)&screenText, 127, "VY: %f", player->vy);
    PASS(e, akgl_text_rendertextat(
	     gamefont,
	     (char *)&screenText,
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     10,
	     30)
	);
    memset((char *)&screenText, 0x00, 128);
    snprintf((char *)&screenText, 127, "DY: %f", physics->drag_y);
    PASS(e, akgl_text_rendertextat(
	     gamefont,
	     (char *)&screenText,
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     10,
	     60)
	);
    
    memset((char *)&screenText, 0x00, 128);
    snprintf((char *)&screenText, 127, "PX: %f", player->x);
    PASS(e, akgl_text_rendertextat(
	     gamefont,
	     (char *)&screenText,
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     220,
	     10)
	);
    memset((char *)&screenText, 0x00, 128);
    snprintf((char *)&screenText, 127, "PY: %f", player->y);
    PASS(e, akgl_text_rendertextat(
	     gamefont,
	     (char *)&screenText,
	     (SDL_Color){255, 255, 255, 255},
	     0,
	     220,
	     30)
	);

    PASS(e, renderer->frame_end(renderer));
    SUCCEED_RETURN(e);
}
