//*****************************************************************************
//
//	SwapView.m.  
//
//	I have condensed, optimized and reformatted the code so that a swapview
//	can be implemented with this source file and a nib.  Added initPopUp 
// 	method.  
//
//		changes 5/25/95	by Felipe A. Rodriguez
//		changes 7/29/95	by Felipe A. Rodriguez
//			-- replaced addSubview in SwapIt method with replaceSubview.  This
//				corrected a bug where textfields remained active after swap
//		changes 3/14/96	by Felipe A. Rodriguez
//			-- optimized class to support more inspectors
//		changes 8/1/97 by Felipe A. Rodriguez
//			-- added support for dynamically loaded inspectors
//		changes 12/11/97 by Felipe A. Rodriguez
//			-- modified support for dynamically loaded inspectors
//
//	This file was derived from:
//	
//			SwapView.m and InspectorController.m
//			by Greg Burd
//			SwapItDemo, ver 2.0
//
//	This code is supplied "as is" the author's makes no warranty as to its 
//	suitability for any purpose.  This code is free and may be distributed 
//	in accordance with the terms of the:
//		
//			GNU GENERAL PUBLIC LICENSE
//			Version 2, June 1991
//			copyright (C) 1989, 1991 Free Software Foundation, Inc.
// 			675 Mass Ave, Cambridge, MA 02139, USA
//
//*****************************************************************************

#import "SwapView.h"
#import <appkit/Window.h>
#import <appkit/Application.h>
#import <dpsclient/psops.h>
#import <dpsclient/wraps.h>
#import <dpsclient/dpsNeXT.h>
#import <appkit/graphics.h>
#import <objc/List.h>
#import <objc/objc.h>
#import <appkit/PopUpList.h>
#import <apps/InterfaceBuilder.h>




@implementation SwapView

//*****************************************************************************
//
// 		attach popup to popUpList 
//
//		popUpCover must be attached to the trigger button of a popUpList in IB
//
//*****************************************************************************

- initPopUp
{
	if(popUpCover)		// if popUpCover s/b hooked to a trigger button in IB
		popup = [popUpCover target];	// popup should point to its popUpList

	return self;
}
//*****************************************************************************
//
// 		designated initilizer for swapviews
//
//*****************************************************************************

- initFrame:(const NXRect *)theFrame
{
char title[] = {"FirstInspector"};

	[super initFrame:theFrame];
	
	lastInspector = NULL;
	currentInspector = NULL;
	backgroundGray = NX_LTGRAY;
	theTitle = title;	
	[self setBackgroundGray:NX_LTGRAY];		// default
	inspectorHashTable = [[HashTable alloc] initKeyDesc:"@" valueDesc:"@"];

	return self;
}
//*****************************************************************************
//
// 		swaps views in and out of inspector's swapview
//
//*****************************************************************************
 
- swapIt
{
	if(lastInspector != inspector)	// make sure this is a new view to swap in  
		{
		if(!inspector)				// no inspector so clean up the background 
			{
			[self lockFocus];
			PSsetgray(backgroundGray);			// use the backgroundGray
			NXRectFill(&bounds);
			[self unlockFocus];
			lastInspector = NULL;			// now the last inspector is NULL 
			NXPing();			// let the window server cetch up... (yawn...)
			}
						// add the subview to SwapView and its responder chain		
		if(lastInspector)
			[self replaceSubview:[lastInspector contentView] 
												with:[inspector contentView]];
		else
			[self addSubview:[inspector contentView]];
		[self display];
		lastInspector = inspector;		// remember the panel it came from 	
		}

	return self;
}
//*****************************************************************************
//
// 		add an inspector for a sender of class matrix
//
//*****************************************************************************

- addInspector:anInspector for:sender
{
	[inspectorHashTable insertKey:[sender selectedCell] value:anInspector];

	return self;
}
//*****************************************************************************
//
// 		this is to allow us to jump to any inspector given its key name 
//
//*****************************************************************************

- inspectorFor:sender
{
	inspector = [inspectorHashTable valueForKey:[sender selectedCell]]; 
	[self swapIt];
	
	return self;
}
//*****************************************************************************
//
// 		target of pop up list button 
//
//*****************************************************************************

- popUpAction:sender 
{
			// set up a pointer to the selectedCell of the matrix 
	theTitle = [[sender selectedCell] title];
	[self swapIt];	 									// swap out the view

	return self;
}

- currentInspector
{
	return currentInspector;
}

- lastInspector
{
	return lastInspector;
}

- (float)backgroundGray
{ 
	return backgroundGray; 
}

- setBackgroundGray:(float)aGray
{
	backgroundGray = aGray;
	return self;
}

- free
{
	return [super free];
}
//*****************************************************************************
//
// 		This should return the id of a panel, which is off screen, and 
//		buffered, but not defered (SwapView needs its gstate).  SwapView will 
//		take the contentView of the panel and swap it in while also removing 
//		the old view, if any, and placing it back into its old panel.
//
//	 WARNING!!!!
//	Don't forget to make sure that the off screen windows are NOT deferred!!!
//	This means make sure that you turn the Deffered switch OFF in IB when
//	looking at the Atributes inspector.  This allows offscreen drawing.  
//	If it was on, then the gstate will be zero!!!!
//
// 		Ideally::  these panels should all be nibs so they have controllers
//				   and the above code should load the nib section if it
//				   already isn't loaded.  It should load here because you only
//				   want to take up memory when it is demanded. 
//
//*****************************************************************************

- whatPanel
{					
	switch(index)				// find out what panel to give to the SwapView
		{
		case 0:
			inspector = firstInspectorPanel;
			break;
		case 1:  				
			inspector = secondInspectorPanel;
			break;
		default:  				// the button title has no related inspector,
			inspector = nil;	// this should never happen.
			break;				
		}
								 
	return inspector;				
}
//*****************************************************************************
//
// 		this is to allow us to jump to any inspector given its index  
//
//*****************************************************************************

- inspect:(int)anIndex
{
	index = anIndex; 
	[self whatPanel];
	[self swapIt];
	
	return self;
}

@end

