/*

dmrename.c -- Renameコマンド

*/

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<dos.h>
#include"dmove86.h"

/*-------------------------------グローバル変数------------------------------*/
static	struct	FILEDATA
{
	char	name[13];
	int	attr;
	int	time[6];
} File;

static	int	Pos;
static	int	No;
/*-------------------DIRENTRY構造体をFILEDATA構造体にコピー------------------*/
static	void	mkcopy(void)
{
	unsigned	i;

	File.attr = Dirtbl[No]->attr;

	i = Dirtbl[No]->date;
	File.time[0] = ((i>>9)+80) % 100;
	File.time[1] = (i>>5) & 15;
	File.time[2] = i & 31;

	i = Dirtbl[No]->time;
	File.time[3] = i >> 11;
	File.time[4] = (i>>5) & 63;
	File.time[5] = (i & 31) << 1;

	for	(i=0 ; i<8 ; i++)
	{
		File.name[i] = Dirtbl[No]->filename[i];
		if	(File.name[i]=='\x05')
			File.name[i] = '\xe5';
	}

	if	(File.attr & _A_VOLID)
	{
		for	(i=0 ; i<3 ; i++)
			File.name[i+8] = Dirtbl[No]->extname[i];

		File.name[11] = '\0';
	}
	else
	{
		File.name[8] = '.';
		for	(i=0 ; i<3 ; i++)
			File.name[i+9] = Dirtbl[No]->extname[i];

		File.name[12] = '\0';
	}
}
/*--------------------------画面にデータを表示する---------------------------*/
static	void	showdata(int p)
{
	if	(p==Pos)
		printf("\033[7m");

	if	(p==0)
		printf("\033[23;3f%-12s\033[23;3f",File.name);
	else if	(p<=6)
	{
		printf("\033[23;%df",16+p);

		if	(File.attr & (64>>p))
			putchar(" ADVSHR"[p]);
		else
			putchar('-');

		putchar('\b');
	}
	else
		printf("\033[23;%df%2d",p*3+4,File.time[p-7]);

	printf("\033[0m");
}
/*-----------------------画面のカーソルを表示／消去する----------------------*/
static	void	putcursor(int f)
{
	printf("\033[19;1f" "\033[%dv" "\033[>1%c\033[2K",
					!f,(f?'l':'h'));
}
/*----------------------File.nameにファイル名を設定する----------------------*/
void	filename_expand(char *buf)
{
	char		fcb[12];
	int		i;
	union	REGS	reg;

	reg.x.ax = 0x2900;
	reg.x.si = (unsigned)buf;
	reg.x.di = (unsigned)fcb;
	int86(0x21,&reg,&reg);

	if	(reg.h.al!=0)	/* ワイルドカードが含まれる? */
		return;

	for	(i=0 ; i<8 ; i++)
		File.name[i] = fcb[i+1];

	File.name[9] = '.';

	for	(i=0 ; i<3 ; i++)
		File.name[i+9] = fcb[i+9];

	File.name[12] = '\0';
}
/*----------------FILEDATA構造体からDIRENTRY構造体に書き戻す-----------------*/
static	void	restore(void)
{
	/* データは正しいと仮定し、ここではエラーチェックはいっさいしない */

	Dirtbl[No]->attr = File.attr;
	Dirtbl[No]->date = ( (File.time[0]+20)%100 << 9 )
				 + (File.time[1]<<5) + File.time[2];
	Dirtbl[No]->time = (File.time[3]<<11) + (File.time[4]<<5) 
				+ (File.time[5]>>1);

	if	(File.attr & _A_VOLID)
	{
		int	i;
		for	(i=0 ; i<11 ; i++)
			Dirtbl[No]->filename[i] = File.name[i];
	}
	else
	{
		int	i;

		for	(i=0 ; i<8 ; i++)
			Dirtbl[No]->filename[i] = File.name[i];

		for	(i=0 ; i<3 ; i++)
			Dirtbl[No]->extname[i] = File.name[9+i];
	}

	if	(Dirtbl[No]->filename[0]=='\xe5')
		Dirtbl[No]->filename[0] = '\x05';
}
/*-------タイムスタンプの入力データが正しい範囲におさまっているか調べる------*/
static	int	islegalnumber(int a)
{
	switch	(Pos)
	{
	case 7:	a = (a>=0 && a<100);	break;
	case 8:	a = (a>=1 && a<=12);	break;
	case 9:	a = (a>=1 && a<=31);	break;
			/* 4月30日など存在しない日付も認めてしまう(^_^;) */
	case 10:a = (a>=0 && a<24);	break;
	case 11:a = (a>=0 && a<60);	break;
	case 12:a = (a>=0 && a<60);	break;
	}

	return a;
}
/*--------------------------------メインルーチン-----------------------------*/
int	dmrename(unsigned no)
{
	char	buf[13];
	char	c;
	int	i;

	No = no;
	mkcopy();

	Pos=0;
	printf("\033[23;25f  /  /     :  :    %10ldbytes\n",
					Dirtbl[no]->filesize);

	for	(i=12 ; i>=0 ; i--)	/* 最後にファイル名を表示するため */
		showdata(i);		/* 後ろから順に出力 */

rep:
	c = dm_getch();
	if	(c==RIGHTKEY && Pos<12)
	{
		showdata(Pos++);
		showdata(Pos);
		goto rep;
	}
	else if	(c==LEFTKEY && Pos>0)
	{
		showdata(Pos--);
		showdata(Pos);
		goto rep;
	}
	else if	(c=='\033')
	{
		printf("\033[23;1f\033[2K");
		return 0;
	}
	else if	(c=='\r')
	{
		restore();
		printf("\033[23;1f\033[2K");
		return 1;
	}

	else if	(Pos==0)	/* ファイル名 */
	{
		if	(iscntrl((unsigned char)c))
			goto beep;
		if	(File.name[0]=='.')	/* "." ".."は名前変更不可 */
			goto beep;

		buf[0] = '\0';
		dm_ungetch(c);

		putcursor(1);
		printf("\033[23;3f");

		if	(strinput(buf,12))
		{
			if	(File.attr & _A_VOLID)
				sprintf(File.name,"%-11.11s",buf);
			else
				filename_expand(buf);
		}

		putcursor(0);
	}
	else if	(Pos<=6)	/* 属性 */
	{
		if	(Pos==2 || Pos==3)	/* _A_SUBDIR/_A_VOLIDビット */
			goto beep;

		if	(c==UPKEY)
			File.attr |= 64>>Pos;
		else if	(c==DOWNKEY)
			File.attr &= ~(64>>Pos);
		else
			goto beep;
	}
	else			/* タイムスタンプ */
	{
		if	(iscntrl((unsigned char)c))
			goto beep;

		dm_ungetch(c);
		buf[0] = '\0';

		putcursor(1);
		printf("\033[23;%df",Pos*3+4);

		if	(strinput(buf,2))
		{
			int	a = atoi(buf);

			if	(islegalnumber(a))
				File.time[Pos-7] = a;
		}

		putcursor(0);
	}
	showdata(Pos);
	goto rep;
beep:
	putchar('\a');
	goto rep;
}
