#import "DAImageBrowser.h"

@implementation DAImageBrowser

+ (DAImageBrowser *)openNewDirectory
{
    DAImageBrowser	*browser = nil;

    DURING
        int		result;
        NSString	*path = NSHomeDirectory();
        NSOpenPanel	*oPanel = [NSOpenPanel openPanel];
        NSArray		*fileTypes = [NSArray arrayWithObjects:@"tiff", @"gif", @"jpg", nil];

        [oPanel setCanChooseDirectories:YES];

        if ( [NSApp keyWindow] != nil )
            path = [[[NSApp keyWindow] representedFilename] stringByDeletingLastPathComponent];

        result = [oPanel runModalForDirectory:path file:nil types:fileTypes];

        if (result == NSOKButton)
        {
            NSString	*file = [oPanel filename];
            NSFileManager *fm = [NSFileManager defaultManager];
            BOOL	isDir = NO;

            browser = [[DAImageBrowser allocDocumentZone:NSStringFromClass([self class])] init];

            if ( [fm fileExistsAtPath:file isDirectory:&isDir] == YES )
            {
                if ( isDir == NO )
                {
                    file = [file stringByDeletingLastPathComponent];
                }
            }
            [browser setRoot:file];
            [browser display];
        }
    HANDLER
    ENDHANDLER
    return browser;
}

- (void)awakeFromNib;
{
    if ( root == nil )
        [self setRoot:NSHomeDirectory()];
}


- (void)setRoot:(NSString *)value
{
    [root autorelease];
    root = [value retain];
    if ( root )
    {
        [window setTitleWithRepresentedFilename:root];
        topFileInfo = [[FilteredFileInfo alloc] initWithPath:root];
    }
}
- (NSString *)root
{
    return root;
}

-(void)imageNext:sender
{
    int	selected = [outlineView selectedRow] + 1;

    if ( selected >= [outlineView numberOfRows] )
        selected = 0;

    [outlineView selectRow:selected byExtendingSelection:NO];
    [outlineView scrollRowToVisible:selected];
    [self displayImage:self];
}

-(void)imagePrev:sender
{
    int	selected = [outlineView selectedRow] - 1;

    if ( selected < 0 )
        selected = 0;

    [outlineView selectRow:selected byExtendingSelection:NO];
    [outlineView scrollRowToVisible:selected];
    [self displayImage:self];
}

- (void)delete:sender;
{
    DURING
    int			row = [outlineView selectedRow];
    FilteredFileInfo	*item = [outlineView itemAtRow:row];
    FilteredFileInfo	*parent = [item parent];
    NSFileManager 	*fm = [NSFileManager defaultManager];

    // this is ugly, but I am trying to hand all formatting issues to Project builder

    if (([item filetype] != NSFileTypeDirectory) || (NSRunAlertPanel(@"Delete Directory !!!", @"Are you sure you want to delete all the contents of %@", @"No", @"Yes", nil, [item filename]) == NSAlertAlternateReturn))
    {
        // maybe because the selected cell is being deleted we get an exception?
        [outlineView deselectAll:self];

        if ( [fm removeFileAtPath:[item fullPathName] handler:self] == YES )
            NSLog( @"Removed %@\n", [item fullPathName] );
        else
            NSLog( @"Error, could not remove %@\n", [item fullPathName] );

        // make the parent reload it's contained files array, should reload next 
        // time we ask for the containedFiles
        [parent setContainedFiles:nil];

        // have the outline view reload the parent.  The outline view should
        // shrink to remove the deleted image.  This causes an exception.

        // if ( parent == topFileInfo )
            [outlineView reloadData];
        // else
        //    [outlineView reloadItem:parent];
        // else

        // try to get the outline view to shrink!!!
        [outlineView noteNumberOfRowsChanged];

        // select the next row
        row++;
        while ((row >= [outlineView numberOfRows]) && ( row > 0 ))
            row--;

        [outlineView selectRow:row byExtendingSelection:NO];
        [outlineView scrollRowToVisible:row];

        // display the next image
        [self displayImage:self];
    }

    HANDLER
    ENDHANDLER
}

- (BOOL)fileManager:(NSFileManager *)fm shouldProceedAfterError:(NSDictionary *)errorInfo
{
    return NO;
}

- (void)displayImage:sender
{
    DURING
    id		item = [outlineView itemAtRow:[outlineView selectedRow]];
    NSImage	*image = [[[NSImage allocWithZone:[self zone]] initWithContentsOfFile:[item fullPathName]] autorelease];

    if ( image )
    {
        NSSize size = [image size];
        [imageView setImage:image];
        [window setTitleWithRepresentedFilename:[item fullPathName]];
        [descText setStringValue:[NSString stringWithFormat:@"%@ (%.1f x %.1f)", [item filename], size.width, size.height]];
    }
    else
    {
        [imageView setImage:nil];
        if ([item filetype] == NSFileTypeDirectory)
            [outlineView expandItem:item];
    }

    HANDLER
    ENDHANDLER
}

/* This routine asks for the object corresponding to the indexth child of item.  If the object is at the top level (i.e. the files contained in your home directory), the outlineView passes an item==nil, so that has to be special cased.  In this case, there is a single FilteredFileInfo corresponding to the home directory that contains all of the top level FilteredFileInfos.
*/
- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
{
    NSArray	*content = nil;
    if (item == nil)  //it's the topmost level
        content = [topFileInfo containedFiles];
    else
        content = [item containedFiles];

    if ( content && ( index < [content count] ))
        return [content objectAtIndex: index];

    return nil;
}

/* This routine checks to see whether a given item is expandable (i.e. needs a little spinning triangle thingy.  In this case, it does if and only if it is a directory.  Of course that doesn't mean that there are necessarily any subitems, since it should be possible to open an empty directory even though there's nothing inside.
*/
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable: (id)item
{
    return ([item filetype] == NSFileTypeDirectory);
}

/* outlineView:numberOfChildrenOfItem: performs a query to see how many children a particular item has.  Presumably the item has already been tested by outlineView:isItemExpandable to make sure it can be opened in the first place.  Again, an item==nil means that it's the top-level (see outlineView:child:ofItem:)
*/
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    if (item == nil)
        return [[topFileInfo containedFiles] count];
    else
        return [[item containedFiles] count];
}


/*  now that it's determined what the right object for a given row is, the NSOutlineView will ask what the appropriate data it should stick into each of the columns for that item.  In this case, the NSTableColumns have been setup in Interface Builder to have identifiers that correspond exactly to the correct accessor methods of the FileInfo objects.  Using the power of the Objective C runtime, these NSStrings are converted into selectors (similar to pointers to virtual functions in C++), which are then called on the items to return the correct information.
*/
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    return [item performSelector: NSSelectorFromString([tableColumn identifier])];
}

- (void)dealloc
{
    /* don't need to release finderListWindow since we never retained it. in general, we probably should have, but since it was only used in awakeFromNib, it wasn't necessary.
    */
    [topFileInfo release];
}


@end
