/* メモ帳 */

#include "../api/api.h"
#include <stdio.h>

int strtol(char *s, char **endp, int base);	/* stdlib.hの関数 */

#define WIN_X	60	/* 横の文字数 */
#define WIN_Y	20	/* 縦の文字数 */
#define TAB		4	/* タブサイズ */
#define FSIZE	512	/* ファイルサイズ（k） */
#define SCR_X	1	/* 横のスクロール文字数 */
#define SCR_Y	1	/* 縦のスクロール文字数 */

char *sspace(char *p);
void tview(int win, unsigned char *p, int xskip);
char *lview(int win, unsigned char *p, int y, int xskip);
int puttab(unsigned char *s, int x, int xskip);

void HariMain(void)
{
	char wbuf[(WIN_X * 8 + 16) * (WIN_Y * 16 + 58)], tbuf[FSIZE * 1024];	/* ウィンドウバッファと256KBのテキストバッファ */
	int win, xskip = 0;					/* ウィンドウハンドルと横の移動量 */
	int i, j;
	char s[30], *p, *q = 0;

	/* ファイル名の取得 */
	p = api_getcmd(s, 30, 0);

	/* ファイルの読み込み */
	i = api_fopen(p, 'r');
	if(i == 0) {
		api_puts("このファイルは存在しません。");
		api_exit();
	}
	j = api_fsize(i, 0);
	if(j > FSIZE * 1024 - 2) {
		j = FSIZE * 1024 - 2;
	}
	tbuf[0] = 0x0a;	/* 番兵用の改行コード */
	api_fread(i, tbuf + 1, j);
	api_fclose(i);
	tbuf[j + 1] = 0;

	/* ウィンドウの準備 */
	sprintf(s, "%s - メモ帳", p);
	win = api_wopen(wbuf, WIN_X * 8 + 16, WIN_Y * 16 + 36, -1, s);

	/* メイン */
	p = tbuf + 1;
	for(;;) {
		tview(win, p, xskip);
		i = api_getd(1);
		if(i == '4') {	/* 左 */
			for(;;) {
				xskip -= SCR_X;
				if(xskip < 0) {
					xskip = 0;
				}
				if(api_getd(0) != '4') {/* 連続処理しない */
					break;
				}
			}
		} else if(i == '6') {	/* 右 */
			for(;;) {
				xskip += SCR_X;
				if(api_getd(0) != '6') {
					break;
				}
			}
		} else if(i == '8') {	/* 上 */
			for(;;) {
				for(j = 0; j < SCR_Y; j++) {
					if(p == tbuf + 1) {
						break;
					}
					for(p--; p[-1] != 0x0a; p--) { }/* 一文字前に0x0aが出るまでさかのぼる */
				}
				if(api_getd(0) != '8') {
					break;
				}
			}
		} else if(i == '2') {	/* 下 */
			for(;;) {
				for(j = 0; j < SCR_Y; j++) {
					for(q = p; *q != 0 && *q != 0x0a; q++) { }
					if(*q == 0x00) {
						break;
					}
					p = q + 1;
				}
				if(api_getd(0) != '2') {
					break;
				}
			}
		}
	}
	api_exit();
}

char *sspace(char *p)
{
	for(; *p == ' '; p++) { }	/* スペースを読み飛ばす */
	return p;
}

void tview(int win, unsigned char *p, int xskip)
{
	int i;

	api_wbox(win, COLOR_FFFFFF, 8, 29, WIN_X * 8 + 7, WIN_Y * 16 + 28);
	for(i = 0; i < WIN_Y; i++) {
		p = lview(win, p, i * 16 + 29, xskip);
	}
	api_wrefresh(win, 8, 29, WIN_X * 8 + 8, WIN_Y * 16 + 29);
	return;
}

char *lview(int win, unsigned char *p, int y, int xskip)
{
	int x = - xskip;
	char s[130];

	for(;;) {
		if(*p == 0) {	/* 終わり */
			break;
		}
		if(*p == 0x0d) {	/* 復帰 */
			p++;
		}
		if(*p == 0x0a) {	/* 改行 */
			p++;
			break;
		}
		if(*p == 0x09) {	/* タブ */
			x = puttab(p, x, xskip);
			p++;
		}
		if((0x81 <= *p && *p <= 0x9f) || (0xe0 <= *p && *p <= 0xfc)) {	/* 全角文字 */
			if(x == -1) {
				s[0] = ' ';
			}
			if(0 <= x && x < WIN_X - 1) {
				s[x] = *p;
				s[x + 1] = p[1];
			}
			if(x == WIN_X - 1) {
				s[x] = ' ';
			}
			x += 2;
			p += 2;
		} else {	/* その他文字 */
			if(0 <= x && x < WIN_X) {
				s[x] = *p;
			}
			x++;
			p++;
		}
	}
	if(x > WIN_X) {
		x = WIN_X;
	}
	if(x > 0) {
		s[x] = 0;
		api_wputs(win, COLOR_000000, 8, y, s);
	}
	return p;
}

int puttab(unsigned char *s, int x, int xskip)
{
	for(;;) {
		if(0 <= x && x < WIN_X) {
			s[x] = ' ';
		}
		x++;
		if((x + xskip) % TAB == 0) {
			 break;
		}
	}
	return x;
}
