/*
 * 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: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/motif/File.c,v $
 *      $Id: File.c,v 1.6 1995/08/29 06:39:28 ghudson Exp $
 *      $Author: ghudson $
 */

#include "global.h"
#include "menu.h"
#include "widget_num.h"
#include "Cursor.h"

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <Xm/Text.h>
#include <Xm/Mu.h>

#ifdef __STDC__
# define        P(s) s
#else
# define P(s) ()
#endif

static int copy P((char *fromfile , char *tofile ));

#undef P

void
File(widget, tag, callback_data)
     Widget widget;
     int tag;
     XmAnyCallbackStruct *callback_data;
{
  MenuEntry *e, *e2;
  register EntryField *f, *fstop;
  char buf1[1024], buf2[4096], modbuf[128];
  char *ptr, *ptr2;
  long code;
  Arg arg;
  struct stat statb;

  if (!current[current_menu])
    {
      if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]),
			    "Olh", "warning.noneSelected"))
	  == NULL)
	ptr = "None selected.";
      MuWarning(ptr);
      return;
    }
  else
    {
      e = nth_entry(menu[current_menu], current[current_menu]);

      switch (tag)
	{
	case COPY_DLG:
	  if (is_menu(e))
	    {
	      if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]),
				    "Olh", "warning.copyMenu"))
		  == NULL)
		ptr = "Can't copy menu.";
	      MuWarning(ptr);
	      return;
	    }
	  MakeDialog(tag);
	  if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]), "Olh",
				"copyLabel.labelString"))
	      != NULL)
	    {
	      sprintf(buf1, ptr, field_value(e, NODE_LABEL));
	      XtSetArg(arg, XmNlabelString, MOTIF_STRING(buf1));
	      XtSetValues(w[COPY_LBL], &arg, 1);
	    }
	  if ((ptr = (char *) getenv("HOME")) == NULL)
	    ptr = "/tmp";
	  strcpy(buf1, ptr);
	  strcat(buf1, "/");
	  ptr2 = (field_value(e, FILE_LOCATION));
	  if ((ptr = rindex(ptr2, '/')) != NULL)
	    strcat(buf1, ptr + 1);

	  /* Unfortunately, this has to be done in 2 steps.  If you do */
	  /* them both at the same time, the text widget gets screwed up. */
	  XtSetArg(arg, XmNvalue, buf1);
	  XtSetValues(w[COPY_TEXT], &arg, 1);
	  XtSetArg(arg, XmNcursorPosition, strlen(buf1));
	  XtSetValues(w[COPY_TEXT], &arg, 1);

	  XtManageChild(w[tag]);
	  _XmGrabTheFocus(w[COPY_TEXT], NULL);
	  break;

	case PRINT_DLG:
	  if (is_menu(e))
	    {
	      if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]),
				    "Olh", "warning.printMenu"))
		  == NULL)
		ptr = "Can't print menu.";
	      MuWarning(ptr);
	      return;
	    }
	  MakeDialog(tag);
	  if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]), "Olh",
				"printDialog.listLabelString"))
	      != NULL)
	    {
	      sprintf(buf1, ptr, field_value(e, NODE_LABEL));
	      XtSetArg(arg, XmNlabelString, MOTIF_STRING(buf1));
	      XtSetValues(XmSelectionBoxGetChild(w[tag], XmDIALOG_LIST_LABEL),
			  &arg, 1);
	    }
	  XtManageChild(w[tag]);
	  break;

	case INFO_DLG:
	  MakeDialog(tag);
	  if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]), "Olh",
				"infoLabel.labelString"))
	      != NULL)
	    {
	      sprintf(buf1, ptr, field_value(e, NODE_LABEL));
	      XtSetArg(arg, XmNlabelString, MOTIF_STRING(buf1));
	      XtSetValues(w[INFO_LBL], &arg, 1);
	    }

	  buf2[0] = '\0';
	  modbuf[0] = '\0';
	  fstop = e->field + e->size;
	  for(f = e->field; f < fstop; f++) {
	    sprintf(buf1, "%-15s %s\n", f->name, f->value);
	    strcat(buf2, buf1);
	    if (!strcasecmp(f->name, POINTER)) {
	      /* Retrieve from pointer -- this is gross and should be */
	      /* re-done, recursively... */
	      code = pointerEntry(f->value, &e2);
	      if (!code && e2) {
		register EntryField *f2, *fstop2;
		
		strcat(buf2, "--- pointer info ---\n");
		fstop2 = e2->field + e2->size;
		for(f2 = e2->field; f2 < fstop2; f2++) {
		  sprintf(buf1, "%-15s %s\n", f2->name, f2->value);
		  strcat(buf2, buf1);
		  if (f2->name == FILE_LOCATION) {
		    if (stat(f2->value,&statb) == 0) {
		      sprintf(modbuf, "%-15s %s", "modify-date",
			      ctime(&statb.st_mtime));
		    }
		  }			    
		}
                if (modbuf[0] != '\0')
	          strcat(buf2, modbuf);
		strcat(buf2, "--------------------\n")
;
	      }
	    }
	  }
	  XmTextSetString(w[INFO_TEXT], buf2);
	  if (!XtIsManaged(w[tag]))
	    XtManageChild(w[tag]);
	  break;
	}
    }
}


