/*After making a font...

You can save it as a binary file with:

    FileWrite("filename.BIN", text.font, 256 * FONT_HEIGHT);

You can load it with:

    U64 *my_font = FileRead("filename.BIN");
    text.aux_font = my_font;

<CTRL-ALT-f> will toggle main font and aux_font.

If you want to change the system font permanently,
save to a file with this font editor program
and cut and paste the code into ::/Kernel/FontStd.ZC.
You will need to recompile Kernel by calling BootHDIns().

See ::/Demo/ExtChars.ZC, ::/Demo/Games/CharDemo.ZC,
::/Demo/Graphics/CharAnimation.ZC and ::/Demo/ScreenCodes.ZC.
*/

#define BLOW_UP_CHAR_X  (18 * FONT_WIDTH)
#define BLOW_UP_CHAR_Y  (4  * FONT_HEIGHT)

U8 cur_ch;

U0 DrawIt(CTask *task, CDC *dc)
{
    I64 i, j, k, c;

    TextPrint(task, 0, 0, BLUE << 4 + YELLOW, "Press <CTRL-ALT-f> to Toggle Aux Font.");
    k = 0;
    for (i = 0; i < 16; i++)
        for (j = 0; j < 16; j++)
        {
            if (k == cur_ch)
            {
                if (Blink)
                    c = (BLUE << 4 + YELLOW) << 8 + k++;
                else
                    c = (YELLOW << 4 + BLUE) << 8 + k++;
            }
            else
                c = (BLUE << 4 + WHITE) << 8 + k++;
            TextChar(task,, j, i + 2, c);
        }

    k = 0;
    for (i = 0; i < FONT_HEIGHT; i++)
        for (j = 0; j < FONT_WIDTH; j++)
        {
            if (Bt(&text.font[cur_ch], k++))
                dc->color = YELLOW;
            else
                dc->color = BLUE;
            GrRect(dc,  BLOW_UP_CHAR_X + j * FONT_WIDTH, 
                        BLOW_UP_CHAR_Y + i * FONT_HEIGHT,
                        FONT_WIDTH, FONT_HEIGHT);
        }
}

U0 FESave(Bool prompt)
{
    U8       old_draw_it = Fs->draw_it;
    CDoc    *doc = DocNew;
    I64      i;

    for (i = 0; i < 256; i++)
    {
        DocPrint(doc, "0x%016X,", text.font[i]);
        if (Bt(char_bmp_safe_dollar, i))
            DocPrint(doc, "//%c", i);
        else if (i == '$')
            DocPrint(doc, "//$$", i);
        DocPrint(doc, "\n");
    }
    Fs->draw_it = NULL;
    DocWrite(doc, prompt);
    Fs->draw_it = old_draw_it;
    DocDel(doc);
}

U0 FontEd()
{
    I64 message_code, arg1, arg2, k;

    SettingsPush; //See SettingsPush
    MenuPush(   "File {"
                "  SaveAs(,CH_CTRLA);"
                "  Abort(,CH_SHIFT_ESC);"
                "  Exit(,CH_ESC);"
                "}");
    AutoComplete;
    DocCursor;
    DocClear;
    Fs->win_inhibit |= WIG_DBL_CLICK;
    cur_ch = 0;
    try
    {
        Fs->draw_it = &DrawIt;
        while (TRUE)
        {
            switch (message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_KEY_DOWN  | 1 << MESSAGE_MS_L_DOWN |
                                                            1 << MESSAGE_MS_R_DOWN | 1 << MESSAGE_MS_MOVE))
            {
                case MESSAGE_KEY_DOWN:
                    switch (arg1)
                    {
                        case 0:
                            switch (arg2.u8[0])
                            {
                                case SC_CURSOR_LEFT:
                                    cur_ch--;
                                    break;

                                case SC_CURSOR_RIGHT:
                                    cur_ch++;
                                    break;

                                case SC_CURSOR_UP:
                                    cur_ch -= 16;
                                    break;

                                case SC_CURSOR_DOWN:
                                    cur_ch += 16;
                                    break;

                            }
                            break;
                            goto fe_done;

                        case CH_CTRLA:
                            FESave(TRUE);
                            break;

                        case CH_ESC:
                            FESave(FALSE);

                        case CH_SHIFT_ESC:
                            goto fe_done;

                        default:
                            cur_ch = arg1;
                    }
                    break;

                case MESSAGE_MS_L_DOWN:
                case MESSAGE_MS_R_DOWN:
                    if (0 <= arg1 < FONT_WIDTH * 16 && 0 <= arg2 - 2 * FONT_HEIGHT < FONT_HEIGHT * 16)
                    {
                        cur_ch = (arg2 / FONT_HEIGHT - 2) * 16 + arg1 / FONT_WIDTH;
                        break;
                    }
                    //fall through
                case MESSAGE_MS_MOVE:
                    k = ((arg2 - BLOW_UP_CHAR_Y) / FONT_HEIGHT) * FONT_WIDTH + (arg1 - BLOW_UP_CHAR_X) / FONT_WIDTH;
                    if (0 <= k < FONT_WIDTH * FONT_HEIGHT)
                    {
                        if (mouse.lb || message_code == MESSAGE_MS_L_DOWN)
                            Bts(&text.font[cur_ch], k);
                        if (mouse.rb || message_code == MESSAGE_MS_R_DOWN)
                            Btr(&text.font[cur_ch], k);
                    }
                    break;
            }
        }
fe_done:
        MessageGet(,, 1 << MESSAGE_KEY_UP);
    }
    catch
        PutExcept;
    MenuPop;
    SettingsPop;
}

FontEd;