#include "dialog.h"

// Debug purposes
int _strlen(const char *str) { int i = 0; while (str[i++]); return i; }

void dialog(dialog_t *dialog)
{
    // Init profiler
    prof_t prof_fps = prof_make();
    uint32_t time = 0;
    uint32_t us_elapsed = 1;

    // Init key event
    key_event_t e;

    // Init characters metadata (who's talking, etc.)
    int talking = 0;

    // Init dialog characters pictures
    img_t char_flipped = img_hflip_create(*(dialog->characters[1]));
    img_t chars_img[2][2] = {
        { img_copy(*(dialog->characters[0])),
          img_darken_create(*(dialog->characters[0])) },
        { char_flipped,
          img_darken_create(char_flipped)}
    };

    // Init text properties
    int current_replica = 0;
    float current_chars = 0, text_speed = 0.000012; // Chars per us
    char wait_change = 0;

    // Entering main loop
    prof_enter(prof_fps);

    while(dialog->text[current_replica])
    {
        // Get last keyboard event
        clearevents();

        // Manage events
        if(keydown(KEY_EXIT)) break;
        if(keydown(KEY_SHIFT) && wait_change == 1)
        {
            // Reset current chars
            current_chars = 0;
            // Waiting for key up
            wait_change = 2;
        }
        if(!keydown(KEY_SHIFT) && wait_change == 2)
        {
            // Change who's speaking
            talking = !talking;
            // Update current replica
            current_replica++;
            // We're not waiting anymore
            wait_change = 0;
        }

        // Manage states
        if(keydown(KEY_SHIFT))
        {
            text_speed = 0.000028;
        } else {
            text_speed = 0.000012;
        }

        // Move text
        if(!wait_change) current_chars += us_elapsed * text_speed;
        if(current_chars > _strlen(dialog->text[current_replica]))
        {
            current_chars = _strlen(dialog->text[current_replica]);
            // This may be dirty (mixing engine and inputs) but who cares?
            if(!keydown(KEY_SHIFT)) wait_change = 1;
        }

        // Clear vram before drawing
        dclear(C_BLACK);

        // Display everything
        img_render_vram(chars_img[0][talking],
            DWIDTH * 0.15,
            DHEIGHT * (0.15 + 0.04 * fcos(time * 0.000005)));
        img_render_vram(chars_img[1][!talking],
            DWIDTH * 0.85 - chars_img[1][0].width,
            DHEIGHT * (0.15 + 0.04 * fsin(time * 0.000005)));

        display_text(dialog->text[current_replica], (int)current_chars);

        dprint_opt(DWIDTH-1, DHEIGHT-1, C_WHITE, C_NONE, DTEXT_RIGHT,
            DTEXT_BOTTOM, "%i FPS", 1000000 / us_elapsed);

        // Update VRAM
        dupdate();

        // Get elapsed time, reset profiler and start it again
        prof_leave(prof_fps);
        us_elapsed = prof_time(prof_fps);
        prof_fps.elapsed = 0;
        prof_enter(prof_fps);

        // Update global time
        time += us_elapsed;
    }

    /* Destroy temporary images */
    for(int i = 0; i < 2; i++)
        img_destroy(chars_img[i][i]);
}


// TODO: optimize this naive algorithm. Soft breaks are not implemented
void display_text(const char *src, int chars)
{
    // If no chars, nothing to do here
    if(chars == 0) return;

    // Init font
    const font_t *current_font = dfont(NULL);

    // Init dialog text buffers
    static char lines[4][50]; // TODO: do not hardcode these sizes

    // Init width, height for line size
    int w, h;

    // Init line and position on line
    int l = 0, p = 0;

    // For each char to be displayed
    for(int i = 0; i < chars; i++)
    {
        // Copy char into a line
        lines[l][p] = src[i];
        lines[l][p+1] = '\0';

        // Get line size
        dsize(lines[l], current_font, &w, &h);

        // If it's too long, move to a new line
        if(w > 0.7 * DWIDTH)
        {
            lines[l][p] = '\0';
            l++; p = 0;
            lines[l][p] = src[i];
            lines[l][p+1] = '\0';
        }

        // Move to next char on the line
        p++;
    }

    // Draw all lines
    for(int i = 0; i < l+1; i++)
    {
        dtext(0.15 * DWIDTH,
            0.6 * DHEIGHT + (current_font->line_height + 4) * i,
            C_WHITE, lines[i]);
    }
}
