#include	"tree.h"
#include	"treefunc.h"

char	*KeisenPtn[]={
	"    ","│  ","├─","└─",
	"    ","|   ","|---","+---" 
};

extern	keisen;
extern	depth;
extern	option;

/** 表示 **/
PutTree( dir ,tree )
Dir 	*dir;
Tree	*tree;
{
	Dir 	*newdir;
	
	if( tree==NULLP )	return NULLP;
	
	PutTree( dir,tree->left );		/* 左tree */
	
	
	if( (tree->attr & _A_SUBDIR)==0 )
	{	PutTreeLine(dir);
		PutTreeFile( tree );
	}
	else
	{	if( (option & OPT_SUM)==0)
		{	PutTreeLine(dir);
			far_put( tree->name );
		}
		newdir=(Dir *)fmalloc( sizeof(DirData) );
		
		/* path\\name\\ の形式にする */
		mk_FilePath( newdir->path, dir->path,dir->name );
		far_strcpy( newdir->name ,tree->name  );
		
		newdir->depth    = dir->depth + 1 ;
		newdir->pathdat  =(dir->pathdat <<1) | (dir->matchfile >1);
		
		
		DirTree( newdir );		/* 下のディレクトリを探索 */
		
		farfree( newdir );
	}
	dir->matchfile --;
	
	
	PutTree( dir,tree->right );		/* 右tree */
	
	farfree( tree );
}

/*** 罫線の表示 ***/
PutTreeLine(dir)
Dir 	*dir;
{
	int 	i;
	
	/* ファイル名までの経路を表示 */
	for( i=(dir->depth)-1 ; i>=0 ; i-- )
		putsn( KeisenPtn[ keisen + (dir->pathdat>>i & 1) ] );
	
	/* 最後のファイルなら線のパターンを変える */
		putsn( KeisenPtn[ keisen+2+(dir->matchfile == 1) ] );
	
}

PutSpace(dir,len)
Dir 	*dir;
int 	len;
{
	int 	i,j,pos;
	
#define	KeiLEN		4	/* 罫線の文字長 */
#define	DirSpace	3	/* ディレクトリ名と点線(?)の隙間 */
	
	i = (dir->depth+1)*KeiLEN +len;
	
	pos=(depth+1 )*KeiLEN + NAMEEXT_MAX +2 ;
	
	
	for( j=0; j<DirSpace && i+j<pos ; i++,j++)
		putchar(' ');
	for( ; i<pos ; i++)
		putchar( (i % 3 )? ' ':'-' );
}

/**** ファイル名表示 ****/
PutTreeFile( tree )
Tree	*tree;
{
	int 	i,j;
	char	tmp[ NAMEEXT_MAX+3 ];	/* name+'.'+ext+'\t'+NULL */
	
	/* ファイル名を 8+4 文字に整形 */
	for( i=0; i<NAMEEXT_MAX ; i++)
		tmp[i] = ' ';
	tmp[i++]='\t';
	tmp[i]=NULLP;
	
	for( i=0; tree->name[i] != NULLP && tree->name[i]!='.' ; i++ )
		tmp[i] = tree->name[i];
	for( j=0; tree->name[i] != NULLP ; i++,j++ )
		tmp[ NAME_MAX+j] = tree->name[i];
	
	puts( tmp );
	
}

/* ディレクトリ名の表示 */
/*
*	ret=1 のときは表示打切りのため、それ以下については
*	せっかく調べたものの、表示はしないこと。
*	
*/
int PutTreeDir(dir)
Dir 	*dir;
{
	int 	ret=0,len=0;
	
	len=far_strlen( dir->name );
	
	if( dir->depth >= depth && dir->matchfile>0 )
	{	putsn(" >");
		len += 2;
		ret = 1;
	}
	PutSpace(dir,len );
	
	PutTreeDirInfo( dir->files, dir->size );
	
	return ret;
}

PutTreeDirInfo( files,size )
unsigned long	files,size;
{
	/* 情報の表示 */
	putnumn( files ,5 );
	putchar(':');
	
	putnumn( size /1024 + ( size % 1024 >0 ), 7 );
	puts("k");
	
}



int far_put(char far *s)
{
	char	*p;
	int 	len;
	
	len=far_strlen(s);
	
	p=(char *)xmalloc(len+1);
	far_strcpy( p, s );
	putsn(p);
	free(p);
	
	return len;
}

/****************************************/
/*
*	無理やり押し込んだ合計表示関数。
*	無駄な処理だらけなのは分かっているが
*/
extern	unsigned long	allfiles;
extern	unsigned long	allsize;

unsigned int wait_pos=0;
#define		WAITPOSMAX	78
cls_wait()
{
	if( wait_pos >=WAITPOSMAX )	wait_pos=WAITPOSMAX;
	
	errputs("\r");
	
	for( ;wait_pos>0 ; wait_pos-- )
		errputs(" ");
	
	errputs("\r");
	
	wait_pos=0;
}
put_wait()
{
	wait_pos++;
	
	if( wait_pos < WAITPOSMAX )
		errputs(".");
	if( wait_pos == WAITPOSMAX )
		cls_wait();
	
}

#define		SUMDEPTH		2
#define		MAXMAXDEPTH		31

PutTreeSum( dir, tree )
Dir 	*dir;
Tree	*tree;
{
	static	unsigned long	oldfiles = 0;
	static	unsigned long	oldsize  = 0;
	static	unsigned long	rootmatch= 0; 
	int 	len=0;
	
	if( dir->depth==0 )		/* 初呼び出し */
	{	depth = SUMDEPTH;
		PutTreeDir( dir );
		depth = MAXMAXDEPTH;
		
		oldfiles = allfiles;
		oldsize  = allsize ;
		rootmatch= dir->matchfile;	/* 罫線表示に使うため保存 */
	}
	else
		put_wait();
	
	PutTree(dir,tree);
	
	
	if( dir->depth==1 )
	{	
		cls_wait();
		
		dir->matchfile = rootmatch--;
		dir->depth=0;
		PutTreeLine(dir);
		dir->depth=1;		/* 表示が狂うのでその場しのぎ(^^;) */
		
		len = far_put( dir->name )+2;
		putsn(" !");
		
		depth = SUMDEPTH;
		PutSpace( dir,len );
		PutTreeDirInfo( allfiles-oldfiles, allsize-oldsize );
		
		oldfiles=allfiles;
		oldsize =allsize ;
		depth = MAXMAXDEPTH;
	}
	
}
