/*

MercuryInstaller メニュールーチン

*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<farstr.h>

#include"mercury.h"
/*---------------------------------定数--------------------------------------*/
#define	KEYWORD_ONELINE		4	/* 1行に表示するキーワードの数       */
#define	KEYWORD_LINENUM		(CEIL(MEMBERSOF(Keyword),KEYWORD_ONELINE))
					/* 画面上でキーワード表示に使う行数  */
#define	KEYWORD_STARTYPOS	3	/* キーワード表示開始番号            */
#define	KEYWORD_XWIDTH		(CON_XWIDTH/KEYWORD_ONELINE)
					/* ひとつのキーワードの表示幅        */
#define	TABLE_STARTYPOS		(KEYWORD_STARTYPOS+KEYWORD_LINENUM+1)
					/* 候補リストの表示開始位置          */
#define	TABLE_LINENUM		(CON_YWIDTH-TABLE_STARTYPOS)
					/* 候補リストの行数                  */
/*------------------------------グローバル変数-------------------------------*/
static	struct DATA far	**Table;	/* 候補リスト                        */

static	int	Table_num;		/* 候補作品数                        */
static	int	Table_cursoroffset;	/* 候補リストの中のカーソルの表示位置*/
static	int	Table_cursorstart;	/* 表示されている作品の実際の番号    */

static	KEYWORD_T Selected_keyword;	/* 選択されたキーワード              */
static	int	Keyword_cursorpos;	/* キーワード表示の中のカーソルの位置*/
/*---------------------------候補リストの画面表示----------------------------*/
#define	table_screeninit() do	/* インライン関数 */	\
{							\
	int	i;					\
	for	(i=0 ; i<TABLE_LINENUM ; i++)		\
		showtable(i);				\
} while(0)						\

static	void	showtable(int offset)
{
	char	buf[80];

	printf("\033[%d;1f",TABLE_STARTYPOS+offset);

	if	(Table_cursoroffset==offset)
		printf("\033[7m");

	if	(Table_cursorstart+offset<Table_num)
	{
		far_strcpy(buf,Table[Table_cursorstart+offset]->title);
		printf("%-*s",TITLEWIDTH,buf);
		far_strcpy(buf,Table[Table_cursorstart+offset]->make);
		printf("%-*s",MAKEWIDTH,buf);
	}
	else
		printf("\033[2K");

	printf("\033[0m");
}

static	void	table_scrollup(void)	/* Table_cursoroffset==0と仮定 */
{
	if	(Table_cursorstart==0)
		return;

	Table_cursoroffset = -1;
	showtable(0);

	Table_cursorstart--;
	printf("\033[%d;1f",TABLE_STARTYPOS);

	if	(Flag_isfmesc)	printf("\033E");
	else			printf("\033[L");

	printf("\033[%d;1f\033[2K",TABLE_STARTYPOS+TABLE_LINENUM);

	Table_cursoroffset = 0;
	showtable(0);
}

