// Copyright 1997-1999 Omni Development, Inc.  All rights reserved.
//
// This software may only be used and reproduced according to the
// terms in the file OmniSourceLicense.html, which should be
// distributed with this project and can also be found at
// http://www.omnigroup.com/DeveloperResources/OmniSourceLicense.html.

#import "OWSGMLTagType.h"

#import <Foundation/Foundation.h>
#import <OmniBase/OmniBase.h>
#import <OmniFoundation/OmniFoundation.h>

#import "OWSGMLTag.h"
#import "OWSGMLAttribute.h"

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OWF/Processors.subproj/SGML.subproj/OWSGMLTagType.m,v 1.5 1999/03/30 21:26:46 kc Exp $")

@implementation OWSGMLTagType

- initWithName:(NSString *)aName dtdIndex:(unsigned int)anIndex;
{
    [super init];
    name = [aName copy];
    dtdIndex = anIndex;
    masterAttributesTagType = nil;
    attributeNames = [[NSMutableArray alloc] init];
    attributeTrie = [[OFTrie alloc] initCaseSensitive:NO];

    attributelessStartTag = [[OWSGMLTag alloc] initWithTokenType:OWSGMLTokenTypeStartTag tagType:self];
    attributelessEndTag = [[OWSGMLTag alloc] initWithTokenType:OWSGMLTokenTypeEndTag tagType:self];
    return self;
}

- (void)dealloc;
{
    [name release];
    [masterAttributesTagType release];
    [attributeNames release];
    [attributeTrie release];
}

- (NSString *)name;
{
    return name;
}

- (unsigned int)dtdIndex;
{
    return dtdIndex;
}

- (OWSGMLTagType *)masterAttributesTagType;
{
    if (masterAttributesTagType)
        return [masterAttributesTagType masterAttributesTagType];
    return self;
}

- (NSArray *)attributeNames;
{
    if (masterAttributesTagType)
        return [masterAttributesTagType attributeNames];
    return attributeNames;
}

- (OFTrie *)attributeTrie
{
    if (masterAttributesTagType)
        return [masterAttributesTagType attributeTrie];
    return attributeTrie;
}

- (BOOL)isNotValidSGML
{
    return isNotValidSGML;
}

- (void)shareAttributesWithTagType:(OWSGMLTagType *)aTagType;
{
    unsigned int                attributeIndex, attributeCount;

    aTagType = [aTagType masterAttributesTagType];
    if (aTagType == self)
        return;

    masterAttributesTagType = [aTagType retain];
    attributeCount = [attributeNames count];
    for (attributeIndex = 0;
         attributeIndex < attributeCount;
         attributeIndex++) {
         [masterAttributesTagType addAttributeNamed:
          [attributeNames objectAtIndex:attributeIndex]];
    }
    [attributeNames release];
    [attributeTrie release];
    attributeNames = nil;
    attributeTrie = nil;
}

- (unsigned int)addAttributeNamed:(NSString *)attributeName;
{
    if (masterAttributesTagType)
        return [masterAttributesTagType addAttributeNamed:attributeName];

    if (![attributeNames containsObject:attributeName]) {
        unsigned int newAttributeIndex;
        OWSGMLAttribute *attribute;

        newAttributeIndex = [attributeNames count];
        if (newAttributeIndex == OWSGMLTagMaxAttributes)
            NSLog(@"OWSGMLTagType: overflowing '%@' attribute table: %@.",
                    name, attributeName);
        attribute = [[OWSGMLAttribute alloc] initWithOffset:newAttributeIndex];
        [attributeNames addObject:attributeName];
        [attributeTrie addBucket:attribute forString:attributeName];
        [attribute release];
        return newAttributeIndex;
    }
    return [attributeNames indexOfObject:attributeName];
}

- (unsigned int)indexOfAttribute:(NSString *)attributeName;
{
    if (masterAttributesTagType)
        return [masterAttributesTagType addAttributeNamed:attributeName];

    return [attributeNames indexOfObject:attributeName];
}

- (BOOL)hasAttributeNamed:(NSString *)attributeName;
{
    if (masterAttributesTagType)
        return [masterAttributesTagType hasAttributeNamed:attributeName];

    return [attributeNames containsObject:attributeName];
}

- (OWSGMLTag *)attributelessStartTag;
{
    return attributelessStartTag;
}

- (OWSGMLTag *)attributelessEndTag;
{
    return attributelessEndTag;
}

// Debugging

- (NSMutableDictionary *)debugDictionary;
{
    NSMutableDictionary *debugDictionary;

    debugDictionary = [super debugDictionary];

    if (name)
        [debugDictionary setObject:name forKey:@"name"];
    [debugDictionary setObject:[NSString stringWithFormat:@"%d", dtdIndex] forKey:@"dtdIndex"];
    if (masterAttributesTagType)
        [debugDictionary setObject:masterAttributesTagType forKey:@"masterAttributesTagType"];
    if (attributeNames)
        [debugDictionary setObject:attributeNames forKey:@"attributeNames"];
    if (attributeTrie)
        [debugDictionary setObject:attributeTrie forKey:@"attributeTrie"];

    return debugDictionary;
}

@end
