#help_index "Graphics/Input"

public I64 PopUpColor(U8 *header=NULL, Bool allow_transparent=TRUE, Bool allow_default=TRUE)
{//Chooser for 16-color, default or transparent.
    I64   i;
    CDoc *doc = DocNew;

    if (header)
        DocPrint(doc, "%s",header);
    if (allow_transparent)
        DocPrint(doc, "$MU,\"TRANSPARENT\",LE=TRANSPARENT$\n");
    for (i = 0; i < COLORS_NUM; i++)
        DocPrint(doc, "$BG,%d$$MU,\"__%-8Z__\",LE=%d$$BG$\n", i, i, "ST_COLORS", i);
    if (allow_default)
        DocPrint(doc, "$BG,WHITE$$MU,\"DEFAULT\",LE=DOC_DEFAULT$$BG$");
    i = PopUpMenu(doc);
    DocDel(doc);

    return i;
}

public I64 PopUpColorLighting(U8 *header=NULL)
{//Chooser for std ZealOS DCLighting() color.
    I64   i;
    CDoc *doc = DocNew;

    if (header)
        DocPrint(doc, "%s", header);
    DocPrint(doc, "\nSingle-Sided means front and back different."
                  "\nDouble-Sided means front and back same."
                  "\n"
                  "\nHalf-Range means 0 to [0,7]"
                  "\n                 [8,15]-8 to [8,15]"
                  "\nFull-Range means 0 to [0,7] to [0,7]+8"
                  "\n");
    DocPrint(doc, "\n$LTPURPLE$Single-Sided Full-Range Double-Sided Full-Range\n$BLACK$");
    for (i = 0; i < COLORS_NUM / 2; i++)
    {
        DocPrint(doc, "$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$ ",  i, i, "ST_COLORS", i);
        DocPrint(doc, "$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$\n", i, i, "ST_COLORS", ROPF_TWO_SIDED+i);
    }
    DocPrint(doc, "\n$LTPURPLE$Single-Sided Half-Range Double-Sided Half-Range\n$BLACK$");
    for (i = 0; i < COLORS_NUM; i++)
    {
        DocPrint(doc, "$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$ ",  i, i, "ST_COLORS", ROPF_HALF_RANGE_COLOR+i);
        DocPrint(doc, "$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$\n", i, i, "ST_COLORS", ROPF_TWO_SIDED + ROPF_HALF_RANGE_COLOR + i);
    }
    i = PopUpMenu(doc);
    DocDel(doc);

    return i;
}

class CTransformForm
{
    F64 x_scale     format "$DA-TRM,A=\"X Scale :%12.6f\"$\n";
    F64 y_scale     format "$DA-TRM,A=\"Y Scale :%12.6f\"$\n";
    F64 z_scale     format "$DA-TRM,A=\"Z Scale :%12.6f\"$\n";

    F64 theta_z         format "\nAngles are in degrees\n"
                           "$DA-TRM,A=\"Z-Axis  :%12.6f\"$\n";
    F64 theta_y         format "$DA-TRM,A=\"Y-Axis  :%12.6f\"$\n";
    F64 theta_x         format "$DA-TRM,A=\"X-Axis  :%12.6f\"$\n";

    F64 x_offset    format "\n$DA-TRM,A=\"X Offset:%12.6f\"$\n";
    F64 y_offset    format "$DA-TRM,A=\"Y Offset:%12.6f\"$\n";
    F64 z_offset    format "$DA-TRM,A=\"Z Offset:%12.6f\"$\n";
};

#help_index "Graphics/Input;Graphics/Math/3D Transformation"
public Bool PopUpTransform(I64 *r)
{//Prompt for Mat4x4 transform.
    CTransformForm *tf = MAlloc(sizeof(CTransformForm));

    tf->x_scale     = 1.0;
    tf->y_scale     = 1.0;
    tf->z_scale     = 1.0;
    tf->theta_x         = 0.0;
    tf->theta_y         = 0.0;
    tf->theta_z         = 0.0;
    tf->x_offset    = 0.0;
    tf->y_offset    = 0.0;
    tf->z_offset    = 0.0;
    if (PopUpForm(tf))
    {
        MemSet(r, 0, 16 * sizeof(I64));
        r[0]    = tf->x_scale * GR_SCALE;
        r[5]    = tf->y_scale * GR_SCALE;
        r[10]   = tf->z_scale * GR_SCALE;
        r[15]   = GR_SCALE;

        Mat4x4RotZ(r, tf->theta_z * pi / 180.0);
        Mat4x4RotY(r, tf->theta_y * pi / 180.0);
        Mat4x4RotX(r, tf->theta_x * pi / 180.0);

        r[3]    = tf->x_offset * GR_SCALE;
        r[7]    = tf->y_offset * GR_SCALE;
        r[11]   = tf->z_offset * GR_SCALE;

        return TRUE;
    }
    else
        return FALSE;
}

#help_index "Graphics/Input"
#define PU_SPACING      10
U0 DrawIt(CTask *task, CDC *dc)
{
    I64   i, j, i1, j1;
    CDoc *doc = DocPut(task);

    for (j = 0; j < 17; j++)
        for (i = 0; i < 17; i++)
        {
            if (j < 16)
                j1 = j;
            else
                j1 = TRANSPARENT;
            if (i < 16)
                i1 = i;
            else
                i1 = TRANSPARENT;
            dc->color = j1 + i1 << 16 + ROPF_DITHER;
            GrRect(dc, i * PU_SPACING, j * PU_SPACING + FramePtr("DitherFrame", task), PU_SPACING, PU_SPACING);
        }
    i = (17 * PU_SPACING + FONT_WIDTH - 1) / FONT_WIDTH;
    if (doc->max_x > i)
        i = doc->max_x;
    WinHorz(task->win_left, task->win_left + i, task);
    WinVert(task->win_top,  task->win_top + doc->max_y + (17 * PU_SPACING + FONT_WIDTH - 1) / FONT_WIDTH, task);
}

I64 DitherColor2(U8 *header=NULL)
{
    I64 message_code, arg1, arg2, res = -1, i, j;

    DocClear;
    "%s", header;
    DocRecalc(DocPut);
    FramePtrAdd("DitherFrame", (DocPut->max_y + 1) * FONT_HEIGHT);
    SettingsPush; //See SettingsPush
    Fs->draw_it = &DrawIt;
    do
    {
        message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_MS_L_DOWN | 1 << MESSAGE_KEY_DOWN);
        if (message_code == MESSAGE_MS_L_DOWN)
        {
            message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_MS_L_UP);
            i = arg1 / PU_SPACING;
            j = (arg2 - FramePtr("DitherFrame")) / PU_SPACING;
            if (arg1 >= 0 && arg2 >= 0 && 0 <= j < 17 && 0 <= i < 17)
            {
                if (j == 16)
                    j = TRANSPARENT;
                if (i == 16)
                    i = TRANSPARENT;
                res = j + i << 16 + ROPF_DITHER;
                goto dc_done;
            }
        }
    }
    while (!(message_code == MESSAGE_KEY_DOWN && (arg1 == CH_ESC || arg1 == CH_SHIFT_ESC)));

    do MessageGet(&arg1, &arg2, 1 << MESSAGE_KEY_UP);
    while (!arg1);
dc_done:
    SettingsPop;
    FramePtrDel("DitherFrame");

    return res;
}

public I64 PopUpColorDither(U8 *header=NULL)
{//Chooser for 2 x 16 colors or transparent.
    U8 buf[STR_LEN];

    StrPrint(buf,"DitherColor2(0x%X);", header);

    return PopUp(buf, Fs);
}