#import "OutlineViewDelegate.h"
#import "Resource.h"
#import "ResourceDocument.h"
#import "ResourceDataSource.h"
#import "ResourceNameCell.h"
#import "ApplicationDelegate.h"

@implementation OutlineViewDelegate

- (id)init
{
	self = [super init];
	if(!self) return nil;
	if(NSAppKitVersionNumber >= 700.0)		// darwin 7.0 == Mac OS 10.3, needed for -setPlaceholderString:
	{
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder:) name:ResourceNameDidChangeNotification object:nil];
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder:) name:ResourceTypeDidChangeNotification object:nil];
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder:) name:ResourceIDDidChangeNotification object:nil];
	}
	return self;
}

- (void)updatePlaceholder:(NSNotification *)notification
{
	Resource *resource = [notification object];
	ResourceNameCell *cell = (ResourceNameCell *) [[outlineView tableColumnWithIdentifier:@"name"] dataCellForRow:[outlineView rowForItem:resource]];
	if([[resource name] isEqualToString:@""])
	{
		if([[resource resID] shortValue] == -16455)
			[cell setPlaceholderString:NSLocalizedString(@"Custom Icon", nil)];
		else [cell setPlaceholderString:NSLocalizedString(@"Untitled Resource", nil)];
	}
}

/*!
@method		tableView:didClickTableColumn:
@pending	not needed in 10.3+, use existing sort functionality
*/

- (void)tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn
{
	NSArray *newResources;
	NSArray *oldResources = [(ResourceDataSource *)[tableView dataSource] resources];
	
	// sort the array
	NSImage *indicator = [tableView indicatorImageInTableColumn:tableColumn];
	NSImage *upArrow = [NSTableView _defaultTableHeaderSortImage];
	if(indicator == upArrow)
		newResources = [oldResources sortedArrayUsingFunction:compareResourcesAscending context:[tableColumn identifier]];
	else newResources = [oldResources sortedArrayUsingFunction:compareResourcesDescending context:[tableColumn identifier]];
	
	// swap new array for old one
	[(ResourceDataSource *)[tableView dataSource] setResources:[NSMutableArray arrayWithArray:newResources]];
	[tableView reloadData];
}

/*!
@function	compareResourcesAscending
@change		2003-10-25 NGS: now uses KVC methods to obtain the strings to compare
*/

int compareResourcesAscending(Resource *r1, Resource *r2, void *context)
{
	NSString *key = (NSString *)context;
	// compare two NSStrings (case-insensitive)
	if([key isEqualToString:@"name"] || [key isEqualToString:@"type"])
		return [(NSString *)[r1 valueForKey:key] caseInsensitiveCompare:(NSString *)[r2 valueForKey:key]];
	// compare two NSNumbers (or any other class)
	else return [(NSNumber *)[r1 valueForKey:key] compare:(NSNumber *)[r2 valueForKey:key]];
}

/*!
@function	compareResourcesDescending
@change		2003-10-25 NGS: now uses KVC methods to obtain the strings to compare
*/

int compareResourcesDescending(Resource *r1, Resource *r2, void *context)
{
	NSString *key = (NSString *)context;
	// compare two NSStrings (case-insensitive)
	if([key isEqualToString:@"name"] || [key isEqualToString:@"type"])
		return -1 * [(NSString *)[r1 valueForKey:key] caseInsensitiveCompare: (NSString *)[r2 valueForKey:key]];
	// compare two NSNumbers (or any other class)
	else return -1 * [(NSNumber *)[r1 valueForKey:key] compare: (NSNumber *)[r2 valueForKey:key]];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
	if([[tableColumn identifier] isEqualToString:@"size"] || [[tableColumn identifier] isEqualToString:@"attributes"])
		return NO;
	else return YES;
}

