/*
** File: hey_readline.c
** Desc: Contains the general hooks for reading a line
** Auth: Colm MacCarthaigh (colmmacc@redbrick.dcu.ie)
** Date: 5/9/01
**
** $Id: hey_readline.c,v 1.2 2001/12/30 23:26:06 c-hey Exp $
*/

/*
** this is some pretty complicated shit - but well worth it :)
** 
** ANSI escapes rock!
*/

#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include "hey_readline.h"
#include "hey_edit.h"
#include "hey_format.h"
#include "hey_arg.h"
#include "dyn_page.h"
#include "config.h"
#include "aux.h"

#ifdef HAVE_LIBREADLINE
/* <bobb> readline includes */
#include <readline/readline.h>
#include <readline/history.h>
#endif

#define LINESIZE 128            /* Should be plenty */

/* are we currently editing ? */
static	int 	 hey_editing;

#ifdef HAVE_LIBREADLINE
/* the line we are currently on */
int hey_line = 0;

/* the total number of lines */
int hey_linetotal = 0;

/* has the last line been appended */
int hey_lastdone = 0;

#endif


/* the expanded prompt */
char	*hey_rlprompt;


/* initialise readline stuff */
void hey_readline_init()
{
#ifdef HAVE_LIBREADLINE

	/* every app should have this set */
	rl_readline_name = "hey";

	/* add our function names */
	rl_add_defun("hey_carriage_return", hey_return, -1);
	rl_add_defun("hey_line_up", hey_lineup, -1);
	rl_add_defun("hey_line_down", hey_linedown, -1);
	rl_add_defun("hey_arrows", hey_arrows, -1);
	rl_add_defun("hey_return", hey_return, -1);

	/* tell readline where to find bindings */
	rl_startup_hook = hey_bindkeys;

#endif
	
	/* make sure prompt is set */
	if((hey_rlprompt = hey_generate_prompt()) == NULL) {
		hey_rlprompt = strdup("");
	}

	/* we are now editing */
	hey_editing = 1;

}

/* we are done reading lines */
void hey_readline_fini()
{

	/* we are done editing */
	hey_editing = 0;

	/* the prompt can upset error messages */
	if(strcmp(hey_rlprompt,""))
		printf("\n");

	/* leaks are bad */
	free(hey_rlprompt);
}

/* actually read a line from standard input */
char *hey_readline(void)
{
#ifndef HAVE_LIBREADLINE
	static char		line[LINESIZE];
#endif
#ifdef HAVE_LIBREADLINE
	char		*line;

	hey_line++;
	hey_linetotal++;
	hey_lastdone = 0;

	if((line = readline(hey_rlprompt)) == NULL) {
		return NULL;
	}

#endif

#ifndef HAVE_LIBREADLINE

	/* print the prompt */
	printf("%s", hey_rlprompt);

	/* get the line */	
	if(!fgets(line,LINESIZE,stdin)) {
		return NULL;
	}

	/* chomp the line */
	if (strlen(line) > 1)
        	if (line[strlen(line) - 1] == '\n') line[strlen(line) -1] = '\0';
#endif

	/* test for EOF */
	if(hey_eof != NULL) {
		if(!strcmp(line,hey_eof)) {
			return NULL;
		}
	}

	/* throw it back */
	return line;
}


/* generate the hey prompt */
char *hey_generate_prompt(void) {
	char     *username;
	hey_user *user;
	char     *prompt_line;
	int       count;
	char     *ptr;
#define MINIBUFSIZE	16
	char     mini_buffer[MINIBUFSIZE];
	
        /* <x> This code is my fault. Blame me :) */
        if (hey_prompt) {

		/* Allocate initial space for the prompt_line */
	        if ((prompt_line = malloc(1)) == NULL) {
			perror_exit("hey: Out of Memory while allocating prompt_line\n");
                }
		
		*prompt_line = '\0';

         	/* Format the username string */
		/* Add the first user name we are heying */
		/* there will always be one .... */
		user = (hey_user *)g_listTraverse(hey_userlist);
		if (user) {
			username = strdup(user->name);
		} else {
			if((username = malloc(1)) == NULL) {
				perror_exit("hey: Out of Memory while allocating username\n");
			}
			*username = '\0';
		}

		/* Add additional names
		 * If we have more than 4, we put in ... to show multiple users */
                for (count = 1; count < hey_nousers ; count++) {
                       	if (count < hey_maxnames) {
				user = (hey_user *)g_listTraverse(NULL);
				username = m_strcat(username, " ");
				username = m_strcat(username, user->name);
			} else {
		       		username = m_strcat(username," ...");
		               	break;
                	}
		}

		/* dosome search and replace */	
	        for (ptr = hey_prompt; *ptr; ptr++) {
			
			if (*ptr == '%') {
				switch(*(ptr + 1)) {
					case '%':
						prompt_line = m_strcat(prompt_line, "%");
						ptr++;
						break;
							
					case 'u':
					case 'U':
						prompt_line = m_strcat(prompt_line, username);
						ptr++;
						break;

					case 'n':
					case 'N':
						snprintf(mini_buffer, MINIBUFSIZE, "%d", hey_nousers);
						prompt_line = m_strcat(prompt_line, mini_buffer);
						ptr++;
						break;
					default:
						snprintf(mini_buffer, MINIBUFSIZE, "%c", *ptr);
						prompt_line = m_strcat(prompt_line, mini_buffer);
						break;
				}		
			} else {
				snprintf(mini_buffer, MINIBUFSIZE, "%c", *ptr);
				prompt_line = m_strcat(prompt_line, mini_buffer);
			}
		}

		free(username);

	} else {
                prompt_line = NULL;
        }

	
	return prompt_line;	
#undef MINIBUFSIZE
}



/* redisplays a hey's buffer after SIGCONT */
void hey_redisplay(void)
{
#ifndef HAVE_LIBREADLINE
	char * ptr;

	if(!hey_editing) return;

	if((ptr = dyn_pageRead(hey_page))) {    	
		do {
			
			printf("%s%s\n",hey_rlprompt,ptr);
		} while ((ptr = dyn_pageRead(NULL)));     
	}

	printf("%s", hey_rlprompt);	

	/* make sure it's all on screen */
	fflush(stdout);

#endif

#ifdef HAVE_LIBREADLINE
	if(!hey_editing) return;

	hey_refresh(0, 0);
#endif
}

