#include "GSDrawFunctions.h"

@implementation GSDrawFunctions (theme)
/*
+ (NSRect) drawButton: (NSRect)border : (NSRect)clip
{ 
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y +1, border.size.width -=2, border.size.height -=2);
	[path appendBezierPathWithRect: r];
	[[NSColor colorWithCalibratedRed: 0.3 green: 0.3 blue: 0.4 alpha: 0.8] set];
	[path setLineWidth: 1.5];
	[path stroke];
}

+ (NSRect) drawDarkButton: (NSRect)border : (NSRect)clip
{ 
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y +1, border.size.width -=2, border.size.height -=2);
	//[path appendBezierPathWithRoundedRectangle: r withRadius: 8.0];
	[path appendBezierPathWithRect: r];
	[[NSColor colorWithCalibratedRed: 0.3 green: 0.3 blue: 0.4 alpha: 0.8] set];
	[path setLineWidth: 1.5];
	[path stroke];
}
*/

+ (NSRect) drawGrayBezelRound: (NSRect)border : (NSRect)clip
{ 
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSBezierPath* path2 = [NSBezierPath bezierPath];
	NSBezierPath* inside = [NSBezierPath bezierPath];
	
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y +3, border.size.width -4, border.size.height -4);
	NSRect r2 = NSMakeRect (border.origin.x + 3, border.origin.y +1, border.size.width -4, border.size.height -4);
	NSRect r3 = NSMakeRect (border.origin.x + 2, border.origin.y +2, border.size.width -4, border.size.height -4);
	float radius = 8;
	if ((border.size.height < 20) || (border.size.width < 20)) { radius = 4; }
	if ((border.size.height < 10) || (border.size.width < 10)) { radius = 2; }
	[path appendBezierPathWithRoundedRectangle: r withRadius: radius];
	[path2 appendBezierPathWithRoundedRectangle: r2 withRadius: radius];
	[inside appendBezierPathWithRoundedRectangle: r3 withRadius: radius];
	[[NSColor colorWithCalibratedRed: 0.3 green: 0.3 blue: 0.4 alpha: 0.8] set];
	[path setLineWidth: 1.5];
	[path2 setLineWidth: 2.5];
	[[NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 0.7] set];
	[path2 stroke];
 	[[NSColor blackColor] set];
	[path stroke];
	[[NSColor windowBackgroundColor] set];
	[inside fill];
	return r3;
}
+ (NSRect) drawGrayBezel: (NSRect)border : (NSRect)clip
{ 
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSBezierPath* path2 = [NSBezierPath bezierPath];
	NSBezierPath* inside = [NSBezierPath bezierPath];
	
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y +3, border.size.width -4, border.size.height -4);
	NSRect r2 = NSMakeRect (border.origin.x + 3, border.origin.y +1, border.size.width -4, border.size.height -4);
	NSRect r3 = NSMakeRect (border.origin.x + 2, border.origin.y +2, border.size.width -4, border.size.height -4);
	[path appendBezierPathWithRect: r];
	[path2 appendBezierPathWithRect: r2];
	[inside appendBezierPathWithRect: r3];
	[[NSColor colorWithCalibratedRed: 0.3 green: 0.3 blue: 0.4 alpha: 0.8] set];
	[path setLineWidth: 1.5];
	[path2 setLineWidth: 2.5];
	[[NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 0.7] set];
	[path2 stroke];
 	[[NSColor blackColor] set];
	[path stroke];
	[[NSColor windowBackgroundColor] set];
	[inside fill];
	return r3;
}
+ (NSRect) drawGroove: (NSRect)border : (NSRect)clip
{ 
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSBezierPath* path2 = [NSBezierPath bezierPath];
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y +3, border.size.width -4, border.size.height -4);
	NSRect r2 = NSMakeRect (border.origin.x + 3, border.origin.y +1, border.size.width -4, border.size.height -4);
	float radius = 8;
	if ((border.size.height < 20) || (border.size.width < 20)) { radius = 4; }
	if ((border.size.height < 10) || (border.size.width < 10)) { radius = 2; }
	[path appendBezierPathWithRoundedRectangle: r withRadius: radius];
	[path2 appendBezierPathWithRoundedRectangle: r2 withRadius: radius];
	[[NSColor colorWithCalibratedRed: 0.3 green: 0.3 blue: 0.4 alpha: 0.8] set];
	[path setLineWidth: 1.5];
	[path2 setLineWidth: 2.5];
	[[NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 0.5] set];
	[path2 stroke];
 	[[NSColor blackColor] set];
	[path stroke];
}

