/* μ、ソース改良版(^^;) */

#include	<stdio.h>
#include	<string.h>
#include	<ctype.h>
#include	<stdlib.h>
#include	<direct.h>
#include	<dos.h>
#include	"defs.h"
#include	"s_disk.h"
#include	"s_text.h"
#include	"replace.h"
#include	"getkey.h"


#define	iskanji(c)	( (((c)>0x80)&&((c)<0xa0)) || (((c)>0xdf)&&((c)<0xfd)) )


/* グローバル */
char	DIRECT=0;		/* １で選択時のキー入力無し */
char	ext[5];			/* 対象となる拡張子 */
char	ext2[6];		/* 細工付き */
char	path[65];		/* カレントパス名 */
char	_asm_(char *);	/* アセンブリインライン関数用 */
char	ex[MAX_CAP][512];	/* 実行文字列用バッファ */
char	PROG[13];		/* このプログラムの名前 */
char	DC[10][100];	/* $Cnと置換される文字列格納用 */
char	DX[10][100];	/* $Xnと置換される文字列格納用 */
char	DCnum=0;		/* $Cnに指定される文字列の数 */
FILE	*fp;
char	repc[10][4]={"$C0","$C1","$C2","$C3","$C4","$C5",
					 "$C6","$C7","$C8","$C9"};
char	repx[10][4]={"$X0","$X1","$X2","$X3","$X4","$X5",
					 "$X6","$X7","$X8","$X9"};



/* 使用法の表示 */
void	usage()
{
		printf("USAGE: mu [-f\x22filename\x22] filename1 filename2 ...  \n");
		printf("\n*****オプション\n");
		printf("-f[filename] ... CFGファイルの指定\n");
		printf("-d ... 選択時のキー入力待ち無し\n");
		printf("\n例： mu -fd:\\mu.cfg mu.doc mu.txt\n");
		printf("(cfgファイルとしてd:\\mu.cfgを使い、$C0はmu.docと、$C1はmu.txtに置換され、*.docの定義を参照する。)\n");
		return;
}




/* 拡張子を得る */
int		MU_getExtName(char *arg1)
{
	char	e[80];
	
	DSK_getExtName(arg1,e);
	if (strlen(e)>3)
	{
		printf("\x1b[32;1m");
		printf("なんだその拡張子名は\n");
		return(1);
	}
	DSK_tolowerFileName(e);
	ext[0]='#';
	strcat(ext,e);
	strcpy(ext2,ext);
	strcat(ext2,"\n");
	
	return(0);
}
	





