/*
 *  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 MILLESECONDS_PER_FRAME 16       /* about 60 frames per second */
#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 ? */
/*
    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(void);

/*  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 MILLESECONDS_PER_FRAME
*/
void
stepParticles(void)
{
    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 * MILLESECONDS_PER_FRAME;
            curr->xvel += 0.0f;
            curr->y += curr->yvel * MILLESECONDS_PER_FRAME;
            curr->x += curr->xvel * MILLESECONDS_PER_FRAME;

            /* 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 =
                    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 * MILLESECONDS_PER_FRAME < speed) {
                    float normx = curr->xvel / speed;
                    float normy = curr->yvel / speed;
                    curr->xvel -=
                        normx * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
                    curr->yvel -=
                        normy * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
                } else {
                    curr->xvel = curr->yvel = 0;        /* stop particle */
                }

                if (curr->color[3] <= MILLESECONDS_PER_FRAME * 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] -= MILLESECONDS_PER_FRAME * 0.1275f;
                }

                /* if we're a dust particle, shrink our size */
                if (curr->type == dust)
                    curr->size -= MILLESECONDS_PER_FRAME * 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 = 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, powf(0.17, exponent));
        speed = 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 * cos(theta);
        p->yvel = speed * sin(theta);
        p->x = emitter->x + emitter->xvel;
        p->y = emitter->y + emitter->yvel;
        p->isActive = 1;
        p->type = dust;
        p->size = 15;
        /* 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;
    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 = -sqrt(2 * ACCEL * (screen_h - y));
    /* set other attributes */
    p->size = 10;
    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 w, h;
    Uint32 startFrame;          /* time frame began to process */
    Uint32 endFrame;            /* time frame ended processing */
    Uint32 delay;               /* time to pause waiting to draw next frame */
    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);

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

    /* 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();

    SDL_GetWindowSize(window, &screen_w, &screen_h);
    glViewport(0, 0, screen_w, screen_h);

    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);
    }

    done = 0;
    /* enter main loop */
    while (!done) {
        startFrame = SDL_GetTicks();
        SDL_Event event;
        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();
        drawParticles();
        SDL_GL_SwapWindow(window);
        endFrame = SDL_GetTicks();

        /* figure out how much time we have left, and then sleep */
        delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
        if (delay > MILLESECONDS_PER_FRAME) {
            delay = MILLESECONDS_PER_FRAME;
        }
        if (delay > 0) {
            SDL_Delay(delay);
        }
    }

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

    return 0;
}