////

+ (void) drawBrowserHeaderInRect: (NSRect) frame
{
	NSBezierPath* path = [NSBezierPath bezierPath];
	[path appendBezierPathWithRect: NSMakeRect(frame.origin.x,frame.origin.y,frame.size.width-1,frame.size.height-1)];
	NSColor* start = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0];
	NSColor* end   = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];
	NSRect topFrame = NSMakeRect (frame.origin.x,frame.origin.y+frame.size.height/2,
				frame.size.width,frame.size.height/2);
	NSRect bottomFrame = NSMakeRect (frame.origin.x,frame.origin.y,frame.size.width,
				frame.size.height/2);
	[GSDrawFunctions drawVerticalGradient: start to: end frame: topFrame];
	[GSDrawFunctions drawVerticalGradient: end to: start frame: bottomFrame];
	[GSDrawFunctions drawVerticalGradient: start to: end frame: frame];
	[[NSColor blackColor] set];
	[path setLineWidth: 1.5];
	[path stroke];
}

+ (void) drawTableHeaderInRect: (NSRect) frame
{
	NSBezierPath* line = [NSBezierPath bezierPath];
	[line moveToPoint: NSMakePoint (frame.origin.x, frame.origin.y + 1)];
	[line lineToPoint: NSMakePoint (frame.origin.x + frame.size.width - 1, frame.origin.y + 1)];
	[line lineToPoint: NSMakePoint (frame.origin.x + frame.size.width - 1, frame.origin.y + frame.size.height)];
	[[NSColor colorWithCalibratedRed: 0.6 green: 0.6 blue: 0.7 alpha: 1.0] set];
	NSColor* start = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0];
	NSColor* end   = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];
	NSRect topFrame = NSMakeRect (frame.origin.x,frame.origin.y+frame.size.height/2,
				frame.size.width,frame.size.height/2);
	NSRect bottomFrame = NSMakeRect (frame.origin.x,frame.origin.y,frame.size.width,
				frame.size.height/2);
	[GSDrawFunctions drawVerticalGradient: start to: end frame: topFrame];
	[GSDrawFunctions drawVerticalGradient: end to: start frame: bottomFrame];
	[GSDrawFunctions drawVerticalGradient: start to: end frame: frame];
	[[NSColor blackColor] set];
	[line setLineWidth: 1.5];
	[line stroke];
}

+ (void) drawTableHeaderCellInRect: (NSRect) frame highlighted: (BOOL) highlighted 
{
	NSBezierPath* line = [NSBezierPath bezierPath];
	NSBezierPath* separation = [NSBezierPath bezierPath];
	[line moveToPoint: NSMakePoint (frame.origin.x, frame.origin.y)];
	[line lineToPoint: NSMakePoint (frame.origin.x + frame.size.width, frame.origin.y)];
	[separation moveToPoint: NSMakePoint (frame.origin.x + frame.size.width - 1, frame.origin.y + 1)];
	[separation lineToPoint: NSMakePoint (frame.origin.x + frame.size.width - 1, frame.origin.y + frame.size.height)];
	NSColor* start = [NSColor colorWithCalibratedRed: 0.6 green: 0.6 blue: 0.6 alpha: 1.0];
	NSColor* end   = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];
	NSRect topFrame = NSMakeRect (frame.origin.x,frame.origin.y+frame.size.height/2,
				frame.size.width,frame.size.height/2);
	NSRect bottomFrame = NSMakeRect (frame.origin.x,frame.origin.y,frame.size.width,
				frame.size.height/2);

	if (highlighted)
	{
		[GSDrawFunctions drawVerticalGradient: start to: end frame: topFrame];
		[GSDrawFunctions drawVerticalGradient: end to: start frame: bottomFrame];
		[GSDrawFunctions drawVerticalGradient: start to: end frame: frame];
	}

	[[NSColor lightGrayColor] set];
	[separation setLineWidth: 1.5];
	[separation stroke];
	[[NSColor blackColor] set];
	[line setLineWidth: 1.5];
	[line stroke];
}

