/*
 * Author: Greg Burd, Mr. Average Developer
 *    (I would like to be a member of the NeXT Developer Support Team.)
 *
 * You may freely copy, distribute and reuse the code in this example.  
 * I disclaim any warranty of any kind, expressed or implied, as to 
 * its fitness for any particular use.
 */

#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>

/**************************************************************/

/*
 * Author: Greg Burd, Mr. Average Developer
 *    (I would like to be a member of the NeXT Developer Support Team.)
 *
 * You may freely copy, distribute and reuse the code in this example.  
 * I disclaim any warranty of any kind, expressed or implied, as to 
 * its fitness for any particular use.
 *
 *
 *		This contains a function that really needs to be in the
 *		NX functions, so I named it as such.  It should be used when
 *		coding delegate functions.
 *		
 *	NXAskDelegate(id delegate, SEL delegateMethod);
 *	
 *		Simply put it makes sure that that the delegate object is not
 *		nil and that it respondsTo: the selector delegateMethod.  If both
 *		of those conditions are satisfied, then it returns true.
 *
 */

#import <objc/objc.h>

extern void* NXAskDelegate(id delegate, SEL selector)
{	
	return (delegate && [delegate respondsTo:selector]);
}


/**************************************************************/
@implementation SwapView

- init
{
	NXRect theFrame = {{0.0, 0.0}, {0.0, 0.0}};
	return [self initFrame:&theFrame];
}

/* designated initilizer */
- initFrame:(NXRect *)theFrame
{
	[super initFrame:theFrame];
	
	lastInspector = NULL;
	currentInspector = NULL;
	backgroundGray = NX_LTGRAY;
	
	return self;
}

- currentInspector
{
	return currentInspector;
}

- lastInspector
{
	return lastInspector;
}

- delegate
{
	return delegate;
}

- setDelegate:(id)anObject
{
	delegate = anObject;
	return self;
}


- (float)backgroundGray
{ return backgroundGray; }

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


/* 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!!!!
 */
 
 
- swapIt:sender
{ [self swapIt]; return self; }
/* this is the real function !! */
- swapIt
{
	NXRect theFrame;
	int gstate;
	id aView, inspector; 

	/* make sure the delegate impliments the whatPanel call */
	if (!NXAskDelegate(delegate, @selector(whatPanel))){
		//logError somewhere
	};
	// call the delegate
	inspector = [delegate whatPanel];
	
	/* make sure that it is a new view to swap in */
	if(lastInspector != inspector) {
		if(lastInspector) {
		/* remove old inspector from view hierarchy */
		aView = [lastInspector contentView];
		[aView removeFromSuperview];
		/* and put it back */
		[lastInspector setContentView:aView];
		}
	
	/* update the offscreen view */
	[inspector display];
	NXPing();
	
	/* no inspector so clean up the background */
	if(!inspector){
		[self lockFocus];
			/* use the backgroundGray */
    		PSsetgray(backgroundGray);
    		NXRectFill(&bounds);
		[self unlockFocus];
		/* now the last inspector is NULL */
		lastInspector = NULL;
		/* let the window server cetch up... (yawn...) */
		NXPing();
	}

	/* put in the new inspector */
	gstate = [inspector gState];
	if (gstate) {
		/* get the frame to composite in */
		[[inspector contentView] getFrame:&theFrame];
		[self lockFocus];
		/* blast the bits over to the view we locked focus on (ie. SwapView) */
		PScomposite((float)theFrame.origin.x,
					(float)theFrame.origin.y,
					(float)theFrame.size.width,
					(float)theFrame.size.height,
					(int)gstate,
					(float)1.0,
					(float)1.0,
					(int)NX_COPY);
		[self unlockFocus];
		/* now add the subview to the SwapView for the responder chain... */
		[self addSubview:[inspector contentView]];
		/* and remember the panel it came from */
		lastInspector = inspector;
		
	}
	/* see whats up out there */
	[[self window] flushWindow];
	}

	return self;
}

- free
{
	return [super free];
}



@end

