/* indent:4  tabsize:8  font:fixed-width */

#import "Preferences.h"
#import <Solitaire/SmallCard.h>
#import <Solitaire/Card.h>

#define TIFF_IMAGE 1
#define EPS_IMAGE 2
#define OTHER_IMAGE 3


@implementation Preferences

static int checkImageType(NSString *filename)
{
    NSString* extension = [filename pathExtension];
	
    if (([extension compare:@"tiff" options:NSCaseInsensitiveSearch] == NSOrderedSame) || ([extension compare:@"tif" options:NSCaseInsensitiveSearch] == NSOrderedSame)) {
        return TIFF_IMAGE;
    }
    if ([extension compare:@"eps" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        return EPS_IMAGE;
    }
    else {
        return OTHER_IMAGE;
    }
}

static NSString* convertColorToString(NSColor * aColor)
{
    float r,g,b;

    [[aColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&r 
	green:&g blue:&b alpha:NULL];

    return [NSString stringWithFormat:@"%6.4f %6.4f %6.4f", r, g, b];
}

static NSColor * convertStringToColor(NSString *aString)
{
    float r, g, b;

    r = g = b = 0;

    if (aString != nil) {
        NSScanner* scanner = [NSScanner scannerWithString:aString];

        [scanner scanFloat:&r];
        [scanner scanFloat:&g];
        [scanner scanFloat:&b];
    }
  
    return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0];
}


- init
{
    BOOL statusPanelUp=NO;
    NSUserDefaults* userDefaults = [NSUserDefaults	standardUserDefaults];
    NSDictionary* defaultsDictionary;
    NSArray* values;
    NSArray* keys;

    values = [NSArray arrayWithObjects:@"0.0 0.2 0.1333", @"0", @"0", @"1", @"", nil];
    keys = [NSArray arrayWithObjects:@"backgroundColor", @"cardSize", @"cardBack", @"preDrawCards", @"imageFileName", nil];
    defaultsDictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];

    [userDefaults registerDefaults:defaultsDictionary];

    backgroundColor = convertStringToColor([userDefaults objectForKey:@"backgroundColor"]);
    [backgroundColor retain];
    cardSize = [userDefaults integerForKey:@"cardSize"];
    cardBack = [userDefaults integerForKey:@"cardBack"];
    preDrawCards = [userDefaults integerForKey:@"preDrawCards"];

    [self showPreferences:self];

    if (![[userDefaults stringForKey:@"imageFileName"] isEqualToString:@""]) {
    	statusPanelUp = YES;
    	[messageField setStringValue:@"Converting Custom Back Image..."];
    	[statusPanel makeKeyAndOrderFront:nil];
        PSWait();
    	imageFileName = [[userDefaults stringForKey:@"imageFileName"] retain]; 
        [self setNewImage:self];
    }
    
    if(preDrawCards){
        statusPanelUp = YES;
    	[messageField setStringValue:@"Pre-Drawing Cards..."];
    	[statusPanel makeKeyAndOrderFront:nil];
        PSWait();

    	if(cardSize == CS_SMALL)
            [[SmallCard class] drawCardImages];	
        else
       	    [[Card class] drawCardImages];
    }

    if(statusPanelUp) [statusPanel close];
    return self;
}


- (void) defaults:sender
{
    [backgroundColorWell setColor:[NSColor colorWithCalibratedRed:0.0
       	green:51.0/255.0 blue:34.0/255.0 alpha:1.0]];
    [cardSizeMatrix selectCellWithTag:CS_SMALL];
    [cardBackMatrix selectCellWithTag:CS_DEFAULT];
    [self saveColor:self];
    [self saveCardSize:self];
    [self saveCardBack:self]; 
}


- (void) saveColor:sender
{
    NSString *buffer;
    
    backgroundColor = [backgroundColorWell color];

    buffer = convertColorToString(backgroundColor);
    [[NSUserDefaults standardUserDefaults] setObject:buffer 
	forKey:@"backgroundColor"]; 
}


- (void) saveCardSize:sender
{
    NSString *buffer;

    cardSize = [cardSizeMatrix selectedTag];
    buffer = [NSString stringWithFormat:@"%d", cardSize];
    [[NSUserDefaults standardUserDefaults] setObject:buffer 
	forKey:@"cardSize"];
    
    if(preDrawCards){
    	if(cardSize == CS_SMALL)
	    [[SmallCard class] drawCardImages];	
	else
       	    [[Card class] drawCardImages];
    } 
}


