/* 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.

static NSColor * scaleRGBColor(NSColor * color, float scale);

static void drawTabLeft(int x,
                    int y,
                    int intImageWidth,
                    int tabHeight,
                    NSColor *strokeColor,
                    NSColor *fillColor
                    );

static void drawTabRight(int x,
                     int y,
                     int intImageWidth,
                     int tabHeight,
                     NSColor *strokeColor,
                     NSColor *fillColor,
                     NSColor *upperStrokeColor
                     );

@implementation MiscTabActionCell

//Not used ...
- (id)init
{
	[super init];
	[self setType:NSTextCellType];
        [self setColor:[NSColor lightGrayColor]];
        [self setFont:[NSFont systemFontOfSize:12]];
        [self setStringValue:@"Tatooo"];
        return self;
}

// Methods Overridden From the Superclass
- initTextCell:(NSString *)aString
// Initializes a new instance of the receiver.
{
    [super initTextCell:aString];
    [self setColor:[NSColor lightGrayColor]];
    [self setFont:[NSFont systemFontOfSize:12]];
    return self;
}


- (void)encodeWithCoder:(NSCoder *)coder
{
  [super encodeWithCoder:coder];
  [coder encodeValueOfObjCType:"f" at:&tabHeight];
  [coder encodeValueOfObjCType:"f" at:&tabBezierImageWidth];
  [coder encodeObject:_color];
  return;
}

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

 // finish the initializing process 
  [coder decodeValueOfObjCType:"f" at:&tabHeight];
  [coder decodeValueOfObjCType:"f" at:&tabBezierImageWidth];

  aColor = [coder decodeObject];
  [self setColor:aColor];
  [self updateForFont];

    return self;
}

- (void)dealloc
{
// This cause IB to crash ... !!! Why ??????
//  [_color autorelease];
  [super dealloc];
}

- (id)copyWithZone:(NSZone *)zone
{
  MiscTabActionCell *cellCopy = [super copyWithZone:zone];
    /* Assume that other initialization takes place here. */

    cellCopy->_color = nil;
    [cellCopy setColor:[self color]];

    return cellCopy;
}




- (void)updateForFont
{
  float	lineHeight, ascender, descender;
  NSFont *fontObj = [self font];
  
  // 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)setFont:(NSFont *)fontObj
// Sets the receiver's font to <fontObj> and fetches font info used
// during the receiver's display.
{
// Do the superclass' init method 
    [super setFont:fontObj];

  [self updateForFont];
}

- (void)setColor:(NSColor *)aColor
{
//  if(![_color isEqual:aColor]) {
      [_color autorelease];
      _color = [scaleRGBColor(aColor,1.) retain];
      _leftUpperSelectedStrokeColor = [scaleRGBColor(_color,1.8) retain];
      _leftUpperStrokeColor = [scaleRGBColor(_color,(2.5/3.)) retain];
      _rightStrokeColor = [scaleRGBColor(_color,(0.4)) retain];
      _selectedFillColor = [scaleRGBColor(_color,1.) retain];
      _fillColor = [scaleRGBColor(_color,0.6) retain];
// }
}


- (NSColor *)color
{
  return _color;
}

- (void)takeColorFrom:sender
{
    [self setColor:[sender color]];
}

- (NSColor *)leftUpperSelectedStrokeColor
{
  return _leftUpperSelectedStrokeColor;
}

- (NSColor *)leftUpperStrokeColor
{
  return _leftUpperStrokeColor;
}

- (NSColor *)rightStrokeColor
{
  return _rightStrokeColor;
}

- (NSColor *)selectedFillColor
{
  return _selectedFillColor;
}

- (NSColor *)fillColor
{
  return _fillColor;
}



- (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 = [[controlView cells] 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);
   */
          drawTabLeft((int)leftImageOrigin.x,
                              (int)leftImageOrigin.y,
                              intImageWidth,
                              (int)tabHeight,
                              [self leftUpperSelectedStrokeColor],
                              [self selectedFillColor]);
          
          } else {
	// Otherwise, draw left tab bezier at leftImageOrigin.
/*            Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
                intImageWidth, (int)tabHeight, NSLightGray,
                unselectedGray);
*/
            drawTabLeft((int)leftImageOrigin.x,
                        (int)leftImageOrigin.y,
                        intImageWidth,
                        (int)tabHeight,
                        [self leftUpperStrokeColor],
                        [self fillColor]);

	// 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 ([[[controlView cells] objectAtIndex:indx - 1] isSelected]) {
	// Draw left tab bezier at leftImageOrigin.
/*	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSLightGray,
		unselectedGray);

*/
          drawTabLeft((int)leftImageOrigin.x,
                      (int)leftImageOrigin.y,
                      intImageWidth,
                      (int)tabHeight,
                      [self leftUpperStrokeColor],
                      [self fillColor]);

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

          drawTabRight((int)leftImageOrigin.x,
                       (int)leftImageOrigin.y,
                       intImageWidth,
                       (int)tabHeight,
//                       [self rightStrokeColor],
                       [[[controlView cells] objectAtIndex:indx-1] rightStrokeColor],
                       [[[controlView cells] objectAtIndex:indx-1] selectedFillColor],
                       [[[controlView cells] objectAtIndex:indx-1] leftUpperSelectedStrokeColor]);

                    
	} 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);

