// Copyright 2001-2002 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 "OWCSSDeclarations.h"

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

#import "OWCSSIdentifier.h"

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OWF/CSS.subproj/OWCSSDeclarations.m,v 1.15 2002/03/09 01:53:48 kc Exp $");

@interface OWCSSDeclarations (Private)
@end

@implementation OWCSSDeclarations

+ (OWCSSDeclarations *)declarations;
{
    return [[[self alloc] init] autorelease];
}


// Init and dealloc

- init;
{
    if ([super init] == nil)
        return self;

    bzero(declarations, sizeof(declarations));

    return self;
}

- (void)dealloc;
{
    [self releaseAndClearDeclarations];
    [super dealloc];
}


// API

- (BOOL)isEmpty;
{
    unsigned int declarationIndex;
    
    declarationIndex = CSSDeclarationsCount;
    while (declarationIndex--)
        if (declarations[declarationIndex] != nil)
            return NO;
    return YES;
}

- (BOOL)isBlock;
{
    return declarations[CSSDisplayDeclarationIndex] == OWCSSBlockIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSListItemIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSCompactIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSRunInIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableRowGroupIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableHeaderGroupIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableFooterGroupIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableRowIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableColumnGroupIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableColumnIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableCellIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSTableCaptionIdentifier
        || declarations[CSSDisplayDeclarationIndex] == OWCSSNoneIdentifier;
}

- (BOOL)startsTable;
{
    return declarations[CSSDisplayDeclarationIndex] == OWCSSTableIdentifier;
}

- (BOOL)hasFontDeclarations;
{
    unsigned int declarationIndex;
    
    for (declarationIndex = CSSFontDeclarationIndex; declarationIndex <= CSSFontWeightDeclarationIndex; declarationIndex++)
        if (declarations[declarationIndex] != nil)
            return YES;
    return NO;
}

- (id)objectAtIndex:(unsigned int)index;
{
    OBPRECONDITION(index < CSSDeclarationsCount);
    return declarations[index];
}

- (void)setObject:(id)object atIndex:(unsigned int)index;
{
    OBPRECONDITION(index < CSSDeclarationsCount);
    if (declarations[index] == object)
        return;

    switch (index) {
        case CSSBackgroundColorDeclarationIndex:
        case CSSBackgroundImageDeclarationIndex:
            if (object != OWCSSInheritIdentifier && object != nil)
                [self setNeedsToStartABoxAtThisLevel];
            break;
        default:
            break;
    }
    [declarations[index] release];
    declarations[index] = [object retain];
}

- (void)addEntriesFromDeclarations:(OWCSSDeclarations *)otherDeclarations;
{
    unsigned int declarationIndex;
    
    if (otherDeclarations == nil)
        return;
    
    declarationIndex = CSSDeclarationsCount;
    while (declarationIndex--) {
        id object;
        
        object = otherDeclarations->declarations[declarationIndex];
        if (object != nil) {
            [declarations[declarationIndex] release];
            declarations[declarationIndex] = [object retain];
        }
    }
    if (otherDeclarations->flags.needsToStartABoxAtThisLevel)
        flags.needsToStartABoxAtThisLevel = YES;
}

- (void)releaseAndClearDeclarations;
{
    unsigned int declarationIndex;
    
    declarationIndex = CSSDeclarationsCount;
    while (declarationIndex--) {
        [declarations[declarationIndex] release];
        declarations[declarationIndex] = nil;
    }
    flags.needsToStartABoxAtThisLevel = NO;
}

- (BOOL)needsToStartABoxAtThisLevel;
{
    return declarations[CSSDisplayDeclarationIndex] == OWCSSBlockIdentifier && flags.needsToStartABoxAtThisLevel;
}

- (void)setNeedsToStartABoxAtThisLevel;
{
    // [self setObject:OWCSSOWNeedsToStartABoxAtThisLevel atIndex:CSSOWNeedsToStartABoxAtThisLevel];
    flags.needsToStartABoxAtThisLevel = YES;
}

@end

@implementation OWCSSDeclarations (Private)

- (NSMutableDictionary *)debugDictionary;
{
    NSMutableDictionary *debugDictionary;
    unsigned int propertyIndex;

    debugDictionary = [NSMutableDictionary dictionary];

    for (propertyIndex = 0; propertyIndex < CSSDeclarationsCount; propertyIndex++)
            if (declarations[propertyIndex] != nil)
                [debugDictionary setObject:declarations[propertyIndex] forKey:[OWCSSPropertyNameIdentifiers[propertyIndex] string]];

    return debugDictionary;
}


@end
