 /*
  * Khoros: $Id: help.c,v 1.3 1992/03/20 22:49:52 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: help.c,v 1.3 1992/03/20 22:49:52 dkhoros Exp $";
#endif

 /*
  * $Log: help.c,v $
 * Revision 1.3  1992/03/20  22:49:52  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xvutils.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    	    file name: help.c                         <<<<
   >>>>                                                       <<<<
   >>>>             Creates a Help Widget     		      <<<<
   >>>>                                                       <<<<
   >>>>                xvf_online_help_wait()		      <<<<              
   >>>>                xvf_create_online_help()		      <<<<              
   >>>>                xvf_unglyph_online_help() 	      <<<<              
   >>>>                xvf_glyph_online_help() 	              <<<<              
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/************************************************************
*
*  Routine Name:  xvf_online_help_wait(path,label)
*
*      Purpose:  Create a large read-only text widget in which one or
*		 more ascii files may be displayed.
*
*		 If the path specified is to a single file, that
*		 file is displayed. If the path specified is a directory, 
*		 the text widget will have one button at the top labeled
*		 with the name of each file in the directory.  Clicking
*		 on such a button will cause the contents of the file labeled
*		 to appear in the text widget.  In either case, the on-line
*		 help widget will be displayed until the user clicks on the
*		 "Quit" button.  This utility will not grab events from the 
*		 application program.
*
*        Input:   path  - character string containing the path of the file 
*			  to be displayed, or the directory of the files to
*			  be displayed in help system widget.  
*			  The path may include a '~' if desired, or may contain
*			  a reference to the KHOROS_HOME system variable.
*
*                 label    - short label for top of help widget.
*			     NULL gives default of "HELP".
*
*    Called By:   the application program
*
*   Written By:   Danielle Argiro
*
*
*************************************************************/

int xvf_online_help_wait(path,label)
char *path;
char *label;
{
   int ok;

   ONLINE_HELP_DONE = false;

   if (xvf_display == NULL)
   {
	fprintf(stderr, "see '%s'\n", path);
	return(true);
   }
   ok = xvf_create_online_help(path,label);

   if (ok == false)
      return(false);

   while(!ONLINE_HELP_DONE)
   {
      xvf_process_event();      /* this does XtNextEvent/DispatchEvent*/
   }
   return(true);
}

/************************************************************
*
*  Routine Name:  xvf_create_online_help(path,label)
*
*      Purpose:  Creates the read-only text widget for the 
*		 online help system.  Lists the filename or directory at the
*		 top.  If the path specified is a directory, puts a command
*		 button at the top for each file in the directory, labeled with
*		 the file name.  Includes a "Quit" button.
*
*        Input:   path  - character string containing the path of the file 
*			  to be displayed, or the directory of the files to
*			  be displayed in help system widget.  
*			  The path may include a '~' if desired, or may contain
*			  a reference to the KHOROS_HOME system variable.
*
*                 label    - short label for top of help widget.
*			     NULL gives default of "HELP".
*
*    Called By:   the application program
*
*   Written By:   Danielle Argiro
*
*
*************************************************************/

