/*
        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 "FlatFileAdaptor.h"
#import "FlatFileContext.h"
#import "FlatFileChannel.h"
#import "FlatFileSQLExpression.h"

@implementation FlatFileAdaptor

+ (NSString *)defaultRowSeparator
{
    return @"\n";
}

+ (NSString *)defaultColumnSeparator
{
    return @",";
}

+ (NSString *)columnHeaderSeparator
{
    return @":";
}

+ (NSDictionary *)defaultConnectionDictionary
{
    static NSDictionary *dict = nil;

    if (!dict)
        dict = [[NSDictionary dictionaryWithObjectsAndKeys:NSHomeDirectory(), FlatFilePathKey, [self defaultRowSeparator], FlatFileRowSeparatorKey, [self defaultColumnSeparator], FlatFileColumnSeparatorKey, @"Y", FlatFileUseHeadersKey, nil] retain];

    return dict;
}

static NSString *externalTypeNames[] = { @"Number", @"String", @"Data", @"Date", nil };

static NSString *internalTypeNames[] = { @"NSDecimalNumber", @"NSString", @"NSData", @"NSCalendarDate", nil };

+ (NSDictionary *)externalToInternalTypeMap
{
    static NSDictionary *externalToInternalTypeMap = nil;

    if (!externalToInternalTypeMap) {
        int i;
        for (i = 0; externalTypeNames[i]; i++);
        externalToInternalTypeMap = [[NSDictionary dictionaryWithObjects:internalTypeNames forKeys:externalTypeNames count:i] retain];
    }

    return externalToInternalTypeMap;
}

+ (NSString *)internalTypeForExternalType:(NSString *)extType model:(EOModel *)model
{
    return [[self externalToInternalTypeMap] objectForKey:extType];
}

+ (NSArray *)externalTypesWithModel:(EOModel *)model
{
    return [[self externalToInternalTypeMap] allKeys];
}

+ (NSString *)defaultExternalType
{
    return externalTypeNames[1];
}

+ (void)assignExternalInfoForAttribute:(EOAttribute *)attribute
{
    [attribute setExternalType:externalTypeNames[[attribute adaptorValueType]]];
}

+ (void)assignExternalInfoForEntity:(EOEntity *)entity
{
    NSEnumerator *attributeEnumerator = [[entity attributes] objectEnumerator];
    EOAttribute *attribute;

    while (attribute = [attributeEnumerator nextObject])
        [self assignExternalInfoForAttribute:attribute];
}

+ (void)assignExternalInfoForEntireModel:(EOModel *)model
{
    NSEnumerator *entityEnumerator = [[model entities] objectEnumerator];
    EOEntity *entity;

    while (entity = [entityEnumerator nextObject])
        [self assignExternalInfoForEntity:entity];
}

- initWithName:(NSString *)name
{
    [super initWithName:name];
    [self setConnectionDictionary:[[self class] defaultConnectionDictionary]];

    return self;
}
    
- createAdaptorContext
{
    return [[[FlatFileContext alloc] initWithFlatFileAdaptor:self] autorelease];
}

- (Class)expressionClass
{
    return [FlatFileSQLExpression class];
}

- (BOOL)isValidQualifierType:(NSString *)typeName model:(EOModel *)model
{
    return ![typeName isEqualToString:@"Data"];
}

- (void)assertConnectionDictionaryIsValid
{
    NSException *exception = nil;
    EOAdaptorContext *adaptorContext;
    EOAdaptorChannel *adaptorChannel;

    if ([self hasOpenChannels])
        return;

    adaptorContext = [self createAdaptorContext];
    adaptorChannel = [adaptorContext createAdaptorChannel];
    NS_DURING
        [adaptorChannel openChannel];
    NS_HANDLER
        exception = localException;
    NS_ENDHANDLER

    [adaptorChannel closeChannel];

    if (exception)
        [exception raise];
}

@end
