/* MiscTabActionCell.m 
 *
 * By Bill Edney, Sean Hill, Mark Onyschuk, and Art Isbell
 * Copyright (C) 1996.  Use governed by the MiscKit license.
 */
 
#import "MiscTabActionCell.h"

#import <AppKit/AppKit.h>


#import "MiscDrawTab.h"	// pswrap that draws tab ends.

@implementation MiscTabActionCell


// Methods Overridden From the Superclass
- initTextCell:(NSString *)aString
// Initializes a new instance of the receiver.
{
    [super initTextCell:aString];

 // finish the initialization process 
    [self finishInitializing];

    return self;
}


- (id)initWithCoder:(NSCoder *)coder
// Performs additional intialization of the receiver after decoding
{
 // do the superclass' awake method 
    self = [super initWithCoder:coder];

 // finish the initializing process 
    [self finishInitializing];

    return self;
}

- (void)setFont:(NSFont *)fontObj
// Sets the receiver's font to <fontObj> and fetches font info used
// during the receiver's display.
{
    float	lineHeight, ascender, descender;

// Do the superclass' init method 
    [super setFont:fontObj];

 // Grab the font information for the contents of the cell 
    ascender = [fontObj ascender];
    descender = [fontObj descender];
    lineHeight = [fontObj capHeight];
    
 // Set tabHeight to match that in EOF IB's StackView.  This results in a
 // height of 17 for Helvetica 12.
    tabHeight = lineHeight - descender + 5.0;

 // Set tabBezierImageWidth to provide reasonable scaling behavior.
    tabBezierImageWidth = tabHeight * 14.0 / 17.0;


}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:controlView
// Draws the receiver inside <cellFrame> in view <controlView>.
{
    float	halfImageWidth = tabBezierImageWidth / 2.0;
    NSPoint	leftImageOrigin,
    		rightImageOrigin;
	
    float	unselectedGray;
	
    NSRect 	textFrame,
    		lowerBezelFrame;
		
    NSArray *controlCellList;
    int		indx,
    		intImageWidth = (int)(tabBezierImageWidth + 0.5);

 // if there are no contents, then punt... 
    if (![self stringValue]) {
	return;
    }

	if([NSWindow defaultDepthLimit]<=NSBestDepth(NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
		unselectedGray = NSDarkGray;
	else
		unselectedGray = 0.5;


 // if <controlView> is not a kind of Matrix (i.e. in IB)
    if (![controlView isKindOfClass:[NSMatrix class]]) {
	[super drawInteriorWithFrame:cellFrame inView:controlView];	
    	return;
    }


    if ([controlView drawsBackground]) {
        [[controlView backgroundColor] set];
        NSRectFill(cellFrame);
    }

 // fetch information about ourselves in our Matrix
    controlCellList = [controlView cells];
    indx = [controlCellList indexOfObject:self];
        

 // set up the lowerBezelFrame that will be used for drawing the bezel
 // at our bottom
    lowerBezelFrame = NSMakeRect(NSMinX(cellFrame) + halfImageWidth, NSMaxY(cellFrame)-1.0, NSWidth(cellFrame), 1.0);

 // set textFrame to cellFrame 
    textFrame = cellFrame;

 // set up the leftImageOrigin 
    leftImageOrigin.x = NSMinX(cellFrame);
    leftImageOrigin.y = NSMaxY(cellFrame);

 // if indx is 0 (we are the first cell) 
    if (indx == 0) {
    // if we are selected 
	if ([self isSelected]) {
	// Draw selected left tab bezier at leftImageOrigin.
	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSWhite, NSLightGray);
	} else {
	// Otherwise, draw left tab bezier at leftImageOrigin.
	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSLightGray,
		unselectedGray);

	// subtract a half tabBezierImageWidth from lowerBezelFrame's x 
	    lowerBezelFrame.origin.x -= halfImageWidth;
	}

    // add a tabBezierImageWidth to textFrame's x 
	textFrame.origin.x += tabBezierImageWidth;

     // subtract a tabBezierImageWidth plus half tabBezierImageWidth minus 1.0
     // from textFrame's width
	textFrame.size.width -= tabBezierImageWidth + halfImageWidth - 1.0;
    } else {
    // subtract a half tabBezierImageWidth from leftImageOrigin's x 
	leftImageOrigin.x -= halfImageWidth;

    // if the cell to left of us is selected 
	if ([[controlCellList objectAtIndex:indx - 1] isSelected]) {
	// Draw left tab bezier at leftImageOrigin.
	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSLightGray,
		unselectedGray);

	// Draw selected right tab bezier at leftImageOrigin.
	    Misc_drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSBlack, NSLightGray);
	} else if ([self isSelected]) {
	// otherwise, if we are selected 

	// Draw right tab bezier at leftImageOrigin.
	// composite tabEndImage to leftImageOrigin 
	    Misc_drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSBlack, unselectedGray);

	// Draw selected left tab bezier at leftImageOrigin.
	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSWhite, NSLightGray);
	} else {
	// Draw left tab bezier at leftImageOrigin.
	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSLightGray,
		unselectedGray);

	// Draw right tab bezier at leftImageOrigin.
	    Misc_drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSBlack, unselectedGray);

	// subtract a half tabBezierImageWidth from lowerBezelFrame's x 
	    lowerBezelFrame.origin.x -= tabBezierImageWidth;

	// add 1.0 to lowerBezelFrame's width 
	    lowerBezelFrame.size.width += 1.0;
	}

    // add a half tabBezierImageWidth to textFrame's x 
	textFrame.origin.x += halfImageWidth;

    // subtract a tabBezierImageWidth minus 1.0 from textFrame's width 
	textFrame.size.width -= tabBezierImageWidth - 1.0;
    }

 // if indx is less than controlCellList's count minus 1 then we're
 // not the last cell, and...
    if (indx < [controlCellList count] - 1) {
    // draw the cell to the right of us 
	[controlView drawCell:[controlCellList objectAtIndex:indx + 1]];
    } else {
    // set up the rightImageOrigin 
	rightImageOrigin.x = NSMinX(cellFrame) + NSWidth(cellFrame)
	  - tabBezierImageWidth;
	rightImageOrigin.y = NSMinY(cellFrame) + NSHeight(cellFrame);

    // if we are selected 
	if ([self isSelected]) {
	// Draw selected right tab bezier at rightImageOrigin.
	    Misc_drawRightTabBezier((int)rightImageOrigin.x,
	    	(int)rightImageOrigin.y, intImageWidth,
		(int)tabHeight, NSBlack, NSLightGray);
	} else {
	// Draw right tab bezier at rightImageOrigin.
	    Misc_drawRightTabBezier((int)rightImageOrigin.x,
	    	(int)rightImageOrigin.y, intImageWidth,
		(int)tabHeight, NSBlack, unselectedGray);
	}

    // subtract a tabBezierImageWidth from textFrame's width 
	textFrame.size.width -= halfImageWidth;

    // add a half tabBezierImageWidth to lowerBezelFrame's width 
	lowerBezelFrame.size.width += halfImageWidth;
    }

 // erase the cell 

 // if we are selected 
    if ([self isSelected]) {
    // set our drawing color to NX_LTGRAY 
	PSsetgray(NSLightGray);
    } else {
	PSsetgray(unselectedGray);
    }
	
	textFrame.size.height = tabHeight;
	textFrame.origin.y = NSMaxY(cellFrame) - tabHeight;

 // fill in textFrame 
    NSRectFill(textFrame);

 // now draw the upper bezel 

 // set our drawing color to NSWhite 
 // if we are selected 
    if ([self isSelected]) {
	PSsetgray(NSWhite);
    } else {
	PSsetgray(NSLightGray);
    }

 // set textFrame's height to 1.0 
    textFrame.size.height = 1.0;

 // fill in textFrame 
    NSRectFill(textFrame);

 // now draw the text 

    // If we are enabled, draw NSBlack, else draw NSLightGray
    if ([self isEnabled])
    	PSsetgray(NSBlack);
    else
	PSsetgray(NSLightGray);

 // draw the cell's contents 

    if ([[NSDPSContext currentContext] isDrawingToScreen] && [[self font] screenFont])
	[[[self font] screenFont] set];
    else
	[[self font] set];

    // The offsets were empirically set by emulating the StackView used in the
    // EOF IB's File Window.
    PSmoveto(NSMinX(textFrame) + 3.0, NSMinY(textFrame) + tabHeight - 4.0);
    PSshow([[self stringValue] cString]);

 // if we are not selected 
    if (![self isSelected]) {
    // draw the lower bezel 

    // set our drawing color to NX_WHITE 
	PSsetgray(NSWhite);

    // fill in lowerBezelFrame 
	NSRectFill(lowerBezelFrame);
    }
}

