/*
	ppgdisp.c
	tab=8
	1994/11/24 padpage.c より分割
	1994/11/27 ファイル読み込みを分割
	1994/11/28
	1995/02/19
*/

#define PPGDISP
#include "padpage.h"

/* sjis 上位:81h-9fh e0h-efh 下位:3fh-fbh !7fh */
#define isk1(c) ( 0x81<=(c) && (c)<=0x9f || 0xe0<=(c) && (c)<=0xef )
#define isk2(c) ( 0x3f<=(c) && (c)<=0xfb && (c) != 0x7f )
#define isck(x,c) (x==0)?(isk1(c)?1:0):(x==1)?2:(x==2)?(isk1(c)?1:0):0;

#define ENDLINE 27

static int linep[MAXLINE];			/* 行ポインタ */
static byte rlinebuf[21][200];			/* 表示用ラインバッファ */


int setline( int ls ){	/* 表示バッファセット */

	static int lb = 0;	/* 前回のls , lc 終了値 */
	static int ll = 0;	/* 最終行 */
	byte k1 = 0;		/* 文字種 */
	int cc = 0;		/* カウンタ */
	int lc,clm,fl;
	byte *lp,c,crf;

	if( mp_eof && ls >= ll ) return( ll );
	if( ls == 0 || lb == ls ) return( ll );
	if( ls < 0 ){			/* 再初期化 */
		lb = ll = 0;
		mp_eof = 0;
	}
/* 	mp_eof = 0; */
	if( lb == 0 ){
		ls = 1;
		linep[ls] = 0;
	}
	if( lb < ls ){ /* ↓ */
		if( lb == 0 ) lc = ls;
		else lc = ( ls - lb ) > maxdisp ? ls : lb + maxdisp ;
		lb = ls + maxdisp;
		if( lc < ll ){
			cc = linep[lc];
		} else {
			cc = linep[ll];
		}
	}else{ /* ↑ */
		cc = linep[ls];
		lc = ls;
		lb = (( lb - ls ) > maxdisp ) ? ls + maxdisp : lb ;
	}
	clm = 0;
	lp = rlinebuf[ lc % maxdisp ];
	while( lc < lb ){
		if( lc >= MAXLINE ){
			mp_eof = 4;		/* ラインオーバー */
			break;
		}
		/* バッファから1文字コピー */
		if( ( fl = getbuff( fp,cc++,&c ) ) != NULL ) {
			mp_eof = fl;
			*(lp + clm) = NULL;
			*rlinebuf[(lc+1) % maxdisp] = ENDLINE;
			linep[lc+1] = cc;
			ll = lc;
			break;
		}
		k1 = isck(k1,c); /* 文字種判定 */
		switch ( c ) {
		case '\t' :
		/* タブの展開 */
			do{
				*(lp + clm++) = ' ';
				if( clm > MAXCLM ){
					crf = ON;
					break;
				}
			} while( ( clm % tabs ) != 0 );
			break;
		case '\33' :
		/* エスケープシーケンス */
			*(lp + clm++) = ' ';
			break;
		case '\r' :
			*(lp + clm++) = NULL;
			if( clm < MAXCLM ) crf = ON;
		case '\n' :
		case 0x7f :
		case 0xff :
			break;
		default:
			if( c < ' ' ) break;
			/* 2バイト文字行端処理 */
			if( clm == MAXCLM && k1 == 1 ){
				cc--;
				crf = ON;
				break;
			}
			*(lp + clm++) = c;
		}
		if( clm > MAXCLM ) crf = ON;
		if( crf == ON ){
			crf = OFF;
			*(lp + clm) = NULL;
			clm = 0;
			lp = rlinebuf[(++lc) % maxdisp];
			if( lc > ll ){
				ll = lc;
				linep[lc] = cc;
			}else{
				cc = linep[lc];
			}
		}
	}
	lb = ls;
	/* 戻り値は最終行 */
	return( ll );
}


int dsppage( int ls, int ll ){	/* 1ページ表示 */

	static const char *footmes[] = {	/* フットメッセージ */
		" --- EOF --- ",
		" --- MEMORY FULL --- ",
		" --- BUFFUR FULL --- ",
		" --- LINE OVER --- "
	};
	static int lb = 0 ;
	int i,f;

	if( ll > 0 ){ /* ll <= 0 再表示 */
		/* line no. 表示 */
		cprintf(ESCSQU"1;65H"ESC_SB" line %4d/%4d "ESC_reset,ls,ll-1);
		if( lb == ls || ls < 1 || ll <= ls ) return ls ;
	}
	lb = ls;
	for( i = ls ; f = ( i < ( ls + maxdisp )) ; i++ ){
	/* １行表示 */
		if( *rlinebuf[i % maxdisp] == ENDLINE ){
			cprintf(ESCSQU"%d;1H"ESC_el0, ((i-ls) % maxdisp)+3);
			break;
		}
		cprintf( ESCSQU"%d;1H%s"ESC_el0,
			((i-ls) % maxdisp)+3, rlinebuf[i % maxdisp]);
	}
	/* foot disp */
	if( f ){ /* break ? */
		i = (i-ls) % maxdisp + 3;
		cprintf( ESCSQU"%d;1H"ESC_SBr"%s"ESC_reset ESC_clr0,
			i , footmes[mp_eof-1]);
	}
	return( ls );

}


int ppgscroll( char a, int s ){	/* auto scroll */
		
	static const char *ar[2] = { "↑↑↑","↓↓↓" };
	int i,d,rr = 0;
	int l,ll=1;

	if( a == '+' ){
		i = 0; d = 1;
	}else
	if( a == '-' ){
		i = 1; d = -1;
	}else
		return s;

	cprintf( ESCSQU"2;30H"ESC_BLi"%s scroll %s"ESC_reset,ar[i],ar[i]);
	for( i = s ; i > 0 ; i += d ){
		rr = dsppage( i,l = setline( i ) );
		if( inkey() != NULL ) break;
		if( mp_eof == NULL ){
			ll = setline( ( ll < l ) ? l : ll );
		} /* else {
			if( mp_eof && rr > ll ) break;
		} */
		wait(sclw);
	}
	cputs( ESCSQU"2;1H"ESC_el0 );
	return ( i + d );			/* 終了時の表示開始行 */
}
