
#import "OATextFieldInspector.h"
#import "OATextField.subproj/OATextField.h"
#import "OATextField.subproj/OATextFieldCell.h"
#import "OATextField.subproj/OATextFieldFormatter.h"
#import "OATextField.subproj/OATextFieldFormatterInspector.h"

#import "RZBundle.h"

#import <objc/HashTable.h>

@interface OATextField (IB)
- (const char *)getInspectorClassName;
@end
@implementation OATextField (IB)
- (const char *)getInspectorClassName
{
    return "OATextFieldInspector";
}
@end

@interface OATextFieldCell (IB)
- (const char *)getInspectorClassName;
@end
@implementation OATextFieldCell (IB)
- (const char *)getInspectorClassName
{
    return "OATextFieldInspector";
}
@end


@implementation OATextFieldInspector

- init
{
    int i, nelem;
    List *formatterList;
	
    char pathname[MAXPATHLEN+1];

    [super init];
 
    if ([[NXBundle bundleForClass:[self class]]
	    getPath:pathname
	    forResource:"OATextFieldInspector"
	    ofType:"nib"]) {
    	[NXApp loadNibFile:pathname
	    owner:self
	    withNames:NO
	    fromZone:[self zone]];
    }

    formatterTable = [[HashTable allocFromZone:[self zone]]
	initKeyDesc:@encode(char*)
	valueDesc:@encode(id)];
     
    formatterList = [RZBundle
	bundlesWithValue:"OATextFieldFormatter" 
	forString:"BundleType"];
    
    for (i = 0, nelem = [formatterList count]; i < nelem; i++) {
	const char *title;
	const char *className;
	const char *inspectorName;
	
	OATextFieldFormatter *formatter;
	OATextFieldFormatterInspector *inspector;
	List *formatterInfo = [[List allocFromZone:[self zone]] initCount:3];
	
	RZBundle *aBundle = [formatterList objectAt:i];
			
	title = [aBundle valueForString:"Title"];
	className = [aBundle valueForString:"ClassName"];
	inspectorName = [aBundle valueForString:"InspectorName"];
	
	formatter = [[[aBundle classNamed:className] alloc] init];
	inspector = [[[aBundle classNamed:inspectorName] alloc] init];
	
	[formatterInfo addObject:formatter];
	[formatterInfo addObject:inspector];
	[formatterInfo addObject:[inspector view]];
	
	[[formatterPopUpButton target] addItem:title];
	[formatterTable insertKey:title value:formatterInfo];
    }	

    [[formatterPopUpButton target] setTarget:self];
    [[formatterPopUpButton target] setAction:@selector(takeFormatterFrom:)];

    formatterNotApplicableView = [formatterNotApplicableWindow contentView];
    
    return self;
}

- (BOOL)wantsButtons
{
    return NO;
}

- ok:sender
{
    [object setChecksMaximumLength:[checkMaximum state]?YES:NO];
    [object setMaximumLength:[maximumLength intValue]];

    [object setChecksMinimumLength:[checkMinimum state]?YES:NO];
    [object setMinimumLength:[minimumLength intValue]];

    [object setChecksMaximumValue:[checkMaximumValue state]?YES:NO];
    [object setMaximumValue:[maximumValue intValue]];

    [object setChecksMinimumValue:[checkMinimumValue state]?YES:NO];
    [object setMinimumValue:[minimumValue intValue]];

    [object setNullable:[nullable state]?YES:NO];
    [object setMandatory:[mandatory state]?YES:NO];

    [object setCaseMapping:[[caseMapping selectedCell] tag]];

    [object setCharacterFiltering:
    	[[[characterFiltering target] itemList] selectedTag]];
	
    [object setFilteringExceptions:[filteringExceptions stringValue]];
     
    [object setRemovesLeadingWhitespace:
    	[clipLeadingWhitespace state]?YES:NO];    
    [object setRemovesTrailingWhitespace:
    	[clipTrailingWhitespace state]?YES:NO];    

    [formatterInspector ok:sender];
    
    return [super ok:sender];
}

