// Modified by Yen-Ju Chen <yjchenx@hotmail.com>
/* 
 * Command.m created by probert on 2001-12-29 17:36:43 +0000
 *
 * Project GSCommander
 *
 * Created with ProjectCenter - http://www.gnustep.org
 *
 * $Id: Command.m,v 1.1 2003/03/28 16:04:27 yjchen Exp $
 */

#include "Command.h"

@implementation Command

- (id)initWithCommand:(NSString *)comm args:(NSArray *)arguments
{
  if ((self = [super init]))
    {
      ASSIGN(args, arguments);
      ASSIGN(command, comm);
    }
  return self;
}

- (void)dealloc
{
  RELEASE(args);
  RELEASE(command);

  [[NSNotificationCenter defaultCenter] removeObserver:self];

  [super dealloc];
}

- (void)setTextView:(NSTextView *)view
{
    ASSIGN(output, view);
    [output setString:@""];
}

- (NSTask *) task
{
  return task;
}

- (void) readData: (NSNotification *) not
{
  NSData *data;

  if((data = [fileHandle availableData])) 
  {
      NSString *s = [[NSString alloc] initWithData:data encoding:[NSString defaultCStringEncoding]];

      [output replaceCharactersInRange:NSMakeRange([[output string] length],0) withString:s];

      [output replaceCharactersInRange:NSMakeRange([[output string] length],0) withString:@"\n"];
  }
}

- (void)executeCommand
{
/* Don't check output view anymore 
  if( output == nil )
    {
      NSRunAlertPanel(@"Attention!", @"No output view available!",@"OK",nil,nil);
      return;
    }
*/

  [output setString:@""];

  pipe = [[NSPipe alloc] init];
  fileHandle = [pipe fileHandleForReading];
  RETAIN(fileHandle);

  task = [[NSTask alloc] init];
  [task setArguments: args];
  [task setLaunchPath: command];
  [task setStandardOutput: pipe];
  [task setStandardError: pipe];

  [[NSNotificationCenter defaultCenter] addObserver:self
                           selector:@selector(readData:)
              name:NSFileHandleDataAvailableNotification
                                      object: fileHandle];

  [[NSNotificationCenter defaultCenter] addObserver:self
                          selector:@selector(taskEnded:)
                     name:NSTaskDidTerminateNotification
                                            object: task];

  [fileHandle waitForDataInBackgroundAndNotify];

  NS_DURING
    [task launch];
  NS_HANDLER
    /* Pretend to be terminated */
    [[NSNotificationCenter defaultCenter] postNotificationName: NSTaskDidTerminateNotification
                                                        object: task];
  NS_ENDHANDLER
/*
  [task waitUntilExit];

  [[NSNotificationCenter defaultCenter] removeObserver:self];

  RELEASE(fileHandle);
  RELEASE(pipe);
  RELEASE(task);
  task = nil;
*/
}

- (void) taskEnded: (NSNotification *) not
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  RELEASE(fileHandle);
  RELEASE(pipe);
  RELEASE(task);
  task = nil;
}

- (void) stop
{
    if( task && [task isRunning] )
    {
        [task terminate];

//	[[NSNotificationCenter defaultCenter] removeObserver:self];

	if( output )
	{
	    RELEASE( output );
	    output = nil;
	}
    }
}

@end