/* いよいよ実行 */
int		MU_exec(char *cfg,char *bat)
{
	char	str[256];		/* fgets用バッファ */
	char	buf[512];		/* 実行用バッファ */
	char	*s;				/* 文字列を区切るときに使う */
	int		count=-1;
	int		flag=0,i;
	int		en;				/* 実行する番号 */
	char	dr[256];		/* $Rを置換する文字列 */
	int		k;				/* キーコード(7bit)格納用 */
	int		pf=0;			/* $Kがあるなら1 */
	FILE	*fp2;			/* バッチ書き出し用 */
	union 	REGS	r;		/* システムコール用レジスタ変数	*/
	struct	SREGS	sr;
	
	int		linn=0;			/* 選択肢の行数 */
	int		elin[MAX_CAP];	/* 選択肢の各行の行数 */
	int		sh;				/* シフトキーとかの状態 */
	int		sel=-1;		/* 現在カーソルの合っている選択肢 */
	
	
	if ((fp=fopen(cfg,"r"))==NULL)
	{
		printf("設定ファイルがオープン出来ません");
		return(1);
	}
	
	if ((fp2=fopen(bat,"w"))==NULL)
	{
		printf("起動ドライブが書き込み禁止になってませんか？");
		return(1);
	}
	
	
	/* 定義を検索する */
	fgets(str,255,fp);
	while(!feof(fp))
	{
		if (strcmp(str,ext2)==0)
		{	flag=1; break;	}
		if (strcmp(str,"#???\n")==0)
		{	flag=1; break;	}
		fgets(str,255,fp);
	}
	
	if (flag==0)
	{
		printf("\x1b[33;1m");
		printf("拡張子(.%s)は登録されてませんな。\n",(ext+1));
		return(1);
	}
	
	fgets(str,255,fp);
	while( (strcmp(str,"{\n")!=0))
	{
		if (feof(fp)) 
		{
			printf("\x1b[33;1m");
			printf("設定ファイルの書き方が妙だよ\n");
			return(1);
		}
		fgets(str,255,fp);
	}
	
	fgets(str,255,fp);
	while( (count<MAX_CAP-1) && (!feof(fp)) && (strcmp(str,"}\n")!=0) )
	{
		if (str[0]!='\n')
		{
			count++;
			strcpy(ex[count],str);
		}
		fgets(str,255,fp);
	}
	
	fclose(fp);
	
	
	
	if (DIRECT==0)
	{
		printf("\x1b*");		/* CLS! */
		
		/* 選択肢の表示 */
		for (i=0;i<=count;i++)
		{
			MU_replace(ex[i],"\n","");
			elin[i]= ((strlen(ex[i]))+MARG+1)/MARG;
			linn+=elin[i];
			printf("%01x:%s\n",i,ex[i]); 
		}
		
		if (count!=0)
		{
			printf("\x1b[36;1;5m");
			printf("何番を実行しますか？");
			STL_normal_color();
			STL_locate(0,0);
			
			loop:;
			for (;;)
			{
				k=KEY_getAdr();
				sh=(k & 0xff);
				k>>=8;
				
				if (isxdigit(k))
				{
					if (isdigit(k))
						k-= '0';
					else
					{
						k=_toupper(k);
						k-= 'A'-10;
					}
					if (k>=0 && k<=count);
						break;
				}
				else if (k==0x1e || k==0x0b)	/* 上 */
				{
					if (sel<=0)
						continue;
					STL_rlocate(-MARG,1-elin[sel]);
					printf("\x1b[37;0m");
					printf("%01x:%s",sel,ex[sel]);
					STL_rlocate(-MARG,-(elin[sel]+elin[sel-1]-1));
					sel--;
					printf("\x1b[33;7m");
					printf("%01x:%s",sel,ex[sel]);
				}
				else if (k==0x1f || k==0x0a)	/* 下 */
				{
					if (sel>=count)
						continue;
					if (sel!=-1)
					{
						STL_rlocate(-MARG,1-elin[sel]);
						printf("\x1b[37;0m");
						printf("%01x:%s",sel,ex[sel]);
						STL_rlocate(-MARG,1);
					}
					sel++;
					printf("\x1b[33;7m");
					printf("%01x:%s",sel,ex[sel]);
				}
				else if (k==0x0d)	/* リターン */
				{	k= (sel!=-1) ? sel : 0;	break;	}
				else if (k==0x1b)	/* ESC */
				{
					STL_normal_color();
					STL_locate(0,linn+1);
					printf("終了します\n");
					return(1);
				}
				else if ((sh & 0x14)==0x14)	/* SHIFT + CTRL */
				{	k=3;	break;	}
				else if ( sh & 0x10 )	/* CTRL */
				{	k=2;	break;	}
				else if ( sh & 0x04 )	/* SHIFT */
				{	k=1;	break;	}
			}
			en=k;
		}
		else
			en=0;
		
		if (en>count)
			goto loop;
		
		STL_locate(0,linn+1);
		printf("\n");
	}
	else
	{
		k=KEY_getAdr();
		sh=k & 0xff;
		if ((sh & 0x14)==0x14)
			k=3;
		else if (sh & 0x10)
			k=2;
		else if (sh & 0x04)
			k=1;
		else
			k=0;
		
		en= (k>count) ? count : k;
	}
	
	
	
	/* 文字列の置換 */
	if (strstr(ex[en],"$K")!=NULL)
		pf=1;
	MU_replace(ex[en],"$K","");
	MU_replace(ex[en],"$E","echo off;");
	for (i=0;i<10;i++)
	{
		MU_replace(ex[en],repc[i],DC[i]);
		MU_replace(ex[en],repx[i],DX[i]);
	}
	MU_replace(ex[en],"$P",path);
	
	
	/* マルチステートメントへの区切り */
	s=strtok(ex[en],";");
	
	while (s!=NULL)
	{
		strcpy(buf,s);
		STL_normal_color();
		if (MU_replace(buf,"$R","[33;1m$R[37;0m"))
		{
			printf("%s\n",buf);
			printf("\x1b[32;1m");
			printf("\n\x1b[33;1m$R\x1b[32;1mに入る文字列は？");
			STL_normal_color();
			
			dr[0]=250;
			r.h.ah=10;	r.x.dx=(unsigned short)dr;	segread(&sr);
			intdosx(&r,&r,&sr);
			dr[dr[1]+2]=0;
			
			MU_replace(buf,"[33;1m$R[37;0m",dr+2);
			MU_replace(buf,"\n","");
		}
		printf("%s\n",buf);
		fprintf(fp2,"%s\n",buf);
		if (pf==1)
			fprintf(fp2,"pause\n");
		s=strtok(NULL,";");
	}
	
	fclose(fp2);
}







