/*
 * This file is part of the OLH On-Line Help system
 *
 *	Chris VanHaren
 *	Lucien Van Elsen
 *      MIT Project Athena
 *
 * Copyright (C) 1990 by the Massachusetts Institute of Technology.
 * For copying and distribution information, see the file "mit-copyright.h".
 *
 *      $Source: /mit/olhdev/src/motif/RCS/callbacks.c,v $
 *      $Id: callbacks.c,v 1.14 1992/05/01 20:47:46 lwvanels Exp $
 *      $Author: lwvanels $
 */

#include "global.h"

#include "menu.h"
#include "widget_num.h"
#include "menupath.h"
#include "Keywords.h"
#include "Cursor.h"

#include <X11/Intrinsic.h>
#include <X11/keysym.h>
#include <Xm/Mu.h>

extern int hist_on;
extern char *hist_on_text;
extern char *hist_off_text;

int suppress_kwd_draw=0;

void
do_keyword_expose(w, data, event, continue_to_dispatch)
     Widget w;
     void * data;
     XEvent *event;
     Boolean *continue_to_dispatch;
{
  static int done=0;

  if (suppress_kwd_draw) {
    suppress_kwd_draw = 0;
    done = 1;
    return;
  }
    
  if (done)
    return;

  if (event->type == Expose) {
    done = 1;
    setup_keyword_dialog();
  }
  return;
}

void
mail(text, bug_or_suggest)
     char *text;
     int bug_or_suggest;
{
  FILE *f = NULL;
  FILE *mach_f;
  char info[512],s[512];
  char *version;

  WAIT_CURSOR;

  if (bug_or_suggest == SUGGEST_SEND_BTN)
    f = popen("/usr/ucb/Mail -s \"OLH suggestion\" olh-suggest",
	      "w");

  if (bug_or_suggest == SENDBUG_SEND_BTN)
    f = popen("/usr/ucb/Mail -s \"OLH BUG\" olh-bugs",
	      "w");

  if (f == NULL)
    {
      MuWarning("Unable to send mail.");
      STANDARD_CURSOR;
      return;
    }

  fprintf(f, "%s\n", text);
  fprintf(f, "-----------------\ncurrent menupath:\n%s\n", menupath);
  if (current[current_menu])
    fprintf(f, "currently selected:   %s\n",
	    field_value(nth_entry(menu[current_menu],
				  current[current_menu]),
			POINTER));

  version = GetDefault(XtDisplay(w[TOPLEVEL]),"Olh", "copyright");
  fprintf(f,"Version: %s\n",
	  ((version==NULL)?"No version info found":version));

  mach_f = popen("machtype -c -d -M -v","r");
  info[0] = '\0';
  if (mach_f != NULL) {
    while (fgets(s,512,mach_f) != NULL) {
      strncat(info,s,strlen(s)-1);
      strcat(info, ", ");
    }
    info[strlen(info) -2] = '\0';
  }
  pclose(mach_f);

  fprintf(f,"Machine information: %s\n",info);
  fclose(f);
  STANDARD_CURSOR;
}


void
menu_callback(widget, tag, callback_data)
     Widget widget;
     int tag;
     XmAnyCallbackStruct *callback_data;
{
  int n;
  Arg arg;

  if (current_menu != tag)
    {
      WAIT_CURSOR;
      XFlush(XtDisplay(w[TOPLEVEL]));

      for (n=current_menu; n > tag; n--)
	del_last_menupath;
      XtUnmanageChildren(menu_btn + tag + 1, current_menu - tag);

      XtSetArg(arg, XmNmenuHistory, menu_btn[tag]);
      XtUnmanageChild(w[MENU_OPT]);
      XtSetValues(w[MENU_OPT], &arg, 1);
      XtManageChild(w[MENU_OPT]);

      current_menu = tag;
      if (current_menu == 0)
	  XtSetSensitive(w[UP_BTN],FALSE);
      do_menu(menu[current_menu]);
      STANDARD_CURSOR;
    }
}

void
list_1_click(widget, tag, callback_data)
     Widget widget;
     caddr_t tag;
     XmListCallbackStruct *callback_data;
{
  switch( (int) tag)
    {
    case KWD_LIST:
      if (k_current[k_current_menu] == 0)
	XtSetSensitive(w[KWD_SEND_BTN],TRUE);
      k_current[k_current_menu] = callback_data->item_position;
      break;

    case MENU_LIST:
      current[current_menu] = callback_data->item_position;
      viewed[current_menu] = FALSE;
      break;

    case HIST_LIST:
      break;
    }
}


void
list_2_click(widget, tag, callback_data)
     Widget widget;
     caddr_t tag;
     XmListCallbackStruct *callback_data;
{
  switch( (int) tag)
    {
    case KWD_LIST:
      k_current[k_current_menu] = callback_data->item_position;
      k_invoke(k_current[k_current_menu]);
      break;

    case MENU_LIST:
      current[current_menu] = callback_data->item_position;
      view(0);
      break;

    case HIST_LIST:
      break;
    }
}


