/***************************************************************************/
/* TestView.m - implementation file for TestView class                     */
/* January 1990 Carl F. Sutter							   */
/* This view is a simple animated bitmap test to see how fast they can     */
/* move around.  The bitmaps are handled by the MovingBitmap class         */
/***************************************************************************/

#import "TestView.h"
#import <stdio.h>		// for fprintf REMOVE THIS AFTER DEBUGGING
#import <string.h>		// for sprintf
#import <dpsclient/psops.h>	// for PSsetgray
#import <appkit/Control.h>	// for setIntValue
#import <appkit/Cell.h>  	// for setEnabled
#import <appkit/nextstd.h>	// for MIN and MAX

@implementation TestView

/***************************************************************************/
/* newFrame: - initialize the new view for the bitmaps to bounce around in */
/***************************************************************************/
- initFrame:(NXRect *)rect
   {
   [super initFrame:rect];
   listMB = [[List alloc] init];			// new list to hold MovingBitmaps
   bMoving = NO;
   bGState = NO;
   bPing = NO;
   bEraseBackground = NO;
   bEraseBitmaps = YES;
   bTightDrawLoop = NO;
   bRandomVelocity = YES;
   dPeriod = 0.0;
   timer = [[Animator alloc] initChronon:dPeriod adaptation:0.0 target:self
                     action:@selector(step:) autoStart:NO eventMask:NX_ALLEVENTS];
   return( self );
   } /* newFrame: 1/25/89 CFS */


/***************************************************************************/
// appDidInit - Delegate message sent after application is set up.
// The Views's window instance variable is now set, so it's size can be 
// found.  Now find the minimum window size for a view of 1x1.
/***************************************************************************/
- appDidInit:(id)sender
   {
   NXRect	nxrWinFrame;
  
   [window getFrame:&nxrWinFrame];	
   nxsMinWindow.width = nxrWinFrame.size.width; /* controls cross whole bottom */
   nxsMinWindow.height = nxrWinFrame.size.height - bounds.size.height + 1.0;
   return( self );
   } /* appDidInit 8/16/89 CFS */
   

/***************************************************************************/
// windowWillResize - Delegate message sent from main window.
// Prevent window from getting so small that the view size is zero.
/***************************************************************************/
- windowWillResize:sender toSize:(NXSize *)frameSize
   {
   frameSize->width  = MAX( frameSize->width,  nxsMinWindow.width );
   frameSize->height = MAX( frameSize->height, nxsMinWindow.height );
   return( self );
   } /* windowWillResize 9/14/89 CFS */
   

/***************************************************************************/
// windowDidResize - Delegate message sent from main window.
// After sizing, reset the limits for the moving bitmaps
/***************************************************************************/
- windowDidResize:sender;
   {
   [listMB makeObjectsPerform:@selector( setFrame: ) with:(id)&bounds];
   return( self );
   } /* windowDidResize 9/14/89 CFS */
   

/***************************************************************************/
/* setPeriod: - changes the period of the timer object			   */
/***************************************************************************/
- setPeriod:sender
   {
   dPeriod = [timerPeriod doubleValue];
   
   [timer free];
   timer = [[Animator alloc] initChronon:dPeriod adaptation:dPeriod target:self
                     action:@selector(step:) autoStart:bMoving eventMask:NX_ALLEVENTS];
   return( self );
   } /* setPeriod: 1/25/90 CFS */


/***************************************************************************/
/* start: - start or stop the timer, and thus the animation			   */
/***************************************************************************/
- start:sender
   {
   bMoving = !bMoving;
   if (bMoving) [timer startEntry];
   else [timer stopEntry];
   return( self );
   } /* start: 1/25/90 CFS */
   
   
/***************************************************************************/
/* step: - step the animation once, called from the timer object		   */
/***************************************************************************/
- step:sender
   {
   if (bTightDrawLoop)
      { /* keep drawing until an event happens - disregards timer delay! */
      [self lockFocus];
      while (![timer shouldBreak])
         {
         [listMB makeObjectsPerform:@selector( move )];
	 [self drawBitmaps];
	 [window flushWindow];
	 }
      [self unlockFocus];
      }
   else /* just draw once */
      {   
      [listMB makeObjectsPerform:@selector( move )];
      [self display];
      }
   return( self );
   } /* step: 1/25/90 CFS */
  
   
/***************************************************************************/
/* create: - make a new moving bitmap, and add it to the list 		   */
/***************************************************************************/
- create:sender
   {
   MovingBitmap	*mbNew;
   char			szTiffFile[40];
   int			nSize;
   
   nSize = [[size selectedCell] tag];
   sprintf( szTiffFile, "%dx%d.tiff", nSize, nSize );

   mbNew = [[MovingBitmap alloc] initFromMachO:szTiffFile inFrame:&bounds];
   if (!bRandomVelocity)
      [mbNew setVelocity:[xVel floatValue] :[yVel floatValue]];
   [listMB addObject:mbNew];
   
   [count setIntValue:[listMB count]];
   [self display];
   return( self );
   } /* create: 1/25/90 CFS */
   
   
/***************************************************************************/
/* removeOne: - remove the last bitmap on the list - the last one created  */
/***************************************************************************/
- removeOne:sender
   {
   BOOL	 bSave = bEraseBackground;
   
   [listMB removeLastObject];
   [count setIntValue:[listMB count]];
   bEraseBackground = TRUE;
   [self display];
   bEraseBackground = bSave;
   return( self );
   } /* removeOne: 1/25/90 CFS */
   

/***************************************************************************/
/* allocateGState: - toggle GState allocation to this view			   */
/***************************************************************************/
- allocateGState:sender
   {
   bGState = !bGState;
   if (bGState) [self allocateGState];	// For faster lock/unlockFocus
   else [self freeGState];
   return( self );
   } /* allocateGState: 1/25/90 CFS */
   

/***************************************************************************/
/* Boolean toggling action methods							   */
/***************************************************************************/
- nxPing:sender          {bPing = !bPing;                      return( self );}
- eraseBackground:sender {bEraseBackground = !bEraseBackground;return( self );}
- eraseBitmaps:sender    {bEraseBitmaps = !bEraseBitmaps;      return( self );}
- tightDrawLoop:sender   {bTightDrawLoop = !bTightDrawLoop;    return( self );}
 
   
/***************************************************************************/
/* randomVel: - toggles random velocity for new bitmaps & enables fields   */
/***************************************************************************/
 - randomVel:sender;
   {
   bRandomVelocity = !bRandomVelocity;
   [xVel setEnabled:!bRandomVelocity];
   [yVel setEnabled:!bRandomVelocity];
   return( self );
   } /* randomVel: 1/25/90 CFS */
   

/***************************************************************************/
/* drawBitmaps - draw the bitmaps							   */
/***************************************************************************/
- drawBitmaps
   {
   if (bEraseBackground)
      {
      PSsetgray( NX_LTGRAY );
      NXRectFill( &bounds );
      }
   if (bEraseBitmaps) [listMB makeObjectsPerform:@selector( erase )];
   [listMB makeObjectsPerform:@selector( draw )];
   if (bPing) NXPing();
   } /* drawBitmaps 1/25/90 CFS */
   

/***************************************************************************/
/* drawSelf:: - draw the current view						   */
/***************************************************************************/
- drawSelf:(NXRect *)r :(int) count
   {
   [self drawBitmaps];
   return( self );
   } /* drawSelf:: 1/25/90 CFS */


@end