int xvf_create_online_help(path, label)
char *path;
char *label;
{
   Widget quit;	  	 /* quit button to get rid of online help 	*/
   Widget glyph_button;  /* glyph widget on online help widget 	 	*/
   Widget glyph_to_form; /* command wid of glyph 			*/

   Widget left_offset, **buttons;
   Arg    arg[25];
   int    i, n, help_type, num_files;
   char name[MaxLength], glyph_name[MaxLength];
   char *top_name, *cap_top_name, *exp_path, *filepath;
   char **filenames, **xvf_get_path_info();
   char   button_name[MaxLength];
   Help_Data *help_data;
   DisplayWid_Data *widget_data;
   
   void   xvf_quit_online_help(),    xvf_display_online_help();
   void   xvf_unglyph_online_help(), xvf_glyph_online_help();

   /*
    *  check for null path
    */
   if (path == NULL)
   {
	xvf_error_wait("help file path specified is NULL", 
			"xvf_online_help", NULL);
        return(false);
   }

   if (label == NULL)
      label = xvf_strcpy("Online Help Pages");

   /*
    *  check for bogus path
    */
   exp_path = vfullpath(path, NULL, NULL);
   if (exp_path == NULL)
   {
	xvf_error_wait("Help page specified not found", 
			"xvf_online_help", NULL);
        return(false);
   }

  /*
   *  go to the specified directory, do a listing into a file,
   *  and read in the filenames to be displayed.
   */
   filenames = xvf_get_path_info(exp_path, &help_type, &num_files);

   if (help_type == BOGUS_PATH)
   {
	xvf_error_wait("Invalid path to help page", 
			"xvf_online_help", NULL);
        return(NULL);
   }

   widget_data = (DisplayWid_Data *) calloc(1, sizeof(DisplayWid_Data));

   sprintf(name,"%d_help",OnlineHelp_cnt);
   sprintf(glyph_name,"%d_help_glyph",Help_cnt);
   OnlineHelp_cnt++;
   top_name = xvf_strcpy(glyph_name);
   cap_top_name = xvf_cap_first_letter(top_name);

   /* 
    * create the glyph widget for the help widget, and add it
    * to the list of toplevels that is used with journal playback.
    */
   n = 0;
   XtSetArg(arg[n], XtNscreen, xvf_screen); 		n++;
   XtSetArg(arg[n], XtNargc, xvf_ac); 	         	n++;
   XtSetArg(arg[n], XtNargv, xvf_av);	          	n++;
   XtSetArg(arg[n], XtNwinGravity, StaticGravity);	n++; 
   XtSetArg(arg[n],XtNmappedWhenManaged,False);         n++;
   widget_data->glyph = XtAppCreateShell(top_name,cap_top_name,
			applicationShellWidgetClass, xvf_display, arg, n);
   xvf_add_toplevel(widget_data->toplevel);

   n = 0;
   XtSetArg(arg[n],XtNwidth,10*xvf_font_width);		n++;
   XtSetArg(arg[n],XtNheight, (Dimension) 2*xvf_font_height);	n++;
   XtSetArg(arg[n],XtNlabel, "help glyph");		n++;
   XtSetArg(arg[n],XtNmappedWhenManaged,True);     	n++;
   glyph_to_form = XtCreateManagedWidget("glyph_to_form",
	commandWidgetClass,widget_data->glyph,arg,n);
   XtAddCallback(glyph_to_form,XtNcallback,xvf_unglyph_online_help,widget_data);

   top_name = xvf_strcpy(name);
   cap_top_name = xvf_cap_first_letter(top_name);

   /* 
    * create the help's toplevel widget, and add it to the
    * list of toplevels that is used with journal playback.
    */
   n = 0;
   XtSetArg(arg[n], XtNscreen, xvf_screen); 		n++;
   XtSetArg(arg[n], XtNargc, xvf_ac); 	         	n++;
   XtSetArg(arg[n], XtNargv, xvf_av);	          	n++;
   XtSetArg(arg[n], XtNwinGravity, StaticGravity);	n++; 
   widget_data->toplevel = XtAppCreateShell(top_name, cap_top_name,
 			   applicationShellWidgetClass, xvf_display, arg, n);
   xvf_add_toplevel(widget_data->toplevel);

   /* create back widget */
   n = 0;
   XtSetArg(arg[n],XtNmappedWhenManaged,True);          n++;
   XtSetArg(arg[n],XtNborderWidth,1);			n++;
   XtSetArg(arg[n],XtNdefaultDistance,4);		n++;
   widget_data->back = XtCreateManagedWidget("onlinehelp_back",
		formWidgetClass, widget_data->toplevel,arg,n);  

   /* create glyph_button widget */
   n = 0;
   XtSetArg(arg[n],XtNlabel,xvf_strcpy("glyph"));		n++;
   XtSetArg(arg[n],XtNwidth,(Dimension) 6*xvf_font_width);	n++;
   XtSetArg(arg[n],XtNmappedWhenManaged,True);			n++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[n],XtNfont,xvf_font);              	n++;
   }
   glyph_button = XtCreateManagedWidget("glyph",
      	commandWidgetClass,widget_data->back,arg,n);
   XtAddCallback(glyph_button,XtNcallback,xvf_glyph_online_help,widget_data);

   /* create label widget */
   n = 0;
   XtSetArg(arg[n],XtNlabel, xvf_strcpy(label));	n++;
   XtSetArg(arg[n],XtNwidth,(Dimension) (58*xvf_font_width)); n++;
   XtSetArg(arg[n],XtNmappedWhenManaged,True);		n++;
   XtSetArg(arg[n],XtNfromHoriz,glyph_button);		n++;
   XtSetArg(arg[n],XtNborderWidth, 0);			n++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[n],XtNfont,xvf_font);              n++;
   }
   widget_data->label = XtCreateManagedWidget("help_wid",
      	labelWidgetClass,widget_data->back,arg,n);

   /* if they provided a directory, need to put up one button widget
      for each file in the directory, labeled with its filename. */
   if (help_type == DIRECTORY_PATH)
   {
       /* alloc & clear buttons array */
        buttons = (Widget **) calloc(1,sizeof(Widget *)*XVFMaxFileNum);
        for (i=0; i< XVFMaxFileNum; i++) buttons[i] = NULL;

	left_offset = NULL;
	for (i = 0; i < num_files; i++)
	{
            help_data = (Help_Data *) calloc(1, sizeof(Help_Data));
	    help_data->wid_data = widget_data;  
	
            buttons[i] = (Widget *) calloc(1,sizeof(Widget));

	    n = 0;
	    XtSetArg(arg[n],XtNfromVert,widget_data->label);    n++;
   	    XtSetArg(arg[n],XtNfromHoriz,left_offset);           n++;
	    XtSetArg(arg[n],XtNlabel,filenames[i]);              n++;
            if (xvf_font != NULL)
            {
                 XtSetArg(arg[n],XtNfont,xvf_font);              n++;
            }
	    sprintf(button_name, "file_button_%d", i); 
            *buttons[i] = XtCreateManagedWidget(button_name,
        		      commandWidgetClass,widget_data->back,arg,n);
	    help_data->filepath = vfullpath(filenames[i], exp_path, NULL);
   	    XtAddCallback(*buttons[i],XtNcallback,
			   xvf_display_online_help, help_data);
	    left_offset = *buttons[i];
	}
   }
   else
   {
        help_data = (Help_Data *) calloc(1, sizeof(Help_Data));
	help_data->wid_data = widget_data; 
	help_data->filepath = NULL; 
   }

   /* create text widget */
   n = 0;
   XtSetArg(arg[n],XtNeditType,XawtextRead);		n++;
   XtSetArg(arg[n],XtNtype,    XawAsciiFile);		n++;
   if (help_type == FILE_PATH)
   {
        XtSetArg(arg[n],XtNstring,  exp_path);		n++;
   }
   else
   {
	filepath = vfullpath(filenames[0], exp_path, NULL);
	XtSetArg(arg[n], XtNstring, filepath); 	n++;
   }
   if (xvf_font != NULL)
   {
                 XtSetArg(arg[n],XtNfont,xvf_font);              n++;
   }
   XtSetArg(arg[n],XtNwidth ,(Dimension) (70*xvf_font_width));	n++;
   XtSetArg(arg[n],XtNscrollVertical,  XawtextScrollWhenNeeded);n++;
   XtSetArg(arg[n],XtNwrap,    XawtextWrapWord);	n++;
   XtSetArg(arg[n],XtNheight,(Dimension) (40*9));	n++;
   XtSetArg(arg[n],XtNinsertPosition,0);		n++;
   XtSetArg(arg[n],XtNleftMargin,LEFT_MARGIN);		n++;
   if (help_type == FILE_PATH)
   {
       XtSetArg(arg[n],XtNfromVert,widget_data->label);  n++;
   }
   else
   {
       XtSetArg(arg[n],XtNfromVert,*buttons[0]);	n++;
   }
   widget_data->text =  XtCreateManagedWidget("text",asciiTextWidgetClass,
	widget_data->back,arg,n); 

   /* create quit button */
   n = 0;
   XtSetArg(arg[n],XtNlabel,"QUIT");			n++;
   XtSetArg(arg[n],XtNfromHoriz,widget_data->label); n++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[n],XtNfont,xvf_font);              n++;
   }
   quit = XtCreateManagedWidget("quit_wid",
	commandWidgetClass,widget_data->back,arg,n);
   XtAddCallback(quit,XtNcallback,xvf_quit_online_help,help_data);

   /* create label widget at bottom, listing source directory */
   n = 0;
   XtSetArg(arg[n],XtNlabel, exp_path);			n++;
   XtSetArg(arg[n],XtNwidth,(Dimension) 70*xvf_font_width);	n++;
   XtSetArg(arg[n],XtNmappedWhenManaged,True);		n++;
   XtSetArg(arg[n],XtNfromVert,widget_data->text);	n++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[n],XtNfont,xvf_font);              n++;
   }
   (void) XtCreateManagedWidget("help_wid", labelWidgetClass, widget_data->back,
			arg, n);

   XtRealizeWidget(widget_data->toplevel);
   XtRealizeWidget(widget_data->glyph);
   XFlush(XtDisplay(widget_data->toplevel));

   xvf_add_protocol_handler(widget_data->toplevel, "WM_DELETE_WINDOW", 
			    xvf_quit_online_help, help_data);

   return(true);
}


