/* ClassAdditions.m
 * Written By:  Thomas Burkholder
 *
 * You may freely copy, distribute, and reuse the code in this example.
 * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
 * fitness for any particular use.
 */

#import "ClassAdditions.h"
#import "StorageAdditions.h"  // category that adds addElementIfAbsent:
#import <objc/objc-class.h>
#import <objc/objc-runtime.h>
#import <objc/List.h>
#import <objc/Storage.h>
#import <string.h>

@implementation Object (ClassAdditions)

+ (BOOL)isPoser
{
	return ([self name][0] == '%');
}

+ realSuperclass
{
	id o;
	// Superclass that isn't a poser
	for(o=[self superclass];(o && [o isPoser]);o = [o superclass]);
	return o;
}

+ (int)subclasses:(id)list allowPosers:(BOOL)yn
							filterWith:(CAObjectFilterFunc)aFunc
{
	NXHashTable *p;
	NXHashState state;
	void *value;
	int count = 0;

	p = objc_getClasses();
	state = NXInitHashState(p);

	while (NXNextHashState(p,&state,&value)) {
		if (((!yn && (([(id)value realSuperclass]==[self class])&&
				(![(id)value isPoser])) ) ||
				((yn) && ([(id)value superclass] == self))) && 
				(!aFunc || aFunc((id)value,self))) {
					count++;
					if (list)
						[list addObject:(id)value];
		}
	}
	return count;
}

+ (int)methodSelectors:(id)storage includeAncestors:(BOOL)yn
						filterWith:(CAElementFilterFunc)aFunc;
{
	struct objc_method_list *methods;
	SEL selector;
	BOOL c;
	int i;
	int total = 0;
	struct objc_class *s;
	
	[storage empty];
	for(s=self,c=YES;(c && s);s = [s superclass],c=yn) {
		for(methods = s->methods;methods;methods=methods->method_next) {
			for(i=0;(i<methods->method_count);i++) {
				selector = (SEL)(methods->method_list[i].method_name);
				if (aFunc(self, selector)) {
					[storage addElementIfAbsent:&selector];
					total++;
				}
			}
		}
	}
	return total;
}

@end