+ (void) drawGradient: (NSData*) gradient withSize: (NSArray*) size 
	border: (NSRect) border
{
        NSAffineTransform *transform;
	NSDictionary* shader;

	transform=[[NSAffineTransform alloc] init];
	transform->matrix.m11=border.size.width;
	transform->matrix.m12=0.0;
	transform->matrix.m21=0.0;
	transform->matrix.m22=border.size.height;
	transform->matrix.tX=border.origin.x;
	transform->matrix.tY=border.origin.y;

	shader = [[NSDictionary alloc] initWithObjectsAndKeys:
			[NSNumber numberWithInt: 1], @"ShadingType",
			[NSArray arrayWithObjects:
				[NSNumber numberWithFloat: 0.0],
				[NSNumber numberWithFloat: 1.0],
				[NSNumber numberWithFloat: 0.0],
				[NSNumber numberWithFloat: 1.0], nil], @"Domain",
			transform, @"Matrix",
                        [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt: 0],@"FunctionType",
                                [NSArray arrayWithObjects:
                                        [NSNumber numberWithFloat: 0.0], // origin.x
                                        [NSNumber numberWithFloat: 1.0], // x + width
                                        [NSNumber numberWithFloat: 0.0], // origin.y
                                        [NSNumber numberWithFloat: 1.0], // y + height
                                        nil],
                                        @"Domain",
                                [NSArray arrayWithObjects:
                                        [NSNumber numberWithFloat: 0.0],
                                        [NSNumber numberWithFloat: 1.0],
                                        [NSNumber numberWithFloat: 0.0],
                                        [NSNumber numberWithFloat: 1.0],
                                        [NSNumber numberWithFloat: 0.0],
                                        [NSNumber numberWithFloat: 1.0],
                                        nil],
                                        @"Range",
                                [NSNumber numberWithInt: 8],@"BitsPerSample",
				size, @"Size",
                                gradient ,@"DataSource",
                                nil], @"Function", 
			nil];

        PSshfill(shader);
	[transform release];
	//[shader release]; //FIXME ..
}

+ (void) drawHorizontalGradient: (NSColor*) start to: (NSColor*) end frame: (NSRect) frame
{

	unsigned char * data;
	int datasize = 6 * sizeof (unsigned char);
	data = malloc (datasize);

	data [0] = [start redComponent] * 255;
	data [1] = [start greenComponent] * 255;
	data [2] = [start blueComponent] * 255;
	data [3] = [end redComponent] * 255;
	data [4] = [end greenComponent] * 255;
	data [5] = [end blueComponent] * 255;

	NSData* gradient = [NSData dataWithBytesNoCopy: data length: datasize];
	NSArray* size = [NSArray arrayWithObjects: [NSNumber numberWithInt: 2], [NSNumber numberWithInt: 1], nil];
	[GSDrawFunctions drawGradient: gradient withSize: size border: frame];
	free (data);
}

+ (void) drawVerticalGradient: (NSColor*) start to: (NSColor*) end frame: (NSRect) frame
{

	unsigned char * data;
	int datasize = 6 * sizeof (unsigned char);
	data = malloc (datasize);

	data [0] = [start redComponent] * 255;
	data [1] = [start greenComponent] * 255;
	data [2] = [start blueComponent] * 255;
	data [3] = [end redComponent] * 255;
	data [4] = [end greenComponent] * 255;
	data [5] = [end blueComponent] * 255;

	NSData* gradient = [NSData dataWithBytesNoCopy: data length: datasize];
	NSArray* size = [NSArray arrayWithObjects: [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 2], nil];
	[GSDrawFunctions drawGradient: gradient withSize: size border: frame];
	free (data);
}

