void snis_slider_draw(struct slider *s)
{
	double v;
	float width, tx1;
	int bar_color = DARKGREEN;
	float ptr_height = s->height / 2.0;
	float ptr_width = s->height / 3.0;

	s->timer++;
	if (s->vertical) {
		snis_slider_draw_vertical(s);
		return;
	}
	float f;

	if (s->fuzz) {
		f = (float) ((snis_randn(1000) - 500.0f) * s->fuzz) / 100000.0f;
		f = f * s->length;
	} else {
		f = 0.0f;
	}

	v = s->sample();
	s->value = (v - s->r1) / (s->r2 - s->r1);
	if (s->value == 0)
		f = 0.0f; /* no fuzz if no power */
	v = s->sample();
	bar_color = choose_barcolor(s, v);
	sng_set_foreground(s->color);
	sng_current_draw_rectangle(0, s->x, s->y, s->length, s->height);
	width = s->value * (s->length - 2.0);
	width = width + f;
	if (width < 0.0)
		width = 0;
	if (width > s->length - 2.0)
		width = s->length - 2.0;
	if (!s->clicked)
		sng_set_foreground(bar_color);
	sng_current_draw_rectangle(1, s->x + 1.0, s->y + 1.0, width, s->height - 2.0);
	if (!s->clicked)
		sng_set_foreground(s->color);

	tx1 = (s->input * s->length) + s->x;

	if (s->clicked) {
		sng_current_draw_line(tx1, s->y, tx1 - ptr_width, s->y - ptr_height);
		sng_current_draw_line(tx1, s->y, tx1 + ptr_width, s->y - ptr_height);
		sng_current_draw_line(tx1 - ptr_width, s->y - ptr_height,
						tx1 + ptr_width, s->y - ptr_height); 
		sng_current_draw_line(tx1, s->y + s->height,
				tx1 - ptr_width, s->y + s->height + ptr_height); 
		sng_current_draw_line(tx1, s->y + s->height,
				tx1 + ptr_width, s->y + s->height + ptr_height); 
		sng_current_draw_line(tx1 - ptr_width, s->y + s->height + ptr_height,
				tx1 + ptr_width, s->y + s->height + ptr_height); 
	}
	sng_abs_xy_draw_string(s->label, s->font,
				s->x + s->length + 5.0, s->y + 2.0 * s->height / 3.0);
}
static void draw_help_screen()
{
	sng_set_foreground(BLACK);
	sng_current_draw_rectangle(1, 50, 50, SCREEN_WIDTH - 100, SCREEN_HEIGHT - 100);
	sng_set_foreground(GREEN);
	sng_current_draw_rectangle(0, 50, 50, SCREEN_WIDTH - 100, SCREEN_HEIGHT - 100);
	draw_help_text(help_text);
}
static void snis_slider_draw_vertical(struct slider *s)
{
	double v;
	int height, ty1;
	int bar_color;
	int ptr_height = s->height / 2;
	int ptr_width = s->height / 3;
	float f;

	if (s->fuzz) {
		f = (float) ((snis_randn(1000) - 500.0f) * s->fuzz) / 100000.0f;
		f = f * s->length;
	} else {
		f = 0.0f;
	}

	s->timer++;
	v = s->sample();
	s->value = (v - s->r1) / (s->r2 - s->r1);
	if (s->value == 0)
		f = 0.0f; /* no fuzz if no power */
	v = s->sample();
	ty1 = (int) (s->y + s->length - s->input * s->length);
	bar_color = choose_barcolor(s, v);
	sng_set_foreground(s->color);
	sng_current_draw_rectangle(0, s->x, s->y, s->height, s->length);
	height = s->value * s->length - 1;
	height += f;
	if (height < 0)
		height = 0;
	if (height > s->length - 1)
		height = s->length - 1;
	if (!s->clicked)
		sng_set_foreground(bar_color);
	sng_current_draw_rectangle(1, s->x + 1, s->y + s->length - height,
					s->height - 2, height);
	if (!s->clicked)
		sng_set_foreground(s->color);

	if (s->clicked) {
		sng_current_draw_line(s->x, ty1, s->x - ptr_height, ty1 - ptr_width);
		sng_current_draw_line(s->x - ptr_height, ty1 - ptr_width, s->x - ptr_height, ty1 + ptr_width);
		sng_current_draw_line(s->x - ptr_height, ty1 + ptr_width, s->x, ty1);

		sng_current_draw_line(s->x + s->height, ty1, s->x + ptr_height + s->height, ty1 - ptr_width);
		sng_current_draw_line(s->x + ptr_height + s->height, ty1 - ptr_width,
			s->x + ptr_height + s->height, ty1 + ptr_width);
		sng_current_draw_line(s->x + ptr_height + s->height, ty1 + ptr_width,
			s->x + s->height, ty1);
	}
	/* sng_abs_xy_draw_string(s->label, s->font, s->x + s->length + 5, s->y + 2 * s->height / 3);  */
} 
void snis_strip_chart_draw(struct strip_chart *sc)
{
	int i, index;
	float x1, y1, x2, y2, w, h, ox, oy;

	sng_set_foreground(sc->color);
	w = sc->width;
	h = sc->height;
	ox = sc->x;
	oy = sc->y;
	sng_current_draw_rectangle(0, ox, oy, w, h);

	x2 = ox;
	y2 = oy;

	for (i = 0; i < sc->history_size; i++) {
		index = (sc->needle + i) % sc->history_size;
		x1 = x2;
		y1 = y2;
		x2 = (w * i) / sc->history_size + ox;
		y2 = oy + h * (255.0 - sc->history[index]) / 255.0;
		sng_current_draw_line(x1, y1, x2, y2);
		sng_abs_xy_draw_string(sc->label, sc->font, ox, oy + h + snis_font_lineheight(sc->font));
	}
	if (sc->warning_on) {
		sng_set_foreground(sc->warn_color);
		sng_abs_xy_draw_string(sc->warning_msg, sc->font, ox + 10, oy + 0.5 * h);
	}
}
void snis_scaling_strip_chart_draw(struct scaling_strip_chart *sc)
{
	int i, index;
	float x1, y1, x2, y2, w, h, ox, oy;
	char toplabel[20], bottomlabel[20];

	sng_set_foreground(sc->color);
	w = sc->width;
	h = sc->height;
	ox = sc->x;
	oy = sc->y;
	sng_current_draw_rectangle(0, ox, oy, w, h);

	x2 = ox;
	y2 = oy;

	sprintf(toplabel, format_string(sc->top), sc->top);
	sprintf(bottomlabel, format_string(sc->bottom), sc->bottom);

	for (i = 0; i < sc->history_size; i++) {
		index = (sc->needle + i) % sc->history_size;
		if (sc->history[index] > sc->top)
			sc->top = sc->history[index];
		if (sc->history[index] < sc->bottom)
			sc->bottom = sc->history[index];
		x1 = x2;
		y1 = y2;
		x2 = (w * i) / sc->history_size + ox;
		y2 = oy + h * (sc->top - sc->history[index] + sc->bottom) / (sc->top - sc->bottom);
		sng_current_draw_line(x1, y1, x2, y2);
		sng_abs_xy_draw_string(sc->label, sc->font, ox, oy + h + snis_font_lineheight(sc->font));
	}
	sng_abs_xy_draw_string(toplabel, sc->font, ox + w, oy);
	sng_abs_xy_draw_string(bottomlabel, sc->font, ox + w, oy + h);
	if (sc->warning_on) {
		sng_set_foreground(sc->warn_color);
		sng_abs_xy_draw_string(sc->warning_msg, sc->font, ox + 10, oy + 0.5 * h);
	}
}