/******************************************************************************
*		       							      *
* console/readline.c (part of rcalc)				       	      *
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.		      *
*								       	      *
* 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 Mass Ave, Cambridge, MA 02139, USA.	       	      *
*								       	      *
******************************************************************************/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "readline.h"		/* This file's header	     		*/

#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>

/*****************************************************************************/
/* Command history definitions.
*/
#define HISTORY_FILE		"." PACKAGE "_history"
#define HISTORY_MAXLINES	100

/* Class definition.
*/
struct _RcReadline
{
	gchar *history_file;
	gchar *prompt;
	gchar *current_line;
};

/*****************************************************************************/

/* TODO: Fill in this function and tab-completion will happen...
*/
static gchar *generate_one_completion( gchar *text, gint state )
{
	return NULL;
}

/*****************************************************************************/

/* These two interface between readline's custom tab-completion engine
** and our tab-completion engine, which is represented by the function
** generate_one_completion() above.
*/
static char **do_tab_completion( char *text, int start, int end )
{
	/* Suppress filename completion */
	rl_attempted_completion_over = 1;

	/* Generate our completions */
	return (char **)completion_matches( text, generate_one_completion );
}

/*****************************************************************************/

/* Counter used to ensure there is never more than one RcReadline in
** existence. This restriction cannot be lifted until something is
** done to allow two histories to be maintained simultaneously.
*/
static guint num_RcReadlines = 0;

/* Contructor
*/
RcReadline *rcc_readline_new( const gchar *the_prompt )
{
	RcReadline *rl;
	gchar *tmp;
	G_CONST_RETURN gchar *home;

	g_assert( the_prompt );

	/* Ensure that there is never more than one RcReadline in existence.
	*/
	num_RcReadlines++;
	g_assert( num_RcReadlines==1 );

	/* Allocate memory for the RcReadline.
	*/
	rl = g_new0( RcReadline, 1 );
	
	/* Build the filename of the history file.
	*/
	home = g_get_home_dir();
	g_assert( home );
	rl->history_file = g_strdup_printf( "%s/%s", home, HISTORY_FILE );
	
	/* Build the prompt.
	*/
	rl->prompt = g_strdup( the_prompt );
	while(( tmp = strstr( rl->prompt, "\\[" ) ))
	{
		tmp[0] = '\1';
		tmp[1] = RL_PROMPT_START_IGNORE;
	}
	while(( tmp = strstr( rl->prompt, "\\]" ) ))
	{
		tmp[0] = '\1';
		tmp[1] = RL_PROMPT_END_IGNORE;
	}
	
	/* Initialise readline - set our name to allow conditional
	** parsing of the ~/.inputrc file, hook in our completion
	** functions, and read and stifle the history.
	*/
	rl_readline_name = PACKAGE;
	rl_attempted_completion_function = (CPPFunction *)do_tab_completion;
	read_history( rl->history_file );
	stifle_history( HISTORY_MAXLINES );

	return rl;
}

/* Destructor
*/
void rcc_readline_delete( RcReadline *rl )
{
	g_assert( rl );

	write_history( rl->history_file );

	if( rl->current_line ) g_free( rl->current_line );
	g_free( rl->history_file );
	g_free( rl->prompt );
	g_free( rl );

	num_RcReadlines = 0;
}

/*****************************************************************************/

/* Get a line of text from the user.
*/
const gchar *rcc_readline_read_line( RcReadline *rl )
{
	gchar *line;

	g_assert( rl );
	
	/* Free the old line (if present) and read another.
	*/
	if( rl->current_line ) g_free( rl->current_line );
	rl->current_line = readline( rl->prompt );
	if( !rl->current_line ) return NULL;

	/* Remove leading and trailing whitespace from the line and,
	** if there is anything left, add it to the history list.
	*/
	line = g_strstrip( rl->current_line );
	if( *line ) add_history( line );

	return line;
}

/*** end of console/readline.c ***********************************************/
