//This is run in a #exe{}.

U8 *kernel_config_options = "MemInit\0"
                            "HeapInit\0"
                            "VarInit\0"
                            "HomeDir\0"
                            "NoMP\0"
                            "MountAHCIAuto\0"
                            "DebugDistro\0"
                            "Help";

#define CONFIG_MEM_INIT         0
#define CONFIG_HEAP_INIT        1
#define CONFIG_VAR_INIT         2
#define CONFIG_HOME_DIR         3
#define CONFIG_NO_MP            4
#define CONFIG_MOUNT_AHCI_AUTO  5
#define CONFIG_DEBUG_DISTRO     6
#define CONFIG_OPTIONS_NUM      7

#define CONFIG_HELP             7

class CKConfig
{
    U8      *disk_cache_size_exp;
    CDoc    *add_dev;
    U8      *debug_distro_file, *debug_distro_start;
    U8      *home_dir;
    Bool    opts[CONFIG_OPTIONS_NUM];
    U8      mem_init_val, heap_init_val, var_init_val, boot_drive_let, mount_ide_auto_hd_let, mount_ide_auto_cd_let;
};

CDoc *KConfigAddDev(CKConfig *c)
{
    I64   ch;
    CDoc *doc = DocNew;

    "\n\nIn anticipation of the drives you will define shortly, enter the drive letter\n"
    "of the drive with your Home directory. ($PURPLE$<ENTER>$FG$ for current drive) Boot Drive:";

    ch = Letter2Letter(CharGet);
    if ('A' <= ch <= 'Z')
        c->boot_drive_let = ch;
    else
        c->boot_drive_let = Drive2Letter(Fs->cur_dv);

    "\n\n$BK,1$$PURPLE$Mount drives so they will be present when you boot.$FG$$BK,0$\n";

    Mount2(c->boot_drive_let, doc, FALSE);

    return doc;
}

U0 KConfigOptions(CKConfig *c)
{
    I64  i;
    U8  *st = NULL, *st2, *st3;
    Bool state;
    do
    {
        Free(st);
        for (i = 0; i < CONFIG_OPTIONS_NUM; i++)
            if (i == CONFIG_HOME_DIR)
                "$PURPLE$%13tz$FG$:\"%s\"\n", i, kernel_config_options, c->home_dir;
            else
                "$PURPLE$%13tz$FG$:%Z\n", i, kernel_config_options, c->opts[i], "ST_OFF_ON";
        "\nType '$PURPLE$Help$FG$' for help.\n";
        st = StrGet("Option ($PURPLE$<ENTER>$FG$ when done):", "");
        i = ListMatch(st, kernel_config_options, LMF_IGNORE_CASE);
        if (i == CONFIG_HELP)
            "\n"
            "$PURPLE$MemInit$FG$ Initializes memory above 0x100000 "
            "to a value at boot.\n"
            "$PURPLE$HeapInit$FG$ Initializes MAlloc() memory to a value.\n"
            "$PURPLE$VarInit$FG$ Initializes global variable memory to a value.\n"
            "$PURPLE$HomeDir$FG$ Set home dir.\n"
            "$PURPLE$NoMP$FG$ No multicore.\n"
            "$PURPLE$MountAHCIAuto$FG$ Auto Mount AHCI drives to 'C' and 'T'.\n"
            "$PURPLE$DebugDistro$FG$ Include RAM Drive in Kernel.ZXE.\n"
            "\n";
        else
            if (0 <= i < CONFIG_OPTIONS_NUM)
            {
                state = c->opts[i] = !c->opts[i];
                switch (i)
                {
                    case CONFIG_MEM_INIT:
                        if (state)
                            c->mem_init_val = I64Get("Val (0-255):", 255, 0, 255);
                        break;

                    case CONFIG_HEAP_INIT:
                        if (state)
                            c->heap_init_val = I64Get("Val (0-255):", 255, 0, 255);
                        break;

                    case CONFIG_VAR_INIT:
                        if (state)
                            c->var_init_val = I64Get("Val (0-255):", 255, 0, 255);
                        break;

                    case CONFIG_HOME_DIR:
                        st2 = StrGet("Home Dir(\"%s\"):", c->home_dir);
                        if (!*st2)
                            st2 = StrNew("::/Home");
                        else if (st2[1] != ':')
                        {
                            st3 = MStrPrint("::%s", st2);
                            Free(st2);
                            st2 = st3;
                        }
                        Free(c->home_dir);
                        c->home_dir = st2;
                        if (StrCompare(c->home_dir, "::/Home"))
                            c->opts[i] = TRUE;
                        else
                            c->opts[i] = FALSE;
                        break;

                    case CONFIG_MOUNT_AHCI_AUTO:
                        if (state)
                        {
                            "First HD Drive Let:";
                            c->mount_ide_auto_hd_let = Letter2Letter(CharGet);
                            if (!('A' <= c->mount_ide_auto_hd_let <= 'Z'))
                                c->mount_ide_auto_hd_let = 0;
                            '\n';
                            if (c->mount_ide_auto_hd_let)
                                "First HD Drive:%C\n", c->mount_ide_auto_hd_let;
                            else
                                "First HD Drive:%C\n", 'C';

                            "First CD Drive Let:";
                            c->mount_ide_auto_cd_let = Letter2Letter(CharGet);
                            if (!('A' <= c->mount_ide_auto_cd_let <= 'Z'))
                                c->mount_ide_auto_cd_let = 0;
                            '\n';
                            if (c->mount_ide_auto_cd_let)
                                "First CD Drive:%C\n", c->mount_ide_auto_cd_let;
                            else
                                "First CD Drive:%C\n", 'T';
                        }
                        else
                        {
                            c->mount_ide_auto_hd_let = 0;
                            c->mount_ide_auto_cd_let = 0;
                        }
                        break;

                    case CONFIG_DEBUG_DISTRO:
                        Free(c->debug_distro_file);
                        c->debug_distro_file  = 0;
                        c->debug_distro_start = 0;
                        if (state)
                        {
                            c->debug_distro_file  = StrGet("Debug Distro File:");
                            c->debug_distro_start = I64Get("Debug Distro Start:");
                        }
                        break;
                }
            }
    }
    while (*st);

    Free(st);
}

CKConfig *KConfigNew()
{
    CKConfig *c = CAlloc(sizeof(CKConfig));

    c->add_dev = KConfigAddDev(c);
    c->home_dir = StrNew("::/Home");
 
    c->disk_cache_size_exp = StrGet("\nDisk Cache Size in Bytes, gets rounded-up funny, "
                                    "($PURPLE$<ENTER>$FG$ will use default.):",
                                    "Scale2Mem(0x80000,0x8000000)");
    KConfigOptions(c);

    return c;
}
 
U0 KConfigDel(CKConfig *c)
{
    DocDel(c->add_dev);
    Free(c->debug_distro_file);
    Free(c->home_dir);
    Free(c->disk_cache_size_exp);
    Free(c);
}