/* Implementation of Form class
 *
 * Copyright (C)  1993, 1994, 1995  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
 *
 * This file is part of an Objective-C class library for a window system
 *
 * Form.m,v 1.48 1995/12/13 22:33:00 fedor Exp
 */

#include "Form.h"

#include "Application.h"
#include "FormCell.h"
#include "TextFieldCell.h"
#include "Window.h"
#include <objc/List.h>
#include <stdlib.h>
#include "stdmacros.h"

extern char *FormInstanceName(void);

@interface Form(WidgetSet)
- _calcSize;
- _setEntryWidth:(NXCoord)width;
@end

@implementation Form : Matrix

static id defaultCellClass;

/* Private methods not declared in interface */

- _setCellTitleWidth
{
    FormCell	*aCell;
    int 	i, count;

    count = [cellList count];
    for (i = 0; i < count; i++) { 
        aCell = [cellList objectAt:i];
        [aCell setTitleWidth:maxTitleWidth];
    }
    return self;
}

/* Public methods */

+ setCellClass:classId
{
    defaultCellClass = classId;

    return self;
}

- initFrame:(const NXRect *)frameRect
{
    [super initFrame:frameRect];
    instancename = FormInstanceName();
    cellClass = [FormCell class];
    return self;
}

- calcSize
{
    [self _calcSize];
    return self;
}

- sizeTo:(NXCoord)width :(NXCoord)height
{
  return [self notImplemented:_cmd];
}

- sizeToFit
{
  return [self notImplemented:_cmd];
}

- (int)selectedIndex
{
    return selectedRow;
}

- setEntryWidth:(NXCoord)width
{
    [self _setEntryWidth:width];
    return self;
}

- setInterline:(NXCoord)spacing
{
    intercell.height = spacing;
    return self;
}

- setBordered:(BOOL)flag
{
  [cell setBordered: flag];
  return self;
}

- setBezeled:(BOOL)flag
{
  [cell setBezeled: flag];
  return self;
}

- setTextAlignment:(int)mode
{
  return [self notImplemented:_cmd];
}

- setTitleAlignment:(int)mode
{
  return [self notImplemented:_cmd];
}

- setFont:fontObj
{
  return [self notImplemented:_cmd];
}

- setTitleFont:fontObj
{
  return [self notImplemented:_cmd];
}

- setTextFont:fontObj
{
  return [self notImplemented:_cmd];
}

- drawCellAt:(int)index
{
    return self;
}

- (const char *)titleAt:(int)index
{
    FormCell	*aCell;

    aCell = [cellList objectAt:index];
    return [aCell title];
} 

- setTitle:(const char *)aTitle at:(int)index
{
    FormCell	*aCell;

    aCell = [cellList objectAt:index];
    [aCell setTitle:aTitle];
    return self;
}

- addEntry:(const char *)aTitle
{
    FormCell	*entry;

    [self addRow];
    entry = [[cellList lastObject] setTitle:aTitle];
    return entry;
}

- addEntry:(const char *)aTitle tag:(int)anInt 
    target:anObject action:(SEL)aSelector
{
    FormCell	*entry;

    entry = [self addEntry:aTitle];
    [entry setTag:anInt];
    [entry setTarget:anObject];
    [entry setAction:aSelector];
    return entry;
}

- insertEntry:(const char *)aTitle at:(int)index
{
    FormCell	*entry;
    
    [self insertRowAt:index];
    entry = [[cellList objectAt:index] setTitle:aTitle];
    return entry;
}

- insertEntry:(const char *)aTitle at:(int)index tag:(int)anInt 
       target:anObject action:(SEL)aSelector
{
    id entry;

    entry = [self insertEntry:aTitle at:index];
    [entry setTag:anInt];
    [entry setTarget:anObject];
    [entry setAction:aSelector];
    return entry;
}

- removeEntryAt:(int)index
{
    [self removeRowAt:index andFree:YES];
    return self;
}

- setTag:(int)anInt at:(int)index
{
    FormCell	*aCell;

    aCell = [cellList objectAt:index];
    [aCell setTag:anInt];
    return self;
}

- setTarget:anObject at:(int)index
{
    FormCell	*aCell;

    aCell = [cellList objectAt:index];
    [aCell setTarget:anObject];
    return self;
}

- setAction:(SEL)aSelector at:(int)index
{
    FormCell	*aCell;

    aCell = [cellList objectAt:index];
    [aCell setAction:aSelector];
    return self;
}

- (int)findIndexWithTag:(int)aTag
{
    FormCell	*entry;
    unsigned int	i;
    
    i = [cellList count];
    while ( i-- ) {
	entry = [cellList objectAt:i];
	if ( [entry tag] == aTag ) {
	    return i;
	}
    }
    return -1;
}

- (const char *)stringValueAt:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    return [entry stringValue];
}

- setStringValue:(const char *)aString at:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    [entry setStringValue:aString];
    return self;
}

- (int)intValueAt:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    return [entry intValue];
}

- setIntValue:(int)anInt at:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    [entry setIntValue:anInt];
    return self;
}

- (float)floatValueAt:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    return [entry floatValue];
}

- setFloatValue:(float)aFloat at:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    [entry setFloatValue:aFloat];
    return self;
}

- (double)doubleValueAt:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    return [entry doubleValue];
}

- setDoubleValue:(double)aDouble at:(int)index
{
    FormCell	*entry;

    entry = [cellList objectAt:index];
    [entry setDoubleValue:aDouble];
    return self;
}


- selectCell:aCell
{
 /*
  * The textCell will invoke this method from its callback.   In this case
  * one wants to select its FormCell instead.
  */
    FormCell		*fCell;
    int			i;
        
    if ( [aCell isKindOf:[FormCell class]] ) {
        return [super selectCell:aCell];
    }
    i = [cellList count];
    while ( i-- ) {
        fCell = [cellList objectAt:i];
	if ( [fCell textCell] == aCell ) {
	    [super selectCell:fCell];
	}
    }
    return self;
}
- selectTextAt:(int)index;
{
    FormCell	*fCell;
    
    fCell = [cellList objectAt:index];
    if ( !fCell ) return nil;
    [[fCell textCell] _selectText ];
    return fCell;
}

- awake
{
    [super awake];
    instancename = FormInstanceName();
    return self;
}
// + newFrame:(const NXRect *)frameRect;

/* Methods not in NeXTStep */

- _managedBy:parent wid:(void*)widget
{   
    [self calcSize];		/* get the maxWidth of titles */
    [self _setCellTitleWidth];	/* set the title width up to the maxWidth */
    [super _managedBy:parent wid:widget];  
    return self;
}


@end
