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

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

#define ACCEL 0.0001f           /* acceleration due to gravity, units in pixels per millesecond squared */
#define WIND_RESISTANCE 0.00005f        /* acceleration per unit velocity due to wind resistance */
#define MAX_PARTICLES 2000      /* maximum number of particles displayed at once */

static GLuint particleTextureID;        /* OpenGL particle texture id */
static SDL_bool pointSizeExtensionSupported;    /* is GL_OES_point_size_array supported ? */
static float pointSizeScale;
/*
    used to describe what type of particle a given struct particle is.
    emitter - this particle flies up, shooting off trail particles, then finally explodes into dust particles.
    trail   - shoots off, following emitter particle
    dust    - radiates outwards from emitter explosion
*/
enum particleType
{
    emitter = 0,
    trail,
    dust
};
/*
    struct particle is used to describe each particle displayed on screen
*/
struct particle
{
    GLfloat x;                  /* x position of particle */
    GLfloat y;                  /* y position of particle */
    GLubyte color[4];           /* rgba color of particle */
    GLfloat size;               /* size of particle in pixels */
    GLfloat xvel;               /* x velocity of particle in pixels per milesecond */
    GLfloat yvel;               /* y velocity of particle in pixels per millescond */
    int isActive;               /* if not active, then particle is overwritten */
    enum particleType type;     /* see enum particleType */
} particles[MAX_PARTICLES];     /* this array holds all our particles */

static int num_active_particles;        /* how many members of the particle array are actually being drawn / animated? */
static int screen_w, screen_h;

/* function declarations */
void spawnTrailFromEmitter(struct particle *emitter);
void spawnEmitterParticle(GLfloat x, GLfloat y);
void explodeEmitter(struct particle *emitter);
void initializeParticles(void);
void initializeTexture();
int nextPowerOfTwo(int x);
void drawParticles();
void stepParticles(double deltaTime);

/*  helper function (used in texture loading)
    returns next power of two greater than or equal to x
*/
int
nextPowerOfTwo(int x)
{
    int val = 1;
    while (val < x) {
        val *= 2;
    }
    return val;
}

/*
    steps each active particle by timestep deltaTime
*/
void
stepParticles(double deltaTime)
{
    float deltaMilliseconds = deltaTime * 1000;
    int i;
    struct particle *slot = particles;
    struct particle *curr = particles;
    for (i = 0; i < num_active_particles; i++) {
        /* is the particle actually active, or is it marked for deletion? */
        if (curr->isActive) {
            /* is the particle off the screen? */
            if (curr->y > screen_h)
                curr->isActive = 0;
            else if (curr->y < 0)
                curr->isActive = 0;
            if (curr->x > screen_w)
                curr->isActive = 0;
            else if (curr->x < 0)
                curr->isActive = 0;

            /* step velocity, then step position */
            curr->yvel += ACCEL * deltaMilliseconds;
            curr->xvel += 0.0f;
            curr->y += curr->yvel * deltaMilliseconds;
            curr->x += curr->xvel * deltaMilliseconds;

            /* particle behavior */
            if (curr->type == emitter) {
                /* if we're an emitter, spawn a trail */
                spawnTrailFromEmitter(curr);
                /* if we've reached our peak, explode */
                if (curr->yvel > 0.0) {
                    explodeEmitter(curr);
                }
            } else {
                float speed =
                    SDL_sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel);
                /*      if wind resistance is not powerful enough to stop us completely,
                   then apply winde resistance, otherwise just stop us completely */
                if (WIND_RESISTANCE * deltaMilliseconds < speed) {
                    float normx = curr->xvel / speed;
                    float normy = curr->yvel / speed;
                    curr->xvel -=
                        normx * WIND_RESISTANCE * deltaMilliseconds;
                    curr->yvel -=
                        normy * WIND_RESISTANCE * deltaMilliseconds;
                } else {
                    curr->xvel = curr->yvel = 0;        /* stop particle */
                }

                if (curr->color[3] <= deltaMilliseconds * 0.1275f) {
                    /* if this next step will cause us to fade out completely
                       then just mark for deletion */
                    curr->isActive = 0;
                } else {
                    /* otherwise, let's fade a bit more */
                    curr->color[3] -= deltaMilliseconds * 0.1275f;
                }

                /* if we're a dust particle, shrink our size */
                if (curr->type == dust)
                    curr->size -= deltaMilliseconds * 0.010f;

            }

            /* if we're still active, pack ourselves in the array next
               to the last active guy (pack the array tightly) */
            if (curr->isActive)
                *(slot++) = *curr;
        }                       /* endif (curr->isActive) */
        curr++;
    }
    /* the number of active particles is computed as the difference between
       old number of active particles, where slot points, and the
       new size of the array, where particles points */
    num_active_particles = (int) (slot - particles);
}

