static char rcsid[] = "@(#)$Id: out_utils.c,v 1.33 2006/04/16 21:01:35 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.33 $   $State: Exp $
 *
 *  Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                           (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  The Elm Mail System 
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/** This file contains routines used for output in the ELM program.

**/

#include "def_elm.h"

DEBUG_VAR(Debug,__FILE__,"ui");

static char err_buffer[SLEN];		/* store last error message */

static time_t LAST_ERROR = 0;
static int is_cancel_error = 0;


static void error_middle P_((CONST char *s));
void show_last_error()
{
    /** rewrite last error message! **/
    if(RawState()) {
	error_middle(err_buffer);
    }
}

void error_wait()
{
    time_t M = time(NULL);

    if (LAST_ERROR + sleepmsg > M && RawState()) {
	int W = LAST_ERROR + sleepmsg  - M;
	DPRINT(Debug,7,(&Debug, 
			"sleeping for %d seconds for error message\n",
			W));
	FlushBuffer();
	error_sleep(W);
    }
}

void clear_error()
{      
    if(RawState()) {
	int LINES, COLUMNS;

	menu_get_sizes(default_context,&LINES, &COLUMNS);

	if ('\0' != err_buffer[0]) 
	    error_wait();
	MoveCursor(LINES-1,0);
	CleartoEOLN();
	err_buffer[0] = '\0';
	is_cancel_error = 0;
    }
}

void Raw_OFF(exiting) 
     int exiting;
{
    if(RawState()) {
	int LINES, COLUMNS;

	menu_get_sizes(default_context,&LINES, &COLUMNS);

	if ('\0' != err_buffer[0]) 
	    error_wait();
	MoveCursor(LINES-1,0);
	CleartoEOLN();
    }
    Raw(OFF);
    NewLine();

    if (exiting)
	switch_title(2);

    if ('\0' != err_buffer[0]) 
	error_middle(err_buffer);

    FlushBuffer();
}

void set_error(s)
     char *s;
{
    strfcpy(err_buffer, s, sizeof err_buffer);
}

static void error_help P_((CONST char *s));
static void error_help (s)
     CONST char *s;
{
    int LINES, COLUMNS;

    menu_get_sizes(default_context,&LINES, &COLUMNS);

    MoveCursor(LINES-1,0);
    CleartoEOLN();
    PutLine0(LINES-1,(COLUMNS-strlen(s))/2,s);
    FlushBuffer();
}

static void error_middle (s)
     CONST char *s;
{
    if(!RawState()) {
	fprintf(stderr,"%s\n", s);
	/* sleep if stderr points to terminal 
	 */
	if (isatty(2)) {
#if POLL_METHOD	  
	    wait_for_timeout(1);
#else
	    sleep(1);
#endif
	}
    } else {
	int LINES, COLUMNS;

	menu_get_sizes(default_context,&LINES, &COLUMNS);
	
	if (strlen(s) < COLUMNS && NULL == strchr(s,'\n'))
	    error_help(s);
	else {
	    char * s1 = safe_strdup(s);
	    char *s2, *s3;
	    
	    for (s2=s1; *s2 != '\0'; s2 = s3) {
		char c;
		for (s3 = s2; *s3 != '\0' && s3 - s2 < COLUMNS && *s3 != '\n'; s3++);
		c = *s3;
		*s3 = '\0';
		error_help(s2);
		*s3 = c;
		if ('\n' == c)
		    s3++;
		if (*s3 != '\0') {   /* Wait between lines ...*/
		    error_sleep(1);
		}
	    }
	    free(s1);
	}
    }
    strfcpy(err_buffer, s, sizeof err_buffer);	/* save it too! */
}

int error(s)
     CONST char *s;
{
    /** outputs error 's' to screen at line 22, centered! **/
  if (0 == strcmp(err_buffer,s)) {
      DPRINT(Debug,7,(&Debug, 
		      "-- duplicate error message\n"));
  } else {
      error_wait();
      LAST_ERROR = time(NULL);
  }
  
  DPRINT(Debug,1,(&Debug,  
		  "ERROR message: %s\n", 
		  s));
  error_middle(s);
  return 0;
}

static int transient P_((CONST char *s));
static int transient(s)
     CONST char *s;
{
    /** outputs error 's' to screen at line 22, centered! **/
    DPRINT(Debug,1,(&Debug,  
		    "TRANSIENT message: %s\n", 
		    s));
    LAST_ERROR = 0;  /* NO SLEEP  */
    error_middle(s);
    strfcpy(err_buffer, s, sizeof err_buffer);	/* save it too! */
    return 0;
}

static char * prompt_it P_((CONST char *str, int pass));
static char * prompt_it (str,pass) 
     CONST char *str;
     int pass;
{
    int len = strlen(str);
    int status;
    char buffer[200];
    int oldstate = RawState();
    int LINES, COLUMNS;

    struct menu_context *cpage = Raw(ON);
	
    buffer[0] = '\0';

 redraw:
    menu_get_sizes(cpage,&LINES, &COLUMNS);

    PutLine0(LINES-3, 0,str);
    CleartoEOS();
    show_last_error();
    status = optionally_enter(buffer,LINES-1-2, len+1,
			      (pass ? OE_PASSWD : 0) |OE_REDRAW_MARK|
			      OE_SIG_CHAR /* Ctrl-C */,
			      sizeof buffer,
			      cpage);
    if (REDRAW_MARK == status) {
	menu_ClearScreen(cpage);   /* Clear possible redraw mark */
		
	/* Call refresh routines of children */
	menu_redraw_children(cpage);

	goto redraw;
    }
    MoveCursor(LINES-3,0);   /* Ack RETURN */
    CleartoEOS();

    Raw(oldstate);

    show_last_error();
    
    if (status != 0)
	return NULL;    
    return safe_strdup(buffer);
}

static void cancel_transient_X   P_((struct string *x));
static void cancel_transient_X(x)
     struct string *x;
{
    int LINES, COLUMNS;
    int pos = 0;
    int vlen;
    struct string *Y;
    int s = 0;

    clear_error();
    menu_get_sizes(default_context,&LINES, &COLUMNS);

    DPRINT(Debug,1,(&Debug,  
		    "CANCEL TRANSIENT message: %S\n", 
		    x));

    is_cancel_error = 1;
    while (NULL != (Y = curses_printable_clip(x,&pos,99,&vlen,COLUMNS-1))) {

	if (vlen > 0) {
	    if (s)
		error_sleep(1);
	    s = 1;
	    
	    MoveCursor(LINES-1,0);
	    CleartoEOLN();
	    PutLineX(LINES-1,(COLUMNS-vlen)/2,FRM("%S"),Y);
	    FlushBuffer();
	    
	}
	free_string(&Y);
	
	if (!vlen)
	    break;
    }
}

static void cancel_clear_X  P_((void));
static void cancel_clear_X()
{ 
    int LINES, COLUMNS;
	
    menu_get_sizes(default_context,&LINES, &COLUMNS);

    MoveCursor(LINES-1,0);
    CleartoEOLN();
    is_cancel_error = 0;
}

void out_util_setup() {
    set_error_handler(error);
    set_transient_handler(transient);
    set_prompt_handler(prompt_it);

    setup_cancel_cb(cancel_set_ttysig_X,
		    cancel_reset_ttysig_X,
		    cancel_transient_X,
		    cancel_clear_X);
}


/* Used by newmbox.c */
int need_refresh_low_line() {
    if ('\0' != err_buffer[0]) {
	clear_error();
	return 1;
    }

    if (is_cancel_error) {
	cancel_clear_X();
	return 1;
    }

    return 0;
}


void lower_prompt(s)
     char *s;
{
  /** prompt user for input on LINES-1 line, left justified **/
  
    if(RawState()) {
	int LINES, COLUMNS;
	
	menu_get_sizes(default_context,&LINES, &COLUMNS);
	
	PutLine0(LINES-1-1,0,s);
	CleartoEOLN();
    } else {
	fprintf(stderr,"%s\n",s);
    }
}

void prompt(s)
     char *s;
{
  /** prompt user for input on LINES-3 line, left justified **/

    if(RawState()) {
	int LINES, COLUMNS;
	
	menu_get_sizes(default_context,&LINES, &COLUMNS);
	
	PutLine0(LINES-4,0,s);
	CleartoEOLN();
    } else {
	fprintf(stderr,"%s\n",s);
    }
}

void prompt_s(page,S)
     struct menu_context  *page;
     CONST struct string *S;
{
  /** prompt user for input on LINES-3 line, left justified **/

    if(RawState()) {
	int LINES, COLUMNS;

	menu_get_sizes(page,&LINES, &COLUMNS);

	menu_PutLineX(page,LINES-4,0,FRM("%S"),S);
	menu_CleartoEOLN(page);
    } else {
	lib_transient(FRM("%S\n"),S);
    }
}



void sleep_message() {
    if (sleepmsg > 0) {
	error_sleep(sleepmsg);
    }
}

void print_center(line,buffer)
     int line; 
     struct string * buffer;
{
    int l1 = string_len(buffer);
    int LINES, COLUMNS;

    menu_get_sizes(default_context,&LINES, &COLUMNS);

    if (l1 <  COLUMNS)
	PutLineX(line,(COLUMNS - l1)/2,FRM("%S"),buffer);        
}

void menu_print_center(ptr,line,buffer)
     struct menu_context  *ptr;
     int line; 
     struct string * buffer;
{
    int l1 = string_len(buffer);
    int LINES, COLUMNS;

    menu_get_sizes(ptr,&LINES, &COLUMNS);

    if (l1 <  COLUMNS)
	menu_PutLineX(ptr,line,(COLUMNS - l1)/2,FRM("%S"),buffer);        
}


void menu_print_format_center(
#if ANSI_C
       struct menu_context  *ptr,
       int lineY,const char *format, const char *line, ...
#else
       ptr,lineY,format,line,va_alist
#endif
       )
#if !ANSI_C
     struct menu_context  *ptr;
     int lineY;
     CONST char *format; 
     CONST char *line;
     va_dcl
#endif
{
    va_list vl;

    struct string *text;

    Va_start(vl, line);           /* defined in defs.h */       
    text = elm_smessage(0,format,line,vl);
    va_end(vl);

    menu_print_center(ptr,lineY,text);

    free_string(&text);
}

void print_format_center(
#if ANSI_C
       int lineY,const char *format, const char *line, ...
#else
       lineY,format,line,va_alist
#endif
)
#if !ANSI_C
       int lineY;
       CONST char *format; 
       CONST char *line;
       va_dcl
#endif
{
    va_list vl;

    struct string *text;

    Va_start(vl, line);           /* defined in defs.h */       
    text = elm_smessage(0,format,line,vl);
    va_end(vl);

    print_center(lineY,text);

    free_string(&text);
}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1