void
File_ok(widget, tag, callback_data)
     Widget widget;
     int tag;
     XmAnyCallbackStruct *callback_data;
{
  char *ptr;
  MenuEntry *e;
  long code;
#ifdef PUTENV
  char string[1024];
#endif

  e = nth_entry(menu[current_menu], current[current_menu]);

  switch (tag)
    {
    case PRINT_DLG:
      WAIT_CURSOR;
      if ((ptr = GetDefault(XtDisplay(w[TOPLEVEL]), "Olh", "wait.lpr"))
	  != NULL)
	{
	  show_message(ptr);
	  WaitForExpose(w[MSG_LBL]);
	}

      ptr = XmTextGetString(XmSelectionBoxGetChild(w[PRINT_DLG],
						    XmDIALOG_TEXT));
#ifdef PUTENV
      sprintf(string, "PRINTER=%s", ptr);
      (void) putenv(string);
#else
      (void) setenv("PRINTER", ptr, TRUE);
#endif
      XtFree(ptr);
      code = viewdoc(e, LPTLN, NULL);
      CLEAR_MSG;
      STANDARD_CURSOR;
      XtUnmanageChild(w[tag]);
      if (code != 0) {
	switch(code) {
	case ERR_MENU_VIEWERFAILED:
	  MuWarningSync("An error occurred during printing; you may want to\n try printing the document again");
	  break;
	default:
	  com_err(program,code,"While trying to print");
	}
	File(w[TOPLEVEL],PRINT_DLG,(XmAnyCallbackStruct *)NULL);
      }
      break;

    case COPY_DLG:
      ptr = XmTextGetString(w[COPY_TEXT]);
      code = copy(field_value(e, FILE_LOCATION), ptr);
      XtFree(ptr);
      XtUnmanageChild(w[tag]);
      if (code != 0)
	File(w[TOPLEVEL],COPY_DLG,(XmAnyCallbackStruct *)NULL);
      break;

    case INFO_DLG:
      XtUnmanageChild(w[tag]);
      break;
    }
}

  
static int
copy(fromfile, tofile)
     char *fromfile, *tofile;
{
  char buf[1024];
  int fd_from, fd_to;
  int n;
  extern int errno;

  WAIT_CURSOR;
  if ((fd_from = open(fromfile, O_RDONLY, 0)) < 1)
    {
      com_err(program, errno, "opening %s for reading.", fromfile);
      STANDARD_CURSOR;
      return(1);
    }

  if ((fd_to = open(tofile, O_CREAT|O_WRONLY, 0644)) < 1)
    {
      close(fd_from);
      com_err(program, errno, "opening %s for writing.", tofile);
      STANDARD_CURSOR;
      return(1);
    }

  while ((n = read(fd_from, buf, sizeof(buf))) > 0)
    if (write (fd_to, buf, n) != n)
      {
	com_err(program,errno, "while writing %s.", tofile);
	close(fd_to);
	close(fd_from);
	STANDARD_CURSOR;
	return(1);
      }

  close(fd_from);
  close(fd_to);
  STANDARD_CURSOR;
  return(0);
}