- (void) saveCardBack:sender
{
    NSString *buffer;

    cardBack = [cardBackMatrix selectedTag];
    buffer = [NSString stringWithFormat:@"%d", cardBack];
    [[NSUserDefaults standardUserDefaults] setObject:buffer 
	forKey:@"cardBack"]; 
}


- (void) savePreDrawState:sender
{
    NSString *buffer;
    
    preDrawCards = [preDrawSwitch state];
    buffer = [NSString stringWithFormat:@"%d", preDrawCards];
    [[NSUserDefaults standardUserDefaults] setObject:buffer 
	forKey:@"preDrawCards"];

    if(preDrawCards){
    	if(cardSize == CS_SMALL)
	    [[SmallCard class] drawCardImages];	
	else
       	    [[Card class] drawCardImages];
    }
    else{
    	[[Card class] freeCardImages];
	[[SmallCard class] freeCardImages];
    } 
}


- (void) setNewImage:sender
{
    NSImageRep* 	originalRep=nil;
    NSButtonCell* 	buttonCell;
    NSRect 			imageRect;
    NSRect 			largeRect = {{0,0},{91.0, 153.0}};
    NSRect 			smallRect = {{0,0},{67.0, 114.0}};
    NSData* 		imageData;
    int 			imageType = checkImageType(imageFileName);
    
    if (imageType == TIFF_IMAGE) {
        imageData = [NSData dataWithContentsOfFile:imageFileName];
        originalRep = [[NSBitmapImageRep alloc] initWithData:imageData];
        (imageRect.size) = [originalRep size];
  
    	if (!imageData) {
            NSRunAlertPanel(@"Custom Image Error",
                            @"Could not find the image file, %@, for the custom card back.",
                            @"OK", nil, nil, imageFileName);
            return;
        }
    }
    else if(imageType == EPS_IMAGE) {
        imageData = [NSData dataWithContentsOfFile:imageFileName];	
        originalRep = [[NSEPSImageRep allocWithZone:[self zone]]
        initWithData:imageData];
        imageRect = [(NSEPSImageRep*)originalRep boundingBox];
        [originalRep setOpaque:YES];

        if (!originalRep) {
            NSRunAlertPanel(@"Custom Image Error", @"Could not find the "
                            @"image file, %@, for the	custom card back.",
                            @"OK", nil, nil, imageFileName);
            return;
        }
    }
    else if(imageType == OTHER_IMAGE){
        NSPasteboard* pasteboard;
        NSData* data;

        pasteboard = [NSPasteboard pasteboardByFilteringFile:imageFileName];
        data = [pasteboard dataForType:NSTIFFPboardType];

        originalRep = [[NSBitmapImageRep allocWithZone:[self zone]]
            initWithData:data];
        (imageRect.size) = [originalRep size];

        if(!originalRep){
            NSRunAlertPanel(@"Custom Image Error", @"Error in converting or could not find the image file, %@, for the custom card back.", @"OK", nil, nil, imageFileName);
            return;
        }
    }
    else {
        NSRunAlertPanel(@"Custom Image Error", @"Image type not supported in Solitaire.", @"OK", nil, nil);
    	return;
    }
    
    [[NSUserDefaults standardUserDefaults] setObject:imageFileName 
	forKey:@"imageFileName"];
    imageRect.origin.x = 0.0; imageRect.origin.y = 0.0;

    if(cardBackImage) [cardBackImage release];
    if(sCardBackImage) [sCardBackImage release];
    
    cardBackImage = [[NSImage allocWithZone:[self zone]] 
	initWithSize:(largeRect.size)];
    [cardBackImage setScalesWhenResized:YES];
    [cardBackImage setCachedSeparately:YES];

    [cardBackImage addRepresentation:[[[NSCachedImageRep alloc] 
	initWithSize:[cardBackImage size] depth:0 
	separate:[cardBackImage isCachedSeparately] alpha:YES] autorelease]];
    [cardBackImage lockFocusOnRepresentation:
	[[cardBackImage representations] lastObject]];
    [originalRep drawInRect:largeRect];
    [cardBackImage unlockFocus];
    
    sCardBackImage = [[NSImage allocWithZone:[self zone]] 
	initWithSize:(smallRect.size)];
    [sCardBackImage setScalesWhenResized:YES];
    [sCardBackImage setCachedSeparately:YES];

    [sCardBackImage addRepresentation:[[[NSCachedImageRep alloc] 
	initWithSize:[sCardBackImage size] depth:0 
	separate:[sCardBackImage isCachedSeparately] alpha:YES] 
	autorelease]];
    [sCardBackImage lockFocusOnRepresentation:
	[[sCardBackImage representations] lastObject]];
    [originalRep drawInRect:smallRect];
    [sCardBackImage unlockFocus];
    
    buttonCell = [cardBackMatrix cellWithTag:3];
    [buttonCell setImagePosition:NSImageOnly];
    [buttonCell setImage:sCardBackImage];
    [buttonCell setEnabled:YES];
    [originalRep release]; 
}
    

