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