/*
        Copyright (c) 1996, NeXT Software, Inc.
        All rights reserved.

        You may freely copy, distribute and reuse the code in this example.
        NeXT disclaims any warranty of any kind, expressed or implied,
        as to its fitness for any particular use.
*/
#import "CustomColumns.h"

// silly category so model objects all know how to get and set their
// modification times
@interface NSObject (_modificationDate)
- (void)_setModificationDate:(NSCalendarDate *)date;
- (NSCalendarDate *)_modificationDate;
@end

@implementation CustomColumns

+ (void)initialize {
    id sharedInstance = [self new];

    // register our column type with the application
    [EOMApp registerColumnName:@"Modification Date" forClass:[EOModel class] provider:sharedInstance];
    [EOMApp registerColumnName:@"Modification Date" forClass:[EOEntity class] provider:sharedInstance];
    [EOMApp registerColumnName:@"Modification Date" forClass:[EORelationship class] provider:sharedInstance];
    [EOMApp registerColumnName:@"Modification Date" forClass:[EOAttribute class] provider:sharedInstance];
    [EOMApp registerColumnName:@"Modification Date" forClass:[EOStoredProcedure class] provider:sharedInstance];

    // register for object change notification so we can change objects modification times
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_objectsChangedInEditingContext:) name:EOObjectsChangedInEditingContextNotification object:nil];    
}

// Method from EOColumnProvider protcol
- (void)initColumn:(NSTableColumn *)col class:(Class)class name:(NSString *)name displayGroup:(EODisplayGroup *)displayGroup document:(EOModelerDocument *)doc
{
    EOColumnAssociation *assoc;
    NSCell	*cell;
    NSDateFormatter *formatter;
    
    // fix up the column    
    [[col headerCell] setStringValue:name];

    // it will be a text field, so set that up
    cell = [[NSTextFieldCell alloc] initTextCell:@""];
    [col setDataCell:cell];
    [cell setEnabled:YES];
    [cell setEditable:NO];
    [cell setScrollable: YES];
    [col setEditable: NO];

    formatter = [[NSDateFormatter alloc] initWithDateFormat:@"%m/%d/%y: %H:%M" allowNaturalLanguage:NO];
    [cell setFormatter:formatter];
    [formatter release];

    // and connect up the displayGroup
    assoc = [[EOColumnAssociation alloc] initWithObject:col];
    [assoc bindAspect:@"value" displayGroup:displayGroup key:@"_modificationDate"];
    [assoc establishConnection];
    [assoc release];
}

+ (void)_objectsChangedInEditingContext:(NSNotification *)notification
{
    // objects changed in some editing context.  If its a model object
    // then set a new modification time in the user dictionary
    EOEditingContext *editingContext = [notification object];
    if ([editingContext isKindOfClass:[EOEditingContext class]]) {
        NSDictionary *userInfo = [notification userInfo];
        NSArray *updatedObjects = [userInfo objectForKey:@"updated"];
        int i = [updatedObjects count];

        // we must turn off observer notification so that our change to this object
        // does not cause us to get called back again ad infinitum.
        // This has the unfortunate side-effect of disabling undo for this
        // change.  Alternatively we could compare the state of the modified
        // object to its currentEventSnapshot and verify that something other
        // than our entry in the userInfo had changed.  This would stop
        // the infinite recursion.
        [EOObserverCenter suppressObserverNotification];
        while (i--) {
            id object = [updatedObjects objectAtIndex:i];
            [object _setModificationDate:[NSCalendarDate date]];
        }
        [EOObserverCenter enableObserverNotification];
    }
}
@end


@implementation NSObject (_modificationDate)
- (void)_setModificationDate:(NSCalendarDate *)date {
    NSMutableDictionary *userInfo = [[(EOModel *)self userInfo] mutableCopy];
    if (!userInfo) userInfo = [NSMutableDictionary new];
    [userInfo setObject:[date description] forKey:@"modificationDate"];
    [(EOModel *)self setUserInfo:userInfo];
    [userInfo release];
}

- (NSCalendarDate *)_modificationDate {
NSString *dateString = [[(EOModel *)self userInfo] objectForKey:@"modificationDate"];

    if (dateString) 
        return [[[NSCalendarDate alloc] initWithString:dateString] autorelease];
    return nil;
}
@end
