/* GdbBrowserCell.m created by ovidiu on Sat 05-Apr-1997 */

#import <AppKit/AppKit.h>
#import "GdbBrowserCell.h"

@implementation GdbBrowserCell

static NSImage* squareImage = nil;
static NSImage* squareHImage = nil;
static NSImage* dotImage = nil;
static NSImage* dotHImage = nil;

static NSCell* titleCell = nil;
static NSCell* valueCell = nil;
static NSCell* imageCell = nil;

+ (void)initialize
{
  NSBundle* bundle = [NSBundle bundleForClass:self];
  NSString* path;

  path = [bundle pathForResource:@"square" ofType:@"tiff"];
  squareImage = [[NSImage alloc] initWithContentsOfFile:path];

  path = [bundle pathForResource:@"squareH" ofType:@"tiff"];
  squareHImage = [[NSImage alloc] initWithContentsOfFile:path];

  path = [bundle pathForResource:@"dotImage" ofType:@"tiff"];
  dotImage = [[NSImage alloc] initWithContentsOfFile:path];

  path = [bundle pathForResource:@"dotImageH" ofType:@"tiff"];
  dotHImage = [[NSImage alloc] initWithContentsOfFile:path];

  titleCell = [[NSCell alloc] initTextCell:@""];
  [titleCell setAlignment:NSLeftTextAlignment];

  valueCell = [[NSCell alloc] initTextCell:@""];
  [valueCell setAlignment:NSLeftTextAlignment];

  imageCell = [[NSCell alloc] initImageCell:nil];
}

- (void)setObjectToDisplay:(id<GdbDisplayValue,NSObject>)anObject
{
  Value* value;
  Type* type;
  tTypeKind typeKind;

  [anObject retain];
  [displayableObject release];
  displayableObject = anObject;

  value = [displayableObject value];
  type = [value type];
  typeKind = [type typeKind];

  if (typeKind == kVoid || typeKind == kScalar || typeKind == kEnum
      || typeKind == kCString)
    [self setLeaf:YES];
  else
    [self setLeaf:NO];
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame
                       inView:(NSView*)view
               backgroundGray:(float)backgroundGray
{
  Value* value = [displayableObject value];
  Type* type = [value type];
  NSRect valueFrame, imageRect;
  NSString* title = [displayableObject title];
  float titleWidth = 0, valueWidth = 0;
  NSString* valueString = nil;

  if (!title)
    title = @"";
  if ([title isEqual:@""] && objectIsArrayComponent) {
    int row, column;

    [(NSMatrix*)view getRow:&row column:&column ofCell:self];
    title = [NSString stringWithFormat:@"[%d]", row];
  }

  [titleCell setStringValue:title];
  [valueCell setStringValue:@""];
  [imageCell setImage:nil];

  switch ([type typeKind]) {
    case kVoid:
      break;
    case kScalar:
    case kEnum:
      if (!(valueString = [value additionalDescription]))
        valueString = [value stringValue];
      [valueCell setStringValue:valueString ? valueString : @""];
      break;
    case kStructure:
      [imageCell setImage:backgroundGray == NSWhite ? dotHImage : dotImage];
      break;
    case kClass:
      [imageCell setImage:backgroundGray == NSWhite ? dotHImage : dotImage];
      if (!(valueString = [value additionalDescription]))
        valueString = [value stringValue];
      [valueCell setStringValue:valueString ? valueString : @""];
      break;
    case kUnion:
      [imageCell setImage:backgroundGray == NSWhite ? dotHImage : dotImage];
      break;
    case kArray:
      [imageCell setImage:backgroundGray == NSWhite
                            ? squareHImage : squareImage];
      break;
    case kPointer:
    case kVoidPointer:
      [imageCell setImage:backgroundGray == NSWhite
                                    ? [isa highlightedBranchImage]
                                    : [isa branchImage]];
      /* Fall through */
    case kCString:
      /* If the value has a description associated with it then display it
         rather than the address. Also make the cell a leaf cell. */
      if (!(valueString = [value additionalDescription]))
        valueString = [value stringValue];
      else
        [self setLeaf:YES];
      [valueCell setStringValue:valueString ? valueString : @""];
      break;
  }

  if (title && ![title isEqual:@""])
    titleWidth = [[titleCell font] widthOfString:title];
  if (valueString && ![valueString isEqual:@""])
    valueWidth = [[valueCell font] widthOfString:valueString];

  [titleCell drawInteriorWithFrame:cellFrame inView:view];

  if (![self isLeaf]) {
    imageRect.size.width = 16;
    imageRect.size.height = cellFrame.size.height;
    imageRect.origin.x = cellFrame.origin.x + cellFrame.size.width
                        - imageRect.size.width;
    imageRect.origin.y = cellFrame.origin.y;
    [imageCell drawInteriorWithFrame:imageRect inView:view];
  }

  if (valueString) {
    valueFrame.size.width = valueWidth + 8;
    valueFrame.size.height = cellFrame.size.height;
    valueFrame.origin.x = cellFrame.origin.x + cellFrame.size.width
        - valueFrame.size.width - ([self isLeaf] ? 0 : imageRect.size.width);
    valueFrame.origin.y = cellFrame.origin.y;
    [valueCell drawInteriorWithFrame:valueFrame inView:view];
  }
}

- (void)drawWithFrame:(NSRect)cellFrame
               inView:(NSView *)controlView
{
  float backgroundGray = NSLightGray;

  PSgsave();

  if (state)
    backgroundGray = NSWhite;
  if (isHighlighted) {
    if (backgroundGray == NSLightGray)
      backgroundGray = NSWhite;
  }

  /* Clear the cell frame */
  PSsetgray (backgroundGray);
  PSrectfill (cellFrame.origin.x, cellFrame.origin.y,
              cellFrame.size.width, cellFrame.size.height);

  [self drawInteriorWithFrame:cellFrame
                       inView:controlView
               backgroundGray:backgroundGray];
  PSgrestore();
}

- (void)highlight:(BOOL)flag
        withFrame:(NSRect)cellFrame
           inView:(NSView*)controlView
{
  isHighlighted = flag;
}

- (void)setState:(int)_state
{
  state = _state;
}

/* Implement stringValue to return a useful string to be shown as title of a
  column in the stack browser. */
- (NSString*)stringValue
{
  return [displayableObject title];
}

- (void)setObjectIsArrayComponent:(BOOL)flag
{
  objectIsArrayComponent = flag;
}

@end
