/*-
 * Copyright (c) 2001
 * Tatsuya Kudoh(CDR/TK),ROYALPANDA.    All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#include<stdlib.h>
#include<fcntl.h>
#include"ks.h"
#include"regg.h"
#include"malloc.h"

#pragma noregalo


#define DIC_FILE	"/rom0/urp_dic"
#define UDIC_FILE	"/ram0/regg.dat"

#define TEXT_FILE	"/ram0/ksnote.txt"

#define FILE_SIZE	(8192/128)

static KSTextArea *Text;

static int handler( KSMsg *msg )
{
	KSTextArea *p;
	unsigned *str;

	p = msg->null.call_data;

	if( msg->type == KS_MSG_STRING ){
		str = msg->string.str;
	}else if( msg->type == KS_MSG_TEXT ){
		str = msg->text.text;
	}else{
		return 0;
	}
	switch( *str ){
	case KEYCODE_UP:
		KSTextAreaPrevLine(p);
		break;
	case KEYCODE_DOWN:
		KSTextAreaNextLine(p);
		break;
	case KEYCODE_LEFT:
		KSTextAreaBackward(p);
		break;
	case KEYCODE_RIGHT:
		KSTextAreaForward(p);
		break;
	case KEYCODE_RETURN:
	case KEYCODE_TAB:
		KSTextAreaInsert(p,str);
		break;
	case KEYCODE_BACKSPACE:
		KSTextAreaDeleteBackward(p,1);
		break;
	case KEYCODE_PRIOR:
		KSTextAreaPageUp(p);
		break;
	case KEYCODE_NEXT:
		KSTextAreaPageDown(p);
		break;
	case KEYCODE_HOME:
		KSTextAreaLineHead(p);
		break;
	case KEYCODE_END:
		KSTextAreaLineEnd(p);
		break;
	case KEYCODE_OPTION:
#if 0
		if( p->mark )
			KSTextAreaResetMark(p);
		else
			KSTextAreaSetMark(p);
#else
		KSSetExitFlag();
#endif
		break;

	default:
		if( *str != 127 && *str >= 32 )
			KSTextAreaInsert(p,str);
		break;
	}
	return 0;
}


static unsigned Code[128];

int main( int argc, char **argv )
{
	unsigned *src;
	unsigned char *dst;
	unsigned char c;
	unsigned char far *Dic;
	int len;
	unsigned code;
	int fd;
	struct stat statbuf;
	int size;
	int readonly;
	int i;
	char *filename;

	if( argc < 2 )
		filename = TEXT_FILE;
	else
		filename = argv[1];

	KSInitialize();

	Dic = mmap(DIC_FILE);
	REGG_set_dictionary(Dic);
	REGG_init_udic(UDIC_FILE);

	KSStartReggFEP(handler,NULL);

	readonly = 0;
	if( stat(filename,&statbuf) == E_FS_FILE_NOT_FOUND ){
		size = FILE_SIZE * 128;
		if( creat(filename,6,FILE_SIZE) != E_FS_SUCCESS ){
			KSWriteStringToConsole(
					"容量不足のため\nセーブ不可能です");
			readonly = 1;
		}
	}else{
		size = statbuf.count * 128;
	}

	Text = KSCreateTextArea(1,0,24,11,size,NULL,NULL);
	KSRegistWindow(&Text->win);

	KSStartReggFEP(handler,Text);

	KSEnableCursor(1);

	KSTextAreaDisplay(Text,0);
	if( readonly == 0 ){
		len = 0;
		fd = open(filename,FMODE_R,0);
		if( fd >= 0 ){
			while( read(fd,&c,1) == 1 ){
				code = c;
				if( code & 0x80 ){
					read(fd,&c,1);
					code = code << 8 | c;
				}
				if( (code & 0xff) == KEYCODE_FILEEND )
					break;

				Code[len++] = code;
				if( len == 127 ){
					Code[127] = 0; 
					len = 0;
					if( KSTextAreaInsert(Text,Code) == 0 )
						break;
				}
			}
			close(fd);
			if( len > 0 ){
				Code[len] = 0;
				KSTextAreaInsert(Text,Code);
			}

			while( KSTextAreaBackward(Text) )
				;
		}else{
			KSWriteStringToConsole(
					"ファイルエラー\nセーブ不可能です");
			readonly = 1;
		}
	}
	KSTextAreaDisplay(Text,1);

	KSMainLoop();

	REGG_save(UDIC_FILE);

	if( readonly == 0 ){
		KSTextAreaDisplay(Text,0);
		while( KSTextAreaForward(Text) )
			;
		fd = open(filename,FMODE_W,0);
		if( fd < 0 )
			return 1;

		len = 0;
		src = Text->buf;
		dst = (unsigned char*)Code;
		while( src < Text->pos1 ){
			if( *src & 0x8000 )
				*dst++ = *src >> 8;
			*dst++ = *src & 0xff;
			src++;
			i = dst - (unsigned char*)Code;
			if( i > 120 ){
				write(fd,(unsigned char far*)Code,i);
				len += i;
				dst = (unsigned char*)Code;
			}
		}
		i = dst - (unsigned char*)Code;
		len += i;
		if( len < size ){
			*dst = KEYCODE_FILEEND;
			i++;
		}
		write(fd,(unsigned char far*)Code,i);

		close(fd);
	}

	return 0;
}
