#import "ITreeNodeD.h"
#import "IDatumD.h"
#import <stdio.h>
#import <appkit/Application.h>
#import "errdebug.h"

@implementation ITreeNodeD

- (ITreeNodeD *)nodeForKey:(char **)theKey
{
    return [self searchForNodeWithKey:theKey withOption:SEARCH];
}

- addNodeForKey:(char **)theKey
{
    return [self searchForNodeWithKey:theKey withOption:ADD];
}

//- (void)setLeaf:aLeaf
//{
//    id datum;
//
//    if ((datum = [self dataForKey:"leaf"]) != nil) {
//        [datum setData:aLeaf];
//    } else {
//        [self insertKeyedObject:[[IDatumD allocFromZone:[self zone]] initWithKey:"leaf" andData:aLeaf]];
//    }
//}
//- leaf
//{
//    return [[self dataForKey:"leaf"] data];
//}

//- (void)setLink:aLink;
//{
//    id datum;
//
//    if ((datum = [self dataForKey:"link"]) != nil) {
//        [datum setData:aLink];
//    } else {
//        [self insertKeyedObject:[[IDatumD allocFromZone:[self zone]] initWithKey:"link" andData:aLink]];
//    }
//}

//- link
//{
//    return [[self dataForKey:"link"] data];
//}

- searchForNodeWithKey:(char **)theKey withOption:(int)opCode
{
    ITreeNodeD *node;

    
    if (*theKey == 0) {
        return self;
    }

    if ((node = [self dataForKey:*theKey]) == nil) {
        if (opCode == SEARCH) {
            return nil;
        } else if (opCode == ADD) {
            node = [[ITreeNodeD allocFromZone:[self zone]] initWithKey: *theKey];
            [self insertKeyedObject:node];
//	    [node setLink:nil];
//	    [node setLeaf:nil];
    	    return [node searchForNodeWithKey:(theKey + 1) withOption:opCode];
        }
    } else if ([node isMemberOf:[ITreeNodeD class]] == YES) {
    	return [node searchForNodeWithKey:(theKey + 1) withOption:opCode];
    } else {
        if (*(theKey + 1) == 0) {
            return node;
        } else {
            return nil;
        }
    }
    return nil;  /* need to fool the compiler */
}

- (void)traverseTreeAndPerform:(SEL)theSelector target:target
{
    int n;
    ITreeNodeD *node;

    [target perform:theSelector with:self];
    for (n = 0; node = [self objectAt:n]; ++n) {
        if ([node isMemberOf:[ITreeNodeD class]] == YES) {
            [node traverseTreeAndPerform:theSelector target:target];
        }
    }
}

- (void)initState:(NXTreeState *)state
{
    state->depth = 0;
    state->nodeState[0].node = self;
    state->nodeState[0].index = 0;
}

- nextState:(NXTreeState *)state
{
    id node;

    DBG(10, fprintf(stderr, "%s %d\n", [state->nodeState[state->depth].node key], state->nodeState[state->depth].index););
    if ((node = [state->nodeState[state->depth].node objectAt:state->nodeState[state->depth].index]) != nil) {
        ++state->nodeState[state->depth].index;
        if ([node isMemberOf:[ITreeNodeD class]] == YES && [node count] > 0) {
	    if (++state->depth > MAX_TREE_STATE_DEPTH) {
		[NXApp terminate:self];
            }
            state->nodeState[state->depth].node = node;
            state->nodeState[state->depth].index = 0;
        }
        return(node);
    } else {
        if (--state->depth >= 0) {
            return [self nextState:state];
        } else {
            return nil;
        }
    }
}

#import <sys/param.h>
#import <libc.h>
void makeTreeKey(const char *originalKey, const char **key, const char *token)
{
    char	**keyptr;
    char	*strtok();
    char	*keytmp;
    
    keytmp = (char *)originalKey;
    keyptr = key;
    *keyptr = strtok(keytmp, token);
    while (++keyptr < &key[MAX_NO_OF_TOKENS -1] &&
    		(*keyptr = strtok(NULL, token)) != NULL );
    *++keyptr = NULL;
    return;
}

@end
