#define LASER_TEMP_MAX          30.0
#define LASER_THRESHOLD_TEMP    10.0
#define MASS_TEMP_MAX           5.0

class CtrlPanelState
{
    I64  shot_radius, fuse_time;
    F64  laser_temperature;
    Bool spacewalk;

} ctrl_panel;

#define CTRL_PANEL_SPACING      33
#define CTRL_PANEL_RANGE        30
#define CTRL_PANEL_BORDER       2
#define CTRL_PANEL_BTTN_SIZE    12

#define TMP_Y   (+2)

U0 DrawCtrlPanelCtrl(CDC *dc, CCtrl *c)
{
    CtrlPanelState *s = c->state;
    F64             d, d_range;

    dc->color = LTRED;
    GrRect(dc,  c->left, c->top, CTRL_PANEL_SPACING * 3 + 2, 
                CTRL_PANEL_SPACING * 2 + CTRL_PANEL_RANGE + CTRL_PANEL_BTTN_SIZE);
    dc->color = DKGRAY;
    GrRect(dc,  c->left + CTRL_PANEL_BORDER, c->top + CTRL_PANEL_BORDER, 
                CTRL_PANEL_SPACING * 3 + 2 - 2 * CTRL_PANEL_BORDER, 
                CTRL_PANEL_SPACING * 2 + CTRL_PANEL_RANGE + CTRL_PANEL_BTTN_SIZE
                -2 * CTRL_PANEL_BORDER);
    dc->color = BLACK;
    GrLine(dc, c->left + CTRL_PANEL_SPACING, (c->top + CTRL_PANEL_BTTN_SIZE) +
                CTRL_PANEL_SPACING, c->left + CTRL_PANEL_SPACING, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING+CTRL_PANEL_RANGE-1);
    GrLine(dc, c->left + 2 * CTRL_PANEL_SPACING + 1, (c->top + CTRL_PANEL_BTTN_SIZE) +
                CTRL_PANEL_SPACING, c->left + 2 * CTRL_PANEL_SPACING + 1, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING + CTRL_PANEL_RANGE - 1);

    dc->color = BLACK;
    GrRect(dc, (c->left + c->right + 1) / 2 - 9 * FONT_WIDTH / 2 - 3, 
                c->top + CTRL_PANEL_BORDER + (CTRL_PANEL_SPACING - FONT_HEIGHT) / 2, 
                9 * FONT_WIDTH + 6, FONT_HEIGHT + 6);

    if (s->spacewalk)
        dc->color =YELLOW;
    else
        dc->color = DKGRAY;
    GrRect(dc, (c->left + c->right + 1) / 2 - 9 * FONT_WIDTH / 2 - 2, 
                c->top + CTRL_PANEL_BORDER + 1 + (CTRL_PANEL_SPACING - FONT_HEIGHT) / 2, 
                9 * FONT_WIDTH + 4, FONT_HEIGHT + 4);

    dc->color = RED;
    GrPrint(dc, (c->left + c->right + 1) / 2 - 9 * FONT_WIDTH / 2, 
                c->top + CTRL_PANEL_BORDER + 3 +
                (CTRL_PANEL_SPACING - FONT_HEIGHT) / 2, "SpaceWalk");
    GrPrint(dc, c->left + CTRL_PANEL_SPACING - 4 * FONT_WIDTH / 2, 
                (c->top + CTRL_PANEL_BTTN_SIZE) +
                CTRL_PANEL_SPACING - FONT_HEIGHT - 2, "Size");
    GrPrint(dc, c->left + 2 * CTRL_PANEL_SPACING + 1 - 4 * FONT_WIDTH / 2, 
                (c->top + CTRL_PANEL_BTTN_SIZE) +
                CTRL_PANEL_SPACING - FONT_HEIGHT - 2, "Fuse");
    dc->color = LTRED;
    GrPrint(dc, c->left + CTRL_PANEL_SPACING - FONT_WIDTH / 2, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING + CTRL_PANEL_RANGE + 3, 
                "%d", s->shot_radius * 10 / CTRL_PANEL_RANGE);
    GrPrint(dc, c->left + 2 * CTRL_PANEL_SPACING + 1 - FONT_WIDTH / 2, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING + CTRL_PANEL_RANGE + 3, 
                "%d", s->fuse_time * 10 / CTRL_PANEL_RANGE);
    GrRect(dc, c->left + CTRL_PANEL_SPACING - 3, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING +
                CTRL_PANEL_RANGE - 1 - s->shot_radius - 2 , 7, 5);
    GrRect(dc, c->left + 2 * CTRL_PANEL_SPACING + 1 - 3, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING +
                CTRL_PANEL_RANGE - 1 - s->fuse_time - 2, 7, 5);
    dc->color = YELLOW;
    GrRect(dc, c->left + CTRL_PANEL_SPACING - 2, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING +
                CTRL_PANEL_RANGE - 1 - s->shot_radius - 1 , 5, 3);
    GrRect(dc, c->left + 2 * CTRL_PANEL_SPACING + 1 - 2, 
                (c->top + CTRL_PANEL_BTTN_SIZE) + CTRL_PANEL_SPACING +
                CTRL_PANEL_RANGE - 1 - s->fuse_time - 1, 5, 3);

    d_range = c->right - c->left - 5 - 5;
    d = s->laser_temperature * d_range / LASER_TEMP_MAX;
    dc->color = BLACK;
    GrRect(dc, c->left + 5 - 1, c->bottom + TMP_Y - 2, d_range + 2, 2 + 1 + 1);
    if (d > 1.0)
    {
        dc->color = GREEN;
        GrRect(dc, c->left + 5, c->bottom + TMP_Y - 1, Min(d, d_range / 3), 2);
        if (d >= d_range / 3)
        {
            dc->color = YELLOW;
            GrRect(dc, c->left + 5 + d_range / 3, c->bottom + TMP_Y - 1, Min(d, 2 * d_range/3)-d_range / 3, 2);
            if (d >= 2 * d_range / 3)
            {
                dc->color = RED;
                GrRect(dc, c->left + 5 + 2 * d_range / 3, c->bottom + TMP_Y - 1, d - 2 * d_range / 3, 2);
            }
        }
    }
}