- (void)highlight:(BOOL)flag withFrame:(NSRect)cellFrame inView:(NSView *)aView
{
	[super highlight:flag withFrame:cellFrame inView:aView];
	[self drawInteriorWithFrame:cellFrame inView:aView];
}

- (NSSize)cellSizeForBounds:(NSRect)aRect
{
	
    NSSize theSize;
    theSize.height = tabHeight;
	theSize.width =  (2*tabBezierImageWidth+
					[[self font] widthOfString:[self stringValue]]);
	return theSize;
}

- (BOOL)trackMouse:(NSEvent *)theEvent 
            inRect:(NSRect)cellFrame
            ofView:(NSView *)controlView
      untilMouseUp:(BOOL)flag
{
        BOOL	boolValue = [super trackMouse:(NSEvent *)theEvent
                             inRect:(NSRect)cellFrame
                             ofView:controlView
                       untilMouseUp:(BOOL)flag];

        [controlView display];

        if ([theEvent type] == NSLeftMouseUp)
        {
                [self setState:![self state]];
        }

        return boolValue;
}

- (BOOL)startTrackingAt:(NSPoint)startPoint inView:aView
{
	[aView sendAction];
	return NO;
}

// Other Instance Methods 
- (void)finishInitializing
{
    [self setFont:[self font]];
}

// Accessor Methods

- (BOOL)isSelected
{
	return ([self isHighlighted] || [self state]);
}
@end