/*===========================================================================
  Copyright (C) 1985-2009 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.TYPE		Module
.IDENTIFICATION	error.c
.AUTHOR    	Alan Richmond [ST-ECF]
.LANGUAGE  	C
.KEYWORDS	Error handling.
.ENVIRONMENT 	
.COMMENTS	Error Handler.
		This module contains the error state: a flag which is TRUE
		if an error has been reported, and an associated message.
		In the ST implementation ( import_ST is defined),
		the error state is passed down to the ST interface.
		A future implementation may use a/the stack structure; the
		present version is primarily designed for use with the 
		Dialogue Manager prompting facility, which reports the error
		to the user. Currently no record of `underlying' errors is
		required, but this may change.
.VERSION 1.0	13-Dec-1985:	Creation
.VERSION 1.1	28-Apr-1986:	check_range added.
.VERSION 2.0	23-May-1986:	Removed ST staff (at lower level).
.VERSION 2.1	12-Jun-1987:	Removed bug in eh_ed_str2
			Added eh_loc_error.
.VERSION 2.2	25-Jun-1987:	Made availabler with SW_Level
			(0 = Minimal - 1 = Full)
.VERSION 2.3	23-Feb-1988:	MIDAS compatibility
.VERSION 2.4	08-Dec-1988:	Truncate text to ensure logged message.
				Be sure eh_ed_str2 logs the mesage.
.VERSION 2.5	14-Jul-1989:	Added eh_ed_as, to be sure that null pointers
			don't result in a crash...

 090831		last modif
-----------------------------*/

#include <midas_def.h>
#include <macrogen.h>
#include <error.h>
#include <string.h>

#define		LINESIZE	(sizeof(locbuf)-1)
						/* Maximum size of a line   */

extern int pm_tr2();


int  eh_put2(), eh_ed_str2();


static	char	locbuf[81]="";
static  char	error_state = 0;
static  char	avoid[] = "";
static  int	keep_bytes = 0;		/* To be sure to get complete message */
static  int	error_lev  = _ERROR_;	/* Error or Warning Level */

/*==========================================================================*/
static int edval (x, i)
/*+++
.PURPOSE Edit the long integer number
.RETURNS The new index in locbuf
.REMARKS 
--------*/
        long int x; 	/* IN: Number ot edit	*/
        int i;		/* IN: Index in locbuf	*/
{
	register int k;
	register long int j;
	MID_STATIC char edbuf[12] = "           ";

  j = ABSOLUTE(x);
  
  for (k = sizeof(edbuf); ;)
  {	edbuf[--k]= (j%10) + '0';
  	j /= 10;
  	if (j == 0)	break;
  }
  if (x < 0)	edbuf[--k] = '-';
  
  i += oscopy(&locbuf[i], &edbuf[k], sizeof(edbuf)-k);
  return(i);
}

/*=========================================================================*/
/* 			Public Routines					   */
/*=========================================================================*/
int eh_state ()
/*+++
.PURPOSE Test for error state, i.e. any error was reported, and not yet cleared
.RETURNS 0 if no error, 1 if error exists.
---------*/
{
  return(error_state);
}

/*=========================================================================*/
int eh_class (class)
/*+++
.PURPOSE Define error level for next message
.RETURNS error state
.REMARKS Class is _ERROR_ or _WARNING_
---------*/
	int	 class;		/* _ERROR_ or _WARNING_		*/
{
  error_lev = class;
  
  return(error_state);
}

/*=========================================================================*/
int eh_put (subr, message, class)
/*+++
.PURPOSE Store error message.
.RETURNS 0 (Not an error) / 1 (Is a error)
.REMARKS Class is _ERROR_ or _WARNING_
---------*/
	char	 *subr;		/* IN: subroutine name (unused)	*/
	char	 *message;	/* IN: message text	*/
	int	 class;		/* _ERROR_ or _WARNING_		*/
{
  return(eh_put2(subr, message, class, strlen(message)));
}

/*=========================================================================*/
int eh_put1(message)
/*+++
.PURPOSE Store error message.
.RETURNS 0 (Not an error) / 1 (Is a error)
.REMARKS Class is _ERROR_ 
---------*/
	char	 *message;	/* IN: message text	*/
{
  return(eh_put2((char *)0, message, _ERROR_, strlen(message)));
}