+ (void) drawDiagonalGradient: (NSColor*) start to: (NSColor*) end frame: (NSRect) frame direction: (int) direction
{

	unsigned char * data;
	int datasize = 12 * sizeof (unsigned char);
	data = malloc (datasize);
	float startR,startG,startB;
	float midR,midG,midB;
	float endR,endG,endB;
	
	startR = [start redComponent];
	startG = [start greenComponent];
	startB = [start blueComponent];
	endR = [end redComponent];
	endG = [end greenComponent];
	endB = [end blueComponent];
	if (endR > startR) midR = endR - startR;
	else midR = startR - endR;
	if (endG > startG) midG = endG - startG;
	else midG = startG - endG;
	if (endB > startB) midB = endB - startB;
	else midB = startB - endB;

	midR = startR + (midR/2);
	midG = startG + (midG/2);
	midB = startB + (midB/2);

	if (direction == 0) // bottom left to top right
	{
		data [0] = startR * 255;
		data [1] = startG * 255;
		data [2] = startB * 255;

		data [3] = midR * 255;
		data [4] = midG * 255;
		data [5] = midB * 255;

		data [6] = midR * 255;
		data [7] = midG * 255;
		data [8] = midB * 255;

		data [9] = endR * 255;
		data [10] = endG * 255;
		data [11] = endB * 255;
	}
	else if (direction == 1) // top left to bottom right
	{
		data [0] = midR * 255;
		data [1] = midG * 255;
		data [2] = midB * 255;

		data [3] = endR * 255;
		data [4] = endG * 255;
		data [5] = endB * 255;

		data [6] = startR * 255;
		data [7] = startG * 255;
		data [8] = startB * 255;

		data [9] = midR * 255;
		data [10] = midG * 255;
		data [11] = midB * 255;
	}

	NSData* gradient = [NSData dataWithBytesNoCopy: data length: datasize];
	NSArray* size = [NSArray arrayWithObjects: [NSNumber numberWithInt: 2], [NSNumber numberWithInt: 2], nil];
	[GSDrawFunctions drawGradient: gradient withSize: size border: frame];
	free (data);
}

+ (void) drawRadioButton: (NSRect) border inView: (NSView*) view highlighted: (BOOL) highlighted 
{
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y + 1, border.size.width -2 , border.size.height -2);
	[path appendBezierPathWithOvalInRect: r];

	NSColor* start = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0];
	NSColor* end   = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];

	NSGraphicsContext *ctxt = GSCurrentContext();
	DPSgsave (ctxt);
	[path addClip];
	[GSDrawFunctions drawVerticalGradient: start to: end frame: border];
	DPSgrestore (ctxt);
	[[NSColor blackColor] set];
	[path setLineWidth: 1.5];
	[path stroke];

	if (highlighted)
	{
		NSBezierPath* pathCircle = [NSBezierPath bezierPath];
		NSRect r = NSMakeRect (border.origin.x +4, border.origin.y +4, border.size.width -8, border.size.height -8);
		[pathCircle appendBezierPathWithOvalInRect: r];
		[[NSColor blackColor] set];
		[pathCircle fill];
	}
}

+ (void) drawMenu: (NSRect) border inView: (NSView*) view 
{
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y + 1, border.size.width -2 , border.size.height -2);
	[path appendBezierPathWithRect: r];

	NSColor* start = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0];
	NSColor* end   = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];

	[GSDrawFunctions drawHorizontalGradient: end to: start frame: border];

	[[NSColor blackColor] set];
	[path setLineWidth: 1.5];
	[path stroke];
}

