/*
 *	Written by Joe Freeman jfreeman@next.com July 1991.
 *	Use this object at your own risk.  
 *	No support or implication of fitness for use is stated or implied.
 *
 *	InspectorPanel:
 *		This object implements a standard inspector panel, similar to
 *		the inspector panel in InterfaceBuilder.  Inspectors have three 
 *		important parts that define the "inspector" part of its 
 *		functionallity, 
 *			A control to determine current inspector
 *			View where variable part of inspector is be displayed.
 *			View that will be scrolled around in variable part.
 *		This object allows the programmer to make connections to all 
 *		elements of the inspector inside a single nib file. It assumes
 *		that the there is a view that acts as the template for the size
 *		of the changable area, an offscreen window that holds the 
 *		images of the of the inspectors, and some kind of matrix of 
 *		buttons that will determine the current inspector, usually
 *		a popup list.
 *
 *		This Panel assumes that all of the inspectors are tiled in
 *		a single window.  That window (contentView) is scrolled around
 *		behind a ClipView that is the size of a single inspector.
 *
 *		All other functionality of the InspectorPanel is identical to
 *		that of standard Panels.  Any number of non changable views
 *		can coexist with the inspection area.
 *
 *		inspectorView
 *				 is the view where the information will be 
 *		displayed in the inspectorPanel.  It is a ClipView that
 *		gives the InspectorPanel size and location information.
 *
 *		offscreenWindow 
 *				is the window who's content view will be 
 *		moved around inside the inspectorView.  The order of the views
 *		(in reference to the order of the popup list is 
 *			.
 *			.
 *			.
 *			m+1 m+2 m+3 ...
 *			n+1 n+2 n+3 ...
 *			0   1   2
 *		setup the offscreenWindow as:
 *			NOT visible on launch
 *			NO resizebar
 *			NOT deferred
 *
 *
 *		The message 
 *			-updateInspector:
 *		causes the sender to be checked to figure out how the offscreen
 *		window should be displayed in the clipview and notifies the
 *		the delegate of the change.
 *
 */



#import "InspectorPanel.h"

#import <appkit/Matrix.h>
#import <appkit/ClipView.h>
#import <appkit/ButtonCell.h>

#import <strings.h>

@implementation InspectorPanel

static char rcsstring[] = 
    "@(#)Object:InspectorPanel.m Developer:Joe Freeman Version:1 August, 1991";

/* 
 *
 *	PRIVATE METHODS (should be, anyway)
 *
 */
 
/* this figures out how many panes there are in x and y in the docView
 * and calculates where the current inspector would be in the docView.
 * it then scrolls that under the clipview.  any nXm array is ok
 */
- showInspector:(int)inspectNum
{
    NXRect inspectorSize;
    NXRect docSize;
    int	offCols;		/* number of rows and cols offscreen */
    int	curRow,curCol;		/* the number of the row and col to display */
    
    [inspectorView   getFrame:&inspectorSize];
    [offscreenWindow getFrame:&docSize];
    
    offCols = docSize.size.width / inspectorSize.size.width;
    curRow =  inspectNum / offCols;
    curCol =  inspectNum % offCols;
    
    [inspectorView 
    	setDrawOrigin:
    		 curCol * inspectorSize.size.width  +1
    		:curRow * inspectorSize.size.height +1];
    
    if ([delegate respondsTo:@selector(inspectorDidChangeTo:)])
    	[delegate inspectorDidChangeTo:inspectNum];
    
    return self;
} 
 
- placeInspectorView:sender
{
    if (offscreenWindow && inspectorView){
    	/* first make it the doc of the clipview */
	[offscreenWindow removeFromSuperview];
	[inspectorView setDocView: offscreenWindow];
	
	[self showInspector:0];
    }
    return self;
}

/* 
 *
 *	outlet setups
 *
 */
 

- setOffscreenWindow:anObject
{
    offscreenWindow = [anObject contentView];
    [self placeInspectorView:self];
    return self;
}

- setInspectorView:anObject
{
    NXRect viewFrame;
    if (!strcmp([anObject name],"ClipView") ) 
   	 inspectorView = anObject;
    else {
    	/* lets drop a clipview on this thing */
    	[anObject getFrame:&viewFrame];
	viewFrame.origin.x = viewFrame.origin.y = 0.0;
    	inspectorView = [[ClipView alloc] initFrame: &viewFrame];
	[anObject addSubview: inspectorView];
    }
    [self placeInspectorView:self];
    return self;
}

/* 
 *
 *	PUBLIC METHODS (should be anyway)
 *
 */
 
/* this works for any linear matrix of buttons or controls.  
 * it figures out which way the matrix is running and calculates which 
 * control sent message (kind of like tag=position) and causes inspector update
 */
- updateInspector:sender
{
    int numRows,numCols;
    
    [sender getNumRows:&numRows numCols:&numCols];
    if (numRows> numCols){
    	[self showInspector: [sender selectedRow]];
    } else {
    	[self showInspector: [sender selectedCol]];
    }
    return self;
}


@end
