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

#include "SDL.h"
#include "common.h"

#define GLYPH_SIZE_IMAGE 16     /* size of glyphs (characters) in the bitmap font file */
#define GLYPH_SIZE_SCREEN 32    /* size of glyphs (characters) as shown on the screen */

static SDL_Texture *texture; /* texture where we'll hold our font */

/* function declarations */
void cleanup(void);
void drawBlank(int x, int y);

static SDL_Renderer *renderer;
static int numChars = 0;        /* number of characters we've typed so far */
static SDL_bool lastCharWasColon = 0;   /* we use this to detect sequences such as :) */
static SDL_Color bg_color = { 50, 50, 100, 255 };       /* color of background */

/* this structure maps a scancode to an index in our bitmap font.
   it also contains data about under which modifiers the mapping is valid
   (for example, we don't want shift + 1 to produce the character '1',
   but rather the character '!')
*/
typedef struct
{
    SDL_Scancode scancode;      /* scancode of the key we want to map */
    int allow_no_mod;           /* is the map valid if the key has no modifiers? */
    SDL_Keymod mod;             /* what modifiers are allowed for the mapping */
    int index;                  /* what index in the font does the scancode map to */
} fontMapping;

#define TABLE_SIZE 51           /* size of our table which maps keys and modifiers to font indices */

/* Below is the table that defines the mapping between scancodes and modifiers to indices in the
   bitmap font.  As an example, then line '{ SDL_SCANCODE_A, 1, KMOD_SHIFT, 33 }' means, map
   the key A (which has scancode SDL_SCANCODE_A) to index 33 in the font (which is a picture of an A),
   The '1' means that the mapping is valid even if there are no modifiers, and KMOD_SHIFT means the
   mapping is also valid if the user is holding shift.
*/
fontMapping map[TABLE_SIZE] = {

    {SDL_SCANCODE_A, 1, KMOD_SHIFT, 33},        /* A */
    {SDL_SCANCODE_B, 1, KMOD_SHIFT, 34},        /* B */
    {SDL_SCANCODE_C, 1, KMOD_SHIFT, 35},        /* C */
    {SDL_SCANCODE_D, 1, KMOD_SHIFT, 36},        /* D */
    {SDL_SCANCODE_E, 1, KMOD_SHIFT, 37},        /* E */
    {SDL_SCANCODE_F, 1, KMOD_SHIFT, 38},        /* F */
    {SDL_SCANCODE_G, 1, KMOD_SHIFT, 39},        /* G */
    {SDL_SCANCODE_H, 1, KMOD_SHIFT, 40},        /* H */
    {SDL_SCANCODE_I, 1, KMOD_SHIFT, 41},        /* I */
    {SDL_SCANCODE_J, 1, KMOD_SHIFT, 42},        /* J */
    {SDL_SCANCODE_K, 1, KMOD_SHIFT, 43},        /* K */
    {SDL_SCANCODE_L, 1, KMOD_SHIFT, 44},        /* L */
    {SDL_SCANCODE_M, 1, KMOD_SHIFT, 45},        /* M */
    {SDL_SCANCODE_N, 1, KMOD_SHIFT, 46},        /* N */
    {SDL_SCANCODE_O, 1, KMOD_SHIFT, 47},        /* O */
    {SDL_SCANCODE_P, 1, KMOD_SHIFT, 48},        /* P */
    {SDL_SCANCODE_Q, 1, KMOD_SHIFT, 49},        /* Q */
    {SDL_SCANCODE_R, 1, KMOD_SHIFT, 50},        /* R */
    {SDL_SCANCODE_S, 1, KMOD_SHIFT, 51},        /* S */
    {SDL_SCANCODE_T, 1, KMOD_SHIFT, 52},        /* T */
    {SDL_SCANCODE_U, 1, KMOD_SHIFT, 53},        /* U */
    {SDL_SCANCODE_V, 1, KMOD_SHIFT, 54},        /* V */
    {SDL_SCANCODE_W, 1, KMOD_SHIFT, 55},        /* W */
    {SDL_SCANCODE_X, 1, KMOD_SHIFT, 56},        /* X */
    {SDL_SCANCODE_Y, 1, KMOD_SHIFT, 57},        /* Y */
    {SDL_SCANCODE_Z, 1, KMOD_SHIFT, 58},        /* Z */
    {SDL_SCANCODE_0, 1, 0, 16}, /* 0 */
    {SDL_SCANCODE_1, 1, 0, 17}, /* 1 */
    {SDL_SCANCODE_2, 1, 0, 18}, /* 2 */
    {SDL_SCANCODE_3, 1, 0, 19}, /* 3 */
    {SDL_SCANCODE_4, 1, 0, 20}, /* 4 */
    {SDL_SCANCODE_5, 1, 0, 21}, /* 5 */
    {SDL_SCANCODE_6, 1, 0, 22}, /* 6 */
    {SDL_SCANCODE_7, 1, 0, 23}, /* 7 */
    {SDL_SCANCODE_8, 1, 0, 24}, /* 8 */
    {SDL_SCANCODE_9, 1, 0, 25}, /* 9 */
    {SDL_SCANCODE_SPACE, 1, 0, 0},      /* ' ' */
    {SDL_SCANCODE_1, 0, KMOD_SHIFT, 1}, /* ! */
    {SDL_SCANCODE_SLASH, 0, KMOD_SHIFT, 31},    /* ? */
    {SDL_SCANCODE_SLASH, 1, 0, 15},     /* / */
    {SDL_SCANCODE_COMMA, 1, 0, 12},     /* , */
    {SDL_SCANCODE_SEMICOLON, 1, 0, 27}, /* ; */
    {SDL_SCANCODE_SEMICOLON, 0, KMOD_SHIFT, 26},        /* : */
    {SDL_SCANCODE_PERIOD, 1, 0, 14},    /* . */
    {SDL_SCANCODE_MINUS, 1, 0, 13},     /* - */
    {SDL_SCANCODE_EQUALS, 0, KMOD_SHIFT, 11},   /* = */
    {SDL_SCANCODE_APOSTROPHE, 1, 0, 7}, /* ' */
    {SDL_SCANCODE_APOSTROPHE, 0, KMOD_SHIFT, 2},        /* " */
    {SDL_SCANCODE_5, 0, KMOD_SHIFT, 5}, /* % */

};