+ (void) drawButton: (NSRect) border inView: (NSView*) view highlighted: (BOOL) highlighted 
{
/*
	if (highlighted)
	{
		[[NSColor selectedControlColor] set];
		NSRectFill (border);
		[GSDrawFunctions drawGrayBezel: border : NSZeroRect];
	}
	else
	{
		[[NSColor controlBackgroundColor] set];
		NSRectFill (border);
		[GSDrawFunctions drawButton: border: NSZeroRect];
	}
*/
	NSBezierPath* path = [NSBezierPath bezierPath];
	NSBezierPath* path2 = [NSBezierPath bezierPath];
	NSRect r = NSMakeRect (border.origin.x + 1, border.origin.y + 1, border.size.width -2 , border.size.height -2);
	//[path appendBezierPathWithRect: r];
	float radius = 8.0;
	if ((border.size.height < 20) || (border.size.width < 20)) { radius = 4; }
	if ((border.size.height < 10) || (border.size.width < 10)) { radius = 2; }
	[path appendBezierPathWithRoundedRectangle: r withRadius: radius];

	NSColor* start = [NSColor colorWithCalibratedRed: 0.8 green: 0.8 blue: 0.8 alpha: 1.0];
	NSColor* end   = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];

	BOOL vertical = NO;

	if ([view isKindOfClass: [NSScroller class]])
	{
		if (border.size.width < border.size.height)
		{
			vertical = YES;
		}
	}

	NSGraphicsContext *ctxt = GSCurrentContext();
	DPSgsave (ctxt);
	[path addClip];
	if (highlighted)
	{
		if (vertical)
			[GSDrawFunctions drawHorizontalGradient: end to: start frame: border];
		else
			[GSDrawFunctions drawVerticalGradient: end to: start frame: border];
	}
	else
	{
		if (vertical)
			[GSDrawFunctions drawHorizontalGradient: start to: end frame: border];
		else
			[GSDrawFunctions drawVerticalGradient: start to: end frame: border];
	}
	DPSgrestore (ctxt);
	[[NSColor blackColor] set];
	//[[NSColor colorWithCalibratedRed: 0.3 green: 0.3 blue: 0.4 alpha: 0.8] set];
	[path setLineWidth: 1.5];
	[path stroke];
	//[GSDrawFunctions drawButton: border : NSZeroRect];

/*
	NSImage* image = [NSImage imageNamed: @"Button.tiff"];
	NSSize imageSize = [image size];
	NSImage* imageLeft = [[NSImage alloc] initWithSize: NSMakeSize (12,imageSize.height)];
	NSImage* imageRight = [[NSImage alloc] initWithSize: NSMakeSize (12,imageSize.height)];
	//NSImage* imageCenter = [[NSImage alloc] initWithSize: NSMakeSize (8,imageSize.height)];
	NSImage* imageCenter = [NSImage imageNamed: @"ButtonCenter.tiff"];

	[imageLeft lockFocus];
	[image compositeToPoint: NSMakePoint (0,0) operation: NSCompositeSourceOver];
	[imageLeft unlockFocus];
	[imageRight lockFocus];
	[image compositeToPoint: NSMakePoint (12-imageSize.width,0) operation: NSCompositeSourceOver];
	[imageRight unlockFocus];
	//[imageCenter lockFocus];
	//[[NSColor redColor] set];
	//NSRectFill(NSMakeRect(0,0,[imageCenter size].width,[imageCenter size].height));
	//[image compositeToPoint: NSMakePoint (-12,0) operation: NSCompositeSourceOver];
	//[imageCenter unlockFocus];

	[imageCenter setScalesWhenResized: YES];
	[imageCenter setSize: NSMakeSize(border.size.width-24,imageSize.height)];
	[imageCenter compositeToPoint: NSMakePoint (border.origin.x+12,border.origin.y) operation: NSCompositeSourceOver];
	[imageLeft compositeToPoint: border.origin operation: NSCompositeSourceOver];
	[imageRight compositeToPoint: NSMakePoint (border.origin.x+border.size.width-12,border.origin.y) operation: NSCompositeSourceOver];
*/
}

+ (void) drawFocusFrame: (NSRect) cellFrame
{
/*
	NSRect rect = NSMakeRect (cellFrame.origin.x + 1, cellFrame.origin.y + 1, cellFrame.size.width - 2, cellFrame.size.height - 2);
	NSDottedFrameRect (rect);
*/
	NSBezierPath* path = [NSBezierPath bezierPath];
	//NSRect rect = cellFrame;
	NSRect rect = NSMakeRect (cellFrame.origin.x + 1, cellFrame.origin.y + 1, cellFrame.size.width - 2, cellFrame.size.height - 2);
	[path appendBezierPathWithRoundedRectangle: rect withRadius: 8.0];
	//[path appendBezierPathWithRect: rect];
	[[NSColor colorWithCalibratedRed: 0.5 green: 0.5 blue: 1.0 alpha: 0.3] set];
	[path setLineWidth: 5];
	[path stroke];
	[[NSColor colorWithCalibratedRed: 0.5 green: 0.5 blue: 1.0 alpha: 0.5] set];
	[path setLineWidth: 3];
	[path stroke];
	[[NSColor colorWithCalibratedRed: 0.4 green: 0.4 blue: 1.0 alpha: 1.0] set];
	[path setLineWidth: 1];
	[path stroke];
}
@end