- (void) showPreferences:sender
{
    if (!preferencesPanel)
    {
        int depth;
    	NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
	
/*
    NSString *path = [[NSBundle bundleForClass:[self class]] 
	pathForResource:@"Preferences.nib" ofType:@"nib"];
    [NSBundle loadNibFile:path externalNameTable:[NSDictionary 
	dictionaryWithObjectsAndKeys:self, @"NSOwner", nil] 
	withZone:[self zone]];
*/

	[NSBundle loadNibNamed:@"Preferences.nib" owner:self];

    [preferencesPanel setFrameAutosaveName:@"PrefPanel"];
	[preferencesPanel registerForDraggedTypes:types];
	[backgroundColorWell setColor:backgroundColor];
	[cardSizeMatrix selectCellWithTag:cardSize];
	[cardBackMatrix selectCellWithTag:cardBack];
	[preDrawSwitch setState:preDrawCards];
	
	if ((depth = [preferencesPanel depthLimit]) == 0)
	    depth = [NSWindow defaultDepthLimit];
	    
	if (depth == 
		NSBestDepth(NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
	    [backgroundColorWell setEnabled:NO];
	else
	    [backgroundColorWell setEnabled:YES];
    
	if(sCardBackImage){
	    NSButtonCell* buttonCell = [cardBackMatrix cellWithTag:3];
	    [buttonCell setImagePosition:NSImageOnly];
	    [buttonCell setImage:sCardBackImage];
	    [buttonCell setEnabled:YES];
	}
    }
    
    if(sender != self) [preferencesPanel makeKeyAndOrderFront:nil]; 
}


- (CardSize) cardSize
{
    return cardSize;
}


- (CardBack) cardBack
{
    return cardBack;
}


- (NSColor *) backgroundColor
{
    return backgroundColor;
}


- (NSImage*) imageForSize:(CardSize)aSize
{
    if(aSize == CS_SMALL)
    	return sCardBackImage;
    	
    return cardBackImage;
}


- (unsigned int) draggingEntered:(id <NSDraggingInfo>)sender
{
    foundFile = NO;
    return [self draggingUpdated:sender];
}


- (unsigned int) draggingUpdated:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard;
    NSArray *imageFileTypes=[NSImage imageFileTypes];

    pboard = [sender draggingPasteboard];
    if ([[pboard types] containsObject:NSFilenamesPboardType]) {
    	NSArray* propertyList;
       	NSString* listItem;
    	NSString* itemExtension;
    	NSEnumerator* listEnumerator;

        propertyList = [pboard propertyListForType:NSFilenamesPboardType];
        listEnumerator = [propertyList objectEnumerator];
        while ((listItem = [listEnumerator nextObject])) {
            itemExtension = [listItem pathExtension];
            if ([imageFileTypes containsObject:itemExtension]) {
                imageFileName = [listItem retain];
		foundFile = YES;
                break;	
            }
        }
    }
    if(!foundFile) 
	    return NSDragOperationNone;
    else
	    return NSDragOperationCopy;
}


- (BOOL) prepareForDragOperation:(id <NSDraggingInfo>)sender
{
    if(foundFile) return YES;
    return NO;
}


- (BOOL) performDragOperation:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard;
    NSArray *imageFileTypes=[NSImage imageFileTypes];

    pboard = [sender draggingPasteboard];
    if ([[pboard types] containsObject:NSFilenamesPboardType]){
	NSArray* propertyList;
	NSString* listItem;
	NSString* itemExtension;
	NSEnumerator* listEnumerator;

	propertyList = [pboard propertyListForType:NSFilenamesPboardType];
	listEnumerator = [propertyList objectEnumerator];
	while ((listItem = [listEnumerator nextObject])) {
	    itemExtension = [listItem pathExtension];
	    if ([imageFileTypes containsObject:itemExtension]) {
		imageFileName = [listItem retain];
		break;	    
	    }
	}
    }
    [NSApp activateIgnoringOtherApps:YES];
    return YES;
}    


- (void) concludeDragOperation:(id <NSDraggingInfo>)sender
{
    [self performSelector:@selector(setNewImage:) withObject:self
                  afterDelay:0.0];
    foundFile = NO;
}

@end