/* callback used to change help file displayed */

void xvf_display_online_help(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
    int   i, stat;
    Arg   arg[MaxArgs];
    Help_Data *help_data;

    help_data = (Help_Data *) clientData;

    stat = open(help_data->filepath,O_RDONLY,0664);
    if (stat <= 0)
    {  /* file not there, or cannot be opened */
        xvf_error_wait("Sorry, unable to find appropriate help file",
           "ONLINE HELP ERROR","OK");
        (void) close(stat);
	return;
    }
    (void) close(stat);

    i = 0;
    XtSetArg(arg[i],XtNstring,  help_data->filepath);   i++;
    XtSetValues(help_data->wid_data->text, arg, i);
    
    XFlush(XtDisplay(widget));
}


/* callback used to exit help */

void xvf_quit_online_help(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   Help_Data *help_data;

   help_data = (Help_Data *) clientData;

   /*
    * delete the help widget's toplevel from the list 
    * used by journal playback before destroying it
    */
   xvf_remove_protocol_handler(help_data->wid_data->toplevel, 
			       "WM_DELETE_WINDOW", xvf_quit_online_help, 
			       help_data);
   xvf_delete_toplevel(help_data->wid_data->toplevel);
   XtUnmapWidget(help_data->wid_data->toplevel);
   XtDestroyWidget(help_data->wid_data->toplevel);

   free(help_data->wid_data);
   if (help_data->filepath != NULL)
      free(help_data->filepath);

   free(help_data);

   ONLINE_HELP_DONE = true;
}


void xvf_unglyph_online_help(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   DisplayWid_Data *wid_data;

   wid_data = (DisplayWid_Data *) clientData;

   XtUnmapWidget(wid_data->glyph);
   XtMapWidget(wid_data->toplevel);
   XSync(xvf_display,0);
}


void xvf_glyph_online_help(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   DisplayWid_Data *wid_data;

   wid_data = (DisplayWid_Data *) clientData;

   XtUnmapWidget(wid_data->toplevel);
   XtMapWidget(wid_data->glyph);
   XSync(xvf_display,0);
}