/*=========================================================================*/
int eh_put2 (subr, message, class, lmsg)
/*+++
.PURPOSE Store error message.
.RETURNS 0 (Not an error) / 1 (Is a error)
.REMARKS Class is _ERROR_ or _WARNING_
---------*/
	char	 *subr;		/* IN: subroutine name (unused)	*/
	char	 *message;	/* IN: message text	*/
	int	 class;		/* _ERROR_ or _WARNING_		*/
	int	 lmsg;		/* IN: Length of message	*/
{
	register char *p;
	register int  i;

  if (!message)		return(0);	/* No message at all ... */

  pm_tr2(class, message, lmsg);

  if (message != locbuf)
  {	for (p = message, i = 0; (i < LINESIZE) && (*p); )
	  	locbuf[i++] = *(p++);
	  locbuf[i] = EOS;
  }

  if(class == _ERROR_)	error_state = 1;

  error_lev  = _ERROR_;		/* Error or Warning Level */

  return(error_state);
}

/*=========================================================================*/
char *eh_loc (level, subr, class)
/*+++
.PURPOSE Retrieve address of a stored error message
.RETURNS Address of message / NULL if no message
.REMARKS 
---------*/
	int	level;			/* TBD	*/
	char	*subr;		/* OUT: subroutine name (unused)	*/
	int	class;			/* TBD	*/
{
  return (error_state ? locbuf : NULL_PTR(char));
}

/*=========================================================================*/
int eh_clear (level)
/*+++
.PURPOSE Clear error state.
.RETURNS 0
.REMARKS 
---------*/
	int	 level;		/* TBD	*/
{
  error_state = 0;
  return(error_state);
}

/***************************************************************************
 * 			eh_ed routines
 ****************************************************************************/

static int eh_ed0(text)
/*+++
.PURPOSE Copies the text to internal buffer
.RETURNS Index of first useable character in internal buffer
.REMARKS Routine not traced. Leaves at least keep_bytes.
---------*/
	char *text;	/* IN: text to copy	*/
{
	register int 	i, l;
	register char 	*p;

  l = LINESIZE - keep_bytes;
  for (i=0, p=text; (i < l) && (*p); )
	locbuf[i++] = *(p++);
  if ( (*p == '\0') && (*(p-1) != ' '))
  		locbuf[i++] = ' ';	/* Add blank */

  if ( (*p) && (i >= 4) )		/* Too long text... */
  { 	p = &locbuf[i-4];
  	*(p++) = '.', *(p++) = '.', *(p++) = '.';
  	*(p++) = ' ';
  }
 
  return(i);
}

/*=========================================================================*/
int eh_ed_as(text, string)
/*+++
.PURPOSE Error: text followed by EOS string
.RETURNS 1
.REMARKS string can be a null pointer.
---------*/
	char 	*text;		/* IN: Text to insert	*/
	char	*string;	/* IN: String to insert, terminated with EOS */
{
	char 	*p;

  p = (string ? string : "<NuLL>");

  return(eh_ed_str2(text, p, strlen(p)));
}

/*=========================================================================*/
int eh_ed_str2	(text, string, length)
/*+++
.PURPOSE Error: text followed by string
.RETURNS 1
.REMARKS Routine not traced
---------*/
	char 	*text;			/* IN: Text to insert	*/
	char	*string;		/* IN: String to insert	*/
	int	length;			/* IN: length of string	*/
{
	register int i, l;
	register char *p;

  keep_bytes = length;
  
  i = eh_ed0(text);

  for (p = string, l = length; (i < LINESIZE) && (--l >= 0) ; )
	locbuf[i++] = *(p++);

  locbuf[i] = EOS;

  return(eh_put2(avoid, locbuf, error_lev, i));
}

/*=========================================================================*/
int eh_ed_i (text, value)
/*++++++++
.PURPOSE Store error message followed by a number.
.RETURNS 1
.REMARKS Routine not traced
---------*/
	char 	*text;			/* IN: EOS-terminated Text to insert*/
	int	value;			/* IN: value to edit		*/
{
  	register int i;
	long int x;

  keep_bytes = 11;
  i = eh_ed0(text);

  if (i < LINESIZE - 11)	
  { 	x = value;
  	i = edval(x, i);
  }
  locbuf[i] = EOS;

  return(eh_put2(avoid, locbuf, error_lev, i));
}

