/*  Window.c  */

/*--------------------------------------------------------------------------*/

#include "common.h"
#include "zprstat.h"
#include "Window.h"
#include "Prntr.h"
#include <strings.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Viewport.h>

extern	char*	ctime();

/*--------------------------------------------------------------------------*/

#define	NUM_COLS	4
#define	NAME_COL	0
#define	LOCATION_COL	1
#define	STATUS_COL	2
#define	NUMBER_COL	3
#define	MAX_ROWS	100

/*--------------------------------------------------------------------------*/

static	Display* display;
static	char	name[1024];
static	char	status[1024];
static	char	number[1024];
static	Widget	toplevel;
static	Widget	vpaned;
static	Widget	title;
static	Widget	timestamp;
static	Widget	spacer;
static	Widget	viewport;
static	Widget	form;
static	Widget	label[MAX_ROWS][NUM_COLS];

static	Arg	vpanedArgs[] = {
    { XtNgripIndent, (XtArgVal)(-500) },
};

static	Arg	headingArgs[] = {
    { XtNskipAdjust, (XtArgVal)True },
};

static	Arg	viewportArgs[] = {
    { XtNallowVert, (XtArgVal)True },
    { XtNuseRight, (XtArgVal)True },
};

/*--------------------------------------------------------------------------*/

int	Window_Initialize(argc, argv, printers)
int*	argc;
char*	argv[];
Prntr*	printers;
{
    char* string[4];
    XtJustify justify[4];
    Arg labelArgs[6];
    Arg h_get[1];
    Arg w_get[1];
    Arg w_set[1];
    int row, col;
    int num_rows;
    int this_height, y_pos, width, this_width;
    Prntr* p;

    toplevel = XtInitialize( NULL, "zprstat", NULL, 0, argc, argv );

    vpaned = XtCreateManagedWidget("vpaned", panedWidgetClass,
				   toplevel,
				   vpanedArgs, XtNumber(vpanedArgs));

    title = XtCreateManagedWidget("Printer Status", labelWidgetClass,
				  vpaned,
				  headingArgs, XtNumber(headingArgs));

    timestamp = XtCreateManagedWidget("", labelWidgetClass,
				      vpaned,
				      headingArgs, XtNumber(headingArgs));

/*
    spacer = XtCreateManagedWidget("spacer", formWidgetClass,
				   vpaned, NULL, 0);
*/
    viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
				     vpaned,
				     viewportArgs, XtNumber(viewportArgs));

    XtSetArg(labelArgs[0], XtNborderWidth, 0);
    XtSetArg(labelArgs[1], XtNtop, XtChainTop);

    string[STATUS_COL] = "???????";
    string[NUMBER_COL] = "???";

    justify[NAME_COL] = XtJustifyLeft;
    justify[LOCATION_COL] = XtJustifyLeft;
    justify[STATUS_COL] = XtJustifyCenter;
    justify[NUMBER_COL] = XtJustifyRight;

    form = XtCreateManagedWidget("form", formWidgetClass, viewport, NULL, 0);

    y_pos = 0;
    for (row = 0, p = printers; p != NULL; row++, p = Prntr_Next(p))
      {
	  string[NAME_COL] = Prntr_Name(p);
	  string[LOCATION_COL] = Prntr_Location(p);
	  XtSetArg(labelArgs[2], XtNvertDistance, y_pos);

	  for (col = 0; col < NUM_COLS; col++)
	    {
		if (col == 0)
		  {
		      XtSetArg(labelArgs[3], XtNleft, XtChainLeft);
		      XtSetArg(labelArgs[4], XtNhorizDistance, 4);
		  }
		else
		  {
		      XtSetArg(labelArgs[3], XtNfromHoriz, label[row][col-1]);
		      XtSetArg(labelArgs[4], XtNhorizDistance, 4);
		  }

		XtSetArg(labelArgs[5], XtNjustify, justify[col]);

		label[row][col] = XtCreateManagedWidget(string[col],
							labelWidgetClass,
							form, labelArgs,
							XtNumber(labelArgs));
	    }

	  XtSetArg(h_get[0], XtNheight, &this_height);
	  XtGetValues(label[row][0], h_get, XtNumber(h_get));
	  y_pos += this_height;

	  num_rows = row + 1;
      }

    for (col = 0; col < NUM_COLS; col++)
      {
	  XtSetArg(w_get[0], XtNwidth, &this_width);
	  width = 0;
	  for (row = 0; row < num_rows; row++)
	    {
		XtGetValues(label[row][col], w_get, XtNumber(w_get));
		width = max(this_width, width);
	    }

	  XtSetArg(w_set[0], XtNwidth, width + 5);
	  for (row = 0; row < num_rows; row++)
	      XtSetValues(label[row][col], w_set, XtNumber(w_set));
      }

    XtRealizeWidget(toplevel); 
    display = XtDisplay(toplevel);

    return ConnectionNumber(display);
}

/*--------------------------------------------------------------------------*/

void	Window_Update(msg, printers)
char*	msg;
Prntr*	printers;
{
    Arg labelArgs[1];
    int row;
    Prntr* p;
    long int t;
    char timestring[13];

    if (msg == NULL) return;

    time(&t);
    strncpy(timestring, &ctime(&t)[4], 12);
    timestring[12] = '\0';
    XtSetArg(labelArgs[0], XtNlabel, timestring);
    XtSetValues(timestamp, labelArgs, XtNumber(labelArgs));

    while (msg[0] != EOS)
      {
	  sscanf(msg, "%s %s %s", name, status, number);

	  for (row = 0, p = printers; p != NULL; row++, p = Prntr_Next(p))
	    {
		if (strcmp(name, Prntr_Name(p)) == 0)
		  {
		      XtSetArg(labelArgs[0], XtNlabel, status);
		      XtSetValues(label[row][STATUS_COL],
				  labelArgs, XtNumber(labelArgs));

		      XtSetArg(labelArgs[0], XtNlabel, number);
		      XtSetValues(label[row][NUMBER_COL],
				  labelArgs, XtNumber(labelArgs));

		      break;
		  }
	    }

	  if ((msg = index(msg, '\n')) == NULL)
	    break;

	  ++msg;
      }
    XFlush(display);
}

/*--------------------------------------------------------------------------*/

void	Window_Event()
{
    XEvent e;

    XtNextEvent(&e);
    XtDispatchEvent(&e);
}

/*--------------------------------------------------------------------------*/

void	Window_Ping()
{
    XNoOp(display);
}

/*--------------------------------------------------------------------------*/
