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

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

#define BRUSH_SIZE 32           /* width and height of the brush */
#define PIXELS_PER_ITERATION 5  /* number of pixels between brush blots when forming a line */

static SDL_Texture *brush = 0;       /* texture for the brush */

/*
    draws a line from (startx, starty) to (startx + dx, starty + dy)
    this is accomplished by drawing several blots spaced PIXELS_PER_ITERATION apart
*/
void
drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy)
{

    float distance = SDL_sqrt(dx * dx + dy * dy);   /* length of line segment (pythagoras) */
    int iterations = distance / PIXELS_PER_ITERATION + 1;       /* number of brush sprites to draw for the line */
    float dx_prime = dx / iterations;   /* x-shift per iteration */
    float dy_prime = dy / iterations;   /* y-shift per iteration */
    SDL_Rect dstRect;           /* rect to draw brush sprite into */
    float x;
    float y;
    int i;

    dstRect.w = BRUSH_SIZE;
    dstRect.h = BRUSH_SIZE;

    /* setup x and y for the location of the first sprite */
    x = startx - BRUSH_SIZE / 2.0f;
    y = starty - BRUSH_SIZE / 2.0f;

    /* draw a series of blots to form the line */
    for (i = 0; i < iterations; i++) {
        dstRect.x = x;
        dstRect.y = y;
        /* shift x and y for next sprite location */
        x += dx_prime;
        y += dy_prime;
        /* draw brush blot */
        SDL_RenderCopy(renderer, brush, NULL, &dstRect);
    }
}

/*
    loads the brush texture
*/
void
initializeTexture(SDL_Renderer *renderer)
{
    SDL_Surface *bmp_surface;
    bmp_surface = SDL_LoadBMP("stroke.bmp");
    if (bmp_surface == NULL) {
        fatalError("could not load stroke.bmp");
    }
    brush =
        SDL_CreateTextureFromSurface(renderer, bmp_surface);
    SDL_FreeSurface(bmp_surface);
    if (!brush) {
        fatalError("could not create brush texture");
    }
    /* additive blending -- laying strokes on top of eachother makes them brighter */
    SDL_SetTextureBlendMode(brush, SDL_BLENDMODE_ADD);
    /* set brush color (red) */
    SDL_SetTextureColorMod(brush, 255, 100, 100);
}

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

    int x, y, dx, dy;           /* mouse location          */
    Uint8 state;                /* mouse (touch) state */
    SDL_Event event;
    SDL_Window *window;         /* main window */
    SDL_Renderer *renderer;
    SDL_Texture *target;
    int done;                   /* does user want to quit? */
    int w, h;

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

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

    SDL_GetWindowSize(window, &w, &h);
    SDL_RenderSetLogicalSize(renderer, w, h);

    /* load brush texture */
    initializeTexture(renderer);

    /* fill canvass initially with all black */
    target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h);
    SDL_SetRenderTarget(renderer, target);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    SDL_SetRenderTarget(renderer, NULL);

    done = 0;
    while (!done) {
        while (SDL_PollEvent(&event) == 1) {
            switch (event.type) {
            case SDL_QUIT:
                done = 1;
                break;
            case SDL_MOUSEMOTION:
                state = SDL_GetMouseState(&x, &y);  /* get its location */
                SDL_GetRelativeMouseState(&dx, &dy);        /* find how much the mouse moved */
                if (state & SDL_BUTTON_LMASK) {     /* is the mouse (touch) down? */
                    SDL_SetRenderTarget(renderer, target);
                    drawLine(renderer, x - dx, y - dy, dx, dy);       /* draw line segment */
                    SDL_SetRenderTarget(renderer, NULL);
                }
                break;
            }
        }

        SDL_RenderCopy(renderer, target, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    /* cleanup */
    SDL_DestroyTexture(brush);
    SDL_DestroyTexture(target);
    SDL_Quit();

    return 0;
}