void
toggle(widget, tag)
     Widget widget;
     int tag;
{
  Arg arg;

  switch (tag)
    {
    case (HIST_TOG):
      hist_on = !hist_on;
      if (hist_on)
	{
	  if (hist_off_text != NULL)
	    {
	      XtSetArg(arg, XmNlabelString, MOTIF_STRING(hist_off_text));
	      XtSetValues(widget, &arg, 1);
	    }
	  XtManageChild(w[HIST_FORM]);
	}
      else
	{
	  if (hist_off_text != NULL)
	    {
	      XtSetArg(arg, XmNlabelString, MOTIF_STRING(hist_on_text));
	      XtSetValues(widget, &arg, 1);
	    }
	  XtUnmanageChild(w[HIST_FORM]);
	}
      break;
    }
}

void
up_menu()
{
  Arg arg;
  char *ptr;

  if (current_menu == 0)
    {
      if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]), "Olh", "message.noMoreUp"))
	  == NULL)
	ptr = "No more up.";
      show_message(ptr);
      return;
    }

  WAIT_CURSOR;
  XtSetArg(arg, XmNmenuHistory, menu_btn[current_menu - 1]);
  XtUnmanageChild(w[MENU_OPT]);
  XtSetValues(w[MENU_OPT], &arg, 1);
  XtManageChild(w[MENU_OPT]);

  if (menu_btn[current_menu] != (Widget) NULL)
    XtUnmanageChild(menu_btn[current_menu]);
  current_menu--;
  if (current_menu == 0)
    XtSetSensitive(w[UP_BTN],FALSE);
  del_last_menupath;
  do_menu(menu[current_menu]);
  STANDARD_CURSOR;
}


void
show_message(string)
     char *string;
{
  Arg arg;
  static char *stored = "";

  if (strcmp(string, stored))
    {
      stored = string;
      XtSetArg(arg, XmNlabelString, MOTIF_STRING(string));
      XtSetValues(w[MSG_LBL], &arg, 1);
    }
}

void
show_k_message(string)
     char *string;
{
  Arg arg;
  static char *stored = "";

  if (w[KWD_MSG] == NULL)
    return;
  if (strcmp(string, stored))
    {
      stored = string;
      XtSetArg(arg, XmNlabelString, MOTIF_STRING(string));
      XtSetValues(w[KWD_MSG], &arg, 1);
    }
}

void
dunno(widget, tag, callback_data)
     Widget widget;
     int tag;
     XmAnyCallbackStruct *callback_data;
{
  Arg arg[10];
  int x, y;
  XtSetArg(arg[0], XmNx, &x);
  XtSetArg(arg[1], XmNy, &y);
  XtGetValues(widget, arg, 2);

  XmMenuPosition(w[FOO], callback_data->event);
  XtManageChild(w[FOO]);
  fprintf(stderr, "Widget is at x=%d, y=%d\n", x, y);
  fprintf(stderr, "Event: x=%d, y=%d\n", callback_data->event->xbutton.x,
	  callback_data->event->xbutton.y);
  fprintf(stderr, "Root: x=%d, y=%d\n", callback_data->event->xbutton.x_root,
	  callback_data->event->xbutton.y_root);
}


void
ListExtra(widget, widget_num, event)
     Widget widget;
     int widget_num;
     XKeyEvent *event;
{
  KeySym ks;

  if (widget_num == MENU_LIST)

    /* Get this working for MENU_LIST first, worry about the other list */
    /* widgets later. */

    {
      ks = XLookupKeysym(event, 0);

      if ((ks == XK_Up) || (ks == XK_Down))
	{
	  if (ks == XK_Up)
	    {
	      if (!current[current_menu])
		current[current_menu] = size_menu(menu[current_menu]) - 1;
	      else
		if (current[current_menu] > 1)
		  current[current_menu] -= 1;
	    }
	  if (ks == XK_Down)
	    {
	      if (!current[current_menu])
		current[current_menu] = 1;
	      else
		if (current[current_menu] < size_menu(menu[current_menu]) - 1)
		  current[current_menu] += 1;
	    }

	  viewed[current_menu] = FALSE;

	  if (current[current_menu] >
	      XmListGetBottomPos((XmListWidget)w[widget_num]))
	    XmListSetBottomPos(w[widget_num], current[current_menu]);
	  else if (current[current_menu] <
		   XmListGetTopPos((XmListWidget)w[widget_num]))
	    XmListSetPos(w[widget_num], current[current_menu]);
	  XmListSelectPos(w[widget_num], current[current_menu], FALSE);

	  return;
	}

      if (ks == XK_Left)
	{
	  XtCallCallbacks(w[UP_BTN], XmNactivateCallback, UP_BTN);
	  return;
	}
      if (ks == XK_Right)
	{
	  XtCallCallbacks(w[VIEW_BTN], XmNactivateCallback, VIEW_BTN);
	  return;
	}

      if ((widget_num == MENU_LIST) || (widget_num == HIST_LIST))
	ScrollList(widget_num, ks, event);
    }
}
