/* Copyright (C) 1993,1994 by the author(s).
 
 This software is published in the hope that it will be useful, but
 WITHOUT ANY WARRANTY for any part of this software to work correctly
 or as described in the manuals. See the ShapeTools Public License
 for details.

 Permission is granted to use, copy, modify, or distribute any part of
 this software but only under the conditions described in the ShapeTools 
 Public License. A copy of this license is supposed to have been given
 to you along with ShapeTools in a file named LICENSE. Among other
 things, this copyright notice and the Public License must be
 preserved on all copies.
 */
/*
 * kbdio.c -- ShapeTools toolkit library
 *
 * Authors: Uli Pralle (Uli.Pralle@cs.tu-berlin.de)
 *          Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de)
 *
 * $Header: kbdio.c[4.0] Thu Jun 24 17:43:16 1993 andy@cs.tu-berlin.de frozen $
 */

#include "config.h"
#include "sttk.h"

#define INITIAL_BUFFER_SIZE 2048 /* for stGetFromStdin() */

EXPORT int   stQuietFlag = FALSE;
EXPORT int   stShutupFlag = FALSE;
EXPORT char* stProgramName = NULL;
EXPORT char  stMessage[ST_MSGLEN];

EXPORT void stLog (msg, logType)
     char *msg;
     int  logType;
{
  FILE *channel;

  if (stShutupFlag || (stQuietFlag && !(logType & ST_LOG_ERROR)))
    return;

  switch (logType & 077) {
  case ST_LOG_MSG:
    channel = stdout;
    break;
  case ST_LOG_MSGERR:
    channel = stderr;
    break;
  case ST_LOG_WARNING:
    channel = stderr;
    fprintf (channel, "%s - warning: ", stProgramName);
    break;
  case ST_LOG_ERROR:
    channel = stderr;
    fprintf (channel, "%s - error: ", stProgramName);
    break;
  }

  if (logType & ST_LOG_NONL)
    fprintf (channel, "%s", msg ? msg : "");
  else
    fprintf (channel, "%s\n", msg ? msg : "");
  fflush (channel);
}

EXPORT char *stGetFromStdin (termChar)
int termChar;
{
    /*
     * Reads from stdin a text terminated by ^D or by a specified
     * single charcter "termChar" at the beginning of a new line.
     * If term_char is -1 text is terminated  by ^D.
     */
    
    char *text ;		/* pointer to text buffer */
    char *tmp ;			/* temporary pointer to text buffer */
    int tindex ;		/* index into text[] (last char read) */
    int c ;			/* char to be read */
    int current_buffer_size = INITIAL_BUFFER_SIZE ;
				/* size of text[] buffer */
    char *prompt = NULL ;	/* prompt for reading from terminal,
				 * also serves a flag whether we read
				 * from a terminal */

    if (isatty(fileno(stdin))) {
	char eofMsg[30] ;
	
	prompt = "> " ;
	if (termChar == -1) {
	    eofMsg[0] = '\0' ;
	} else {
	    sprintf (eofMsg, " or single '%c' on a line", termChar) ;
	}
	sprintf (stMessage, "Enter text, terminated with your EOF character%s:", eofMsg);
	stLog (stMessage, ST_LOG_MSG);
	stLog (prompt, ST_LOG_MSG | ST_LOG_NONL);
    }

    /* allocate initial text buffer */
    text = malloc(INITIAL_BUFFER_SIZE) ;
    if (text == NULL) {
	return ("") ;
    }
    tindex = 0 ;

    /* read loop */
    while ((c = fgetc (stdin)) != EOF) {

	/* check for single termChar on line */
	if (c == '\n' &&
	    tindex > 0 &&
	    text[tindex - 1] == termChar &&
	    (tindex == 1 || text[tindex - 2] == '\n')) {
	    
	    /* termChar is only char on line, so stop reading */
	    tindex-- ;		/* remove termChar from text */
	    break ;
	}

	/* add char to text */
	text[tindex++] = c ;

	/* enlarge buffer if necessary */
	if (tindex == current_buffer_size) {
	    current_buffer_size *= 2 ;
	    tmp = realloc(text, current_buffer_size) ;
	    if (tmp == NULL) {
		/* if realloc() failed, return *something* at least */
		text[tindex - 1] = '\0' ;
		return text ;
	    }
	    text = tmp ;
	}

	/* print prompt if necessary */
	if (c == '\n' && prompt != NULL) {
	    stLog (prompt, ST_LOG_MSG | ST_LOG_NONL) ;
	}
    }
    clearerr(stdin) ;		/* make further reads from stdin possible */

    if (c == EOF & prompt != NULL) {
	fputc ('\n', stdout) ;
    }

    /* free unneeded part of allocated memory */
    text[tindex] = '\0' ;
    tmp = realloc(text, strlen(text) + 1) ;
    if (tmp != NULL) {
	text = tmp ;
    }

    /* and go! */
    return text ;
}


/*===================
 * stAskConfirm
 *===================*/

#define minimum(x,y) (((x) <= (y)) ? (x) : (y)) 

#ifdef SIGCONT
LOCAL jmp_buf stHere;

LOCAL Sigret_t conthand () {
  sprintf (stMessage, "%s:", stThisTransaction.tr_fname);
  stLog (stMessage, ST_LOG_MSG);
  longjmp (stHere, 1);
}
#endif

EXPORT int stAskConfirm (message, defaultAnswer)
     char *message;
     char *defaultAnswer;
{
  /*  returns true if the answer is equivalent to 'defaultAnswer' (assumption)
   */
  char strbuf[ST_MSGLEN], answer[ST_MSGLEN], *cp;

  if (message == (char *)NULL)
    return (TRUE);
  if (!isatty (fileno (stdin)))
    return (TRUE);
  if (stQuietFlag)
    return (TRUE);
#ifdef SIGCONT
  setjmp (stHere);
  signal (SIGCONT, conthand);
#endif
  fflush (stdin);
  sprintf (stMessage, "%s [%s] ", message, defaultAnswer);
  stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL);
  strbuf[0] = '\0';
  answer[0] = '\0';
  gets (strbuf);
#ifdef SIGCONT  
  signal (SIGCONT, SIG_DFL);
#endif
  sscanf (strbuf, "%s", answer);
  if (answer[0] == '\0')
    return (TRUE); /* assumption acknowledged */
  cp = answer;
  while (*cp ? (*cp++ |= ' ') : 0); /* make sure answer is lowercase */
  return (!strncmp (defaultAnswer, answer, minimum(strlen(defaultAnswer), strlen(answer))));
}

/*=====================
 * get terminal width
 *=====================*/

EXPORT int stGetTermWidth (fileDes)
     int fileDes;
{
#ifdef TIOCGWINSZ
  struct winsize termSize;

  if (ioctl (fileDes, TIOCGWINSZ, (caddr_t) &termSize) == 0) {
    /* some environments (e.g. emacs) return fishy values (0) -- correct this */
    return (termSize.ws_col ? termSize.ws_col : 80);
  }
#endif
  return 80;
}
