
#import "InfoView.h"

#import <math.h>

#define RANDINT(n) (rand() % ((n)+1))		 

inline float restrictValue(float val, float max, float min)
{
	if (val > max)
		return max;
    	else if (val < min)
		return min;
    	else
		return val;
}

@implementation InfoView

- initWithFrame:(NSRect)frameRect;
{
  	[super initWithFrame:frameRect];	
   	oldImage = frontImage = [NSImage imageNamed:@"OutOfTheWood"];
	image = [NSImage imageNamed:@"Credits"];
   	bat = [NSImage imageNamed:@"bat"];
	toggle = YES;
   	imageSize = [image size];
	batSize = [bat size];
   	buffer = [[NSImage alloc] initWithSize:imageSize];  	
	[self compositeWithDissolve:NO andDelta:0.0];
	frontPage = YES;
	animateTimer = nil;
   	return self;
}
   
- (void)dealloc;
{
	[self removeTimer];
   	[image release];
   	[oldImage release];
   	[buffer release];
	[bat release]; 
   	return [super dealloc];
}

- (void)compositeWithDissolve:(BOOL)aBool andDelta:(float)aDelta
{
	NSPoint pt = {0.0,0.0};

   	[buffer lockFocus];
  	[oldImage compositeToPoint:pt operation:NSCompositeCopy];
   	if(aBool)
   		[image dissolveToPoint:pt fraction:aDelta];    
   	[buffer unlockFocus]; 
}

- (void)compositeWithChecker:(BOOL)aBool andDelta:(float)aDelta
{
    NSRect rects[64], r;
    NSSize imgSize,rectSize;
    NSPoint pt = {0.0,0.0};
    float height,h;
    int x, y, index;
	id img;
    
    [buffer lockFocus];
	[oldImage compositeToPoint:pt operation:NSCompositeCopy];
	if(!aBool){
		[buffer unlockFocus];
		return;
	}
    imgSize = [image size];
    img = [[NSImage alloc] initWithSize:imgSize];
    rectSize.width = imgSize.width / 8;
    rectSize.height = imgSize.height / 8;
    height = 2 * aDelta * rectSize.height;
    h = height - rectSize.height;
    for(x = 0; x < 8; x ++){
		for(y = 0; y < 8; y ++){
	    	index = x + y * 8;
	    	if(height > rectSize.height){
				if((x % 2) == (y % 2)){
		    		rects[index] = NSMakeRect(x * rectSize.width, (y + 1) * rectSize.height - h, rectSize.width, h);
				} else {
		    		rects[index] = NSMakeRect(x * rectSize.width, y * rectSize.height, rectSize.width, rectSize.height);
				}
	    	} else {
				if((x % 2) != (y % 2)){
		    		rects[index] = NSMakeRect(x * rectSize.width, y * rectSize.height, rectSize.width, height);
				} else {
		   			rects[index] = NSMakeRect(0, 0, 0, 0);
				}
	    	}
		}
    }
    [img lockFocus];
    PSsetgray(0.0);
    PSsetalpha(0.0);
    r = NSMakeRect(0, 0, imgSize.width, imgSize.height);
    NSRectFill(r);
    PSsetalpha(1.0);
    NSRectFillList(rects,64);
    [image compositeToPoint:pt operation:NSCompositeSourceIn];
    [img unlockFocus];
    [img compositeToPoint:pt operation:NSCompositeSourceOver];
    [buffer unlockFocus];
    [img release]; 
}

- (void)drawRect:(NSRect)rect;
{
   NSPoint p = {0.0, 0.0};
	
   PSsetgray(NSLightGray);
   NSRectFill([self bounds]);
   [buffer compositeToPoint:p operation:NSCompositeCopy];
}

- (void)mouseDown:(NSEvent *)thisEvent 
{
   	delta = 0.0;		
   	[self compositeWithDissolve:NO andDelta:delta];
    	[self display];
	animationDissolve =YES;
	animationCrowl = NO;
	animationStep = 0; 
	if(!animateTimer)
		animateTimer = [[NSTimer scheduledTimerWithTimeInterval:.03 
			target:self selector:@selector(animationClick:) 
			userInfo:self repeats:YES] retain];
}

