// MOClassVariable.m
//
// by Mike Ferris
// Part of MOKit
// Copyright 1993, all rights reserved.

// ABOUT MOKit
// 
// MOKit is a collection of useful and general objects.  Permission is 
// granted by the author to use MOKit in your own programs in any way 
// you see fit.  All other rights to the kit are reserved by the author 
// including the right to sell these objects as part of a LIBRARY or as 
// SOURCE CODE.  In plain English, I wish to retain rights to these 
// objects as objects, but allow the use of the objects as pieces in a 
// fully functional program.  NO WARRANTY is expressed or implied.  The author 
// will under no circumstances be held responsible for ANY consequences to 
// you from the use of these objects.  Since you don't have to pay for 
// them, and full source is provided, I think this is perfectly fair.

#import "MOKit/MOClassVariable.h"
#import <objc/objc-runtime.h>

#define CLASS_VERSION		0
#define CLASS_NAME			"MOClassVariable"

@implementation MOClassVariable

+ initialize
// Set the version.
{
	if (self == objc_lookUpClass(CLASS_NAME))  {
		[self setVersion:CLASS_VERSION];
	}
	return self;
}

- init
// Just call the DI.
{
	return [self initDoesFreeValues:NO];
}

- initDoesFreeValues:(BOOL)flag
// Designated Initializer.
// Allocate the hashtable used to store the values.
{
	[super init];
	ht = [[HashTable allocFromZone:[self zone]] 
				initKeyDesc:"%" valueDesc:"@"];
	doesFreeValues = flag;
	return self;
}

- free
// Free the hashtable (objects too, if we're supposed to).
{
	if (doesFreeValues)  [ht freeObjects];
	[ht free];
	return [super free];
}

- setObject:obj forClass:(Class)class
// The old value for the class (if any) is freed if doesFreeValues is YES, 
// otherwise it returns the previous value.  Returns nil if doesFreeValues is
// YES.
{
	NXAtom className = NXUniqueString([class name]);
	id prevVal = nil;
	
	if (obj)  {
		// insert the new value
		prevVal = (id)[ht insertKey:className value:obj];
	}  else  {
		// no new value, just remove the old
		prevVal = (id)[ht valueForKey:className];
		if (prevVal)  [ht removeKey:className];
	}
	
	if (doesFreeValues)  {
		if (prevVal)  [prevVal free];
		return nil;
	}  else  {
		return prevVal;
	}
}

- getObjectForClass:(Class)class
// Look up the value for the given class.  Returns nil if no value has 
// been set.
{
	NXAtom className = NXUniqueString([class name]);
	return (id)[ht valueForKey:className];
}

@end
