/*************************************************************************
*	プログラミングヘルパ
*************************************************************************/

char	   *MACROKEY_PGHELP_PATH = "ProgHelp_path";
char	   *_PGHELP_FN = "_index";

#define	_PGHELP_HASH_MAX		(16)
#define	_PGHELP_SIZ_FNINF		(16)

#define	_PGHELP_SIZ_TAG			(40)	/* タグサイズ					*/
#define	_PGHELP_SIZ_FNC			(28)	/* タグ格納する関数名の長さ		*/
#define	_PGHELP_POS_FNC			(_PGHELP_SIZ_TAG - _PGHELP_SIZ_FNC)
										/* タグ中の関数名格納位置		*/

int		_pgHelp_hash(char *name)
{
	int			hash, ch;

	hash = 0;
	while ( *name )
	{
		ch = (*name) & 0xFF;
		hash = hash + (ch * 31);
		++name;
	}
	return (hash & (_PGHELP_HASH_MAX-1));
}

int		_pgHelp(char *name)
{
	char	   *path, fnIndex[256], fn[256];
	char	   *fpIndex, *fp;
	int			ret, hash, numfn, n, ch, i;
	char		*s, *p, buf[BUFSIZ];
	char	   *fntbl, fninf[_PGHELP_SIZ_FNINF];
	char		tag[_PGHELP_SIZ_TAG+4], func[_PGHELP_SIZ_FNC+4];

	char		fbuf[64];
	long		fpos;

	int			x0, y0;
	char	   *dlg;
	char	   *txtPtr;

	DSP_writePage(1);
	x0 = y0 = DLGPOS_CENTER_OF_SCN;
	txtPtr = NULL;

	hash = _pgHelp_hash(name);
	if ( (path = AMAC_getName( SysMacro, MACROKEY_PGHELP_PATH)) == NULL )
	{
		sprintf(buf, "%sMANUAL/", AplGetStartPath() );
		AMAC_setKey( SysMacro, MACROKEY_PGHELP_PATH, buf );
		if ( (path = AMAC_getName( SysMacro, MACROKEY_PGHELP_PATH)) == NULL )
			return (ERR);
	}

	/* インデックファイル名の取得	------------------------------------*/
	sprintf( fnIndex, "%s%s.%03d", path, _PGHELP_FN, hash );
	if ( (fpIndex = fopen(fnIndex,"rb")) == NULL )
	{
		DLG_tmpMsgTime( DLGPOS_MOS_SET_CENTER, DLGPOS_MOS_SET_CENTER,
		    C_MBLACK, C_DLGBASE, COLMIX(C_ERROR,C_GRAY),
		    3, "  %s : \n  Can't open index file!! ", fnIndex );
		return (ERR);
	}

	ret = 0;
	for(;;)
	{
		if ( fread(tag,_PGHELP_SIZ_TAG,1,fpIndex) < 1 )	/* ファイル位置情報	*/
		{
			ret = -1;
			break;
		}
		if ( strncmp( name, tag + _PGHELP_POS_FNC, _PGHELP_SIZ_FNC) == 0 )
			break;
	}
	fclose(fpIndex);

	if ( ret )
	{	/* 指定の検索パターンはない	*/
		DLG_tmpMsgTime( DLGPOS_MOS_SET_CENTER, DLGPOS_MOS_SET_CENTER,
		    C_MBLACK, C_DLGBASE, COLMIX(C_ERROR,C_GRAY),
		    3, "  %s : \n  Pattern not found!! ", name );
		return (ERR);
	}

	/* ファイル名テーブルの読み込み	------------------------------------*/
	sprintf( fnIndex, "%s%s.tbl", path, _PGHELP_FN );
	if ( (fpIndex = fopen(fnIndex,"rb")) == NULL )
	{
		DLG_tmpMsgTime( DLGPOS_MOS_SET_CENTER, DLGPOS_MOS_SET_CENTER,
		    C_MBLACK, C_DLGBASE, COLMIX(C_ERROR,C_GRAY),
		    3, "  %s : \n  Can't open index file!! ", fnIndex );
		return (ERR);
	}
	fpos = tag[0] * _PGHELP_SIZ_FNINF;
	fseek(fpIndex,fpos,SEEK_SET);
	fread(fninf,_PGHELP_SIZ_FNINF,1,fpIndex);
	fclose(fpIndex);

	if ( fninf[0] != tag[0] )	/* ファイル番号が一致しない	*/
		return (ERR);

	sprintf(fn,"%s%s", path, fninf + 1);
	if ( (fp = fopen(fn,"rb")) == NULL )
	{
		DLG_tmpMsgTime( DLGPOS_MOS_SET_CENTER, DLGPOS_MOS_SET_CENTER,
		    C_MBLACK, C_DLGBASE, COLMIX(C_ERROR,C_GRAY),
		    3, "  %s : \n  Can't open manual file!! ", fn );
		return (ERR);
	}
	fpos = _getDword(tag + 1);
	fseek(fp,fpos,SEEK_SET);

	/* 説明内容の読み込み	--------------------------------------------*/
	fgets(buf,BUFSIZ,fp);	/* read header line */
	while ( fgets(buf,BUFSIZ,fp) != NULL )
	{
		if ( buf[0] == '.' )
			break;
		txtPtr = DLG_txtSetLinBuf( txtPtr, 8, 80, "%s", buf );
	}
	fclose(fp);

	if ( (dlg = DLG_txtOpen(x0,y0,80,20,txtPtr,0)) == NULL )
	{
		DLG_txtFreeLinBuf( txtPtr );
		return (ERR);
	}
	DLG_txtSetTitle( dlg, "PROGRAM HELPER" );
	DLG_txtSetGuideMsg( dlg, "Function : %s", name );
	DLG_txtStart( dlg );
	DLG_txtClose( dlg );
	DLG_txtFreeLinBuf( txtPtr );

	return (NORMAL);
}


/*************************************************************************
*	カーソル位置の単語の説明を見る
*************************************************************************/

int		TxdUsr_pg_help( char *txd )
{
	int			ret, ch, len;
	char		func[_PGHELP_SIZ_FNC+4];
	size_t		curLnL, curOfs;
	char	   *dlg;

	if ( TxdGet_selFlag(txd) != 0 )		/* 選択中なら処理しない	*/
		return (0);

	/* 現在カーソル位置を取得	*/
	curLnL = TxdGet_curPosLnL(txd);
	curOfs = TxdGet_curPosOfs(txd);

	if ( (ch = TXD_getch(txd)) > 0 && ch < 256 && (isalpha(ch) || ch == '_') )
	{
		len = 0;
		while( len < _PGHELP_SIZ_FNC )
		{
			ch = TXD_getch(txd);
			TXD_cmdJump( txd, TXD_CUR_RIGHT );
			if ( isalpha(ch) || isdigit(ch) || ch == '_' )
			{
				func[len++] = ch;
			} else
				break;
		}
		func[len] = '\0';
		TXD_jumpPos( txd, curLnL, curOfs );
		if ( len == 0 )
			return (NORMAL);
	} else
		func[0] = '\0';

	DSP_writePage(1);
	dlg = DLG_getsOpen( DLGPOS_MOS_SET_HOME, DLGPOS_MOS_SET_HOME, 320,
	    "検索パターンを入力してください。" );
	DLG_getsSetTitle( dlg, "PATTERN" );
	ret = DLG_getsStart( dlg, _PGHELP_SIZ_FNC, func );
	DLG_getsClose(dlg);
	if ( ret <= 0 )
		return (0);

	_pgHelp( func );

	return (0);
}
