
// Copyright (c) 1997 by Don Yacktman
// All rights reserved.
// Permission to use this code in your application, whether
// commercial, shareware, or freeware, is granted.
// This notice may not be removed or altered.


#import "FlyingWindow.h"
#import <libc.h>

static id contentImage = nil;

@implementation FlyingWindow

- initAt:(NSPoint *)thePoint
{
	// set up window with image and put it on the screen centered at thePoint
	NSRect theFrame;
    // make sure we have the mini-envelope image loaded
	if (!contentImage)
        contentImage = [NSImage imageNamed:@"FlyingIcon.tiff"];
    // set up our frame (where we'll be on the screen and our size)
    // get the size from the image
	theFrame.size = [contentImage size];
    // place our selves on the screen so that our center is at the
	// point passed in by the caller of this method
	theFrame.origin.x = thePoint->x - NSWidth(theFrame) / 2;
	theFrame.origin.y = thePoint->y - NSHeight(theFrame) / 2;
    // call the superclass designate initializer to set ourself up.
	[self initWithContentRect:theFrame styleMask:NSBorderlessWindowMask backing:NSBackingStoreRetained defer:NO screen:NULL];
	// set up a new random velocity vector
	velocity.x = (random() % HORIZ_JUMPS) - HORIZ_JUMPS / 2;
	velocity.y = (random() % VERT_JUMPS) + MIN_VERT;

    // create an NSImageView and insert it into ourself so that
	// the mini-envelope image will be displayed
    {
        NSImageView *imageView = [[NSImageView alloc] initWithFrame:[[self contentView] frame]];
        [imageView setImage:contentImage];
        [imageView setImageAlignment:NSImageAlignCenter]; // this is redundant since it is the default
        [imageView setImageFrameStyle:NSImageFrameNone]; // this is redundant since it is the default
        [imageView setImageScaling:NSScaleNone]; // make sure the image isn't resized at all
        [imageView setEditable:NO]; // make sure no one can replace the image by dragging in a new one
        [[self contentView] addSubview:imageView];
    }
	// put us on the screen immediately
    [self orderFront:nil];
	return self;
}

- reInitAt:(NSPoint *)thePoint
{	// re-init the window as above, but for already created window.
    // ideally, the code above should call this method and not be a
	// cut and paste job.  The problem is that some of the things
    // need to be set up in varying orders between the two methods.
    // So we'd have to break the initializations into seperate private
    // methods and call those methods from this and the above method.
    // To reduce complexity in this example, I chose to not do that,
    // even though IMHO it is a better design.
    // get the frame size
	NSSize theSize;
	theSize = [contentImage size];
    // reset our position on the screen, as above, so that we are centered on thePoint
	[self setFrameOrigin:NSMakePoint((thePoint->x - theSize.width / 2), (thePoint->y - theSize.height / 2))];
    // set up a new random velocity vector
	velocity.x = (random() % HORIZ_JUMPS) - HORIZ_JUMPS / 2;
	velocity.y = (random() % VERT_JUMPS) + MIN_VERT;
    // put us on the screen
	[self orderFront:nil];
	return self;
}

- move
{	// move us one animation step.
    // get our window's frame
	NSRect theFrame = [self frame];
    // Move ourself by the amount our present velocity requires
	[self setFrameOrigin:NSMakePoint((NSMinX(theFrame) + velocity.x), (NSMinY(theFrame) + velocity.y))];
    // update the velocity, taking gravity into account
	velocity.y -= GRAVITY;
	return self;
}

- (BOOL)onScreen
{	// are we still on the screen, or did we move out of bounds?
    NSRect theFrame = [self frame];
    NSScreen *myscreen = [self screen];

    // normalize (translate) to the screen's position
	theFrame.origin.x -= [myscreen frame].origin.x;
    theFrame.origin.y -= [myscreen frame].origin.y;
	// consider us on screen if we're off the top since we'll be
	// coming back down sometime
    if (!myscreen) { // no screen returned?  Use standard NeXT screen size
		if ((NSMaxX(theFrame) < 0) || (NSMaxY(theFrame) < 0) ||
				(NSMinX(theFrame) > 1120.0)) return NO;
		return YES;
	}
	// if we are off the left, right, or bottom side of the screen,
	// then we are off the screen.
    if ((NSMaxX(theFrame) < NSMinX(([myscreen frame]))) ||
        (NSMinX(theFrame) > NSMaxX(([myscreen frame]))) ||
        (NSMaxY(theFrame) < NSMinY(([myscreen frame])))) {
		return NO;
	}
    // otherwise, we're on the screen.
	return YES;
}

@end