/* AppController.m created by fred on Wed 22-Sep-1999 */

#import "AppController.h"

#import "Dock.h"

//	----------------------------------------------------------------------------

@implementation AppController

- init
{	[super init];
	itsLaunchedApps = [[NSMutableSet alloc] init];
	itsDocks = [[NSMutableArray alloc] init];
	return self;
}

//	----------------------------------------------------------------------------

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

//	----------------------------------------------------------------------------

- (void)registerDock:(Dock *)aDock
{	[itsDocks addObject:aDock];
}

//	----------------------------------------------------------------------------

- (NSString *)libraryPath
{	return [@"~/Library/DaffyDocks" stringByExpandingTildeInPath];
}

//	----------------------------------------------------------------------------

- (BOOL)loadStartupDocks
{	NSEnumerator *e = [[NSFileManager defaultManager] enumeratorAtPath:[self libraryPath]];
	id o;
	BOOL theFlag = NO;

	while (o=[e nextObject])
		if ([[o pathExtension] isEqual:@"dock"])
		{	Dock *theDock = [[[Dock alloc] initFromPath:[[self libraryPath] stringByAppendingPathComponent:o]] autorelease];
			if (!theDock)
				NSLog( @"**** Cannot load dock from [%@]", o );
			else
			{	[theDock makeKeyAndOrderFront:self];
				[self registerDock:theDock];
				theFlag = YES;
			}
		}

	return theFlag;
}

//	----------------------------------------------------------------------------

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{		//	We listen to the workspace notifications
		//	Unfortunately, the workspace don't send the 'will' notifications, and we'll have to devise a way to find the application already launched
	[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(_workspaceDidLaunchApplication:) name:NSWorkspaceDidLaunchApplicationNotification object:nil];
	[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(_workspaceDidTerminateApplication:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];

{
		//	Note that we have a race condition, because we can't sync the workspace with the result of ListApplications.sh (grep'ing for apps is a hack, anyway)
		//	I choosed to grep after so it'll work correctly in the most likely situation (the user launches many apps at login along with its dock, so it is unlikely that applications are quitting while dock is launching)
	NSTask *theTask = [[NSTask alloc] init];
	NSPipe *thePipe = [NSPipe pipe];
	[theTask setStandardOutput:thePipe];
	[theTask setLaunchPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"ListApplications" ofType:@"sh"]];
	[theTask setArguments:[NSArray array]];
	[theTask launch];

		//	I choosed to use the ASCII encoding (ie: if anyone put accentuated chars in path names, he'll get what he deserves) because I don't know which one I am supposed to put (basically, it depends on the encoding used by /bin/ps')
		//	It'll break on real unicode platform.
		//	Maybe I should use NSProprietaryStringEncoding ?
	[itsLaunchedApps addObjectsFromArray:[[[[NSString alloc] initWithData:[[thePipe fileHandleForReading] readDataToEndOfFile]
			encoding:NSASCIIStringEncoding] autorelease] componentsSeparatedByString:@"\n"]];

//	NSLog( @"%@", itsLaunchedApps );
	[theTask waitUntilExit];
}

		//	Create the Library sub directory
	[[NSFileManager defaultManager] createDirectoryAtPath:[self libraryPath] attributes:nil];

		//	We didn't have any dock. We create one by default.
	if (![self loadStartupDocks])
	{	Dock *theDefaultDock;

			//	We create a dock from the default one
		NSLog( @"Creating default dock" );
		theDefaultDock = [[[Dock alloc] initFromPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"Default" ofType:@"dock"]] autorelease];

NSLog( @"%@", theDefaultDock );

			//	We change its path, so it get saved in the startup directory
		[theDefaultDock setPath:[[self libraryPath] stringByAppendingPathComponent:@"Startup.dock"]];

			//	And write it
		[theDefaultDock doSave:self];

NSLog( @"%@", theDefaultDock );
		[theDefaultDock makeKeyAndOrderFront:self];

		[self registerDock:theDefaultDock];
	}

}

- (void)_updateDocks
{	NSEnumerator *e = [itsDocks objectEnumerator];	
	Dock *o;

	while (o=[e nextObject])
		[o layout];
}

- (void)_workspaceDidLaunchApplication:(NSNotification *)aNotification
{
//	NSLog( @"%@", aNotification );
	[itsLaunchedApps addObject:[[aNotification userInfo] objectForKey:@"NSApplicationName"]];

	[self _updateDocks];
}

- (void)_workspaceDidTerminateApplication:(NSNotification *)aNotification
{
//	NSLog( @"%@", aNotification );
	[itsLaunchedApps removeObject:[[aNotification userInfo] objectForKey:@"NSApplicationName"]];

	[self _updateDocks];
}

- (BOOL)applicationLaunched:(NSString *)aPath
{	return [itsLaunchedApps containsObject:aPath];	
}

@end
