/* x11_commandline.c -- Simple prompt for X11
   Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>

   This file is part of Jade.

   Jade 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, or (at your option)
   any later version.

   Jade 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 Jade; see the file COPYING.	If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "jade.h"
#include "jade_protos.h"

#include <string.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

_PR u_char *sys_prompt(VW *, u_char *, u_char *);

/*
 * returns a string got from the command line
 * it (the string) must be valstrfree()'ed after use.
 * cursor should be off.
 */
u_char *
sys_prompt(VW *vw, u_char *prompt, u_char *original)
{
    u_char *cmdline;
    int cmdlen;
    int promptlen = strlen(prompt);
    if(!sys_unsleep_vw(vw))
	return(FALSE);
    cmdline = str_dup(original ? original : (u_char *)"");
    if(cmdline)
    {
	POS oldcursor = vw->vw_CursorPos;
	long oldstartcol = vw->vw_StartCol;
	long prevx;
	char keepgoing = 0;

	cmdlen = strlen(cmdline) + 1;
	vw->vw_CursorPos.pos_Col = promptlen + cmdlen - 1;
	vw->vw_CursorPos.pos_Line = vw->vw_StartCol + vw->vw_MaxY - 1;
	prevx = vw->vw_CursorPos.pos_Col;
	if(vw->vw_CursorPos.pos_Col >= vw->vw_MaxX)
	    vw->vw_StartCol = vw->vw_CursorPos.pos_Col - vw->vw_MaxX + 1;
	else
	    vw->vw_StartCol = 0;

	redraw_cmd_line(vw, prompt, cmdline, promptlen, cmdlen - 1);
	cmd_line_cursor(vw, CURS_ON);

	while(!keepgoing)
	{
	    XEvent ev;
	    XWindowEvent(x11_display, vw->vw_Window,
			 KeyPressMask | ExposureMask | StructureNotifyMask,
			 &ev);
	    switch(ev.type)
	    {
		KeySym ks;
		u_char buf[256];
		int len;
	    case MappingNotify:
		XRefreshKeyboardMapping(&ev.xmapping);
		continue;
	    case KeyPress:
		cmd_line_cursor(vw, CURS_OFF);
		len = XLookupString(&ev.xkey, buf, 255, &ks, NULL);
		buf[len] = 0;
		switch(ks)
		{
		case XK_Delete:
		    if(cmdlen > 1)
		    {
			u_char *newline;
			vw->vw_CursorPos.pos_Col--;
			cmdlen--;
			newline = str_dupn(cmdline, cmdlen - 1);
			if(newline)
			{
			    str_free(cmdline);
			    cmdline = newline;
			}
		    }
		    break;
		case XK_Return:
		    keepgoing = 1;
		    break;
		case XK_Escape:
		    keepgoing = -1;
		    break;
		case XK_Up:
		case XK_Down:
		    if(last_prompted)
		    {
			u_char *temp = cmdline;
			cmdline = last_prompted;
			last_prompted = temp;
			cmdlen = strlen(cmdline) + 1;
			vw->vw_CursorPos.pos_Col = cmdlen + promptlen - 1;
			prevx = 20000;
		    }
		    break;
		default:
		    if(len)
		    {
			u_char *newline = str_dupn(cmdline, cmdlen + len);
			if(newline)
			{
			    strcat(newline, buf);
			    str_free(cmdline);
			    cmdline = newline;
			    cmdlen += len;
			    vw->vw_CursorPos.pos_Col += len;
			}
		    }
		    break;
		}
		break;
	    case ConfigureNotify:
		x11_update_dimensions(vw, ev.xconfigure.width,
				  ev.xconfigure.height);
		continue;
	    case Expose:
		vw->vw_Flags |= VWFF_FORCE_REFRESH;
		draw_message_line(vw);
		prevx = 20000;
		cmd_line_cursor(vw, CURS_OFF);
		break;
	    default:
		continue;
	    }
	    if(vw->vw_CursorPos.pos_Col >= vw->vw_MaxX)
	    {
		vw->vw_StartCol = vw->vw_CursorPos.pos_Col - vw->vw_MaxX + 1;
		redraw_cmd_line(vw, prompt, cmdline, promptlen, cmdlen - 1);
	    }
	    else
	    {
		vw->vw_StartCol = 0;
		if(prevx >= vw->vw_MaxX)
		    redraw_cmd_line(vw, prompt, cmdline, promptlen,
				    cmdlen - 1);
		else if(prevx < vw->vw_CursorPos.pos_Col)
		    redraw_cmd_line_from(vw, prompt, cmdline, promptlen,
					 cmdlen - 1, prevx);
		else
		    redraw_cmd_line_from(vw, prompt, cmdline, promptlen,
					 cmdlen - 1, vw->vw_CursorPos.pos_Col);
	    }
	    prevx = vw->vw_CursorPos.pos_Col;
	    cmd_line_cursor(vw, CURS_ON);
	}
	if(keepgoing < 0)
	{
	    str_free(cmdline);
	    cmdline = NULL;
	}
	else
	{
	    str_free(last_prompted);
	    last_prompted = str_dup(cmdline);
	}
	cmd_line_cursor(vw, CURS_OFF);
	vw->vw_CursorPos = oldcursor;
	vw->vw_StartCol = oldstartcol;
	return(cmdline);
    }
    return(FALSE);
}