/*
    This function maps an SDL_KeySym to an index in the bitmap font.
    It does so by scanning through the font mapping table one entry
    at a time.

    If a match is found (scancode and allowed modifiers), the proper
    index is returned.

    If there is no entry for the key, -1 is returned
*/
int
keyToIndex(SDL_Keysym key)
{
    int i, index = -1;
    for (i = 0; i < TABLE_SIZE; i++) {
        fontMapping compare = map[i];
        if (key.scancode == compare.scancode) {
            /* if this entry is valid with no key mod and we have no keymod, or if
               the key's modifiers are allowed modifiers for that mapping */
            if ((compare.allow_no_mod && key.mod == 0)
                || (key.mod & compare.mod)) {
                index = compare.index;
                break;
            }
        }
    }
    return index;
}

/*
    This function returns and x,y position for a given character number.
    It is used for positioning each character of text
*/
void
getPositionForCharNumber(int n, int *x, int *y)
{
    int renderW, renderH;
    SDL_RenderGetLogicalSize(renderer, &renderW, &renderH);

    int x_padding = 16;         /* padding space on left and right side of screen */
    int y_padding = 32;         /* padding space at top of screen */
    /* figure out the number of characters that can fit horizontally across the screen */
    int max_x_chars = (renderW - 2 * x_padding) / GLYPH_SIZE_SCREEN;
    int line_separation = 5;    /* pixels between each line */
    *x = (n % max_x_chars) * GLYPH_SIZE_SCREEN + x_padding;
    *y = (n / max_x_chars) * (GLYPH_SIZE_SCREEN + line_separation) +
        y_padding;
}

void
drawIndex(int index)
{
    int x, y;
    getPositionForCharNumber(numChars, &x, &y);
    SDL_Rect srcRect =
        { GLYPH_SIZE_IMAGE * index, 0, GLYPH_SIZE_IMAGE, GLYPH_SIZE_IMAGE };
    SDL_Rect dstRect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
    drawBlank(x, y);
    SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
}

/*  draws the cursor icon at the current end position of the text */
void
drawCursor(void)
{
    drawIndex(29);              /* cursor is at index 29 in the bitmap font */
}

/* paints over a glyph sized region with the background color
   in effect it erases the area
*/
void
drawBlank(int x, int y)
{
    SDL_Rect rect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
    SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
    SDL_RenderFillRect(renderer, &rect);
}

