/*****
 NAME
 	cdir.m - source code for CDir class
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#include <coconut/cdir.h>
#include <coconut/cfile.h>
#include <coconut/cidlist.h>
#include <coconut/cconststr.h>
#include <coconut/cmemalloc.h>
#include <coconut/ptext.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>

@implementation CDir

+ (boolean) isDirExist: (const char *) name
{
	boolean	result ;
	DIR *	dirp ;

	dirp = opendir(name) ;
	if(dirp != NULL && errno == 0){
		result = (closedir(dirp) == 0) ;
	} else{
		result = FALSE ;
	}
	return result ;
}

- init
{
	path_list = [[CIdList alloc] init] ;
	max_path_len = 0 ;
	return [super init] ;
}

- (void) dealloc
{
	[path_list release] ;
	[super dealloc] ;
}

- (boolean) appendPath: (id <PBasicStr>) path
{	
	const char *	ptr ;
	u_int		len ;

	[path_list append: path] ;
printf("appendPath: %s\n", [path ptr]) ;
	if((len = strlen(ptr = [path ptr])) > max_path_len)
		max_path_len = len ;
	return [CDir isDirExist: ptr] ;
}

- (id <PConstStr>) searchFile: (const char *) fname
{
	id <PBasicStr>	dirname ;
	id <PConstStr>	result = nil ;
	char *		testpath ;
	char *		testptr ;
	char		c ;
	u_int		len ;

	/* +2 means the "/" and EOS */
	len = sizeof(char *) * (max_path_len + strlen(fname) + 2) ;
	testpath = [CMemAlloc allocate: sizeof(char *) * len] ;

	dirname = (id <PBasicStr>) [path_list moveToHead] ;
	for( ; dirname ; dirname = (id <PBasicStr>) [path_list moveNext]){
		strcpy(testpath, [dirname ptr]) ;
		/* replace EOS by "/" */
		for(testptr = testpath ; (c = *testptr) != '\0' ; testptr++)
			;
		*(testptr++) = '/' ;
		strcpy(testptr, fname) ;
		if([CFile isFileExist: testpath]){
			result = [[CConstStr alloc] init] ;
			[result setPtr: testpath] ;
			break ;
		}
	}
	[CMemAlloc free: testpath] ;
	return result ;
}

- (int) count
{
	return [path_list count] ;
}

- print: (id <PIndentStream>) stream
{
	id <PBasicStr>	dirname ;

	[stream putPtr: "(dir\n"] ;
	[stream incLevel] ;
	  dirname = (id <PBasicStr>) [path_list moveToHead] ;
	  for( ; dirname ; dirname = (id <PBasicStr>) [path_list moveNext]){
	  	[dirname print: stream] ;
		[stream putChar: '\n'] ;
	  }
	[stream decLevel] ;
	[stream putPtr: ")\n"] ;
	return nil ;
}

@end