U0 UpdateDerivedCtrlPanelCtrl(CCtrl *c)
{
    CtrlPanelState *s = c->state;

    c->left     = c->win_task->pix_width - (CTRL_PANEL_SPACING * 3 + 2);
    c->right    = c->left + CTRL_PANEL_SPACING * 3 + 2;
    c->top      = c->win_task->pix_height - (CTRL_PANEL_SPACING * 2 + CTRL_PANEL_RANGE + CTRL_PANEL_BTTN_SIZE);
    c->bottom   = c->top + CTRL_PANEL_SPACING * 2 + CTRL_PANEL_RANGE;

    s->shot_radius  = ClampI64(s->shot_radius, 0, CTRL_PANEL_RANGE - 1);
    s->fuse_time    = ClampI64(s->fuse_time,   0, CTRL_PANEL_RANGE - 1);
}

U0 LeftClickCtrlPanel(CCtrl *c, I64 x, I64 y, Bool)
{
    CtrlPanelState *s = c->state;

    if (y < c->top + CTRL_PANEL_BORDER + (CTRL_PANEL_SPACING - FONT_HEIGHT) / 2 + FONT_HEIGHT + 6)
        s->spacewalk = TRUE;
    else
    {
        if (x < (c->right + c->left) / 2)
            s->shot_radius = CTRL_PANEL_RANGE - 1 - (y - (c->top + CTRL_PANEL_SPACING + CTRL_PANEL_BTTN_SIZE));
        else
            s->fuse_time = CTRL_PANEL_RANGE - 1 - (y - (c->top + CTRL_PANEL_SPACING + CTRL_PANEL_BTTN_SIZE));
    }
    if (c->update_derived_vals)
        (*c->update_derived_vals)(c);
}

CCtrl *CtrlPanelNew()
{
    CCtrl *c = CAlloc(sizeof(CCtrl));

    MemSet(&ctrl_panel, 0, sizeof(ctrl_panel));
    c->win_task = Fs;
    c->flags = CTRLF_SHOW | CTRLF_CAPTURE_LEFT_MS;
    c->type = CTRLT_GENERIC;
    c->state = &ctrl_panel;
    c->draw_it = &DrawCtrlPanelCtrl;
    c->left_click = &LeftClickCtrlPanel;
    c->update_derived_vals = &UpdateDerivedCtrlPanelCtrl;
    QueueInsert(c, Fs->last_ctrl);
    TaskDerivedValsUpdate;

    return c;
}

U0 CtrlPanelDel(CCtrl *c)
{
    QueueRemove(c);
    Free(c);
}