/*
    This draws all the particles shown on screen
*/
void
drawParticles()
{

    /* draw the background */
    glClear(GL_COLOR_BUFFER_BIT);

    /* set up the position and color pointers */
    glVertexPointer(2, GL_FLOAT, sizeof(struct particle), particles);
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct particle),
                   particles[0].color);

    if (pointSizeExtensionSupported) {
        /* pass in our array of point sizes */
        glPointSizePointerOES(GL_FLOAT, sizeof(struct particle),
                              &(particles[0].size));
    }

    /* draw our particles! */
    glDrawArrays(GL_POINTS, 0, num_active_particles);

}

/*
    This causes an emitter to explode in a circular bloom of dust particles
*/
void
explodeEmitter(struct particle *emitter)
{
    /* first off, we're done with this particle, so turn active off */
    emitter->isActive = 0;
    int i;
    for (i = 0; i < 200; i++) {

        if (num_active_particles >= MAX_PARTICLES)
            return;

        /* come up with a random angle and speed for new particle */
        float theta = randomFloat(0, 2.0f * 3.141592);
        float exponent = 3.0f;
        float speed = randomFloat(0.00, SDL_powf(0.17, exponent));
        speed = SDL_powf(speed, 1.0f / exponent);

        /* select the particle at the end of our array */
        struct particle *p = &particles[num_active_particles];

        /* set the particles properties */
        p->xvel = speed * SDL_cos(theta);
        p->yvel = speed * SDL_sin(theta);
        p->x = emitter->x + emitter->xvel;
        p->y = emitter->y + emitter->yvel;
        p->isActive = 1;
        p->type = dust;
        p->size = 15 * pointSizeScale;
        /* inherit emitter's color */
        p->color[0] = emitter->color[0];
        p->color[1] = emitter->color[1];
        p->color[2] = emitter->color[2];
        p->color[3] = 255;
        /* our array has expanded at the end */
        num_active_particles++;
    }

}

/*
    This spawns a trail particle from an emitter
*/
void
spawnTrailFromEmitter(struct particle *emitter)
{

    if (num_active_particles >= MAX_PARTICLES)
        return;

    /* select the particle at the slot at the end of our array */
    struct particle *p = &particles[num_active_particles];

    /* set position and velocity to roughly that of the emitter */
    p->x = emitter->x + randomFloat(-3.0, 3.0);
    p->y = emitter->y + emitter->size / 2.0f;
    p->xvel = emitter->xvel + randomFloat(-0.005, 0.005);
    p->yvel = emitter->yvel + 0.1;

    /* set the color to a random-ish orangy type color */
    p->color[0] = (0.8f + randomFloat(-0.1, 0.0)) * 255;
    p->color[1] = (0.4f + randomFloat(-0.1, 0.1)) * 255;
    p->color[2] = (0.0f + randomFloat(0.0, 0.2)) * 255;
    p->color[3] = (0.7f) * 255;

    /* set other attributes */
    p->size = 10 * pointSizeScale;
    p->type = trail;
    p->isActive = 1;

    /* our array has expanded at the end */
    num_active_particles++;

}

/*
    spawns a new emitter particle at the bottom of the screen
    destined for the point (x,y).
*/
void
spawnEmitterParticle(GLfloat x, GLfloat y)
{

    if (num_active_particles >= MAX_PARTICLES)
        return;

    /* find particle at endpoint of array */
    struct particle *p = &particles[num_active_particles];

    /* set the color randomly */
    switch (rand() % 4) {
    case 0:
        p->color[0] = 255;
        p->color[1] = 100;
        p->color[2] = 100;
        break;
    case 1:
        p->color[0] = 100;
        p->color[1] = 255;
        p->color[2] = 100;
        break;
    case 2:
        p->color[0] = 100;
        p->color[1] = 100;
        p->color[2] = 255;
        break;
    case 3:
        p->color[0] = 255;
        p->color[1] = 150;
        p->color[2] = 50;
        break;
    }
    p->color[3] = 255;
    /* set position to (x, screen_h) */
    p->x = x;
    p->y = screen_h;
    /* set velocity so that terminal point is (x,y) */
    p->xvel = 0;
    p->yvel = -SDL_sqrt(2 * ACCEL * (screen_h - y));
    /* set other attributes */
    p->size = 10 * pointSizeScale;
    p->type = emitter;
    p->isActive = 1;
    /* our array has expanded at the end */
    num_active_particles++;
}

