/*
 * $Id: gen_misc.c,v 1.10 1994/08/10 03:39:15 mintha Exp jim $
 *
 * Set of general routines for use in C programs.
 * These routines do some error checking, and print errors.
 *
 * $Log: gen_misc.c,v $
 * Revision 1.10  1994/08/10 03:39:15  mintha
 * Moved interactive to both x/non-x
 *
 * Revision 1.9  1994/08/09  21:51:53  mintha
 * Added get_info_level
 *
 * Revision 1.8  1994/02/06  23:47:21  mintha
 * Got rid of unused variables
 *
 * Revision 1.7  1993/12/20  07:03:12  mintha
 * Added stdarg include
 *
 * Revision 1.6  1993/10/20  09:53:04  mintha
 * Include gen_utils_x now
 *
 * Revision 1.5  1993/10/05  11:22:37  mintha
 * Updates notify if running X windows interactively
 *
 * Revision 1.4  1993/10/05  09:58:44  mintha
 * flush show_info output
 *
 * Revision 1.3  1993/10/05  09:51:45  mintha
 * New show_info, pop_error updates, libversion etc.
 *
 * Revision 1.2  1993/09/23  09:18:21  mintha
 * Added comments
 *
 * Revision 1.1  1993/09/23  09:17:16  mintha
 * Initial revision
 *
 */

/* Do we have X windows - even if we aren't using it */
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "gen_utils_x.h"

#ifdef HAVE_X_WINDOWS
#include <xview/panel.h>
#include <xview/notice.h>
#include <xview/xview.h>

extern Panel panel;
#endif

extern boolean interactive;
static FILE *info_file = stdout;
static int info_level = STATUS;

/*
 * pop_error - Put up a popup with an error message, or a message to stderr
 *             if we aren't running interactively.
 */

void 
pop_error(int err_num, char *fmt, ...)
{
  va_list args;
  char msg[HUGE_STR];
  
  va_start(args, fmt);
  vsprintf(msg, fmt, args);
  va_end(args);
  
  fprintf(stderr, "%s\n", msg);

#ifdef HAVE_X_WINDOWS 
  if(interactive)
    notice_prompt(panel, NULL,
		  NOTICE_MESSAGE_STRINGS, msg, NULL,
		  NOTICE_BUTTON_YES, "OK", NULL);
#endif

  if(err_num != NO_ERR)
    finish(err_num);
}

/*
 * show_info - Show some information about status.
 */

void
show_info(int level, char *fmt, ...)
{
  va_list args;

  if(info_file == NULL)
    return;
  
  if(level <= info_level)
    {
      va_start(args, fmt);
      vfprintf(info_file, fmt, args);
      va_end(args);
      if(interactive)
	fprintf(info_file, "\r");
      fflush(info_file);
#ifdef HAVE_X_WINDOWS
      if(interactive)
	  notify_dispatch();
#endif
    }
}

/*
 * set_info_file - Set the file pointer for info messages.
 *                 Default is set to stdout.  Can be set to NULL to
 *                 disable info messages.
 */

void
set_info_file(FILE *fp)
{
  info_file = fp;
}

/*
 * set_info_level - Set the level for info messages.  Messages at or 
 *                  below this level are printed.  Level NONE (0) is
 *                  no messages.
 */

void
set_info_level(int level)
{
  info_level = level;
}

/*
 * get_info_level - Get the current info level.
 */

int
get_info_level(void)
{
  return info_level;
}

/*
 * chk_malloc - Allocate some memory, and return the pointer to
 *              it.  Print error message if not available.
 */

void *
chk_malloc(unsigned int size)
{
  void *ptr;
  
  ptr = (void *) malloc(size);
  if(ptr == NULL)
    pop_error(ERR_MALLOC, "Error mallocing memory");

  return ptr;  
}

/*
 * chk_free - Frees memory pointed to be the pointer, checks to
 *            make sure we are not freeing NULL :)
 */

void 
chk_free(void *ptr)
{
  if(ptr == NULL)
    pop_error(ERR_FREE, "Tried to free NULL reference");
  
  free(ptr);
}

/*
 * chk_cdf - Check for an error in a CDF routine
 */

void
chk_cdf(int error, char *routine)
{
  if(error != -1)
    return;
  
  pop_error(ERR_CDF, "Error: %d in CDF function %s", error, routine);
}
  
/*
 * chk_hdf - Check for an error in an HDF routine.
 */

void 
chk_hdf(int error, char *routine)
{
  if(error == 0)
    return;

  pop_error(ERR_HDF, "Error: %d in HDF function %s", error, routine);
}

/*
 * chk_read - Reads a block of 'size' bytes into 'buff' from 'file'.
 *            Checks to ensure that the block was read correctly.
 *            Returns FALSE if it wasn't.
 */

boolean
chk_read(int file, char *buff, int size)
{
  int nread;
  
  nread = read(file, buff, size);
  
  if(nread != size)
    {
      pop_error(NO_ERR, "Error reading %d byte block.  Read %d bytes", size, nread);
      return FALSE;
    }

  return TRUE;
}

/*
 * chk_write - Writes a block of 'size' bytes from 'buff' into 'file'.
 *             Checks to ensure that the block was written correctly.
 *             Returns FALSE if it wasn't.
 */

boolean
chk_write(int file, char *buff, int size)
{
  int nwrote;
  
  nwrote = write(file, buff, size);
  
  if(nwrote != size)
    {
      pop_error(NO_ERR, "Error writing %d byte block.  Wrote %d bytes", size, nwrote);
      return FALSE;
    }
  
  return TRUE;
}

/*
 * chk_rtn - Checks the return value of a function, and issues
 *           an error if it is not what the given value is.
 */

void
chk_rtn(int rtn, int should_be, char *err)
{
  if(rtn != should_be)
    pop_error(ERR_GEN, "Error: %s", err);
}

/*
 * lib_version - Return a string with the library version
 */

char *
lib_version(void)
{
  static char ver[STR_LEN];
  
  sprintf(ver, "%s", LIBJIM_VERSION);
  return ver;
}

