// Copyright 2003-2005, 2007-2008 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/developer/sourcecode/sourcelicense/>.
//
// $Header: svn+ssh://source.omnigroup.com/Source/svn/Omni/tags/OmniSourceRelease/2008-03-20/OmniGroup/Frameworks/OmniFoundation/XML/OFXMLElement.h 98770 2008-03-17 22:25:33Z kc $

#import <Foundation/NSObject.h>

#import <OmniFoundation/OFXMLWhitespaceBehavior.h>

@class NSArray, NSMutableArray, NSMutableDictionary, NSMutableString;
@class OFXMLDocument, OFXMLElement;

typedef void (*OFXMLElementApplier)(OFXMLElement *element, void *context);


@interface OFXMLElement : NSObject
{
    NSString *_name;
    NSMutableArray *_children;
    NSMutableArray *_attributeOrder;
    NSMutableDictionary *_attributes;
    struct {
        unsigned int ignoreUnlessReferenced : 1;
        unsigned int markedAsReferenced     : 1;
    } _flags;
}

- initWithName:(NSString *)name attributeOrder:(NSMutableArray *)attributeOrder attributes:(NSMutableDictionary *)attributes; // RECIEVER TAKES OWNERSHIP OF attributeOrder and attributes!
- initWithName:(NSString *)name;


- (id)deepCopy;
- (OFXMLElement *)deepCopyWithName:(NSString *)name;

- (NSString *) name;
- (NSArray *) children;
- (unsigned int)childrenCount;
- (id) childAtIndex: (unsigned int) childIndex;
- (id) lastChild;
- (unsigned int)indexOfChildIdenticalTo:(id)child;
- (void)insertChild:(id)child atIndex:(unsigned int)childIndex;
- (void) appendChild: (id) child;  // Either a OFXMLElement or an NSString
- (void) removeChild: (id) child;
- (void) removeChildAtIndex: (unsigned int) childIndex;
- (void)removeAllChildren;
- (void)setChildren:(NSArray *)children;
- (void)sortChildrenUsingFunction:(int (*)(id, id, void *))comparator context:(void *)context;
- (OFXMLElement *)firstChildNamed:(NSString *)childName;
- (OFXMLElement *)firstChildAtPath:(NSString *)path;
- (OFXMLElement *)firstChildWithAttribute:(NSString *)attribute value:(NSString *)value;

- (void)setIgnoreUnlessReferenced:(BOOL)yn;
- (BOOL)ignoreUnlessReferenced;
- (void)markAsReferenced;
- (BOOL)shouldIgnore;

- (NSArray *) attributeNames;
- (NSString *) attributeNamed: (NSString *) name;
- (void) setAttribute: (NSString *) name string: (NSString *) value;
- (void) setAttribute: (NSString *) name value: (id) value;
- (void) setAttribute: (NSString *) name integer: (int) value;
- (void) setAttribute: (NSString *) name integer: (int) value;
- (void) setAttribute: (NSString *) name real: (float) value;  // "%g"
- (void) setAttribute: (NSString *) name real: (float) value format: (NSString *) formatString;

- (OFXMLElement *)appendElement:(NSString *)elementName containingString:(NSString *)contents;
- (OFXMLElement *)appendElement:(NSString *)elementName containingInteger:(int)contents;
- (OFXMLElement *)appendElement:(NSString *)elementName containingReal:(float)contents; // "%g"
- (OFXMLElement *)appendElement:(NSString *)elementName containingReal:(float)contents format:(NSString *)formatString;
- (OFXMLElement *)appendElement:(NSString *)elementName containingDate:(NSDate *)date;
- (void) removeAttributeNamed: (NSString *) name;
- (void)sortAttributesUsingFunction:(int (*)(id, id, void *))comparator context:(void *)context;
- (void)sortAttributesUsingSelector:(SEL)comparator;

- (void)applyFunction:(OFXMLElementApplier)applier context:(void *)context;

- (NSData *)xmlDataAsFragment; // Mostly useful for debugging since this assumes no whitespace is important

// Debugging
- (NSMutableDictionary *)debugDictionary;
- (NSString *)debugDescription;

@end

@interface NSObject (OFXMLWriting)
- (void)appendXML:(struct _OFXMLBuffer *)xml withParentWhiteSpaceBehavior: (OFXMLWhitespaceBehaviorType) parentBehavior document: (OFXMLDocument *) doc level: (unsigned int) level;
- (BOOL)xmlRepresentationCanContainChildren;
- (NSObject *)createFrozenElement;
@end