/* just sets the endpoint of the particle array to element zero */
void
initializeParticles(void)
{
    num_active_particles = 0;
}

/*
    loads the particle texture
 */
void
initializeTexture()
{

    int bpp;                    /* texture bits per pixel */
    Uint32 Rmask, Gmask, Bmask, Amask;  /* masks for pixel format passed into OpenGL */
    SDL_Surface *bmp_surface;   /* the bmp is loaded here */
    SDL_Surface *bmp_surface_rgba8888;  /* this serves as a destination to convert the BMP
                                           to format passed into OpenGL */

    bmp_surface = SDL_LoadBMP("stroke.bmp");
    if (bmp_surface == NULL) {
        fatalError("could not load stroke.bmp");
    }

    /* Grab info about format that will be passed into OpenGL */
    SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ABGR8888, &bpp, &Rmask, &Gmask,
                               &Bmask, &Amask);
    /* Create surface that will hold pixels passed into OpenGL */
    bmp_surface_rgba8888 =
        SDL_CreateRGBSurface(0, bmp_surface->w, bmp_surface->h, bpp, Rmask,
                             Gmask, Bmask, Amask);
    /* Blit to this surface, effectively converting the format */
    SDL_BlitSurface(bmp_surface, NULL, bmp_surface_rgba8888, NULL);

    glGenTextures(1, &particleTextureID);
    glBindTexture(GL_TEXTURE_2D, particleTextureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                 nextPowerOfTwo(bmp_surface->w),
                 nextPowerOfTwo(bmp_surface->h),
                 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    /* this is where we actually pass in the pixel data */
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp_surface->w, bmp_surface->h, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, bmp_surface_rgba8888->pixels);

    /* free bmp surface and converted bmp surface */
    SDL_FreeSurface(bmp_surface);
    SDL_FreeSurface(bmp_surface_rgba8888);

}

int
main(int argc, char *argv[])
{
    SDL_Window *window;         /* main window */
    SDL_GLContext context;
    int drawableW, drawableH;
    int done;                   /* should we clean up and exit? */

    /* initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fatalError("Could not initialize SDL");
    }
    /* seed the random number generator */
    srand(time(NULL));
    /*
       request some OpenGL parameters
       that may speed drawing
     */
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
    SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
    SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

    /* create main window and renderer */
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480,
                                SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
    context = SDL_GL_CreateContext(window);

    /* The window size and drawable size may be different when highdpi is enabled,
     * due to the increased pixel density of the drawable. */
    SDL_GetWindowSize(window, &screen_w, &screen_h);
    SDL_GL_GetDrawableSize(window, &drawableW, &drawableH);

    /* In OpenGL, point sizes are always in pixels. We don't want them looking
     * tiny on a retina screen. */
    pointSizeScale = (float) drawableH / (float) screen_h;

    /* load the particle texture */
    initializeTexture();

    /*      check if GL_POINT_SIZE_ARRAY_OES is supported
       this is used to give each particle its own size
     */
    pointSizeExtensionSupported =
        SDL_GL_ExtensionSupported("GL_OES_point_size_array");

    /* set up some OpenGL state */
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glViewport(0, 0, drawableW, drawableH);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof((GLfloat) 0,
             (GLfloat) screen_w,
             (GLfloat) screen_h,
             (GLfloat) 0, 0.0, 1.0);

    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glEnable(GL_POINT_SPRITE_OES);
    glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, 1);

    if (pointSizeExtensionSupported) {
        /* we use this to set the sizes of all the particles */
        glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
    } else {
        /* if extension not available then all particles have size 10 */
        glPointSize(10 * pointSizeScale);
    }

    done = 0;
    /* enter main loop */
    while (!done) {
        SDL_Event event;
        double deltaTime = updateDeltaTime();
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                done = 1;
            }
            if (event.type == SDL_MOUSEBUTTONDOWN) {
                int x, y;
                SDL_GetMouseState(&x, &y);
                spawnEmitterParticle(x, y);
            }
        }
        stepParticles(deltaTime);
        drawParticles();
        SDL_GL_SwapWindow(window);
        SDL_Delay(1);
    }

    /* delete textures */
    glDeleteTextures(1, &particleTextureID);
    /* shutdown SDL */
    SDL_Quit();

    return 0;
}
