//
//  myView.m
//  myTest
//
//  Created by Dr. H. Nikolaus Schaller on Mon Jan 05 2004.
//  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
//

#import "myView.h"

@implementation NSView (hierarchy)

- (NSString *) _descriptionWithSubviews
{
	NSMutableString *s=[NSMutableString stringWithString:[self description]];
	NSEnumerator *e=[[self subviews] objectEnumerator];
	NSView *v;
	while((v=[e nextObject]))
		{ // prefix all lines with @"  "
		NSString *sub=[v _descriptionWithSubviews];
		NSArray *suba=[sub componentsSeparatedByString:@"\n"];
		[s appendFormat:@"\n  %@", [suba componentsJoinedByString:@"\n  "]];
		}
	return s;
}

@end

@implementation NSTabView (hierarchy)

- (void) awakeFromNib;
{
	[self selectTabViewItemAtIndex:0];
	NSLog(@"awakeFromNib: %@", [self _descriptionWithSubviews]);
	[self selectTabViewItemAtIndex:1];	// switch
	NSLog(@"awakeFromNib: %@", [self _descriptionWithSubviews]);
}

@end

@interface NSGraphicsContext (NSPrivate)
- (void) _setShape:(NSBezierPath *) path;
@end

static NSImage *image;

@implementation myViewFlipped

- (BOOL) isFlipped; { return YES; }

@end

@implementation myView

- (BOOL) isFlipped; { return NO; }

- (void) drawRect:(NSRect)aRect
{
	NSRect r;
	NSPoint pnt;
	NSAffineTransform *atm;
	NSView *v;
	NSLog(@"myView drawRect:%@", NSStringFromRect(aRect));
	NSLog(@" flipped=%d", [self isFlipped]);
	NSLog(@" graphicscontext=%@", [NSGraphicsContext currentContext]);
	NSLog(@" attribs=%@", [[NSGraphicsContext currentContext] attributes]);
	r=NSMakeRect(0.0, 0.0, 10.0, 10.0);	// a small rect
	NSRectFill(r); // draw specified rect in default color
	[[NSColor greenColor] set];
	NSFrameRect(aRect); // draw full rect in green color
	[[NSColor redColor] set];
	r=NSMakeRect(30.0, 20.0, 100.0, 60.0);
	NSFrameRect(r); // draw specified rect in red
	// use default attributes
	[@"Test 0123456789012345 abcdefghij\n\thällö" drawInRect:r withAttributes:[NSDictionary dictionary]];
	NSFrameRect(NSMakeRect(0.0, 10.0, 170.0, 1.0)); // draw line
	[@"Test-gj" drawAtPoint:NSMakePoint(70.0, 10.0) withAttributes:[NSDictionary dictionary]];
	
	if(!image)
		image=[[NSImage imageNamed:@"Lion"] retain];
	NSLog(@"image size=%@", NSStringFromSize([image size]));
	[image setFlipped:![image isFlipped]];	// flip image
	[image compositeToPoint:NSMakePoint(50.0, 130.0) operation:NSCompositeCopy];	// 1
	[image setFlipped:![image isFlipped]];
	[image setSize:NSMakeSize(32.0, 32.0)];
	NSLog(@"image size=%@", NSStringFromSize([image size]));
	[image compositeToPoint:NSMakePoint(50.0, 180.0) operation:NSCompositeCopy];	// 2
	[image recache];
	[image compositeToPoint:NSMakePoint(100.0, 180.0) operation:NSCompositeCopy];	// 3
	[image setScalesWhenResized:YES];
	[image compositeToPoint:NSMakePoint(50.0, 230.0) operation:NSCompositeCopy];	// 4
	[image recache];
	[image drawInRect:r=NSMakeRect(150.0, 210.0, 40.0, 40.0) fromRect:NSZeroRect operation:NSCompositeCopy fraction:0.5];	// 5 this one should scale
	pnt=r.origin;
	[[NSColor redColor] set];
	[NSBezierPath fillRect:NSMakeRect(pnt.x-2.0, pnt.y-2.0, 4.0, 4.0)];	// draw a marker
	[image drawInRect:r=NSMakeRect(150.0, 150.0, 40.0, 40.0) fromRect:NSMakeRect(10.0, 10.0, 20.0, 20.0) operation:NSCompositeSourceOver fraction:1.0];	// 5b this one should scale and show transparence
	pnt=r.origin;
	[NSBezierPath fillRect:NSMakeRect(pnt.x-2.0, pnt.y-2.0, 4.0, 4.0)];	// draw a marker
	atm=[NSAffineTransform transform];
	[atm rotateByDegrees:angle];
	NSLog(@"atm for rotate = %@", atm);
	[atm concat];
	atm=[NSAffineTransform transform];
	[atm translateXBy:10.0 yBy:10.0];
	[atm rotateByDegrees:angle];
	NSLog(@"atm for translate&rotate = %@", atm);
	[[NSColor yellowColor] set];
	[NSBezierPath fillRect:NSMakeRect(150.0, 100.0, 30.0, 30.0)];	// draw rotated rectangle
	[image compositeToPoint:pnt=NSMakePoint(100.0, 230.0) operation:NSCompositeCopy];		// 6 note: this operation does not rotate or scale the image but only the origin
	[NSBezierPath fillRect:NSMakeRect(pnt.x-2.0, pnt.y-2.0, 4.0, 4.0)];	// draw a marker
	[image drawAtPoint:pnt=NSMakePoint(150.0, 230.0) fromRect:NSZeroRect operation:NSCompositeCopy fraction:0.5];	// 7 this one rotates by 5 degrees
	[NSBezierPath fillRect:NSMakeRect(pnt.x-2.0, pnt.y-2.0, 4.0, 4.0)];	// draw a marker
	r=NSMakeRect(150.0, 20.0, 100.0, 60.0);
	[@"Rotated Text" drawInRect:r withAttributes:nil];
	[@"Red Text" drawAtPoint:NSMakePoint(150.0, 40.0) withAttributes:[NSDictionary dictionaryWithObject:[NSColor redColor]
																								 forKey:NSForegroundColorAttributeName]];
	v=nil;
	NSLog(@"convertPoint:%@ fromView:%@ -> %@", NSStringFromPoint(r.origin), v, NSStringFromPoint([self convertPoint:r.origin fromView:v]));
	NSLog(@"convertPoint:%@ toView:%@ -> %@", NSStringFromPoint(r.origin), v, NSStringFromPoint([self convertPoint:r.origin toView:v]));
	NSLog(@"convertSize:%@ fromView:%@ -> %@", NSStringFromSize(r.size), v, NSStringFromSize([self convertSize:r.size fromView:v]));
	NSLog(@"convertSize:%@ toView:%@ -> %@", NSStringFromSize(r.size), v, NSStringFromSize([self convertSize:r.size toView:v]));
	NSLog(@"convertRect:%@ fromView:%@ -> %@", NSStringFromRect(r), v, NSStringFromRect([self convertRect:r fromView:v]));
	NSLog(@"convertRect:%@ toView:%@ -> %@", NSStringFromRect(r), v, NSStringFromRect([self convertRect:r toView:v]));
	// CHECKME: what about rotated view transformation? Does convertRect return a converted bounding box???
}