*/


          drawTabRight((int)leftImageOrigin.x,
                       (int)leftImageOrigin.y,
                       intImageWidth,
                       (int)tabHeight,
//                       [self rightStrokeColor],
                       [[[controlView cells] objectAtIndex:indx-1] rightStrokeColor],
                       [[[controlView cells] objectAtIndex:indx-1] fillColor],
                       [[[controlView cells] objectAtIndex:indx-1] leftUpperStrokeColor]);

            
	// Draw selected left tab bezier at leftImageOrigin.
/*	    Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
	    	intImageWidth, (int)tabHeight, NSWhite, NSLightGray);
*/
          drawTabLeft((int)leftImageOrigin.x,
                              (int)leftImageOrigin.y,
                              intImageWidth,
                              (int)tabHeight,
                              [self leftUpperSelectedStrokeColor],
                              [self selectedFillColor]);



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

*/
          drawTabLeft((int)leftImageOrigin.x,
                      (int)leftImageOrigin.y,
                      intImageWidth,
                      (int)tabHeight,
                      [self leftUpperStrokeColor],
                      [self fillColor]);


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

*/
          drawTabRight((int)leftImageOrigin.x,
                       (int)leftImageOrigin.y,
                       intImageWidth,
                       (int)tabHeight,
//                       [self rightStrokeColor],
                       [[[controlView cells] objectAtIndex:indx-1] rightStrokeColor],
                       [[[controlView cells] objectAtIndex:indx-1] fillColor],
                       [[[controlView cells] objectAtIndex:indx-1] leftUpperStrokeColor]);


           // 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 < [[controlView cells] count] - 1) {
    // draw the cell to the right of us 
      [controlView drawCell:[[controlView cells] objectAtIndex:indx + 1]];
      [controlView setNeedsDisplay:YES];
    }
    /*********** WE ARE THE LAST CELL !!!! *************/
    else {
      [controlView setNeedsDisplay:YES];
    // 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);
*/
          drawTabRight((int)rightImageOrigin.x,
                       (int)rightImageOrigin.y,
                       intImageWidth,
                       (int)tabHeight,
                       [self rightStrokeColor],
                       [self selectedFillColor],
                       [self leftUpperSelectedStrokeColor]
                       );
            
	} else {
	// Draw right tab bezier at rightImageOrigin.
/*	    Misc_drawRightTabBezier((int)rightImageOrigin.x,
	    	(int)rightImageOrigin.y, intImageWidth,
		(int)tabHeight, NSBlack, unselectedGray);
*/
         drawTabRight((int)rightImageOrigin.x,
                       (int)rightImageOrigin.y,
                       intImageWidth,
                       (int)tabHeight,
                       [self rightStrokeColor],
                       [self fillColor],
                      [self leftUpperStrokeColor]);

	}

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

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

 //********************** erase the cell 
