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

#import "SDL.h"
#import "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 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 = (SCREEN_WIDTH - 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 */

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

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