/*!
@method		outlineView:willDisplayCell:forTableColumn:item:
@change		2003-10-25 NGS: Moved functionality of NameFormatter into this method, removed NameFormatter class.
@change		2003-10-24 NGS: Swapped row colours so first row is white (as per 10.3), conditionalised drawing line background colours to system versions < 10.3, since in 10.3 it is handled by the nib file.
@change		2003-10-24 NGS: Added iconForResourceType method to app delegate instead of interrogating the cache here.
@pending	remove setting of the cell formatter when that capability is in interface builder
*/

- (void)outlineView:(NSOutlineView *)olView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
	Resource *resource = (Resource *)item;
	NSString *identifier = [tableColumn identifier];
	
	// set formatters for cells (remove when IB can set a formatter for an entire table column)
	if([identifier isEqualToString:@"size"])			[cell setFormatter:sizeFormatter];
	else if([identifier isEqualToString:@"attributes"])	[cell setFormatter:attributesFormatter];
	
	// set resource icon
	if([identifier isEqualToString:@"name"])
	{
		if(![resource representedFork])
			[(ResourceNameCell *)cell setImage:[(ApplicationDelegate *)[NSApp delegate] iconForResourceType:[resource type]]];
		else [(ResourceNameCell *)cell setImage:[(ApplicationDelegate *)[NSApp delegate] iconForResourceType:nil]];
		
		if([[resource name] isEqualToString:@""])
		{
			if([cell respondsToSelector:@selector(setPlaceholderString:)])	// 10.3+
			{
				// 10.3+ uses placeholder strings
				if([[resource resID] shortValue] == -16455)	// don't bother checking type since there are too many icon types
					[cell setPlaceholderString:NSLocalizedString(@"Custom Icon", nil)];
				else if([[resource type] isEqualToString:@"carb"] && [[resource resID] shortValue] == 0)
					[cell setPlaceholderString:NSLocalizedString(@"Carbon Identifier", nil)];
				else if([[resource type] isEqualToString:@"pnot"] && [[resource resID] shortValue] == 0)
					[cell setPlaceholderString:NSLocalizedString(@"File Preview", nil)];
				else if([[resource type] isEqualToString:@"STR "] && [[resource resID] shortValue] == -16396)
					[cell setPlaceholderString:NSLocalizedString(@"Creator Information", nil)];
				else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 1)
					[cell setPlaceholderString:NSLocalizedString(@"File Version", nil)];
				else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 2)
					[cell setPlaceholderString:NSLocalizedString(@"Package Version", nil)];
				else [cell setPlaceholderString:NSLocalizedString(@"Untitled Resource", nil)];
			}
			else
			{
				// pre-10.3, set text colour to grey and set title accordingly
				if([[resource resID] shortValue] == -16455)
					[cell setTitle:NSLocalizedString(@"Custom Icon", nil)];
				else if([[resource type] isEqualToString:@"carb"] && [[resource resID] shortValue] == 0)
					[cell setTitle:NSLocalizedString(@"Carbon Identifier", nil)];
				else if([[resource type] isEqualToString:@"pnot"] && [[resource resID] shortValue] == 0)
					[cell setTitle:NSLocalizedString(@"File Preview", nil)];
				else if([[resource type] isEqualToString:@"STR "] && [[resource resID] shortValue] == -16396)
					[cell setTitle:NSLocalizedString(@"Creator Information", nil)];
				else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 1)
					[cell setTitle:NSLocalizedString(@"File Version", nil)];
				else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 2)
					[cell setTitle:NSLocalizedString(@"Package Version", nil)];
				else [cell setTitle:NSLocalizedString(@"Untitled Resource", nil)];
				
//				if([[outlineView selectedItems] containsObject:resource])
//					[cell setTextColor:[NSColor whiteColor]];
//				else [cell setTextColor:[NSColor grayColor]];
			}
		}
	}
	
	// draw alternating blue/white backgrounds (if pre-10.3)
	if(NSAppKitVersionNumber < 700.0)
	{
		int row = [olView rowForItem:item];
		if(row % 2)	[cell setBackgroundColor:[NSColor colorWithCalibratedRed:0.93 green:0.95 blue:1.0 alpha:1.0]];
		else		[cell setBackgroundColor:[NSColor whiteColor]];
					[cell setDrawsBackground:YES];
	}
}

