/*                               -*- Mode: C -*- 
 * info.c -- manage info boxes.
 * 
 * Author          : 
 * Created On      : Tue Apr 20 08:24:53 1999
 * Last Modified By: 
 * Last Modified On: Mon Aug 16 08:31:26 1999
 * Status          : Unknown, Use with caution!
 * 
 * Unless other notices are present in any part of this file
 * explicitly claiming copyrights for other people and/or 
 * organizations, the contents of this file is fully copyright 
 * (C) 1999 Peter Bosch, all rights reserved.
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <errno.h>

#include "info.h"

static info_t *ilist;

static void i_redraw(info_t *b);

info_t *
i_new(Display *display, Window win, GC gc, XFontStruct *mf, Pixmap stipple,
      int x, int y, int width, int height, unsigned long fg, unsigned long bg, 
      unsigned long hi, unsigned long lo, int active, char *info)
{
  info_t *i;

  i = (info_t *)malloc(sizeof(info_t));
  if (i == NULL) return NULL;

  i->i_display = display;
  i->i_win     = win;
  i->i_gc      = gc;
  i->i_mf      = mf;
  i->i_stipple = stipple;
  i->i_x       = x;
  i->i_y       = y;
  i->i_width   = width;
  i->i_height  = height;
  i->i_fg      = fg;
  i->i_bg      = bg;
  i->i_hi      = hi;
  i->i_lo      = lo;
  i->i_active  = active;
  i->i_info    = strdup(info);
  i->i_next    = ilist;
  ilist	       = i;
  return i;
}

void
i_destroy(info_t *i)
{
  free(i->i_info);
  free(i);
}

void
i_destroyall()
{
  while (ilist) {
    info_t *i;

    i = ilist->i_next;
    i_destroy(ilist);
    ilist = i;
  }
}

void
i_setactive(info_t *i, int active)
{
  if (i->i_active != active) {
    i->i_active = active;
    i_redraw(i);
  }
}

void
i_info(info_t *i, char *info)
{
  free(i->i_info);
  i->i_info = strdup(info);
  i_redraw(i);
}

static void
i_redraw(info_t *i)
{
  int ix, iy, n;

  XSetForeground(i->i_display, i->i_gc, i->i_bg);
  XFillRectangle(i->i_display, i->i_win, i->i_gc, i->i_x + 1, i->i_y + 1,
		 i->i_width - 1, i->i_height - 1);
  
  XSetForeground(i->i_display, i->i_gc, i->i_hi);
  for (n = 0; n != 3; n++) {
    XDrawLine(i->i_display, i->i_win, i->i_gc, i->i_x + n, 
	      i->i_y + i->i_height - n, i->i_x + n,  i->i_y + n);
    XDrawLine(i->i_display, i->i_win, i->i_gc, i->i_x + n, i->i_y + n,  
	      i->i_x + i->i_width - n, i->i_y + n);
  }

  XSetForeground(i->i_display, i->i_gc, i->i_lo);

  for (n = 0;  n != 3; n++) {
    XDrawLine(i->i_display, i->i_win, i->i_gc, i->i_x + n + 1, 
	      i->i_y + i->i_height - n, i->i_x + i->i_width - n, 
	      i->i_y + i->i_height - n);
    XDrawLine(i->i_display, i->i_win, i->i_gc, i->i_x + i->i_width - n, 
	      i->i_y + i->i_height - n, i->i_x + i->i_width - n,
	      i->i_y + n + 1);
  }

  XSetForeground(i->i_display, i->i_gc, i->i_bg);
  for (n = 0; n != 3; n++) {
    XDrawPoint(i->i_display, i->i_win, i->i_gc, i->i_x + n, 
	       i->i_y + i->i_height - n);
    XDrawPoint(i->i_display, i->i_win, i->i_gc, i->i_x + i->i_width - n, 
	       i->i_y + n);
  }

  XSetForeground(i->i_display, i->i_gc, i->i_fg);
  XDrawRectangle(i->i_display, i->i_win, i->i_gc, i->i_x, i->i_y,
		 i->i_width, i->i_height);

  if (!i->i_active) {
    XSetFillStyle(i->i_display, i->i_gc, FillStippled);
    XSetStipple(i->i_display, i->i_gc, i->i_stipple);
  }

  ix = i->i_x + i->i_width / 2 - 
    XTextWidth(i->i_mf, i->i_info, strlen(i->i_info) / 2);
  iy = i->i_y + i->i_height / 2 - 
    (i->i_mf->ascent + i->i_mf->descent) / 2 + i->i_mf->ascent;

  XDrawString(i->i_display, i->i_win, i->i_gc, ix, iy, 
	      i->i_info, strlen(i->i_info));
  if (!i->i_active)
    XSetFillStyle(i->i_display, i->i_gc, FillSolid);
}

void
i_redrawall()
{
  info_t *i = ilist;

  i = ilist;
  while (i) {
    i_redraw(i);
    i = i->i_next;
  }
}
