/*************************************************
*                      Smailmon                  *
*************************************************/

/* Copyright (c) University of Cambridge 1995. */

/* P. Hazel, February 1995*/
/* Last Modified: March 1995 */

#include "smailmon.h"

/* This module contains code for handling the popup menus. */

static char message_id[20];
static Widget menushell;

static Widget text_create(char *, int);



static Arg queue_get_arg[] = {
  { "textSink",   (XtArgVal)NULL },
  { "textSource", (XtArgVal)NULL },
  { "string",     (XtArgVal)NULL } };

static Arg menushell_arg[] = {
  { "label",      (XtArgVal)NULL } };

static Arg button_arg[] = {
  { XtNfromVert, (XtArgVal) NULL },         /* must be first */
  { XtNlabel,    (XtArgVal) " Dismiss " },
  { "left",      XawChainLeft },
  { "right",     XawChainLeft },
  { "top",       XawChainBottom },
  { "bottom",    XawChainBottom } };
  
static Arg text_arg[] = {
  { XtNfromVert, (XtArgVal) NULL },         /* must be first */
  { "editType",  XawtextEdit },
  { "string",    (XtArgVal)"" },            /* dummy to get it going */
  { "scrollVertical", XawtextScrollWhenNeeded },
  { "wrap",      XawtextWrapWord }, 
  { "top",       XawChainTop },
  { "bottom",    XawChainBottom } };

static Arg item_1_arg[] = {
  { XtNfromVert,  (XtArgVal)NULL },         /* must be first */
  { "label",      (XtArgVal)" Message log" } };

static Arg item_2_arg[] = {
  { XtNfromVert,  (XtArgVal) NULL },        /* must be first */
  { "label",      (XtArgVal)" Headers" } };



/*************************************************
*        Destroy the menu when popped down       *
*************************************************/

/* Attempts to use this cause crashes. */

static void popdownAction(Widget w, XtPointer client_data, XtPointer call_data)
{
XtDestroyWidget(w);
}



/*************************************************
*          Display the message log               *
*************************************************/

static void msglogAction(Widget w, XtPointer client_data, XtPointer call_data)
{
char buffer[256];
Widget text = text_create((char *)client_data, 200);
FILE *f;
sprintf(buffer, "%s/../msglog/%s", input_dir, (char *)client_data);
f = fopen(buffer, "r");
if (f == 0)
  text_show(text, "No msglog file found\n");
else 
  {
  while (fgets(buffer, 256, f) != NULL)
    text_show(text, "%s", buffer);
  fclose(f);    
  }  
}



/*************************************************
*             Display a message's headers        *
*************************************************/

static void headersAction(Widget w, XtPointer client_data, XtPointer call_data)
{
char buffer[1024];
Widget text = text_create((char *)client_data, 500);

if (!read_spool_init((char *)client_data)) 
  {
  text_show(text, "Failed to read spool file\n");
  return;
  }  

while (read_spool(buffer)) text_show(text, "%s\n", buffer);
read_spool_tidy();
}




/*************************************************
*              Dismiss a text window             *
*************************************************/

static void dismissAction(Widget w, XtPointer client_data, XtPointer call_data)
{
XtPopdown((Widget)client_data);
XtDestroyWidget((Widget)client_data);
}



/*************************************************
*             Set up popup text window           *
*************************************************/

static Widget text_create(char *name, int height)
{
Widget textshell, form, text, button;

/* Create a popup shell widget to display as an additional
toplevel window. */

textshell = XtCreatePopupShell("textshell", topLevelShellWidgetClass,
  toplevel_widget, NULL, 0);
xs_SetValues(textshell, 4, 
  "title",     name,
  "iconName",  name,
  "minWidth",  100, 
  "minHeight", 100);

/* Create a form widget, containing the text widget and the
dismiss button widget. */  

form = XtCreateManagedWidget("textform", formWidgetClass,
  textshell, NULL, 0);
xs_SetValues(form, 1, "defaultDistance", 8);

text = XtCreateManagedWidget("texttext", asciiTextWidgetClass,
  form, text_arg, XtNumber(text_arg));
xs_SetValues(text, 3,
  "width",           700,
  "height",          height, 
  "translations",    text_trans);
XawTextDisplayCaret(text, FALSE);

/* Use the same font as for the queue display */

if (queue_font != NULL)
  {
  XFontStruct *f = XLoadQueryFont(X_display, queue_font);
  if (f != NULL) xs_SetValues(text, 1, "font", f);
  }
  
button_arg[0].value = (XtArgVal)text;
button = XtCreateManagedWidget("dismiss", commandWidgetClass,
  form, button_arg, XtNumber(button_arg));
XtAddCallback(button, "callback",  dismissAction, (XtPointer)textshell);

/* Get the toplevel popup displayed, and yield the text widget so
that text can be put into it. */

XtPopup(textshell, XtGrabNone);
return text;
}




