/*
 *	$Source: /u1/X/xman/RCS/buttons.c,v $
 *	$Header: buttons.c,v 1.2 87/01/28 16:39:55 swick Exp $
 */

#ifndef lint
static char *rcsid_buttons_c = "$Header: buttons.c,v 1.2 87/01/28 16:39:55 swick Exp $";
#endif	lint

#include "xman.h"

/*
 * Various menu routines
 */

/*
 * Called when a mouse button goes down in the TEXT window,
 * which is a pseudo-menu when displaying manual sections.
 */

/*ARGSUSED*/
void
MyButtonProc(clientData,eventp) ClientData clientData; XEvent *eventp;
{
  Window subw;
  int mousex, mousey;
  register struct manual *mp = &manual[section];
  int x,y;
  static int lastx, lasty;
  short int state;
  static struct entry *ep;
  int i;
  char manname[128];
  extern char *prepEntry();

  /* are we just displaying a man page? */
  if(manualing) {
    if(eventp->type == ButtonPressed) {
      XQueryMouseButtons(w,&mousex,&mousey,&subw,&state);

      /*
       * 1  means try to go forward a page (left button)
       * -1 means back a page (middle button)
       */
      if(state & LeftMask) {
	ReDisplayProc((ClientData) 1,eventp);
	return;
      }
      else if(state & MiddleMask) {
	ReDisplayProc((ClientData) -1,eventp);
	return;
      }
      else if(state & RightMask) {
	SectionsProc((ClientData) NULL,section,w);
	return;
      }
    }
    return;
  }
  /*
   * We have man SECTIONS in the window, treat as a menu
   */
  XQueryMouseButtons(w,&mousex,&mousey,&subw,&state);
  /* find row and column mouse is in */
  x = (mousex - mp->startx)/mp->width;
  y = (mousey - mp->starty)/mp->height;
  /*
   * Left button down means a selection
   */
  if((eventp->type == ButtonPressed) || (eventp->type == MouseMoved)) {
    if(!(state & LeftMask)) return; /* ignore other buttons for now */

    if((mousex < mp->startx) || (mousey < mp->starty)
       || ((i = x+y*mp->ncols) >= mp->nentries))
      return;				/* mouse is out of range */
    /*
     * See if we need to uninvert a previous selection
     */
    if((ep != NULL) && (eventp->type == MouseMoved)) {
      if(ep == &mp->entries[i])
	return;				/* same as last pick */
      putstr(w,
	     lastx*mp->width+mp->startx,
	     lasty*mp->height+mp->starty,
	     prepEntry(ep->label,mp->colpad),bodynormal,0);
    }
    /*
     * Ok, they selected something, invert it
     */
    ep = &mp->entries[i];
    putstr(w,
	   x*mp->width+mp->startx,
	   y*mp->height+mp->starty,
	   prepEntry(ep->label,mp->colpad),bodynormal,1);
    lastx = x;
    lasty = y;
  }
  else if((eventp->type == ButtonReleased) && (ep != NULL)) {
    /*
     * On button released actually invoke the selection (display man page)
     */

    /* uninvert for feedback */
    putstr(w,
	   lastx*mp->width+mp->startx,
	   lasty*mp->height+mp->starty,
	   prepEntry(ep->label,mp->colpad),bodynormal,0);
    /*
     * Whoops, out of range, treat it as a "cancel previous down button"
     * so they can select and drag with mouse down to some ridiculous
     * place to change their minds.
     */
    if((mousex < mp->startx) || (mousey < mp->starty)
       || ((i = x+y*mp->ncols) >= mp->nentries))
      return;				/* mouse is out of range */
    /*
     * Ok, we got one, see if it's cat'able
     */
    if(mp->cat) {
      sprintf(manname,"%s/%s",mp->cat,ep->label);
      if((manfp = fopen(manname,"r")) == NULL) {
	XClear(w);
	putstr(w,mincol,minrow,"Sorry, couldn't find that man page.",
	       bodybold,0);
	XFlush();
	return;
      }
      mantmp[0] = '\0';
    }
    else {	/* have to format the man page */
      char cmd[128];

      XClear(w);
      putstr(w,mincol,minrow,"Formatting entry...",bodybold,0);
      XFlush();
      sprintf(manname,"%s/%s",mp->man,ep->label);
      strcpy(mantmp,TMPFILE);
      mktemp(mantmp);
      sprintf(cmd,MANFMT,manname,mantmp);
      if((system(cmd) != 0) || (manfp = fopen(mantmp,"r")) == NULL) {
	XClear(w);
	putstr(w,mincol,minrow,"Something went wrong, sorry.",bodybold,0);
	XFlush();
	unlink(mantmp);
	return;
      }
    }
    manualing = 1;		/* need to remember current state of display */
    pagetell[0] = 0;		/* first page @lseek location zero */
    curpage = 0;
    ep = NULL;			/* no entry currently selected */
    XDefineCursor(w,xpage_cursor);
    ReDisplayProc((ClientData) 0,eventp);
    /* it's ok that it's still open, at least on UNIX */
    if(mantmp[0] != '\0') unlink(mantmp);
  }
  return;
}
/*
 * Called on a ButtonPressed in the titlebar
 *
 */
void
IconifyProc(clientData, eventp)
ClientData clientData;			/* if TRUE, iconify; else de-iconify */
XEvent *eventp;
{
    if (clientData) {
      XUnmapWindow( w );
      XMapWindow( xicon );
    } else {
      XUnmapWindow( xicon );
      XMapWindow( w );
    }
}

/*
 * Called when the user selects QUIT from the Options menu
 */
void
Finis()
{
  exit(0);
}
/*
 * The apropos Option from the menu
 * Right now I just run apropos (various config dependant stuff
 * in config.h) into a file and paginate that to the display.
 * I guess we could re-implement a search of /usr/man/whatis ourselves,
 * I dunno...
 */
void
Apropos()
{
  char buf[APROPOSLEN+1];
  char cmdbuf[100+APROPOSLEN+1];

  buf[0] = '\0';
  if(DialogueBox(w,"Apropos? ",buf,APROPOSLEN+1,NULL,NULL) == NULL)
    return;
  strcpy(mantmp,TMPFILE);
  mktemp(mantmp);
  sprintf(cmdbuf,"%s %s | %s > %s",APROPOS,buf,APROPOSFILTER,mantmp);
  if(system(cmdbuf) != 0) {
    eprintf("Something went wrong trying to run %s\n",cmdbuf);
    return;
  }
  if(manfp != NULL)
    fclose(manfp);
  if((manfp = fopen(mantmp,"r")) == NULL) {
    eprintf("lost temp file? out of temp space?\n");
    return;
  }
  unlink(mantmp);
  mantmp[0] = '\0';
  manualing = 1;
  pagetell[0] = 0;
  curpage = 0;
  XDefineCursor(w,xpage_cursor);
  return;
}
