/***************************************************************************/
/* MovingBitmap.m - interface file for MovingBitmap class                  */
/* January 1990 Carl F. Sutter							   */
/***************************************************************************/

#import "MovingBitmap.h"
#import <dpsclient/dpsclient.h>	// for NX_COPY or other compositing op
#import <dpsclient/psops.h>		// for PSsetgray
#import <dpsclient/wraps.h>		// for PScompositerect
#import <appkit/nextstd.h>		// for MIN and MAX
#import <time.h>				// for time
#import <stdlib.h>			// for rand and srand

@implementation MovingBitmap

/***************************************************************************/
/* newFromMachO:inFrame: - make a new bitmap from the given name 		   */
/***************************************************************************/
+ newFromMachO:(const char *)tiffFile inFrame:(NXRect *)limits;
   {
   self = [super new];
   bmpPiece = [Bitmap newFromMachO:tiffFile];
   [bmpPiece getSize:&nxsPiece];
   srand( time( 0 ) );  /* randomize the random number generator */
   flXVel = (float)((rand() % 11) - 5);
   flYVel = (float)((rand() % 11) - 5);
   flXPos = flOldXPos = limits->size.width / 2.0;
   flYPos = flOldYPos = limits->size.height / 2.0;
   [self setFrame:limits];
   return( self );
   } /* newFromMachO:inFrame: 1/25/90 CFS */


/***************************************************************************/
/* setFrame: - set the new bounds for the bitmap's world			   */
/***************************************************************************/
- setFrame:(NXRect *)nxrFrame
   {
   nxrLimits = *nxrFrame;
   nxrLimits.size.width -= nxsPiece.width;
   nxrLimits.size.height -= nxsPiece.height;
   /* if the bitmap is out of the view, move it to the nearest edge */
   flXPos = MIN( NX_MAXX( &nxrLimits ), MAX( NX_X( &nxrLimits ), flXPos ) );
   flYPos = MIN( NX_MAXY( &nxrLimits ), MAX( NX_Y( &nxrLimits ), flYPos ) );
   return( self );
   } /* setFrame: 1/25/90 CFS */
   

/***************************************************************************/
/* setPosition:: - set the current position of the bitmap			   */
/***************************************************************************/
- setPosition:(float)xPos :(float)yPos
   {
   flXPos = xPos;
   flYPos = yPos;
   return( self );
   } /* setPosition:: 1/25/90 CFS */
   

/***************************************************************************/
/* setVelocity:: - set the current velocity of the bitmap			   */
/***************************************************************************/
- setVelocity:(float)xVel :(float)yVel
   {
   flXVel = xVel;
   flYVel = yVel;
   return( self );
   } /* setVelocity:: 1/25/90 CFS */
 

/***************************************************************************/
/* move - move the bitmap by one velocity step, bounce off of walls if hit */
/***************************************************************************/
- move
   {
   /* save current position for erasing */
   flOldXPos = flXPos;
   flOldYPos = flYPos;
   /* move one velocity step */
   flXPos += flXVel;
   flYPos += flYVel;
   /* bounce off of a vertical wall if there is a collision */
   if ((flXPos < NX_X( &nxrLimits )) || (flXPos > NX_MAXX( &nxrLimits )))
      {
      flXPos -= flXVel;
      flXVel = -flXVel;
      }
   /* bounce off of a horizontal wall if there is a collision */
   if ((flYPos < NX_Y( &nxrLimits )) || (flYPos > NX_MAXY( &nxrLimits )))
      {
      flYPos -= flYVel;
      flYVel = -flYVel;
      }
   return( self );
   } /* move 1/25/90 CFS */
   

/***************************************************************************/
/* erase - erase the areas under the old bitmap positions 		  	   */
/* PScompositerect just fills a rectangle with the current color & alpha   */
/***************************************************************************/
- erase
   {
   NXRect   nxrFill = { flOldXPos, flOldYPos, nxsPiece.width, nxsPiece.height };
   
   PSsetgray( NX_LTGRAY );
   PSsetalpha( 1 ); /* opaque */
   PScompositerect( flOldXPos, flOldYPos, nxsPiece.width, nxsPiece.height, NX_SOVER );
   return( self );
   } /* erase 1/25/90 CFS */
   

/***************************************************************************/
/* draw - composite the bitmap to the screen 			      	   */
/***************************************************************************/
- draw
   {
   /* use floor to make the bitmap draw on a unit edge, otherwise it might */
   /* spill over by one pixel */
   NXPoint	nxpPosition = { floor(flXPos), floor(flYPos) };
   
   [bmpPiece composite:NX_SOVER toPoint:&nxpPosition];
   return( self );
   } /* draw 1/25/90 CFS */


@end
