/*
8086|Printman/POSTCARD 設定シート
Copyright (c) 1993,94 Delmonta

*/

#include<string.h>
#include"dprint.h"

static	unsigned	Startpos;
static	struct SHEETDAT	*Sheet;
static	unsigned	Num;
static	int		*Ret;

static	unsigned	Sheet_ypos;

/*---------------------------------------------------------------------------*/

static	int	minimum(unsigned y)
{
register int	i = Sheet[y].min;

	if	(i>=SHEET_CREF(0))
		i = Ret[i-SHEET_CREF(0)];

	return i;
}

static	int	maximum(unsigned y)
{
register int	i = Sheet[y].max;

	if	(i>=SHEET_CREF(0))
		i = Ret[i-SHEET_CREF(0)];
	return i;
}

/*---------------------------------------------------------------------------*/

static	void	sheet_putchoices(unsigned y, unsigned x)
{
	struct SHEETSEL	*dat = (struct SHEETSEL *)Sheet[y].pos;

	if	(Ret[y]==x)
	{
		if	(Sheet_ypos == y)
			printf("\033[7;37m");
		else
			printf("\033[36m");
	}

	printf("\033[%u;%uH%s\033[0;37m",Startpos+y,dat[x].xpos,dat[x].mes);
}

/*---------------------------------------------------------------------------*/

static	void	sheet_putdat(unsigned y)
{

	if	(Sheet[y].type == SHEET_SELECT)
	{
		sheet_putchoices(y,Ret[y]);
	}
	else
	{
		char	buf[8];

		printf("\033[%u;18f", Startpos+y);

		if	(Sheet_ypos==y)
			printf("\033[7;37m");

		switch	(Sheet[y].type)
		{
		case SHEET_VALUE1:
			printf("%4d",Ret[y]);
			break;
		case SHEET_VALUE2:
			printf("%s",putfract(buf,Ret[y]));
			break;
		case SHEET_STRING:
			printf("%*s",-Sheet[y].max,(char *)Sheet[y].pos);
			break;		/* maxに'-'をつけないと右寄せになる */
		}
		printf("\033[0;37m");
	}
}

/*---------------------------------------------------------------------------*/

static	void	chkval(unsigned start)
{
	unsigned	i;

	for	(i=start ; i<Num ; i++)
	{
		int	s,l;

		if	(Sheet[i].type != SHEET_VALUE1
					&& Sheet[i].type != SHEET_VALUE2)
			continue;

		s = minimum(i);
		l = maximum(i);

		if	(Ret[i]<s)	Ret[i] = s;
		else if	(Ret[i]>l)	Ret[i] = l;

		sheet_putdat(i);

		if	(Sheet[i].type==SHEET_VALUE1)
		{
			printf("\033[%u;28f(%4d〜%4d)",Startpos+i,s,l);
		}
		else
		{
			char	buf[2][8];

			putfract(buf[0],s);
			putfract(buf[1],l);

			printf("\033[%u;30f(%s〜%s)",Startpos+i,buf[0],buf[1]);
		}
	}
}

/*---------------------------------------------------------------------------*/

bool	dp_sheetselect(unsigned startpos, struct SHEETDAT sheet[],
							unsigned num,int ret[])
{
	int	i,j;
	char	c;

	char	buf[64];		/* 文字列入力に使うバッファ */

	Startpos = startpos;
	Sheet    = sheet;		/* 下請け関数でも値を共用できる */
	Num      = num;			/* ようにするための配慮		*/
	Ret      = ret;

	Sheet_ypos = 0;

	for	(i=0 ; i<num ; i++)		/* 設定シートの初期化 */
	{
		printf("\033[%u;1f%-16s",Startpos+i,sheet[i].mes);

		switch	(sheet[i].type)
		{
		case SHEET_SELECT:
			for	(j=0 ; j<sheet[i].max ; j++)
				sheet_putchoices(i,j);
			break;
		case SHEET_VALUE1:
			printf("\033[36m[     ]\033[37m");
			break;
		case SHEET_VALUE2:
			printf("\033[36m[    .  ]\033[37m");
			break;
		case SHEET_STRING:
			printf("\033[36m[%62s]\033[37m","");
		}

	}

	chkval(0);
	sheet_putdat(0);

sheetsel_rep:
	c = dp_getch();

	if	(c=='\r' || c=='\033')
	{
		for	(i=startpos ; i<startpos+num ; i++)
			printf("\033[%u;1f\033[2K",i);

		return (c=='\r' ? TRUE : FALSE);
	}
	else if	(c==EXTKEY_H)
	{
		dp_getch();
	}
	else if	(c==UPKEY && Sheet_ypos>0)
	{
		sheet_putdat(Sheet_ypos--);
		sheet_putdat(Sheet_ypos  );
	}
	else if	(c==DOWNKEY && Sheet_ypos+1<num)
	{
		sheet_putdat(Sheet_ypos++);
		sheet_putdat(Sheet_ypos  );
	}
	else if	(sheet[Sheet_ypos].type==SHEET_SELECT)
	{
		if	(c==LEFTKEY && ret[Sheet_ypos]>0)
		{
			sheet_putchoices(Sheet_ypos,ret[Sheet_ypos]--);
			sheet_putchoices(Sheet_ypos,ret[Sheet_ypos]  );
		}
		else if	(c==RIGHTKEY &&
			ret[Sheet_ypos]+1 < sheet[Sheet_ypos].max)
		{
			sheet_putchoices(Sheet_ypos,ret[Sheet_ypos]++);
			sheet_putchoices(Sheet_ypos,ret[Sheet_ypos]  );
		}
		else
			putchar('\7');
	}
	else if	(c<' ')
		putchar('\7');
	else
	{
		dp_ungetch(c);

		printf("\033[%u;18f\033[0;37m",startpos+Sheet_ypos);

		switch	(sheet[Sheet_ypos].type)
		{
		case SHEET_VALUE1:
			i = dp_getval();
			if	(i!=-1)
			{
				ret[Sheet_ypos] = i;
				chkval(Sheet_ypos);
			}
			break;
		case SHEET_VALUE2:
			if	(dp_getval2(&i))
			{
				ret[Sheet_ypos] = i;
				chkval(Sheet_ypos);
			}
			break;
		case SHEET_STRING:
			strcpy(buf,(char *)sheet[Sheet_ypos].pos);
			if	(strinput(buf,sheet[Sheet_ypos].max))
				strcpy((char *)sheet[Sheet_ypos].pos,buf);
		}
		sheet_putdat(Sheet_ypos);
	}
	goto sheetsel_rep;
}

/*---------------------------------------------------------------------------*/

bool	input_st_ed(const char *mes,int *start, int *end)
{
static	struct SHEETDAT	sheet[] =
	{
		{SHEET_VALUE1,"始点",1,DUMMY,NULL},
		{SHEET_VALUE1,"終点",SHEET_CREF(0),DUMMY,NULL},
	};

	int	ret[2];

	if	(!iscardexist())
		return FALSE;

	sheet[0].max = sheet[1].max = Cardnum;
	ret[0]       = 1;
	ret[1]       = Cardnum;

	printf("\033[%d;1f%sする範囲\n",SYSLINE_START,mes);

	if	(!dp_sheetselect(SYSLINE_START,sheet,2,ret))
		return FALSE;

	*start = ret[0] - 1;	/* ユーザーにはカードは1番から始まっているよ */
	*end   = ret[1] - 1;	/* うに見せているので、0から始まるように補正 */

	return TRUE;
}
