/*
** DWCachedImage
** 
** CHANGES:
** 0.2  (pozytron) Added ability to not draw backdrop.
*/

#import "DWCachedImage.h"
#import "NSImageExtensions.h"


@implementation DWCachedImage

/* Initialization */

    + (id) cachedImageWithImage: (id) theImage; {
        return [[[DWCachedImage alloc] initWithImage: theImage] autorelease];
    }
    
    - (id) initWithImage: (id) theImage; {
        self = [self init];
        originalImage = [theImage retain];
        return self;
    }
    
    - (id) init; {
        self = [super init];
        usesWhiteSilhouetteWhenAppropriate = YES;
        drawsBackground = YES;
        return self;
    }
    
    - (void) dealloc; 
    {
        int i;
        for (i=0; i<kDWColorTotalIndices; i++) {
            [cachedImages[i] release];
        }
        [originalImage release];
        [super dealloc];
    }
    
    - (id) copyWithZone: (id) theZone; {
        return [self retain];
    }


/* API */

    - (void) setUsesWhiteSilhouetteWhenAppropriate: (BOOL) value; {
        usesWhiteSilhouetteWhenAppropriate = value;
    }

    - (void) setDrawsBackground: (BOOL) value; {
        drawsBackground = value;
    }

    - (void) setImage: (id) theImage; {
        [originalImage release];
        originalImage = [theImage retain];
    }

    - (NSImage*) originalImage; {
        return originalImage;
    }

    - (id) imageWithBackgroundColorIndex: (int) dwColorIndex; 
    {
        //return nil;
        
        if (!originalImage) return nil;
    
        id opaqueImage, imageAtop;

        /* lookup */
            
            if ((opaqueImage = cachedImages[dwColorIndex])) {
                return opaqueImage;
            }

        /* else draw & cache */

            NSSize theSize = [originalImage size];

        /* choose between the original image or the white silhouette */
                        
            BOOL useWhiteSilhouette = (usesWhiteSilhouetteWhenAppropriate) && (dwColorIndex == kDWColorAlternateIndex);

            imageAtop = (useWhiteSilhouette) ? [originalImage whiteSilhouette] : originalImage;

        /* the following correction is necessary, otherwise there are fractional pixels (common when text is rendered) that result in a visual quirk */
        
            theSize.width = ceil(theSize.width);
            theSize.height = ceil(theSize.height);
        
        /* create the opaque image */
        
            opaqueImage = [[NSImage alloc] initWithSize: theSize];
            [opaqueImage setFlipped: YES];

        /* render */

            [opaqueImage lockFocus];
                [[DWColor colorForIndex: dwColorIndex] set];
                if (drawsBackground) NSRectFill([opaqueImage rect]);
                [imageAtop drawAtPoint: NSZeroPoint fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
            [opaqueImage unlockFocus];
    
        /* cache */
            
            cachedImages[dwColorIndex] = opaqueImage;
        
        /* log */

            #if 0
            NSLog(@"caching: %@", originalImage);
            #endif

        return opaqueImage;
    }


/* Drawing */
 
    - (void) drawAtPoint: (NSPoint) thePoint withBackgroundColorIndex: (int) dwColorIndex; {
        id image = [self imageWithBackgroundColorIndex: dwColorIndex];
        [image drawAtPoint: thePoint fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
    }

@end