/* Implementation of Cell class
 *
 * Copyright (C)  1993  The Board of Trustees of  
 * The Leland Stanford Junior University.  All Rights Reserved.
 *
 * Authors: Scott Francis, Fred Harris, Paul Kunz,
 *          Imran Qureshi, and Libing Wang (SLAC)
 *	    Fred Harris (U Hawaii)
 *	    Make Kienenberger (Alaska)
 *
 * This file is part of an Objective-C class library for a window syste
 *
 * Cell.m,v 1.82 1995/12/13 22:32:55 fedor Exp
 */

#include "Cell.h"

#include "Application.h"
#include <objc/hashtable.h>
#include "NXImage.h"
#include <stdlib.h>

extern char *CellInstanceName(void);

@implementation Cell:Object

- init
{
    [super init];
    instancename = CellInstanceName();
    return self;
}

- initTextCell:(const char *)aString
{
    [self init];
    [self setStringValue:aString];
    return self;
}

- initIconCell:(const char *)iconName
{
    [self init];
    [self setIcon:iconName];
    return self;
}

- free
{
    if ( contents ) {
	free(contents);
    }
    if ( arglist ) {
	free(arglist);
    }
    return [super free];
}

- controlView
{
    return nil;		/* as in NeXTSTEP */
}

- _setControlView:aView
{
    controlView = aView;
    return self;
}
- (int) type
{ 
    return cFlags1.entryType;
}

- setType:(int)aType
{
    cFlags1.entryType = aType;
    return self;
}

- (int)state
{
    return cFlags1.state;
}

- setState:(int)value
{
    cFlags1.state = value ? 1 : 0;
    return self;
}

- (BOOL)isContinuous
{
    return cFlags2.continuous ? YES : NO;
}

- setContinuous:(BOOL)flag
{
    cFlags2.continuous = flag?1:0;
    return self;
}

- (BOOL)isEditable
{
    return cFlags1.editable ? YES : NO;
}

- setEditable:(BOOL)flag
{
    cFlags1.editable = flag?1:0;
    return self;
}

- (BOOL)isSelectable
{
    return cFlags1.selectable ? YES : NO;
}

- setSelectable:(BOOL)flag
{
    cFlags1.selectable = flag?1:0;
    return self;
}

- (BOOL)isBordered
{
    return cFlags1.bordered ? YES : NO;
}
    
- setBordered:(BOOL)flag
{
    cFlags1.bordered = flag?1:0;
    return self;
}
- (BOOL)isBezeled
{
    return cFlags1.bezeled ? YES : NO;
}

- setBezeled:(BOOL)flag
{
    cFlags1.bezeled = flag?1:0;
    return self;
}

- (BOOL)isScrollable
{
    return cFlags1.scrollable ? YES : NO;
}

- setScrollable:(BOOL)flag
{
    cFlags1.scrollable = flag?1:0;
    return self;
}

- incrementState
{
  cFlags1.state = (cFlags1.state) ? 0 : 1;
  return self;
}

- target
{
    return nil;		/* as in NeXTSTEP */
}

- setTarget:anObject
{
    return self;	/* as in NeXTSTEP */
}

/* Archiving methods */

- read:(TypedStream*)typedStream
{
	int a;

    [super read:typedStream];
    objc_read_string(typedStream, &contents);
	objc_read_type(typedStream, "i", &a);
	[self setEnabled:a];
#ifdef DEBUG
    fprintf(stderr, "reading Cell=%s\n", contents);
#endif
    return self;
}

- write:(NXTypedStream *)stream
{
  int a;

  [super write:stream];
  objc_write_string(stream, &contents);
  a = !cFlags1.disabled;
  objc_write_type(stream, "i", &a);
  return self;
}

- awake
{
    [super awake];
    instancename = CellInstanceName();

    return self;
}

- setFloatingPointFormat:(BOOL)autoRange
     left:(unsigned)leftDigits right:(unsigned)rightDigits
{
  /* Not terribly import to implement but maybe X has a way already */
    return self;
}

-(const char *)stringValue
{
    return contents;
}

- setStringValue:(const char *)aString
{
    if (contents && contents != aString) {
		free(contents);
    }
    if (aString) {
	contents = NXCopyStringBuffer(aString);
    } else {
	contents = NXCopyStringBuffer("Cell");
    }
    return self;
}

- setStringValueNoCopy:(const char *)aString
{
  return [self notImplemented:_cmd];
}

- setStringValueNoCopy:(char *)aString shouldFree:(BOOL)flag
{
  return [self notImplemented:_cmd];
}

- (const char *)icon
{
    if (!contents) 
	return (const char *)nil;
    return contents;
}

- setIcon:(const char *)iconName
{
    if (contents)
		free(contents);
    contents = NXCopyStringBuffer(iconName);
    return self;
}

- setIntValue:(int)anInt
{
    char temp[100];
    sprintf(temp, "%d", anInt);
    [self setStringValue:temp];
    return self;
}

- (int)intValue
{
    const char 	*temp;
    
    temp = [self stringValue];
    return ( atoi(temp) );
}

- setFloatValue:(float)aFloat
{
    char temp[100];
    sprintf(temp, "%g", aFloat);
    [self setStringValue:temp];
    return self;
}

- (float)floatValue
{
    const char 	*temp;
    float 	f;
    
    temp = [self stringValue];
    f = (float)atof(temp);
    return f;
}

- setDoubleValue:(double)aDouble
{
    char temp[100];
    sprintf(temp, "%g", aDouble);
    [self setStringValue:temp];
    return self;
}

