/*
 *  accelerometer.c
 *  written by Holmes Futrell
 *  use however you want
 */

#include "SDL.h"
#include <math.h>
#include "common.h"

#define DAMPING 0.5f;           /* after bouncing off a wall, damping coefficient determines final speed */
#define FRICTION 0.0008f        /* coefficient of acceleration that opposes direction of motion */
#define GRAVITY_CONSTANT 0.004f /* how sensitive the ship is to the accelerometer */

/*  If we aren't on an iPhone, then this definition ought to yield reasonable behavior */
#ifndef SDL_IPHONE_MAX_GFORCE
#define SDL_IPHONE_MAX_GFORCE 5.0f
#endif

static SDL_Joystick *accelerometer;     /* used for controlling the ship */

static struct
{
    float x, y;                 /* position of ship */
    float vx, vy;               /* velocity of ship (in pixels per millesecond) */
    SDL_Rect rect;              /* (drawn) position and size of ship */
} shipData;

static SDL_Texture *ship = 0;        /* texture for spaceship */
static SDL_Texture *space = 0;       /* texture for space (background */

void
render(SDL_Renderer *renderer, int w, int h, double deltaTime)
{
    double deltaMilliseconds = deltaTime * 1000;
    float speed;

    /* get joystick (accelerometer) axis values and normalize them */
    float ax = SDL_JoystickGetAxis(accelerometer, 0);
    float ay = SDL_JoystickGetAxis(accelerometer, 1);

    /* ship screen constraints */
    Uint32 minx = 0.0f;
    Uint32 maxx = w - shipData.rect.w;
    Uint32 miny = 0.0f;
    Uint32 maxy = h - shipData.rect.h;

#define SINT16_MAX ((float)(0x7FFF))

    /* update velocity from accelerometer
       the factor SDL_IPHONE_MAX_G_FORCE / SINT16_MAX converts between
       SDL's units reported from the joytick, and units of g-force, as reported by the accelerometer
     */
    shipData.vx +=
        ax * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
        deltaMilliseconds;
    shipData.vy +=
        ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
        deltaMilliseconds;

    speed = SDL_sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy);

    if (speed > 0) {
        /* compensate for friction */
        float dirx = shipData.vx / speed;   /* normalized x velocity */
        float diry = shipData.vy / speed;   /* normalized y velocity */

        /* update velocity due to friction */
        if (speed - FRICTION * deltaMilliseconds > 0) {
            /* apply friction */
            shipData.vx -= dirx * FRICTION * deltaMilliseconds;
            shipData.vy -= diry * FRICTION * deltaMilliseconds;
        } else {
            /* applying friction would MORE than stop the ship, so just stop the ship */
            shipData.vx = 0.0f;
            shipData.vy = 0.0f;
        }
    }

    /* update ship location */
    shipData.x += shipData.vx * deltaMilliseconds;
    shipData.y += shipData.vy * deltaMilliseconds;

    if (shipData.x > maxx) {
        shipData.x = maxx;
        shipData.vx = -shipData.vx * DAMPING;
    } else if (shipData.x < minx) {
        shipData.x = minx;
        shipData.vx = -shipData.vx * DAMPING;
    }
    if (shipData.y > maxy) {
        shipData.y = maxy;
        shipData.vy = -shipData.vy * DAMPING;
    } else if (shipData.y < miny) {
        shipData.y = miny;
        shipData.vy = -shipData.vy * DAMPING;
    }

    /* draw the background */
    SDL_RenderCopy(renderer, space, NULL, NULL);

    /* draw the ship */
    shipData.rect.x = shipData.x;
    shipData.rect.y = shipData.y;

    SDL_RenderCopy(renderer, ship, NULL, &shipData.rect);

    /* update screen */
    SDL_RenderPresent(renderer);

}

void
initializeTextures(SDL_Renderer *renderer)
{

    SDL_Surface *bmp_surface;

    /* load the ship */
    bmp_surface = SDL_LoadBMP("ship.bmp");
    if (bmp_surface == NULL) {
        fatalError("could not ship.bmp");
    }
    /* set blue to transparent on the ship */
    SDL_SetColorKey(bmp_surface, 1,
                    SDL_MapRGB(bmp_surface->format, 0, 0, 255));

    /* create ship texture from surface */
    ship = SDL_CreateTextureFromSurface(renderer, bmp_surface);
    if (!ship) {
        fatalError("could not create ship texture");
    }
    SDL_SetTextureBlendMode(ship, SDL_BLENDMODE_BLEND);

    /* set the width and height of the ship from the surface dimensions */
    shipData.rect.w = bmp_surface->w;
    shipData.rect.h = bmp_surface->h;

    SDL_FreeSurface(bmp_surface);

    /* load the space background */
    bmp_surface = SDL_LoadBMP("space.bmp");
    if (bmp_surface == NULL) {
        fatalError("could not load space.bmp");
    }
    /* create space texture from surface */
    space = SDL_CreateTextureFromSurface(renderer, bmp_surface);
    if (!space) {
        fatalError("could not create space texture");
    }
    SDL_FreeSurface(bmp_surface);

}



int
main(int argc, char *argv[])
{

    SDL_Window *window;         /* main window */
    SDL_Renderer *renderer;
    int done;                   /* should we clean up and exit? */
    int w, h;

    /* initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
        fatalError("Could not initialize SDL");
    }

    /* create main window and renderer */
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI);
    renderer = SDL_CreateRenderer(window, 0, 0);
    
    SDL_GetWindowSize(window, &w, &h);
    SDL_RenderSetLogicalSize(renderer, w, h);

    /* print out some info about joysticks and try to open accelerometer for use */
    printf("There are %d joysticks available\n", SDL_NumJoysticks());
    printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
    accelerometer = SDL_JoystickOpen(0);
    if (accelerometer == NULL) {
        fatalError("Could not open joystick (accelerometer)");
    }
    printf("joystick number of axis = %d\n",
           SDL_JoystickNumAxes(accelerometer));
    printf("joystick number of hats = %d\n",
           SDL_JoystickNumHats(accelerometer));
    printf("joystick number of balls = %d\n",
           SDL_JoystickNumBalls(accelerometer));
    printf("joystick number of buttons = %d\n",
           SDL_JoystickNumButtons(accelerometer));

    /* load graphics */
    initializeTextures(renderer);

    /* setup ship */
    shipData.x = (w - shipData.rect.w) / 2;
    shipData.y = (h - shipData.rect.h) / 2;
    shipData.vx = 0.0f;
    shipData.vy = 0.0f;

    done = 0;
    /* enter main loop */
    while (!done) {
        double deltaTime = updateDeltaTime();
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                done = 1;
            }
        }
        render(renderer, w, h, deltaTime);
        SDL_Delay(1);
    }

    /* delete textures */
    SDL_DestroyTexture(ship);
    SDL_DestroyTexture(space);

    /* shutdown SDL */
    SDL_Quit();

    return 0;

}
