//**************************************************************************
//	Copyright (c)1993 KNOPS EDV-Anlagen Gerd Knops
//
//	Project	: GTools
//	File	: MonsterShelf
//	Author	: Brian Pinkerton, Gerd Knops
//	Date	: 931223
//
//**************************************************************************
//
//	History:
//	931223 Converting to GTool
//
//**************************************************************************
//	<CLASSDESCRIPTION>
//	«description»
//
//**************************************************************************
#import <GKappkit/GKappkit.h>
#import "MonsterShelf.h"
#import "ShelfView.h"
//**************************************************************************
@implementation MonsterShelf
//**************************************************************************
// Class methods
//**************************************************************************
+ initialize
{
	[self new];
	
	return self;
}
+ new
{
	static id	sharedInstance=nil;
	
	if(!sharedInstance)
	{
		sharedInstance=[MonsterShelf alloc];
		[sharedInstance init];
	}
	
	return sharedInstance;
}
//**************************************************************************
// Factory & Initializing methods
//**************************************************************************
- init
{
    prefPanel = nil;

	[[self module]setupMenuItem:0 target:self
					selector:@selector(doPreferences:)];

	[[NXApp delegate]addDelegate:self];

    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];

    return self;
}
//**************************************************************************
// Preferences Panel
//**************************************************************************
- doPreferences:sender
{
	if(!prefPanel)
	{
		if([[self module]loadNib:"Preferences" owner:self])
		{
			[self localize:prefPanel];
			[prefPanel setDelegate:self];
			[prefPanel setFreeWhenClosed:YES];
			[prefPanel setOneShot:YES];
		}
	}

	[prefPanel orderFront:self];
    [gridValue setIntValue:[shelfView gridValue]];
    if([shelfView gridEnabled])
	{
		[gridSwitch setState:YES];
	}

    [tileSwitch setState:[shelfView useBackgroundTile]];

    return self;
}
//**************************************************************************
// Delegate Methods for Preferences Panel
//**************************************************************************
- windowWillClose:sender
{
	if(sender==prefPanel)
	{
		//
		// make sure we're in sync
		//
    	[self enableGrid:self];			
		[self enableBG:self];
    	prefPanel = nil;
	}
	
	return self;
}
//**************************************************************************
// Implementation Methods
//**************************************************************************
- enableGrid:sender
{
    unsigned int	newValue = [gridValue intValue];

    if([shelfView gridValue]!=newValue)
	{
		#ifdef DEBUG
			puts("gridValue changed!");
		#endif
		[shelfView setGridValue:newValue];
	}
	[gridValue setIntValue:[shelfView gridValue]];
	
	if([shelfView gridEnabled]!=[gridSwitch state])
	{
		#ifdef DEBUG
			puts("gridSwitch changed!");
		#endif
   		[shelfView setGridEnabled:[gridSwitch state]];
	}
	
    return self;
}
- enableBG:sender
{
	if([shelfView useBackgroundTile]!=[tileSwitch state])
	{
		#ifdef DEBUG
			puts("tileSwitch changed!");
		#endif
    	[shelfView setBackgroundEnabled:[tileSwitch state]];
	}
    return self;
}
- createViewFor:(const char *) fullPath
{
    [shelfView createViewForPath:fullPath at:NULL];
    return self;
}
//**************************************************************************
// Delegate Methods for Application
//**************************************************************************
- app:sender mounted:(const char *) fullPath
{
    [self createViewFor:fullPath];
    return self;
}
- app:sender unmounted:(const char *) fullPath
{
    [shelfView removeViewForPath:fullPath];
    return self;
}
@end
//**************************************************************************
// Category for Object
//**************************************************************************
@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
//***********************************************************************EOF