int		main(int argc,char **argv)
{
		int		i=0;
	char	*s;				/* PROGを作るためのポインタ */
	char	bat[100];		/* 作られるバッチファイルのフルパス */
	char	bPath[100];		/* cfgファイルのフルパス */
	int		r=0;
	
	
	if (argc<2)
	{
		usage();
		return(1);
	}
	
	/* argv[0]の最後の'\'をサーチして、PROGを作る */
	for (s=argv[0]+strlen(argv[0])-1; *s!='\\' ; s--)
		;
	strcpy(PROG,s+1);
	
	/* CFGファイルをサーチ */
	label:;
	if (argv[r+1][0]=='-' || argv[r+1][0]=='/' )
	{
		if (argv[r+1][1]=='f' || argv[r+1][1]=='F' )
		{
			strcpy(bPath,&argv[1][2]);
			r++;
			goto label;
		}
		else if (argv[r+1][1]=='d' || argv[r+1][1]=='D' )
		{
			DIRECT=1;
			r++;
			goto label;
		}
		else
		{
			printf("パラメータエラーです。\n");
			return(1);
		}
	}
	else
	{
		strcpy(bPath,argv[0]);
		MU_replace(bPath,PROG,"MU.CFG");
	}
	
	strcpy(bat,argv[0]);
	MU_replace(bat,PROG,"___MU___.BAT");
	
	
	/* DC,DXの割当 */
	DCnum=argc-r-1;
	for (i=0;i<DCnum;i++)
	{
		if (strlen(argv[1+r+1])>99)
		{	printf("ファイル名が長すぎます。\n");	return(1);	}
		strcpy(DC[i],argv[i+r+1]);
		strcpy(DX[i],argv[i+r+1]);
	}
	for (i=DCnum;i<10;i++)
	{
		strcpy(DC[i],"");
		strcpy(DX[i],"");
	}
	
	/* DXの作成 */
	for (i=0;i<DCnum;i++)
	{
		s=DX[i];
		while(1)
		{
			if( (*s=='.') || (*s==0) )
				break;
			else
				s++;
		}
		*s=0;
	}
	
	/* CFGファイルを検索する際の拡張子は？ */
	if (MU_getExtName(DC[0])!=0)
		return(1);
	
	getcwd(path,64);
	
	/* ルートディレクトリ対策 */
	i=0;
	while(1)
	{
		if (path[i]=='\0')
		{
			if (i>0)
			{
				if (iskanjif(path,&path[i-1]))
					break;
				else if (path[i-1]=='\\')
				{
					path[i-1]='\0';
					break;
				}
			}
			else
				break;
		}
		i++;
	}
	
	MU_exec(bPath,bat);
	
	STL_normal_color();
	
	return(0);
}


