#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <jctype.h>
#include    <dos.h>
#include    "dir.h"
#include    "tree.h"

#define TRUE		1
#define FALSE		0
#define ERR		(-1)

#define	STRLEN		256

static	char	tree_buff[STRLEN + 2];

/**************
gDIR1
egDIR2...
ebDIR3...
bDIR4
**************/

char	*pathtree(DIRTREE *dp)
{
    if ( dp == NULL ) {
	strcpy(tree_buff, "\\");
	return tree_buff;
    }

    if ( dp->root == NULL )
	tree_buff[0] = '\0';
    else
	pathtree(dp->root);

    strcat(tree_buff, "\\");
    strcat(tree_buff, dp->name);

    return tree_buff;
}
static	void	subtree(DIRTREE *dp)
{
    if ( dp == NULL )
	tree_buff[0] = '\0';
    else {
	subtree(dp->root);
	strcat(tree_buff, (dp->next != NULL ? "e" : "  "));
    }
}
char	*strtree(DIRTREE *dp)
{
    subtree(dp->root);
    strcat(tree_buff, (dp->next == NULL ? "b" : "g"));
    strcat(tree_buff, dp->name);
    if ( !dp->flag )
	strcat(tree_buff, "c");
    return tree_buff;
}
void	closetree(DIRTREE *dp)
{
    DIRTREE *tp;

    while ( dp != NULL ) {
	closetree(dp->child);
	tp = dp->next;
	free(dp);
	dp = tp;
    }
}
DIRTREE	*opentree(DIRTREE *top)
{
    DIR *dir;
    DIRECT *dp;
    DIRTREE *tp;
    DIRTREE *np;
    DIRTREE *bp = NULL;

    if ( (dir = opendir(pathtree(top), 0)) == NULL )
	return top;

    while ( (dp = readdir(dir)) != NULL ) {
	if ( root_check(dp->d_name) || !IS_DIR(dp) )
	    continue;
	if ( (tp = (DIRTREE *)malloc(sizeof(DIRTREE))) == NULL ) {
	    message("opentree malloc error");
	    break;
	}

	tp->next = tp->child = tp->link = NULL;
	tp->root = top;
	tp->flag = FALSE;
	strcpy(tp->name, dp->d_name);

	if ( bp == NULL )
	    bp = tp;
	else
	    np->next = np->link = tp;
	np = tp;
    }

    closedir(dir);

    if ( top != NULL ) {
	top->flag = TRUE;
	top->child = bp;
	if ( (tp = bp) != NULL ) {
	    while ( tp->link != NULL )
		tp = tp->link;
	    tp->link = top->link;
	    top->link = bp;
	}
    } else
	top = bp;

    return top;
}
int	menutree(int x, int y)
{
    DIRTREE *top = NULL;
    DIRTREE *dp;
    int rc = FALSE;
    int no = 0;
    int n, max;
    char **av;

    if ( (top = opentree(top)) == NULL )
	return ERR;

    while ( rc == FALSE ) {
	dp = top;
	for ( max = 1 ; dp != NULL ; max++ )
	    dp = dp->link;

	if ( (av = (char **)malloc(sizeof(char *) * (max + 1))) == NULL )
	    return ERR;

	sprintf(tree_buff, "%c:\\", _getdrive() + 'A' - 1);
	av[0] = strdup(tree_buff);

	dp = top;
	for ( n = 1 ; n < max ; n++ ) {
	    av[n] = strdup(strtree(dp));
	    dp = dp->link;
	}
	av[n] = NULL;

	if ( (no = menu(x, y, no, av)) < 0 )
	    rc = ERR;
	else {
	    if ( no == 0 ) {
		chcwdir("\\");
		rc = TRUE;
	    }
	    dp = top;
	    for ( n = 1 ; n < no ; n++ )
		dp = dp->link;
	    if ( dp->flag ) {
		chcwdir(pathtree(dp));
		rc = TRUE;
	    } else {
		opentree(dp);
/***********************************************
		if ( dp->child == NULL ) {
		    chcwdir(pathtree(dp));
		    rc = TRUE;
		}
************************************************/
	    }
	}

	for ( n = 0 ; n < max ; n++ )
	    free(av[n]);
	free(av);
    }

    closetree(top);

    return FALSE;
}