- (double)doubleValue
{
    const char 	*temp;
    
    temp = [self stringValue];
    return ( atof(temp) );
}

- takeIntValueFrom:sender
{
    [self setIntValue:[sender intValue]];
    return self;
}

- takeFloatValueFrom:sender
{
    [self setFloatValue:[sender floatValue]];
    return self;
}

- takeDoubleValueFrom:sender
{
    [self setDoubleValue:[sender doubleValue]];
    return self;
}

- takeStringValueFrom:sender
{
   [self setStringValue:[sender stringValue]];
   return self;
}

- (BOOL)isOpaque
{
  [self notImplemented:_cmd];
  return 0;
}

- (BOOL)isEnabled
{
    return (!cFlags1.disabled);
}

- setEnabled:(BOOL)flag
{
    cFlags1.disabled = !flag;
    [self _setEnabled:flag];
    return self;
}

- (BOOL)isHighlighted
{
    return cFlags1.highlighted ? YES : NO;
}

- (int)alignment
{
    return cFlags1.alignment;
}

- setAlignment:(int)mode
{
    cFlags1.alignment = mode;
    return self;
}

/* As with NeXTSTEP, these methods don't really do anything except 
 * keeping compiler warning messages away 
 */
- sendAction
{
    return nil;
}
- setAction:(SEL)anAction
{
    return self;
}
- (SEL) action
{
    return (SEL)0;
}
- (int) tag
{
    return (-1);
}
- setTag:(int)anInt
{
    return self; 
}

- copyFromZone:(NSZone *)zone
{
    Cell	*newCell;
    
//    newCell = [[[self class] allocFromZone:zone] init];
    newCell = [super copyFromZone:zone];
    [newCell _copy];
    [newCell setStringValue:contents];
  /* The following are done in order to create copied widget */
    [newCell setState:cFlags1.state];
    [newCell setAlignment:cFlags1.alignment];
    [newCell setEnabled:!cFlags1.disabled];
    if (controlView)
    	[newCell _setFrame:&_frame inView:controlView];
    if ( parentid ) {
        [newCell _managedBy:parentid];
    }
    return newCell;
}

- calcCellSize:(NXSize *)theSize
{
    static NXRect aRect;

    NXSetRect(&aRect,0.0,0.0,1000000.0,1000000.0);
    return [self calcCellSize:theSize inRect:&aRect];
    
}

- calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect
{
    
    switch (cFlags1.type) {
    case NX_NULLCELL:
        break;
        theSize->width = 0.0;
        theSize->height = 0.0;
    case NX_TEXTCELL:
/*FIXME! not finished! */
        theSize->width = 10.0;
        theSize->height = 10.0;
        break;
    case NX_ICONCELL:
        [(NXImage *)support getSize:theSize];
        break;
    }
    
    if (cFlags1.bordered) {
        theSize->width  += 1.0;
        theSize->height += 1.0;
    }
    else if (cFlags1.bezeled) {
/* what is the size of the bezeling?? */
        theSize->width  += 1.0;
        theSize->height += 1.0;
    }
        
    return self;
    
}

- (int)getParameter:(int)aParameter
{
  [self notImplemented:_cmd];
  return 0;
}

- setParameter:(int)aParameter to:(int)value
{
  return [self notImplemented:_cmd];
}

- getIconRect:(NXRect *)theRect
{
  return [self notImplemented:_cmd];
}

- getTitleRect:(NXRect *)theRect
{
  return [self notImplemented:_cmd];
}

- getDrawRect:(NXRect *)theRect
{
  return [self notImplemented:_cmd];
}

- calcDrawInfo:(const NXRect *)aRect
{
  /* Does nothing */
  return self;
}

- setTextAttributes:textObj
{
  return [self notImplemented:_cmd];
}

- drawInside:(const NXRect *)cellFrame inView:controlView
{
  /* FIXME: Implement */
  return self;
}

- drawSelf:(const NXRect *)cellFrame inView:controlView
{
  /* FIXME: Implement */
  return self;
}

- highlight:(const NXRect *)cellFrame inView:controlView lit:(BOOL)flag
{
  /* FIXME: Implement */
  return self;
}

- (int)mouseDownFlags
{
  [self notImplemented:_cmd];
  return 0;
}

- getPeriodicDelay:(float*)delay andInterval:(float*)interval
{
  return [self notImplemented:_cmd];
}

- (BOOL)startTrackingAt:(const NXPoint *)startPoint inView:controlView
{
  [self notImplemented:_cmd];
  return 0;
}

- (BOOL)continueTracking:(const NXPoint *)lastPoint
                      at:(const NXPoint *)currentPoint inView:controlView
{
  [self notImplemented:_cmd];
  return 0;
}

- stopTracking:(const NXPoint *)lastPoint at:(const NXPoint *)stopPoint
        inView:controlView mouseIsUp:(BOOL)flag
{
  return [self notImplemented:_cmd];
}

- (BOOL)trackMouse:(NXEvent *)theEvent inRect:(const NXRect *)cellFrame
            ofView:controlView
{
  [self notImplemented:_cmd];
  return 0;
}

- edit:(const NXRect *)aRect inView:controlView editor:textObj
  delegate:anObject event:(NXEvent *)theEvent
{
  return [self notImplemented:_cmd];
}

- select:(const NXRect *)aRect inView:controlView editor:textObj
              delegate:anObject start:(int)selStart length:(int)selLength
{
  return [self notImplemented:_cmd];
}

- endEditing:textObj
{
  return [self notImplemented:_cmd];
}


@end