static	void	table_scrolldown(void)	/*Table_cursoroffset==TABLE_LINENUM-1*/
{					/*と仮定                             */
	if	(Table_cursorstart+1>=Table_num)
		return;

	Table_cursoroffset = -1;
	showtable(TABLE_LINENUM-1);

	Table_cursorstart++;
	printf("\033[%d;1f",TABLE_STARTYPOS);

	if	(Flag_isfmesc)	printf("\033R");
	else			printf("\033[M");

	Table_cursoroffset = TABLE_LINENUM-1;
	showtable(TABLE_LINENUM-1);
}
/*---------------------------候補リストを初期化------------------------------*/
static	void	init_table(void)
{
	struct	DATA	far	*p;

	Table_num = 0;

	printf("\033[%d;1fしばらくお待ちください",CON_YWIDTH);

	for	(p=Data ; p!=NULL ; p=p->next)
	{
		if	((p->keywords&Selected_keyword)!=Selected_keyword)
			continue;

		if	(patternmatch(p->title) || patternmatch(p->make))
			Table[Table_num++] = p;
	}

	printf("\033[2K");

	Table_cursorstart = 0;
	if	(Table_cursoroffset>0)
		Table_cursoroffset = 0;

	table_screeninit();
}
/*------------------------------キーワードの表示-----------------------------*/
static	void	showkeyword(int n)
{
	printf("\033[%d;%df",n/KEYWORD_ONELINE+KEYWORD_STARTYPOS,
				n%KEYWORD_ONELINE*KEYWORD_XWIDTH+1);

	if	(n==Keyword_cursorpos)	putchar('<');
	else				putchar(' ');

	if	(Selected_keyword & (1UL<<n))
		printf("\033[7m");

	printf("%-*s\033[0m",KEYWORD_XWIDTH-2,Keyword[n]);

	if	(n==Keyword_cursorpos)	putchar('>');
	else				putchar(' ');
}
/*----------------------------画面全体の初期化-------------------------------*/
static	void	menu_screeninit(void)
{
	int	i;

	showcursor(0);

	printf("\033[2JMercuryInstaller Version " VERSION "  Copyright (c) Delmonta "__DATE__);

	for	(i=0 ; i<Keywordnum ; i++)
		showkeyword(i);

	printf("\033[7;36m\033[%d;1f%-*s\033[7;37m \033[7;36m%-*s\033[0m",
		TABLE_STARTYPOS-1,TITLEWIDTH-1,"作 品 名",MAKEWIDTH,"作 者");
}
/*--------------------------------検索機能-----------------------------------*/
static	void	menu_search(void)
{
	static	char	pattern[64] = "";
	auto	char	buf[64];

	strcpy(buf,pattern);

	showcursor(1);
	printf("\033[%d;1f検索する文字列>",CON_YWIDTH);
	if	(ds_strinput(buf,sizeof(buf)-1))
	{
		strcpy(pattern,buf);
		patternmatch_init(pattern);
		init_table();
	}

	showcursor(0);
	printf("\033[%d;1f\033[2K",CON_YWIDTH);
					/* これは本来は不要だが､モジュールの */
					/* 独立性を保つという意味で書いておく*/
}
/*-------------------------候補の中から作品を選択----------------------------*/
static	void	select(void)
{
	static	int	cursoroffset_save = 0;

	int	keypos_save = Keyword_cursorpos;

	Keyword_cursorpos = -1;
	showkeyword(keypos_save);

	if	(Table_num==0)
	{
		putchar('\a');
		return;
	}

	Table_cursoroffset = cursoroffset_save;
	showtable(Table_cursoroffset);

	while	(1)
	{
		switch	(ds_getch())
		{
		case FKEY_UP:
			if	(Table_cursoroffset>0)
			{
				showtable(Table_cursoroffset--);
				showtable(Table_cursoroffset);
			}
			else
				table_scrollup();

			break;
		case FKEY_DOWN:
			if	(Table_cursoroffset<TABLE_LINENUM-1)
			{
				showtable(Table_cursoroffset++);
				showtable(Table_cursoroffset);
			}
			else
				table_scrolldown();

			break;
		case FKEY_RIGHT:
			Table_cursorstart += TABLE_LINENUM;
			if	(Table_cursorstart>=Table_num)
				Table_cursorstart = Table_num-1;

			table_screeninit();
			break;
		case FKEY_LEFT:
			Table_cursorstart -= TABLE_LINENUM;
			if	(Table_cursorstart<0)
				Table_cursorstart = 0;

			table_screeninit();
			break;
		case FKEY_CR:
			if	(Table_cursorstart+Table_cursoroffset>=Table_num)
				break;

			textviewer(Table[Table_cursorstart+Table_cursoroffset]);
			menu_screeninit();
			table_screeninit();
			break;
		case FKEY_F1:
			menu_search();
			break;
		case FKEY_ESC:
		case FKEY_F10:
			cursoroffset_save = Table_cursoroffset;
			Table_cursoroffset = -1;
			showtable(cursoroffset_save);
			Keyword_cursorpos = keypos_save;
			showkeyword(Keyword_cursorpos);
			return;
		}
	}
}
/*-------------------------メニューのメインルーチン--------------------------*/
extern	void	menu(void)
{
	int	c;

	if	((Table=malloc(sizeof(*Table)*Datanum))==NULL)
	{
		printf("メモリ不足です.\n");
		exit(1);
	}

	menu_screeninit();
	init_table();

	while	(1)
	{
		switch	(ds_getch())
		{
		case FKEY_UP:
			if	(Keyword_cursorpos>=KEYWORD_ONELINE)
			{
				showkeyword(Keyword_cursorpos-=4);
				showkeyword(Keyword_cursorpos+4);
			}
			break;
		case FKEY_DOWN:
			if	(Keyword_cursorpos<Keywordnum-KEYWORD_ONELINE)
			{
				showkeyword(Keyword_cursorpos+=4);
				showkeyword(Keyword_cursorpos-4);
			}
			break;
		case FKEY_RIGHT:
			if	(Keyword_cursorpos<Keywordnum-1)
			{
				showkeyword(Keyword_cursorpos++);
				showkeyword(Keyword_cursorpos);
			}
			break;
		case FKEY_LEFT:
			if	(Keyword_cursorpos>0)
			{
				showkeyword(Keyword_cursorpos--);
				showkeyword(Keyword_cursorpos);
			}
			break;
		case ' ':
			Selected_keyword ^= 1UL<<Keyword_cursorpos;
			showkeyword(Keyword_cursorpos);
			init_table();
			break;
		case FKEY_F10:
		case FKEY_ESC:
		case FKEY_BREAK:
			if	((c=putmessage("終了しますか(y/n)"))=='Y' ||
							c=='y')
			{
				showcursor(1);
				printf("\033[2J");
				exit(0);
			}
			break;
		case FKEY_CR:
			select();
			break;
		}
	}
}
/*------------------------------ End of MENU.C ------------------------------*/