*****************

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

      textFrame.size.height = tabHeight;
      textFrame.origin.y = NSMaxY(cellFrame) - tabHeight;
      
      NSRectFill(textFrame);
      
 // 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);
      [[self leftUpperSelectedStrokeColor] set];
    } else {
//	PSsetgray(NSLightGray);
        [[self leftUpperStrokeColor] set];
    }

 // set textFrame's height to 1.0 
    textFrame.size.height = 1.0;
    
    if (indx < [[controlView cells] count] - 1) {
      textFrame.size.width += 2.;
    }
    //Last tab
    else {
      textFrame.size.width += 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);
//
        [lightColor set];

 // 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]);


    //**************** draw the lower bezel 
****************

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

    // set our drawing color to NX_WHITE 
//	PSsetgray(NSWhite);
      [[[[self controlView] selectedCell] leftUpperSelectedStrokeColor] set];
    // fill in lowerBezelFrame 
	NSRectFill(lowerBezelFrame);
    }
    	[[controlView window] flushWindow];

}

- (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];
    [controlView setNeedsDisplay:YES];
        if ([theEvent type] == NSLeftMouseUp)
        {
                [self setState:![self state]];
        }

        return boolValue;
}

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


// Accessor Methods

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


static NSColor * scaleRGBColor(NSColor * c, float scale)
{
    return [NSColor colorWithCalibratedRed :[[c colorUsingColorSpaceName:NSCalibratedRGBColorSpace]
            redComponent]*scale
           green:[[c colorUsingColorSpaceName:NSCalibratedRGBColorSpace] greenComponent]*scale
           blue:[[c colorUsingColorSpaceName:NSCalibratedRGBColorSpace] blueComponent]*scale
                         alpha:1.0];
}


static void drawTabLeft(int x,
                    int y,
                    int intImageWidth,
                    int tabHeight,
                    NSColor *strokeColor,
                    NSColor *fillColor
                    )
{
  float		stroke_red, stroke_green, stroke_blue;
  float		fill_red, fill_green, fill_blue;

  stroke_red =
    [[strokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] redComponent];
  stroke_green =
    [[strokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] greenComponent];
  stroke_blue =
    [[strokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] blueComponent];

  fill_red =
    [[fillColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] redComponent];
  fill_green =
    [[fillColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] greenComponent];
  fill_blue =
    [[fillColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] blueComponent];

  Misc_drawColorLeftTabBezier((int)x,
                              (int)y,
                              intImageWidth,
                              (int)tabHeight,
                              stroke_red,
                              stroke_green,
                              stroke_blue,
                              fill_red,
                              fill_green,
                              fill_blue);

}

static void drawTabRight(int x,
                     int y,
                     int intImageWidth,
                     int tabHeight,
                     NSColor *strokeColor,
                     NSColor *fillColor,
                     NSColor *upperStrokeColor
                     )
{
  float		stroke_red, stroke_green, stroke_blue;
  float		fill_red, fill_green, fill_blue;
  float		upper_stroke_red, upper_stroke_green, upper_stroke_blue;

  stroke_red =
    [[strokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] redComponent];
  stroke_green =
    [[strokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] greenComponent];
  stroke_blue =
    [[strokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] blueComponent];

  fill_red =
    [[fillColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] redComponent];
  fill_green =
    [[fillColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] greenComponent];
  fill_blue =
    [[fillColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] blueComponent];

  upper_stroke_red =
    [[upperStrokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] redComponent];
  upper_stroke_green =
    [[upperStrokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] greenComponent];
  upper_stroke_blue =
    [[upperStrokeColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] blueComponent];

  //Il faut mofifier cette fonction pour rajouter la couleur du petit segment
  //du dessus.
  Misc_drawColorRightTabBezier((int)x,
                              (int)y,
                              intImageWidth,
                              (int)tabHeight,
                              stroke_red,
                              stroke_green,
                              stroke_blue,
                              fill_red,
                              fill_green,
                              fill_blue,
                               upper_stroke_red,
                               upper_stroke_green,
                               upper_stroke_blue);

}
