/* BBRegion.m				 
 *
 * Here we have basic Region. It can handle references to bonds and
 * atoms, it can create their shapes and knows about rendering settings.
 * However. Really stroing atoms/bonds should be left to a molecule.
 * Regions are only logical parts of a molecule.
 *
 * For interface-info see the header file. The comments in this file mostly
 * cover only the real implementation details.
 *
 * Written by: 		Thomas Engel
 * Created:    		09.03.1994 (Copyleft)
 * Last modified: 	12.11.1994
 */

#define CURRENT_VERSION 1

#import "BBRegion.h"
#import "BBBasicShapeBallsSticks.h"
#import "BBCameraWindow.h"
#import <misckit/MiscString.h>

@implementation BBRegion

+ initialize
{
	if ( self == [BBRegion class] )
		[BBRegion setVersion:CURRENT_VERSION];

	return self;
}

- init
{
	self = [super init];
	if( !self ) return self;

	// OK. We really are an object...here we go with our init.

	atomList = [BBSuitcase new];
	[atomList setName:"Atoms"];
	[atomList setImage:[NXImage findImageNamed:"AtomListIcon"]];

	bondList = [BBSuitcase new];
	[bondList setName:"Bonds"];
	[bondList setImage:[NXImage findImageNamed:"BondListIcon"]];

	[self setName:"Untitled Region"];
	[self setImage:[NXImage findImageNamed:"RegionIcon"]];
	[self addObject:atomList];
	[self addObject:bondList];
	
	[self setColor:NX_COLORWHITE];
	[self setShapeClass:[BBBasicShapeBallsSticks class]];
	[self setShapesInRegionColor:NO];
	

	return self;
}

- free
{
	// Let's free what we created. Don't real free the objects.
	// If we had our own style settings we should free them.
	
	if( [self doesHaveDrawingStyle] ) [drawingStyle free];
	if( [self doesHaveRotationStyle] ) [rotationStyle free];
	[[atomList empty] free];
	[[bondList empty] free];
	
	return [super free];
}

- setColor:(NXColor)aColor
{
	color = aColor;
	return self;
}

- (NXColor)color
{
	return color;
}

- setShapesInRegionColor:(BOOL)flag
{	
	shapesInRegionColor = flag;
	return self;
}

- (BOOL)shapesInRegionColor
{
	return shapesInRegionColor;
}

- setDrawingStyle:aStyle
{
	drawingStyle = aStyle;
	return self;
}

- drawingStyle
{
	if( !drawingStyle ) return [[self molecule] drawingStyle];
	return drawingStyle;
}

- (BOOL)doesHaveDrawingStyle
{
	if( drawingStyle ) return YES;
	return NO;
}

- setRotationStyle:aStyle
{
	rotationStyle = aStyle;
	return self;
}

- rotationStyle
{
	if( !rotationStyle ) return [[self molecule] rotationStyle];
	return rotationStyle;
}

- (BOOL)doesHaveRotationStyle
{
	if( rotationStyle ) return YES;
	return NO;
}

- beaker
{
	return [[self molecule] beaker];
}

- molecule
{
	// We will tell to which molecule we belong.
	// This is easy because every atom/bond carries this information.
	
	if( [atomList count] > 0 )
		return [[atomList objectAt:0] molecule];
	
	if( [bondList count] > 0 )
		return [[bondList objectAt:0] molecule];
	
	else return nil;
}

- addAtom:anAtom
{
	[atomList addObject:anAtom];
	return self;
}

- atomList
{
	return atomList;
}

- addBond:aBond
{
	[bondList addObject:aBond];
	return self;
}

- bondList
{
	return bondList;
}

- open:sender
{
	id	aList;
	
	aList = [List new];
	[aList addObject:self];
	[[[self displayClass] alloc] initFrom:aList 
							     asPartOf:[self beaker]];
	[aList free];
	return self;
}

- displayClass
{
	return [BBCameraWindow class];
}

- setShapeClass:aClass
{
	shapeClass = aClass;
	return self;
}

- shapeClass
{
	return shapeClass;
}

- shape
{
	id	ourShape;
	
	ourShape = [[[self shapeClass] alloc] initFrom:self 
										  asPartOf:[self molecule]];
	return ourShape;
}

- groupClass
{
	return [BBSuitcase class];
}

/*
 * Archiving the whole Region...
 */
 
- read:(NXTypedStream *)stream
{
	int version;
	
	[super read:stream];
	version = NXTypedStreamClassVersion( stream, "BBRegion" );
	
	// Version 1
		
	if ( version == CURRENT_VERSION )
	{
	//	NXReadTypes( stream, "@", &moleculeList );
	//	NXReadTypes( stream, "@", &cameraList );
	}
	else
		NXRunAlertPanel( NULL, "Unknown version of the BBBeaker class.\n"\
							   "Maybe you should get a new release of BeakerBoy",
						 "Ooops", NULL, NULL );
	return self;
}

- write:(NXTypedStream *)stream
{
	[super write:stream];
	
	// Version 1:
	// Filename and all the browser stuff is not archived! Those infos are
	// created at launch time.
	
	//NXWriteTypes( stream, "@", &moleculeList );
	//NXWriteTypes( stream, "@", &cameraList );
	
	return self;
}

@end

/*
 * History: 12.11.94 Added archiving and versioning.
 *
 *			30.10.94 Switched to the MiscString.
 *
 *			17.05.94 Added flexible shape creation.
 *
 *			27.03.94 Started to include the different renderSettings.
 *
 *			10.03.94 Switched to the shape method.
 *
 *			09.0.3.94 First coding
 *
 *
 * Bugs: - Setting the name during init should support localization!
 */