/*******************************************************************************
 Copyright (c) 2005-2006 Jordy Rose
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 
 Except as contained in this notice, the name(s) of the above copyright holders
 shall not be used in advertising or otherwise to promote the sale, use or other
 dealings in this Software without prior authorization.
*******************************************************************************/

//
//  FileInfoCell.m
//  Dockyard
//

#import "FileInfoCell.h"

/*!
 * Displays information like the Finder's column view, with an icon displayed
 * centered at the top of the cell, and information is printed below. Has basic
 * support for being in an NSBrowser, though this is not really recommended.
 *
 * @see FileInfoView
 */
@implementation FileInfoCell
- (id)initWithCoder:(NSCoder *)decoder
{
	self = [super initWithCoder:decoder];
	if (self != nil) {
		if ([decoder respondsToSelector:@selector(allowsKeyedCoding)] && [decoder allowsKeyedCoding] &&
			[decoder containsValueForKey:@"keyedCoding"]) {
			
			image = [[decoder decodeObjectForKey:@"image"] retain];
		} else {
			image = [[decoder decodeObject] retain];
		}
	}
	return self;
}

- (void)dealloc {
	[image release];
	[super dealloc];
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
	[super encodeWithCoder:encoder];
	if ([encoder respondsToSelector:@selector(allowsKeyedCoding)] && [encoder allowsKeyedCoding]) {
		[encoder encodeObject:image forKey:@"image"];
		[encoder encodeBool:YES forKey:@"keyedCoding"];
		
	} else {
		[encoder encodeObject:image];
	}
}

- (id)copyWithZone:(NSZone *)zone
{
	FileInfoCell *copy = [super copyWithZone:zone];
	copy->image = [[self image] copy];
	return copy;
}

/*!
 * Sets the cell's image to <code>anImage</code>. This image will be displayed
 * centered above any text in the cell.
 */
- (void)setImage:(NSImage *)anImage
{
    if (anImage != image) {
        [image release];
        image = [anImage copy];
    }
}

/*!
 * Returns the image currently being displayed.
 */
- (NSImage *)image
{
    return [[image retain] autorelease];
}

/*!
 * Draws the cell's image, centered at the top of the cell. Then draws the cell's
 * text in the remaining space. If the cell has no image currently set, simply
 * insets the text a little before drawing it.
 */
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
	if ([self drawsBackground]) {
		[[self backgroundColor] set];
		NSRectFill(cellFrame);
	}
	
	NSImage *currentImage = [self image];
	if (currentImage != nil) {
		// Draw image
		NSRect imageFrame = [self imageRectForBounds:cellFrame];
		float imageHeight = imageFrame.size.height;
		
		if ([controlView isFlipped])
			imageFrame.origin.y = imageHeight - 15;
		else
			imageFrame.origin.y = 15;
		[currentImage compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];

		// Draw text
		NSRect textFrame = [self titleRectForBounds:cellFrame];
		if ([controlView isFlipped])
			textFrame.origin.y += imageHeight - 20;
//		else
//			textFrame.origin.y += 20;
					
		[super drawWithFrame:textFrame inView:controlView];
		
	} else {
		cellFrame = [self titleRectForBounds:cellFrame];
		if ([controlView isFlipped])
			cellFrame.origin.y	-= 20;
//		else
//			cellFrame.origin.y	+= 20;
					
		[super drawWithFrame:cellFrame inView:controlView];
	}
}

/*!
 * Returns the space used to draw the cell's image, which is centered at the top.
 * The image is drawn above the text.
 *
 * @see #titleRectForBounds:
 */
- (NSRect)imageRectForBounds:(NSRect)cellFrame
{
	NSImage *currentImage = [self image];
    if (currentImage != nil) {
		NSRect imageFrame = cellFrame;
		NSSize imageSize = [currentImage size];
		imageFrame.size.height = imageSize.height + 30;
		
		imageFrame.origin.x = cellFrame.origin.x + ceil((cellFrame.size.width - imageSize.width) / 2);
		imageFrame.origin.y = 15;
		
        return imageFrame;
    }
    else
        return NSZeroRect;
}

/*!
 * Returns the space used to draw the cell's text, which is inset from the edge of the
 * cell on all sides. The text is drawn below the image.
 *
 * @see #imageRectForBounds:
 */
- (NSRect)titleRectForBounds:(NSRect)cellFrame
{
	NSImage *currentImage = [self image];
	
	cellFrame = [super titleRectForBounds:cellFrame];

	cellFrame.size.height	-= (currentImage != nil) ? [currentImage size].height + 30 : 30;
	cellFrame.size.width	-= 20;
	cellFrame.origin.x		+= 15;
	cellFrame.origin.y		+= 10;
	
	return cellFrame;
}

/*!
 * Returns the total size needed to display this cell, including both the 
 * text and the image.
 */
- (NSSize)cellSizeForBounds:(NSRect)bounds
{
	bounds.size.width -= 20;
	bounds.origin.x += 10;
	NSSize cellSize = [super cellSizeForBounds:bounds];
	
	NSImage *currentImage = [self image];
	if (currentImage == nil) {
		cellSize.height += 10;
		
	} else {
		cellSize.height += [currentImage size].height + 30;
		int width = [currentImage size].width + 30;
		if (cellSize.width < width)
			cellSize.width = width;
	}
	return cellSize;
}

#pragma mark -

/*!
 * Support for being a browser cell. Returns the default image.
 *
 * @see NSBrowserCell#branchImage
 */
+ (NSImage *)branchImage
{
	return [NSBrowserCell branchImage];
}

/*!
 * Support for being a browser cell. Returns the default highlighted image.
 *
 * @see NSBrowserCell#highlightedBranchImage
 */
+ (NSImage *)highlightedBranchImage
{
	return [NSBrowserCell highlightedBranchImage];
}

/*!
 * Support for being a browser cell. Returns <code>nil</code>, representing the
 * default color (I hope).
 *
 * @see NSBrowserCell#highlightColorInView:
 */
- (NSColor *)highlightColorInView:(NSView *)controlView
{
	return nil;
}

/*!
 * Support for being a browser cell. Returns the private flag used by NSCell
 * to represent leaves.
 *
 * @see NSBrowserCell#isLeaf
 */
- (BOOL)isLeaf
{
	return _cFlags.isLeaf;
}

/*!
 * Support for being a browser cell. Sets the private flag used by NSCell
 * to represent leaves.
 *
 * @see NSBrowserCell#setLeaf:
 */
- (void)setLeaf:(BOOL)flag
{
	if (flag)
		_cFlags.isLeaf = 1;
	else
		_cFlags.isLeaf = 0;
}

/*!
 * Support for being a browser cell. Returns the private flag used by NSCell
 * to represent whether or not the cell is loaded.
 *
 * @see NSBrowserCell#isLoaded
 */
- (BOOL)isLoaded
{
	return _cFlags.isLoaded;
}

/*!
 * Support for being a browser cell. Sets the private flag used by NSCell
 * to represent whether or not the cell is loaded.
 *
 * @see NSBrowserCell#setLoaded:
 */
- (void)setLoaded:(BOOL)flag
{
	if (flag)
		_cFlags.isLoaded = 1;
	else
		_cFlags.isLoaded = 0;
}

/*!
 * Support for being a browser cell. Does nothing.
 *
 * @see NSBrowserCell#reset
 */
- (void)reset
{
}

/*!
 * Support for being a browser cell. Does nothing.
 *
 * @see NSBrowserCell#set
 */
- (void)set
{
}
@end
