
#import "Tree.h"
#import "MiscTreeFilter.h"
#import <misckit/misckit.h>

static id createMiscTree(NXStream *stream, Properties *props, NXZone *zone);
static int getNextNodeLabel(char *buffer, int n, NXStream *stream);
static const char *treeFileType = "tree";

@implementation MiscTreeFilter

+ filterWithProps:(Properties *)props inZone:(NXZone *)aZone
{
	const char *fileName;
	id openpanel = [OpenPanel new];
	NXStream *aStream;
	const char *const fileTypes[] = {treeFileType, NULL};
	id result;

	[openpanel allowMultipleFiles:NO];
	if([openpanel runModalForTypes:fileTypes]){
		fileName = [openpanel filename];
		if((aStream = NXMapFile(fileName, NX_READONLY)) == NULL){
			NXRunAlertPanel(NULL, "File %s could not be opened for reading.", NULL, NULL, NULL, fileName);
			return nil;
		}
		result = createMiscTree(aStream, props, aZone);
		NXCloseMemory(aStream, NX_FREEBUFFER);
		return result;
	}
	return nil;
}

@end

static int getNextNodeLabel(char *buffer, int n, NXStream *stream)
{
	int c, i = 0, blanks = 0;
	int tnums = 0;
	
	while(((c = NXGetc(stream)) != EOF) && (i < n-1) && (c == ' ' || c == '\t')){
		if(c == ' '){
			blanks++;
			if(blanks == 3){
				blanks = 0;
				tnums++;
			}	 
		} else	
			tnums++;
	}
	buffer[i++] = c;	
	while(((c = NXGetc(stream)) != EOF) && (i < n-1)){
		if(c == '\n')
			break;
		else
			buffer[i++] = c;
	}
	if(c == EOF)
		tnums = -1;
	buffer[i] = 0;	
	return tnums;
}


static id createMiscTree(NXStream *stream, Properties *props, NXZone *zone)
{
	int tnums, lastTNums = 0, i;
	id lastNode, node;
	char labelBuffer[MAXPATHLEN];
	
	tnums = getNextNodeLabel(labelBuffer,MAXPATHLEN,stream);
	lastNode = node = nil;
	tnums = getNextNodeLabel(labelBuffer,MAXPATHLEN,stream);
	while(tnums != -1){
		if(labelBuffer){
			node = [[Tree allocFromZone:zone] initLabel:labelBuffer props:props];
			if(lastNode){
				if(lastTNums >= tnums)
					for(i = 0; i <= lastTNums - tnums && [lastNode parent]; i++, lastNode = [lastNode parent]);
				[lastNode addTree:node];
			}
			lastNode = node;
			lastTNums = tnums;
		}
		tnums = getNextNodeLabel(labelBuffer,MAXPATHLEN,stream);
	}
	while([node parent])
		node = [node parent];
	return node;
}	
		
	