// Copyright 1997-1998 Omni Development, Inc.  All rights reserved.

#import "OBObject.h"

#import <Foundation/Foundation.h>
#import <objc/objc.h>
#import <objc/objc-class.h>
#import <objc/objc-runtime.h>

#import "rcsid.h"

RCS_ID("$Header: /Network/Developer/Source/CVS/OmniGroup/OmniBase/OBObject.m,v 1.8 1998/01/12 06:53:09 kc Exp $")

@implementation OBObject

static IMP                  nsObjectDescription;

#ifdef DEBUG_INITIALIZE
static NSMutableDictionary *initializedClasses;
#endif
#ifdef DEBUG_ALLOC
static BOOL OBObjectDebug = NO;
#endif

+ (void)initialize;
{
    static BOOL                 initialized = NO;
    Method                      descriptionMethod;

    [super initialize];

    if (!initialized) {
        initialized = YES;

        descriptionMethod = class_getInstanceMethod([NSObject class], @selector(description));
        nsObjectDescription = descriptionMethod->method_imp;

#ifdef DEBUG_INITIALIZE
#warning OBObject initialize debugging enabled
	NSLog(@"+[OBObject initialize] debugging enabled--"
		@"should deactivate this in production code");
	initializedClasses = [[NSMutableDictionary alloc] initWithCapacity:512];
#endif
    }

#ifdef DEBUG_INITIALIZE
    [initializedClasses setObject:self forKey:NSStringFromClass(self)];
#endif
}

#if defined(DEBUG_INITIALIZE) || defined(DEBUG_ALLOC)
+ allocWithZone:(NSZone *)zone;
{
#ifdef DEBUG_INITIALIZE
    if (![initializedClasses objectForKey:NSStringFromClass(self)]) {
	NSLog(@"+[%@ initialize] didn't call [super initialize]", self);
	[initializedClasses setObject:self forKey:NSStringFromClass(self)];
    }
#endif
#ifdef DEBUG_ALLOC
#warning OBObject alloc/dealloc debugging enabled
    if (OBObjectDebug) {
	OBObject *newObject;

        newObject = [super allocWithZone:zone];
        NSLog(@"alloc: %@", NSStringFromClass(self));
        
	return newObject;
    }
#endif
    return [super allocWithZone:zone];
}
#endif

- (void)dealloc;
{
#ifdef DEBUG_ALLOC
    if (OBObjectDebug)
	NSLog(@"dealloc: %@", OBShortObjectDescription(self));
#endif
    NSDeallocateObject(self);
}

@end

@implementation OBObject (Debug)

unsigned int MaxDebugDepth = 3;

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

    debugDictionary = [NSMutableDictionary dictionary];
    [debugDictionary setObject:OBShortObjectDescription(self) forKey:@"__self__"];

    return debugDictionary;
}

- (NSString *)descriptionWithLocale:(NSDictionary *)locale
                             indent:(unsigned int)level
{
    if (level < MaxDebugDepth)
        return [[self debugDictionary] descriptionWithLocale:locale indent:level];
    else
	return [self shortDescription];
}

- (NSString *)description;
{
    return [self descriptionWithLocale:nil indent:0];
}

- (NSString *)shortDescription;
{
    return [super description];
}

@end

NSString *OBShortObjectDescription(id anObject)
{
    if (!anObject)
        return nil;
    return nsObjectDescription(anObject, @selector(description));
}
