#import "Controller.h"
#import "ShelfView.h"

#import <appkit/appkit.h>


@implementation Controller

- init
{
    infoPanel = nil;
    prefPanel = nil;

    return self;
}


- appDidInit:sender
{
    NXRect	contentRect;
    NXScreen	*screens;
    int		screenCount;
    id		shelfWindow;
    id		workspace = [Application workspace];
    char	*mountedList = NULL;

#if	1 || WORK_AROUND_WORKSPACE_BUG
    /*
     *  This code works around a Workspace bug in 3.0 that prevents Workspace
     *  from dealing with disks effectively if it gets a request for icons
     *  before it's really initialized.  Calling this method before getting
     *  icons allows Workspace to initialize itself correctly.  The bug is
     *  fixed in 3.1, so we can eventually delete this code.
     */
    {
    BOOL junk;
    char *desc = NULL, *fsType = NULL;
    [[Application workspace] getInfoForFileSystemAt:"/"
		    isRemovable:&junk  isWritable:&junk
		    isUnmountable:&junk description:&desc
		    type:&fsType];
    if (desc)
    	free(desc);
    if (fsType)
    	free(fsType);
    }
#endif	

    [NXApp getScreens:&screens count:&screenCount];

    shelfWindow = [[Window allocFromZone:[self zone]]
		    initContent:&screens[0].screenBounds
		    style:NX_TOKENSTYLE
		    backing:NX_BUFFERED buttonMask:0 defer:NO];
    
    [[shelfWindow contentView] getFrame:&contentRect];
    shelfView = [[ShelfView allocFromZone:[shelfWindow zone]]
		 initFrame:&contentRect];
    [[shelfWindow setContentView:shelfView] free];

    PSsetwindowlevel(-2147483647, [shelfWindow windowNum]);

    [shelfWindow setAvoidsActivation:YES];
    [NXApp preventWindowOrdering];

    [shelfWindow display];
    [shelfWindow orderBack:self];

    /*
     *  UI is up and initialized.  Do some other things:
     *    1) scan for mounted things that we should stick up on the UI
     *       NOTE: because we couldn't get the list of removable media
     *             prior to 3.1, we need to be careful.
     *    2) start listening for changes in the file system
     */
    if ([workspace respondsTo:@selector(getMountedRemovableMedia:)] &&
        [workspace getMountedRemovableMedia:&mountedList])
        [self perform:@selector(createViewFor:) withPaths:mountedList];

    if (mountedList)
    	free(mountedList);

    [workspace beginListeningForDeviceStatusChanges];
    [NXApp hide:self];

    return self;
}


/*
 *  Put up a panel.  We have to handle two cases:
 *  1) The panel is not present because it hasn't been loaded yet, or
 *     because the user closed a previous one.  In this case, we load the
 *     panel from the nib section.
 *  2) The panel hasn't been closed by the user.  In this case, just
 *     pop up the window.
 */
- doPanel:(id *)panel named:(const char *) name
{
    char	path[MAXPATHLEN];
    id		bundle = [NXBundle mainBundle];

    if (!*panel && [bundle getPath:path forResource:name ofType:"nib"])
	[NXApp loadNibFile:path owner:self withNames:NO fromZone:[self zone]];
	    
    [*panel makeKeyAndOrderFront:self];

    return self;
}


- doInfo:sender
{
    return [self doPanel:&infoPanel named:"Info"];
}


- doPreferences:sender
{
    [self doPanel:&prefPanel named:"Preferences"];

    [gridValue setIntValue:[shelfView gridValue]];
    if ([shelfView gridEnabled])
	[gridSwitch setState:YES];

    [tileSwitch setState:[shelfView useBackgroundTile]];

    return self;
}


/*
 *  Find out if a window just closed.  If it was the info panel or the pref
 *  panel, forget about its identity, since it will free itself on close.
 */
- windowWillClose:sender
{
    if (sender == infoPanel)
	infoPanel = nil;
    else if (sender == prefPanel) {
    	[self enableGrid:self];			/* make sure we're in sync */
	[self enableBG:self];
    	prefPanel = nil;
    }

    return self;
}


- enableGrid:sender
{
    unsigned int	newValue = [gridValue intValue];

    [shelfView setGridValue:newValue];
    if ([shelfView gridValue] != newValue)
	[gridValue setIntValue:[shelfView gridValue]];

    [shelfView setGridEnabled:[gridSwitch state]];

    return self;
}

- enableBG:sender
{
    [shelfView setBackgroundEnabled:[tileSwitch state]];
    return self;
}

- createViewFor:(const char *) fullPath
{
    [shelfView createViewForPath:fullPath at:NULL];
    return self;
}


- app:sender mounted:(const char *) fullPath
{
    [self createViewFor:fullPath];
    return self;
}


- app:sender unmounted:(const char *) fullPath
{
    [shelfView removeViewForPath:fullPath];
    return self;
}

@end


@implementation Object(BriansPathMethods)
- (void) perform:(SEL) sel withPaths:(const char *) paths
{
    const char	*scan = paths;
    char	*copy;
    char	aPath[MAXPATHLEN];

    if (!paths || !*paths)
    	return;

    do {
    	copy = aPath;

    	while (*scan && *scan != '\t')
	    *copy++ = *scan++;
        *copy = '\0';

        if (*scan == '\t')
	    scan++;

	[self perform:sel with:(id) aPath];

    } while (*scan);
}
@end