/*************************************************
*            Set up menu in queue window         *
*************************************************/

/* We have added an action table that causes this function to
be called, and set up button 2 in the text widgets to call it. */

void menu_create(Widget w, XEvent *event, String *actargs, Cardinal *count)
{
char buffer[512];
Window dummy;
int line;
XawTextPosition p;
XtTranslations menu_trans;
Widget sink, src, popupform, menu_line, item_1, item_2;
char *s;

/* Get the sink and source and the current text pointer */

queue_get_arg[0].value = (XtArgVal)(&sink);
queue_get_arg[1].value = (XtArgVal)(&src);
queue_get_arg[2].value = (XtArgVal)(&s);
XtGetValues(w, queue_get_arg, 3);

/* Find the line number of the pointer in the window, and the
character offset of the top lefthand of the window. */

line = (event->xbutton).y / XawTextSinkMaxHeight(sink, 1);
p = XawTextTopPosition(w);

/* Find the start of the line on which the button was clicked. */

while (line-- > 0)
  {
  while (s[p] != 0 && s[p++] != '\n');
  }

/* Now pointing either at 0 or 1st char after \n, or very 1st char.
If 0, the click was beyond the end of the data; ignore. If on a
continuation line, move back to the main line. */

if (s[p] == 0) return;

while (p > 0 && s[p+5] == ' ')
  {
  p--;
  while (--p > 0 && s[p] != '\n');
  }

/* Now pointing at very first char, or \n. If the latter, advance to
first character of line. Then extract the message id. */

if (s[p] == '\n') p++;

/***
if (s[p] == 0) strcpy(message_id, "testing"); else
***/

strncpy(message_id, s+p+4, 14);
message_id[14] = 0;

/* Create the popup shell and the other widgets that comprise the menu.
Set the translations and pointer shape, and add the callback pointers. */

menushell_arg[0].value = (XtArgVal)message_id;
menushell = XtCreatePopupShell("menu", simpleMenuWidgetClass,
  queue_widget, menushell_arg, XtNumber(menushell_arg));
XtAddCallback(menushell, "popdownCallback", popdownAction, NULL);
 
menu_trans = XtParseTranslationTable(
  "<EnterWindow>:   highlight()\n\
   <LeaveWindow>:   unhighlight()\n\
   <BtnMotion>:     highlight()\n\
   <BtnUp>:         MenuPopdown()notify()unhighlight()\n\
  ");

xs_SetValues(menushell, 2,
  "cursor",       XCreateFontCursor(X_display, XC_arrow),
  "translations", menu_trans);

menu_line = XtCreateManagedWidget("line", smeLineObjectClass, menushell,
  NULL, 0);

item_1_arg[0].value = (XtArgVal)menu_line;
item_1 = XtCreateManagedWidget("item1", smeBSBObjectClass, menushell,
  item_1_arg, XtNumber(item_1_arg));
XtAddCallback(item_1, "callback",  msglogAction, (XtPointer)message_id);

item_2_arg[0].value = (XtArgVal)item_1;
item_2 = XtCreateManagedWidget("item2", smeBSBObjectClass, menushell,
  item_2_arg, XtNumber(item_2_arg));
XtAddCallback(item_2, "callback",  headersAction, (XtPointer)message_id);

/* Arrange that the menu pops up with the first item selected. */

xs_SetValues(menushell, 1, "popupOnEntry", item_1);
}

/* End of menu.c */
