/* 
 * xvinfo.c - 'Info' box handling functions
 *
 * callable functions:
 *
 *   CreateInfo(geom)       -  creates the infoW window.  Doesn't map it.
 *   InfoBox(vis)           -  random processing based on value of 'vis'
 *                             maps/unmaps window, etc.
 *   RedrawInfo(x,y,w,h)    -  called by 'expose' events
 *   SetInfoMode(mode)      -  changes amount of info Info window shows
 *   SetISTR(st, fmt, args) - sprintf's into ISTR #st.  Redraws it in window 
 *   char *GetISTR(st)      - returns pointer to ISTR #st, or NULL if st bogus
 */

/*
 * Copyright 1989, 1990, 1991, 1992 by John Bradley and
 *                       The University of Pennsylvania
 *
 * Permission to use, copy, and distribute for non-commercial purposes,
 * is hereby granted without fee, providing that the above copyright
 * notice appear in all copies and that both the copyright notice and this
 * permission notice appear in supporting documentation.
 *
 * The software may be modified for your own purposes, but modified versions
 * may not be distributed.
 *
 * This software is provided "as is" without any expressed or implied warranty.
 *
 * The author may be contacted via:
 *    US Mail:   John Bradley
 *               GRASP Lab, Room 301C
 *               3401 Walnut St.
 *               Philadelphia, PA  19104
 *
 *    Phone:     (215) 898-8813
 *    EMail:     bradley@cis.upenn.edu
 */


#define  NEEDSVARARGS

#include "xv.h"
#include "bitmaps.h"

/* max length of an Info String */
#define ISTRLEN 80

/* baseline of top line of text */
#define TOPBASE (36 + penn_height/2 + 4 + 8 + ASCENT)
#define STLEFT  100   /* left edge of strings */

static Pixmap graspPix, pennPix;
static char istrs[NISTR][ISTRLEN];

#ifdef __STDC__
static void DrawStrings(void);
static void DrawFieldName(int);
static void RedrawString(int);
#else
static void DrawStrings(), DrawFieldName(), RedrawString();
#endif



/***************************************************/
void CreateInfo(geom)
char *geom;
{
  XClassHint classh;
  CARD32     data[2];
  Atom       prop;

  infoW = CreateWindow("xv info", geom, INFOWIDE, INFOHIGH, infofg, infobg);
  if (!infoW) FatalError("can't create info window!");

  classh.res_name = "xv";
  classh.res_class = "XVinfo";
  XSetClassHint(theDisp, infoW, &classh);

  data[0] = (CARD32)XInternAtom(theDisp, "WM_DELETE_WINDOW", FALSE);
  data[1] = (CARD32)time((long *)0);
  prop = XInternAtom(theDisp, "WM_PROTOCOLS", FALSE),

  XChangeProperty(theDisp, infoW, prop, prop,
		  32, PropModeReplace, (unsigned char *) data, 2);

  pennPix = XCreatePixmapFromBitmapData(theDisp, infoW, penn_bits, penn_width, 
			      penn_height, infofg, infobg, dispDEEP);
  graspPix = XCreatePixmapFromBitmapData(theDisp,infoW,grasp_bits,grasp_width, 
			      grasp_height, infofg, infobg, dispDEEP);
}
  

/***************************************************/
void InfoBox(vis)
int vis;
{
  if (vis) XMapRaised(theDisp, infoW);
  else     XUnmapWindow(theDisp, infoW);

  infoUp = vis;
}


/***************************************************/
void RedrawInfo(x,y,w,h)
int x,y,w,h;
{
  int  i;
  XRectangle xr;

  xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
  XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);

  XSetForeground(theDisp, theGC, infofg);
  XSetBackground(theDisp, theGC, infobg);

  /* draw the two icons */
  XCopyArea(theDisp, pennPix, infoW, theGC, 0, 0, penn_width, penn_height,
	    36 - penn_width/2, 36 - penn_height/2);
  XCopyArea(theDisp, graspPix, infoW, theGC, 0, 0, grasp_width, grasp_height,
	    INFOWIDE - 36 - grasp_width/2, 36 - grasp_height/2);

  /* draw the credits */
  sprintf(str,"XV   -   %s",REVDATE);
  CenterString(infoW, str, INFOWIDE/2, 36-LINEHIGH);
  CenterString(infoW, "by John Bradley  (bradley@cis.upenn.edu)"
	       , INFOWIDE/2, 36);
  CenterString(infoW, "Copyright 1989-1992, University of Pennsylvania",
	       INFOWIDE/2, 36+LINEHIGH);

  /* draw the dividing lines */
  i = 36 + penn_height/2 + 4;
  XDrawLine(theDisp, infoW, theGC, 0, i, INFOWIDE, i);
  XDrawLine(theDisp, infoW, theGC, 0, i+2, INFOWIDE, i+2);

  XDrawLine(theDisp, infoW, theGC, 0, INFOHIGH-20, INFOWIDE, INFOHIGH-20);
  XDrawLine(theDisp, infoW, theGC, 0, INFOHIGH-22, INFOWIDE, INFOHIGH-22);

  XDrawLine(theDisp, infoW, theGC, 0, INFOHIGH-40, INFOWIDE, INFOHIGH-40);
  XDrawLine(theDisp, infoW, theGC, 0, INFOHIGH-42, INFOWIDE, INFOHIGH-42);

  DrawStrings();
  XSetClipMask(theDisp, theGC, None);
}


