#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <malloc.h>

#ifdef  MSDOS
#include    <jctype.h>
#endif

#include    "defs.h"
#include    "key.h"

int	GETCH();
void	UNGETCH(int ch);
void	LOCATE(int x,int y);
void	REPCHR(int ch,int n);
void	BEEP(void);
void	BAKSPC(int n);
void	PUTC(int ch);
void	PUTS(char *str);
void	FLUSH(void);

#define	HISMAX	16

static	char	*hisv[HISMAX + 1];
static	char	undo_buf[128];

int     iskan(char *p)
{
    if ( iskanji(*p) && iskanji2(*(p+1)) )
        return TRUE;
    else
        return FALSE;
}
int     kan_pos(char *p, int n)
{
    int     i;

    for ( i = n ; i > 0 ; ) {
        if ( *p == '\0' ) {
            return (n - i);
        } else if ( iskan(p) ) {
            i -= 2;
            p += 2;
        } else {
            i--;
            p++;
        }
    }
    return (n + i);
}
char	*stralloc(char *str)
{
    char *p;

    if ( (p = (char *)malloc(strlen(str) + 1)) != NULL )
	strcpy(p, str);
    return p;
}
int	input(int x, int y, int cols, int max, int no, char *buf)
{
    int  i, n, ch;
    char *p;
    static int len = 0;
    static int pos = 0;
    static int top = 0;

    for ( ; ; ) {
	while ( top > 0 && (pos - top) < 10 )
	    top = kan_pos(buf, top - 10);

	while ( (pos - top) >= (cols - 5) )
	    top = kan_pos(buf, top + 10);

	p = buf + top;
	n = 0;
	i = cols;
	LOCATE(x, y);

	if ( top > 0 ) {
	    BOLDCOL();
	    PUTANK('<');
	    NOMCOL();
	    n++;
	}

	if ( (len - top) > cols )
	    i--;

	while ( (n + top) < len && n < i ) {
	    if ( iskan(p) ) {
		if ( (n + 2) > i )
		    break;
		PUTKAN((p[0] << 8) | (p[1] & 0xFF));
		n += 2;
		p += 2;
	    } else {
		PUTANK(*p);
		n += 1;
		p += 1;
	    }
	}

	if ( (n + top) < len ) {
	    BOLDCOL();
	    PUTANK('>');
	    NOMCOL();
	    n++;
	}

	REPCHR(' ', cols - n);
	LOCATE(x + (pos - top), y);
	FLUSH();

	while ( KBHIT() == 0 )
	    wait_loop();

	ch = GETCH();

	if ( ch == K_END_LINE ) {
	    buf[len] = '\0';
	    len = pos = top = 0;

	    if ( buf[0] != '\0' ) {
		if ( hisv[0] != NULL && strcmp(hisv[0], buf) == 0 )
		    break;
		if ( hisv[HISMAX - 1] != NULL )
		    free(hisv[HISMAX - 1]);
		for ( n = (HISMAX - 1) ; n > 0 ; n-- )
		    hisv[n] = hisv[n - 1];
		hisv[0] = stralloc(buf);
	    }
	    break;

	} else if ( ch == K_BACK_SPC && pos > 0 ) {
	    pos = kan_pos(buf, pos - 1);
	    p = &(buf[pos]);
	    n = (iskan(p) ? 2 : 1);
	    len -= n;
	    memcpy(p, p + n, len - pos);

	} else if ( ch == K_DEL_CHAR && pos < len ) {
            p = &(buf[pos]);
            n = (iskan(p) ? 2 : 1);
            len -= n;
            memcpy(p, p + n, len - pos);

	} else if ( ch == K_LEFT_CUR && pos < len ) {
            p = &(buf[pos]);
            n = (iskan(p) ? 2 : 1);
            pos += n;

	} else if ( ch == K_RIGHT_CUR && pos > 0 ) {
            pos = kan_pos(buf, pos - 1);

	} else if ( ch == K_CUT_BUFF ) {
	    strncpy(undo_buf, buf, len);
	    undo_buf[len] = '\0';

	} else if ( ch == K_DEL_LINE ) {
	    strncpy(undo_buf, buf, len);
	    undo_buf[len] = '\0';
	    pos = len = 0;

	} else if ( ch == K_UNDO_LINE ) {
	    pos = len = strlen(undo_buf);
	    memcpy(buf, undo_buf, len);

	} else if ( ch == K_HIS_LINE ) {
	    while ( pos < max && buf[pos] != '\0' )
		pos++;
	    len = pos;

	} else if ( ch == K_GETS_WIND ) {
	    if ( (pos += get_wind(no, TRUE, max - pos, buf + pos)) > len )
		len = pos;

	} else if ( ch == K_GETS_SRC ) {
	    if ( (pos += get_wind(0, FALSE, max - pos, buf + pos)) > len )
		len = pos;

	} else if ( ch == K_GETS_DIS ) {
	    if ( (pos += get_wind(1, FALSE, max - pos, buf + pos)) > len )
		len = pos;

	} else if ( ch == K_HISTORY ) {
	    for ( n = 0 ; n < HISMAX ; n++ ) {
		if ( hisv[n] == NULL )
		    break;
	    }
	    if ( n > 0 ) {
		SAVESCREEN();
		n = menu(x + 5, y - 2 - n, 0, hisv);
		LOADSCREEN();
		FLUSH();
		if ( n >= 0 ) {
		    pos = len = strlen(hisv[n]);
		    memcpy(buf, hisv[n], len);
		}
	    }

	} else if ( (ch & 0xFF00) == 0 && ch >= ' ' && ch != 0x7F ) {
	    if ( iskanji(ch) ) {
		i = GETCH();
		if ( iskanji2(i) ) {
		    ch = (ch << 8) | i;
		    n = 2;
		    if ( ch == 0x8140 )		/* SPC */
			ch = 0x2020;
		} else {
		    UNGETCH(i);
		    n = 1;
		}
	    } else {
		n = 1;
	    }

	    if ( (len + n) > max ) {
		BEEP();
		continue;
	    }

	    if ( pos < len ) {
		p = &(buf[len + (n - 1)]);
		for ( i = len - pos ; i > 0 ; i--,p-- )
		    *p = *(p - n);
	    }

	    if ( n == 1 ) {
		buf[pos++] = ch;
	    } else {
		buf[pos++] = ch >> 8;
		buf[pos++] = ch;
	    }

	    len += n;

	} else if ( (ch & 0xFF00) != 0 || ch < ' ' ) {
	    break;
	}
    }

    return ch;
}