/* moves backwards one character, erasing the last one put down */
void
backspace(void)
{
    int x, y;
    if (numChars > 0) {
        getPositionForCharNumber(numChars, &x, &y);
        drawBlank(x, y);
        numChars--;
        getPositionForCharNumber(numChars, &x, &y);
        drawBlank(x, y);
        drawCursor();
    }
}

/* this function loads our font into an SDL_Texture and returns the SDL_Texture  */
SDL_Texture*
loadFont(void)
{

    SDL_Surface *surface = SDL_LoadBMP("kromasky_16x16.bmp");

    if (!surface) {
        printf("Error loading bitmap: %s\n", SDL_GetError());
        return 0;
    } else {
        /* set the transparent color for the bitmap font (hot pink) */
        SDL_SetColorKey(surface, 1, SDL_MapRGB(surface->format, 238, 0, 252));
        /* now we convert the surface to our desired pixel format */
        int format = SDL_PIXELFORMAT_ABGR8888;  /* desired texture format */
        Uint32 Rmask, Gmask, Bmask, Amask;      /* masks for desired format */
        int bpp;                /* bits per pixel for desired format */
        SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask,
                                   &Amask);
        SDL_Surface *converted =
            SDL_CreateRGBSurface(0, surface->w, surface->h, bpp, Rmask, Gmask,
                                 Bmask, Amask);
        SDL_BlitSurface(surface, NULL, converted, NULL);
        /* create our texture */
        texture =
            SDL_CreateTextureFromSurface(renderer, converted);
        if (texture == 0) {
            printf("texture creation failed: %s\n", SDL_GetError());
        } else {
            /* set blend mode for our texture */
            SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
        }
        SDL_FreeSurface(surface);
        SDL_FreeSurface(converted);
        return texture;
    }
}

int
main(int argc, char *argv[])
{
    int index;                  /* index of last key we pushed in the bitmap font */
    SDL_Window *window;
    SDL_Event event;            /* last event received */
    SDL_Keymod mod;             /* key modifiers of last key we pushed */
    SDL_Scancode scancode;      /* scancode of last key we pushed */
    int width;
    int height;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Error initializing SDL: %s", SDL_GetError());
    }
    /* create window */
    window = SDL_CreateWindow("iPhone keyboard test", 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
    /* create renderer */
    renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_GetWindowSize(window, &width, &height);
    SDL_RenderSetLogicalSize(renderer, width, height);

    /* load up our font */
    loadFont();

    /* draw the background, we'll just paint over it */
    SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
    SDL_RenderFillRect(renderer, NULL);
    SDL_RenderPresent(renderer);

    int done = 0;
    /* loop till we get SDL_Quit */
    while (!done && SDL_WaitEvent(&event)) {
        switch (event.type) {
        case SDL_QUIT:
            done = 1;
            break;
        case SDL_KEYDOWN:
            index = keyToIndex(event.key.keysym);
            scancode = event.key.keysym.scancode;
            mod = event.key.keysym.mod;
            if (scancode == SDL_SCANCODE_DELETE) {
                /* if user hit delete, delete the last character */
                backspace();
                lastCharWasColon = 0;
            } else if (lastCharWasColon && scancode == SDL_SCANCODE_0
                       && (mod & KMOD_SHIFT)) {
                /* if our last key was a colon and this one is a close paren, the make a hoppy face */
                backspace();
                drawIndex(32);  /* index for happy face */
                numChars++;
                drawCursor();
                lastCharWasColon = 0;
            } else if (index != -1) {
                /* if we aren't doing a happy face, then just draw the normal character */
                drawIndex(index);
                numChars++;
                drawCursor();
                lastCharWasColon =
                    (event.key.keysym.scancode == SDL_SCANCODE_SEMICOLON
                     && (event.key.keysym.mod & KMOD_SHIFT));
            }
            /* check if the key was a colon */
            /* draw our updates to the screen */
            SDL_RenderPresent(renderer);
            break;
        case SDL_MOUSEBUTTONUP:
            /*      mouse up toggles onscreen keyboard visibility */
            if (SDL_IsTextInputActive()) {
                SDL_StopTextInput();
            } else {
                SDL_StartTextInput();
            }
            break;
        }
    }
    cleanup();
    return 0;
}

/* clean up after ourselves like a good kiddy */
void
cleanup(void)
{
    SDL_DestroyTexture(texture);
    SDL_Quit();
}