@end

@implementation RKOutlineView

/*!
@method		draggingSourceOperationMaskForLocal:
*/
- (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)local
{
    if(local) return NSDragOperationEvery;
    else return NSDragOperationCopy;
}

- (void)keyDown:(NSEvent *)event
{
	int selectedRow = [self selectedRow];
	if(selectedRow != -1 && [[event characters] isEqualToString:[NSString stringWithCString:"\r"]])
		[self editColumn:0 row:selectedRow withEvent:nil select:YES];
	else if(selectedRow != -1 && [[event characters] isEqualToString:[NSString stringWithCString:"\x7F"]])
		[(ResourceDocument *)[[[self window] windowController] document] deleteSelectedResources];
	else [super keyDown:event];
}

- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)selector
{
	// pressed return, end editing
	if(selector == @selector(insertNewline:))
	{
		[[self window] makeFirstResponder:self];
		[self abortEditing];
		return YES;
	}
	
	// pressed tab, move to next editable field
	else if(selector == @selector(insertTab:))
	{
		int newColumn = ([self editedColumn] +1) % [self numberOfColumns];
		NSString *newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
		if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
		{
			newColumn = (newColumn +1) % [self numberOfColumns];
			newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
			if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
				newColumn = (newColumn +1) % [self numberOfColumns];
		}
		
		[self editColumn:newColumn row:[self selectedRow] withEvent:nil select:YES];
		return YES;
	}
	
	// pressed shift-tab, move to previous editable field
	else if(selector == @selector(insertBacktab:))
	{
		int newColumn = ([self editedColumn] + [self numberOfColumns] -1) % [self numberOfColumns];
		NSString *newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
		if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
		{
			newColumn = (newColumn + [self numberOfColumns] -1) % [self numberOfColumns];
			newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
			if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
				newColumn = (newColumn + [self numberOfColumns] -1) % [self numberOfColumns];
		}
		
		[self editColumn:newColumn row:[self selectedRow] withEvent:nil select:YES];
		return YES;
	}
	
	return NO;
}

/*!
@method		_sendDelegateDidClickColumn:
@pending	not needed in 10.3+, use existing sort functionality
*/

//- (void)_sendDelegateDidMouseDownInHeader:(int)columnIndex
- (void)_sendDelegateDidClickColumn:(int)columnIndex
{
//	if(NSAppKitVersionNumber < 700.0)
	{
		NSTableColumn *tableColumn = [[self tableColumns] objectAtIndex:columnIndex];
		NSImage *indicator = [self indicatorImageInTableColumn:tableColumn];
		NSImage *upArrow = [NSTableView _defaultTableHeaderSortImage];
		NSImage *downArrow = [NSTableView _defaultTableHeaderReverseSortImage];
		if(indicator)
		{
			// column already selected
			if(indicator == upArrow)
				[self setIndicatorImage:downArrow inTableColumn:tableColumn];
			else [self setIndicatorImage:upArrow inTableColumn:tableColumn];
		}
		else	// new column selected
		{
			// if there is an existing selection, clear it's image
			if([self highlightedTableColumn] != nil)
				[self setIndicatorImage:nil inTableColumn:[self highlightedTableColumn]];
			
			// sort name and type columns ascending by default
			if([[tableColumn identifier] isEqualToString:@"name"] || [[tableColumn identifier] isEqualToString:@"type"])
				[self setIndicatorImage:upArrow inTableColumn:tableColumn];
			// sort all other columns descending by default
			else [self setIndicatorImage:downArrow inTableColumn:tableColumn];
			[self setHighlightedTableColumn:tableColumn];
		}
		[[self delegate] tableView:self didClickTableColumn:tableColumn];
	}
//	else [super _sendDelegateDidClickColumn:columnIndex];
}

@end