
/* --------------------------------------------------#
   the implementation of an IB inspector for a Form.
   This is practically identical to the original Form
   inspector.
    
   Copyright 1992 Don McGregor
   You may freely use this code in any way you wish.
   however, you may not charge any money for the use
   of it.
   
   No warranty of any kind, etc, etc.
 --------------------------------------------------#*/

#import <appkit/Application.h>
#import <appkit/TextFieldCell.h>
#import <appkit/TextField.h>
#import <appkit/Matrix.h>
#import <appkit/Window.h>
#import <objc/List.h>

#import "GeneralFormCell.h"
#import "GeneralForm.h"
#import "GeneralFormInspector.h"


@implementation GeneralFormInspector

/* << The first two class methods don't get inherited >> */

+ finishLoading:(struct mach_header *) hdr {
    NIBDidLoadClass(self, hdr);
    return nil;
}

+ startUnloading
{
    NIBWillUnloadClass(self);
    return nil;
}

- init
{
  /*--------------------------------------------------------------
     Initialize and all that.      --------------------------------------------------------------*/
       
  [super init];
  [NXApp loadNibSection:"GeneralFormInspector.nib" owner:self];
  return self;
}


- ok:sender
{
  /*--------------------------------------------------------------
      The 'ok:" method looks at the contents of the various controls
      in the IB inspector, and sets the state of the object being
      inspected accordingly.  This is a bit long and probably should
      be broken up into a few methods.
  --------------------------------------------------------------*/
  
  int	t, i;
  
  [[NXApp mainWindow] makeFirstResponder:[NXApp mainWindow]];
  [window endEditingFor:self];
  
  	//The background gray for the Form
  
  if ((t = [[backGrayMatrix selectedCell] tag]) == 0) {
	[object setBackgroundGray:-1.0];
    } else {
	[object setBackgroundGray:(t - 1) / 3.0];
    }

  	//Title alignment
     
   if ((t = [[alignMatrix selectedCell] tag]) == 0) {
	[object setTitleAlignment:NX_LEFTALIGNED];
    } else if (t == 1) {
	[object setTitleAlignment:NX_CENTERED];
    } else {
	[object setTitleAlignment:NX_RIGHTALIGNED];
    }

	//The alignment of the text within the form cells
	
   if ((t = [[textMatrix selectedCell] tag]) == 0) {
	[object setTextAlignment:NX_LEFTALIGNED];
    } else if (t == 1) {
	[object setTextAlignment:NX_CENTERED];
    } else {
	[object setTextAlignment:NX_RIGHTALIGNED];
    }

   	//The check boxes for cell tags = position and
	//whether the fields are scrollable.

   if([[optionsMatrix cellAt:0 :0] state] == 1)
     {
     	 /*set the cell tags to reflect their positon in Form.
	  *if this option is not set, they're left to be whatever
	  *they were before.
	 */
	 
       for(i = 0; i < [object cellCount]; i++)
	 [object setTag:i at:i];
     }
     
     	//Whether fields are scrollable.  If the option is off,
	//the fields are set to non-scrollable.
	
   if([[optionsMatrix cellAt:1 :0] state] == 1)
      {
        /*set the fields to be scrollable*/
       
       for(i = 0; i < [object cellCount]; i++)
	   [[object cellAt:i :0] setScrollable:YES];
      }
     else
      {
	  for(i = 0; i < [object cellCount]; i++)
	   [[object cellAt:i :0] setScrollable:NO];
      }
      
      
      	//Get the tag from the form at the bottom
	
     [object setTag:[tagForm intValueAt:0]];
	 
  return [super ok:sender];
}
  
  
  
- revert:sender
{
  /*--------------------------------------------------------------
     "revert:" finds the current state of the object, and sets
     the state of the IB inspector accordingly.  It's sort of the
     flip side of the ok: method.  
     
     This is pretty long too, but conceptually simple.
  --------------------------------------------------------------*/
  
  BOOL	allTheSame;
  int	i, j, k;
  
  [window endEditingFor:self];

	//The background gray
	
    if ([object backgroundGray] < 0.0) {
	[backGrayMatrix selectCellAt:0 :0];
    } else {
	[backGrayMatrix selectCellAt:0 :([object backgroundGray] * 3.0) + 1];
    }
    
    	//Set the title alignment to the previous value.  The 
	//assumption is that whatever the first cell's value
	//is is the same for the rest of them.  This is an OK
	//assumption, since you can only set "group" values from
	//within IB.
	
    if([[[object cellList] objectAt:0] titleAlignment] == NX_LEFTALIGNED)
      [alignMatrix selectCellWithTag:0];
    
    if([[[object cellList] objectAt:0] titleAlignment] == NX_RIGHTALIGNED)
      [alignMatrix selectCellWithTag:2];
      
    if([[[object cellList] objectAt:0] titleAlignment] == NX_CENTERED)
      [alignMatrix selectCellWithTag:1];


	//Do the same thing for the text alignment
   
    if([[[object cellList] objectAt:0] alignment] == NX_LEFTALIGNED)
      [textMatrix selectCellWithTag:0];

    if([[[object cellList] objectAt:0] alignment] == NX_RIGHTALIGNED)
      [textMatrix selectCellWithTag:2];
      
    if([[[object cellList] objectAt:0] alignment] == NX_CENTERED)
      [textMatrix selectCellWithTag:1];
      
      
      	//Look at the tags for the Cells.  If they match their positon,
	//we can set the options matrix first checkbox to yes.
	
    allTheSame = YES;
    i = [object cellCount];
    
    for(j = 0; j < i; j++)
      {
         k = [[object cellAt:j :0] tag];	 
         if(k != j)
	     allTheSame = NO;
      }
      
    if(allTheSame)
        [optionsMatrix selectCellWithTag:0];
     else
        [optionsMatrix setState:0 at:0 :0];
      
      	//Do the same thing for the scrollable option.  This option can
	//be reset by the Cell inspector.

    allTheSame = YES;
    
    for(j = 0; j < i; j++)
      {
         if([[[object cellList] objectAt:j] isScrollable] == NO)
	    allTheSame = NO;
      }

    if(allTheSame)
        [optionsMatrix selectCellWithTag:1];
     else
        [optionsMatrix setState:0 at:1 :0];	


	//Find the tag for the Form object and make the field reflect
	//that.

    [tagForm setIntValue:[object tag] at:0];

  return [super revert:sender];
}

	//Archiving
	
- read:(NXTypedStream*)stream
{
  
  [super read:stream];
  
  backGrayMatrix 	= NXReadObject(stream);
  alignMatrix 		= NXReadObject(stream);
  textMatrix 		= NXReadObject(stream);
  optionsMatrix 	= NXReadObject(stream);
  tagForm 		= NXReadObject(stream);
  
  return self;
}
  
- write:(NXTypedStream*)stream
{
  
  [super write:stream];
  
  NXWriteObjectReference(stream, backGrayMatrix);
  NXWriteObjectReference(stream, alignMatrix);
  NXWriteObjectReference(stream, textMatrix);
  NXWriteObjectReference(stream, optionsMatrix);
  NXWriteObjectReference(stream, tagForm);

  return self;
}

@end