/***************************************************/
static void DrawStrings()
{
  int i;
  for (i=0; i<6; i++) DrawFieldName(i);     /* draw the field titles */
  for (i=0; i<NISTR; i++) RedrawString(i);  /* draw the field values */
  XFlush(theDisp);
}


/***************************************************/
static void DrawFieldName(fnum)
int fnum;
{
  static char *fname[6] = {  "Filename:", "Format:", "Resolution:", 
			     "Cropping:", "Expansion:", "Colors:" };

  XSetForeground(theDisp, theGC, infofg);
  XSetBackground(theDisp, theGC, infobg);

  if (infoMode == INF_NONE || infoMode == INF_STR) return;
  if (infoMode == INF_PART && fnum>=3) return;

  XDrawString(theDisp, infoW, theGC, 10, TOPBASE + fnum*LINEHIGH, 
		fname[fnum], strlen(fname[fnum]));
}


/***************************************************/
static void RedrawString(st)
int st;
{
  /* erase area of string, and draw it with new contents */
  
  if (infoMode == INF_NONE) return;
  if (infoMode == INF_STR && st > ISTR_WARNING) return;
  if (infoMode == INF_PART && st > ISTR_RES) return;


  if (st == ISTR_INFO) {
    XSetForeground(theDisp, theGC, infobg);
    XFillRectangle(theDisp, infoW, theGC, 0, INFOHIGH-39, INFOWIDE, 17);
    XSetForeground(theDisp, theGC, infofg);
    CenterString(infoW, istrs[st], INFOWIDE/2, INFOHIGH-31);
  }
  else if (st == ISTR_WARNING) {
    XSetForeground(theDisp, theGC, infobg);
    XFillRectangle(theDisp, infoW, theGC, 0, INFOHIGH-19, INFOWIDE, 17);
    XSetForeground(theDisp, theGC, infofg);
    CenterString(infoW, istrs[st], INFOWIDE/2, INFOHIGH-10);
  }
  else {
    XSetForeground(theDisp, theGC, infobg);
    XFillRectangle(theDisp, infoW, theGC, 
		   STLEFT, TOPBASE - ASCENT + (st-ISTR_FILENAME)*LINEHIGH, 
		   INFOWIDE-STLEFT, LINEHIGH);
    XSetForeground(theDisp, theGC, infofg);
    XDrawString(theDisp, infoW, theGC, STLEFT,TOPBASE
		+ (st-ISTR_FILENAME)*LINEHIGH,	istrs[st], strlen(istrs[st]));
  }
}



/***************************************************/
void SetInfoMode(mode)
int mode;
{
  int y1, y2;

  infoMode = mode;
  if (infoUp) {   /* only do this if window is mapped */
    y1 = TOPBASE - ASCENT;
    y2 = INFOHIGH-43;

    XSetForeground(theDisp, theGC, infobg);

    XFillRectangle(theDisp, infoW, theGC, 0, y1, INFOWIDE, y2-y1);
    XFillRectangle(theDisp, infoW, theGC, 0, INFOHIGH-39, INFOWIDE, 17);
    XFillRectangle(theDisp, infoW, theGC, 0, INFOHIGH-19, INFOWIDE, 17);

    DrawStrings();
  }
}


/***************************************************/
/*VARARGS0*/
void SetISTR(va_alist)
va_dcl
{
  va_list args;
  char    *fmt;
  int     stnum;

  /* InfoStr( ISTR, format, arg1, arg2, ...) */

  va_start(args);

  stnum = va_arg(args, int);
  if (stnum<0 || stnum>=NISTR) return;

  fmt = va_arg(args, char *);
  vsprintf(istrs[stnum], fmt, args);
  va_end(args);
  
  if (infoUp) {
    RedrawString(stnum);
    XFlush(theDisp);
  }

  if (stnum == ISTR_COLOR) 
    SetISTR(ISTR_INFO,"%s  %s", formatStr, istrs[ISTR_COLOR]);


  if (ctrlUp && (stnum == ISTR_INFO || stnum == ISTR_WARNING)) {
    DrawCtrlStr();
    XFlush(theDisp);
  }
}


/***************************************************/
char *GetISTR(stnum)
int stnum;
{
  /* returns pointer to ISTR string */
  if (stnum < 0 || stnum>=NISTR) return(NULL);
  return (istrs[stnum]);
}