- revert:sender
{
    [mandatory setState:
    	[object isMandatory]?1:0];
    [nullable setState:
    	[object isNullable]?1:0];

    [caseMapping selectCellWithTag:[object caseMapping]];
    
    [characterFiltering setTitle:
    	[[[[characterFiltering target] itemList]
		findCellWithTag:[object characterFiltering]]
			title]];
    [[[characterFiltering target] itemList] selectCell:
    	[[[characterFiltering target] itemList] findCellWithTag:
		[object characterFiltering]]];

    [filteringExceptions setStringValue:[object filteringExceptions]];
    
    [clipLeadingWhitespace setState:
    	[object doesRemoveLeadingWhitespace]?1:0];

    [clipTrailingWhitespace setState:
    	[object doesRemoveTrailingWhitespace]?1:0];
	
    [maximumLength setIntValue:[object maximumLength]];
    [minimumLength setIntValue:[object minimumLength]];

    [maximumValue setIntValue:[object maximumValue]];
    [minimumValue setIntValue:[object minimumValue]];
        
    if ([object doesCheckMaximumLength]) {
	[checkMaximum setState:YES];
	[maximumLength setEnabled:YES];
	[maximumLength setEditable:YES];
    } else {
	[checkMaximum setState:NO];
	[maximumLength setEnabled:NO];
    }
    
    if ([object doesCheckMinimumLength]) {
	[nullable setState:YES];
	[checkMinimum setState:YES];
	[minimumLength setEnabled:YES];
	[minimumLength setEditable:YES];
    } else {
	[nullable setState:NO];
	[checkMinimum setState:NO];
	[minimumLength setEnabled:NO];
    }

    if ([object doesCheckMaximumValue]) {
	[checkMaximumValue setState:YES];
	[maximumValue setEnabled:YES];
	[maximumValue setEditable:YES];
    } else {
	[checkMaximumValue setState:NO];
	[maximumValue setEnabled:NO];
    }
    
    if ([object doesCheckMinimumValue]) {
	[checkMinimumValue setState:YES];
	[minimumValue setEnabled:YES];
	[minimumValue setEditable:YES];
    } else {
	[checkMinimumValue setState:NO];
	[minimumValue setEnabled:NO];
    }
    
    [self setFormatterPopUpButtonTitle];
    
    return [super revert:sender];
}

- takeCheckMinimumFrom:sender
{
    BOOL checks = [sender state] ? YES : NO;
    
    if (checks) {
	[minimumLength setEnabled:YES];
	[minimumLength setEditable:YES]; 
    } else {
	[minimumLength setEnabled:NO];
    }
    return [self ok:sender];
}

- takeCheckMaximumFrom:sender
{
    BOOL checks = [sender state] ? YES : NO;
    
    if (checks) {
	[maximumLength setEnabled:YES];
	[maximumLength setEditable:YES];
    } else {
	[maximumLength setEnabled:NO];
    }
    return [self ok:sender];
}

- takeCheckMinimumValueFrom:sender
{
    BOOL checks = [sender state] ? YES : NO;
    
    if (checks) {
	[minimumValue setEnabled:YES];
	[minimumValue setEditable:YES]; 
    } else {
	[minimumValue setEnabled:NO];
    }
    return [self ok:sender];
}

- takeCheckMaximumValueFrom:sender
{
    BOOL checks = [sender state] ? YES : NO;
    
    if (checks) {
	[maximumValue setEnabled:YES];
	[maximumValue setEditable:YES];
    } else {
	[maximumValue setEnabled:NO];
    }
    return [self ok:sender];
}

- takeIsMandatoryFrom:sender
{
    [self ok:sender];
    return [self revert:sender];
}

- takeFormatterFrom:sender
{
    const char *title = [[sender selectedCell] title];
    id formatter = [(List *)[formatterTable valueForKey:title] objectAt:0];

    [object setTextFieldFormatter:formatter];

    return [self revert:sender];
}

- setFormatterPopUpButtonTitle
{
    OATextFieldFormatter *formatter;
    
    if ((formatter = [object textFieldFormatter]) == nil) {
	[formatterPopUpButton setTitle:"None"];
	[formatterInspectorBox setContentView:formatterNotApplicableView];
	[formatterInspectorBox update];
    } else {
	const char         *key;
	List		   *value;

	NXHashState         state = [formatterTable initState];

	while ([formatterTable nextState:&state
		key:(void*)&key
		value:(void *)&value]) {	    
	    if ([formatter class] == [[value objectAt:0] class]) {
	    	[formatterPopUpButton setTitle:key];
		
		if ([value count] > 1) {
		    formatterInspector = [value objectAt:1];
		    
		    [formatterInspector setObject:[object textFieldFormatter]];
		    [formatterInspector revert:self];
		    
		    if ([value count] > 2) {
			[formatterInspectorBox
			    setContentView:[value objectAt:2]];
		    } else {
			[formatterInspectorBox
			    setContentView:formatterNotApplicableView];
		    }
		    [formatterInspectorBox update];
		} else {
		    [formatterInspectorBox
			setContentView:formatterNotApplicableView];
		    [formatterInspectorBox update];
		}
	    	break;
	    }
	}
    }
    return self;
}

@end