- (void) animation;
{
	angle+=10.0;
	NSLog(@"animation: angle=%f", angle);
	[self setNeedsDisplay:YES];
	[self performSelector:_cmd withObject:nil afterDelay:0.1];
	[boundsRotationView setBoundsRotation:angle];
	[boundsRotationView setNeedsDisplay:YES];
	[frameRotationView setFrameRotation:angle];
	[frameRotationView setNeedsDisplay:YES];
}

- (void) mouseDown: (NSEvent*) event;
{
	NSLog(@"mouseDown: %@", event);
	NSLog(@"focus view: %@", [NSView focusView]);	// should be nil!
	NSLog(@"graphics context: %@", [NSGraphicsContext currentContext]);
#if 0
	{
	NSRect f;
	NSBezierPath *bp;
	NSLog(@"mouseDown: %@", event);
	NSLog(@"focus view: %@", [NSView focusView]);	// should be nil!
	NSLog(@"graphics context: %@", [NSGraphicsContext currentContext]);
	f=[self frame];	// we define the frame...
	bp=[NSBezierPath bezierPathWithOvalInRect:f];
	[self lockFocus];
	[[NSGraphicsContext currentContext] _setShape:bp];	// this should make the window oval...
	[self unlockFocus];
	}
#endif
	[NSObject cancelPreviousPerformRequestsWithTarget:self];	// cancel any still running timer
	angle=-5.0;	// restart
	[self animation];
}

#if 0
NSString *flags(unsigned char *addr)
{
	NSString *str=@"";
	int i;
	for(i=64-8; i<64+8; i++)
		{
		str=[str stringByAppendingFormat:@"%02x", addr[i]];
		}
	return str;
}
#endif

- (void) awakeFromNib;
{
	NSView *cv;
	NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
	NSLog(@"window frame %@", NSStringFromRect([[self window] frame]));
	cv=[[self window] contentView];
	NSLog(@"view frame %@", NSStringFromRect([cv frame]));
	NSLog(@"view bounds %@", NSStringFromRect([cv bounds]));
//	[cv scaleUnitSquareToSize:NSMakeSize(0.5, 0.5)];	mySTEP does not handle scaling
	[cv setNeedsDisplay:YES];
	NSLog(@"view frame %@", NSStringFromRect([cv frame]));
	NSLog(@"view bounds %@", NSStringFromRect([cv bounds]));
	image=[[NSImage imageNamed:@"Default"] copy];
	NSLog(@"Default image=%@", image);
	NSLog(@"Default size=%@", NSStringFromSize([image size]));
	[[self window] makeKeyAndOrderFront:nil];
#if 0
	{
		int i=NSNoImage;
	NSButtonCell *bc=[[NSButtonCell alloc] init];
	NSLog(@"\n_CFlags=%@", flags(bc));
	for(i=0; i<=NSImageOverlaps; i++)
		{
		[bc setImagePosition:i];
		NSLog(@"imagePosition=%d\n_CFlags=%@", [bc imagePosition], flags(bc));
		}
	}
#endif
	angle=5.0;
}

@end

/* Findings:

NSString:
drawInRect always starts at the top left edge of the box
The horizontal bar of the letter T starts approx. 2-3 pixels below
The left edge touches the surrounding box
Text wraps to next line at blank characters - overlong lines are cut off

drawAtPoint either draws below (if flipped) or above (if not flipped) the specified point
If drawing is above, the descenders are touching the origin
If drawing is below, it starts approx. 2-3 pixels below

*/

@implementation CalcButton
@end

@implementation SilverBox
@end
