/* 
   NSObject.h

   Interface to NSObject

   Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
   
   Author:	Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
   Date:	August 1995
   
   H.N.Schaller, Dec 2005 - API revised to be compatible to 10.4
 
   This file is part of the mySTEP Library and is provided
   under the terms of the GNU Library General Public License.
*/ 

#ifndef _mySTEP_H_NSObject
#define _mySTEP_H_NSObject

// import everything we need from the basic runtime system (incl. POSIX headers)

#import <Foundation/NSObjCRuntime.h>
#import <Foundation/NSZone.h>


@protocol NSObject

- (id) autorelease;
- (Class) class;
- (BOOL) conformsToProtocol:(Protocol *)aProtocol;
- (NSString *) description;
- (unsigned) hash;
- (BOOL) isEqual:(id) anObject;
- (BOOL) isKindOfClass: (Class)aClass;
- (BOOL) isMemberOfClass: (Class)aClass;
- (BOOL) isProxy;
- (id) performSelector:(SEL)aSelector;
- (id) performSelector:(SEL)aSelector withObject:(id)anObject;
- (id) performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
- (oneway void) release;
- (BOOL) respondsToSelector:(SEL)aSelector;
- (id) retain;
- (unsigned) retainCount;
- (id) self;
- (Class) superclass;
- (NSZone *) zone;

- (id) _nimp:(SEL) cmd;

@end

@protocol NSCopying
- (id) copyWithZone:(NSZone *) zone;
@end


@protocol NSMutableCopying
- (id) mutableCopyWithZone:(NSZone *) zone;
@end


@protocol NSCoding
- (void) encodeWithCoder:(NSCoder*) aCoder;
- (id) initWithCoder:(NSCoder*) aDecoder;
@end

@interface NSObject  <NSObject, NSCoding>
{												
    Class isa;										// pointer to instance's 
}													// class structure

+ (id) alloc;
+ (id) allocWithZone:(NSZone *) z;
+ (Class) class;
+ (BOOL) conformsToProtocol:(Protocol *)aProtocol;
+ (id) copyWithZone:(NSZone *) zone;
+ (NSString*) description;
+ (void) initialize;
+ (IMP) instanceMethodForSelector: (SEL)aSelector;
+ (NSMethodSignature*) instanceMethodSignatureForSelector:(SEL)aSelector;	// define in NSMethodSignature.h or NSClassDescription.h?
+ (BOOL) instancesRespondToSelector: (SEL)aSelector;
+ (BOOL) isSubclassOfClass:(Class)aClass;
+ (void) load;
+ (id) mutableCopyWithZone:(NSZone *) zone;
+ (id) new;
+ (void) poseAsClass:(Class)aClass;
+ (void) setVersion:(int)aVersion;
+ (Class) superclass;
+ (int) version;

//- (unsigned long) classCode;	// -> NSScriptClassDescription
- (NSString *) className;
- (id) copy;
- (void) dealloc;
- (void) doesNotRecognizeSelector: (SEL)aSelector;
- (void) finalize;
- (void) forwardInvocation:(NSInvocation*) anInvocation;
- (id) init;
- (IMP) methodForSelector: (SEL)aSelector;
- (NSMethodSignature*) methodSignatureForSelector:(SEL)aSelector;	// -> NSMethodSignature.h?
- (id) mutableCopy;
//- (NSDictionary *) scriptingProperties;	// -> NSScriptClassDescription
//- (void) setScriptingProperties:(NSDictionary *) properties;	// -> NSScriptClassDescription

@end

#ifdef __mySTEP__
extern unsigned long __NSAllocatedObjects;
#endif

static inline NSObject *NSAllocateObject(Class aClass, unsigned int extra, NSZone *zone)							// object allocation
{
	id newobject=nil;
#ifdef __mySTEP__
	if (CLS_ISCLASS (aClass))
		{
		int size = aClass->instance_size + sizeof(struct _object_layout);
		if ((newobject = NSZoneMalloc(zone, size)) != nil)
			{
			memset (newobject, 0, size);
			newobject = (id)&((_object_layout)newobject)[1];
			newobject->class_pointer = aClass;
			}
		//		fprintf(stderr, "%08x [%s alloc:%d]\n", new, aClass->name, size);
		}
	__NSAllocatedObjects++;	// one more
#endif
	return newobject;
}

static inline void NSDeallocateObject(NSObject *anObject)					// object deallocation
{
#ifdef __mySTEP__
	if (anObject != nil)
		{
		_object_layout o = &((_object_layout)anObject)[-1];
		
		//	fprintf(stderr, "%08x [%s dealloc]\n", anObject, anObject->isa->name);
		((id)anObject)->class_pointer = (void*)0xdeadface;
		
		objc_free(o);
		}
	__NSAllocatedObjects--;	// one less
#endif
}

static inline NSObject *NSCopyObject(NSObject *obj, unsigned int extraBytes, NSZone *zone)
{
	id newobject=nil;
#ifdef __linux__
	int size = ((id)obj)->class_pointer->instance_size + sizeof(struct _object_layout) + extraBytes;
	if ((newobject = NSZoneMalloc(zone, size)) != nil)
		{
		newobject = (id)&((_object_layout)newobject)[1];
		newobject->class_pointer = ((id)obj)->class_pointer;	// same as original
		}
	// fprintf(stderr, "%08x [%s copyObject:%d]\n", new, aClass->name, size);
	memcpy(newobject, obj, ((id)obj)->class_pointer->instance_size);
#endif
	return newobject;
}

void NSIncrementExtraRefCount(id anObject);
BOOL NSDecrementExtraRefCountWasZero(id anObject);

typedef enum _NSComparisonResult 
{
	NSOrderedAscending = -1,
	NSOrderedSame, 
	NSOrderedDescending

} NSComparisonResult;

enum { NSNotFound = 0x7fffffff };

@interface NSObject (Miscellaneous)
- (id) _subclass:(SEL) cmd;
- (id) _error:(const char *)aString, ...;
@end

#endif /* _mySTEP_H_NSObject */