- (void)start:sender
{
	[self display];
	[self removeTimer];
	animationDissolve = NO;
	animationCrowl = YES;
	animationStep = 0;
	randDirection = 0;
	batRect.origin.y = 50.0;
	batRect.origin.x = 50.0;
	batRect.size.width = batSize.width;
	batRect.size.height = batSize.height / 4;
	if(!animateTimer)
		animateTimer = [[NSTimer scheduledTimerWithTimeInterval:.03 
			target:self selector:@selector(animationClick:) 
			userInfo:self repeats:YES] retain]; 
}

- (void)stop:(id)sender
{
	[self removeTimer];
}

- (void)animationClick:(NSTimer *)timer
{
	if(animationCrowl)
		[self animateCrowl];
	if(animationDissolve)
		[self animateDissolve];
	PSWait(); 
}

- (void)animateCrowl
{
	NSRect tmpRect;
	int nr;

	[self lockFocus];
		[self drawBackground:batRect];
		if(animationStep % 11 == 0)
			randDirection = RANDINT(7);
		switch(randDirection){
			case 0 :batRect.origin.x += 1;
					break;
			case 1 :batRect.origin.x += 1;
					batRect.origin.y += 1;
					break;
			case 2 :batRect.origin.y += 1;
					break;
			case 3 :batRect.origin.x -= 1;
					batRect.origin.y += 1;
					break;
			case 4 :batRect.origin.x -= 1;
					break;
			case 5 :batRect.origin.x -= 1;
					batRect.origin.y -= 1;
					break;
			case 6 :batRect.origin.y -= 1;
					break;
			case 7 :batRect.origin.x += 1;
					batRect.origin.y -= 1;
					break;
		}	
		animationStep++;
		batRect.origin.x = restrictValue(batRect.origin.x,200,50);
		batRect.origin.y = restrictValue(batRect.origin.y,230,50);
		tmpRect = NSMakeRect(0, 0, batSize.width, batSize.height / 4);
		nr = animationStep % 8;
		switch(nr){
			case 1:
			case 6:
					tmpRect.origin.y += batSize.height / 4;
					break;
			case 2:
			case 5:
					tmpRect.origin.y += batSize.height / 2;
					break;
			case 3:
			case 4:
					tmpRect.origin.y += 3 * batSize.height / 4;
					break;
		}
		[bat compositeToPoint:batRect.origin fromRect:tmpRect operation:NSCompositeSourceOver];
		[[self window] flushWindow];
	[self unlockFocus]; 
}

- (void)animateDissolve
{
	id dummy;

	delta = delta + 0.20;
	if(toggle)
		[self compositeWithDissolve:YES andDelta:delta];
	else
		[self compositeWithChecker:YES andDelta:delta];
	[self display];
	if(delta < 1.0)
		return;
	toggle = !toggle;
	dummy = oldImage;
    	oldImage = image;
    	image = dummy;
	frontPage = (!frontPage);
	[self removeTimer];
	if(frontPage)
		[self start:self]; 
}

- (void)removeTimer
{
	if(animateTimer){
		[animateTimer invalidate]; 
		[animateTimer release];
		animateTimer = nil;
	} 
}

- (void)drawBackground:(NSRect)rect
{
    NSRect tmpRect = rect;

    tmpRect.origin.x = floor(NSMinX(tmpRect));
    tmpRect.origin.y = floor(NSMinY(tmpRect));
    if ([[NSDPSContext currentContext] isDrawingToScreen]) {
		PSsetgray(NSWhite);
		PScompositerect(NSMinX(tmpRect), NSMinY(tmpRect),
			 			 NSWidth(tmpRect), NSHeight(tmpRect), NSCompositeSourceOver);
    }
    [frontImage compositeToPoint:tmpRect.origin fromRect:tmpRect operation:NSCompositeSourceOver]; 
}

- (BOOL)windowShouldClose:(id)sender
{
	id dummy;
	
	[self stop:self];
	if(!frontPage){
		toggle = !toggle;
		frontPage = YES;
		dummy = oldImage;
    	oldImage = image;
    	image = dummy;
		[self compositeWithDissolve:NO andDelta:0.0];
	}
	return YES;
}


@end
