# import <appkit/Panel.h>
# import <appkit/Button.h>
# import <appkit/ScrollView.h>
# import <appkit/ActionCell.h>
# import <appkit/Cursor.h>
# import "ExecApp.h"

@implementation ExecApp

+ new
{
	self = [super new];
	executive = [[[Executive new] setTarget:self]
						setAction:@selector(commandDone:result:)];
	return(self);
}

- free
{
	[queueMatrix free];
	return([super free]);
}

- setCommand:anObject
{
	command = anObject;
	return(self);
}

- setAsync:anObject
{
	async = anObject;
	return(self);
}

- setCommandType:anObject
{
	commandType = anObject;
	return(self);
}

- setPipeOutputWindow:anObject
{
	pipeOutputWindow = anObject;
	return(self);
}

- setPipeOutputSV:anObject
{
	pipeOutputSV = anObject;
	pipeOutputText = [pipeOutputSV docView];
	return(self);
}

- setUpScrollView:sv
{	NXRect			r;
	Matrix			*mat;
	static NXSize	inter = { 0.0, 0.0 };
	NXSize			size;

	[sv setBackgroundGray:NX_LTGRAY];
	[sv getDocVisibleRect:&r];
	[[sv setDocView:(mat = [Matrix newFrame:&r mode:NX_LISTMODE
														cellClass:[ActionCell class]
														numRows:0
														numCols:1])] free];
	[sv setDocCursor:NXArrow];
	[mat setAutoscroll:YES];
	[mat getCellSize:&size];
	size.width = r.size.width;
	size.height -= 2;
	[[[mat setCellSize:&size] setIntercell:&inter] setBackgroundGray:NX_LTGRAY];
	return(mat);
}

- setQueueSV:anObject
{
	queueSV = anObject;
	queueMatrix = [self setUpScrollView:queueSV];
	return(self);
}

- commandDone:(int)which result:(int)err
{	int			row,col;

	NXRunAlertPanel("Async Command Done",
						(err == 0) ? "No errors" : "However, error %d occurred.",
						"Good",NULL,NULL,err);
	[queueMatrix getRow:&row andCol:&col ofCell:[queueMatrix findCellWithTag:which]];
	[queueMatrix removeRowAt:row andFree:YES];
	[queueMatrix sizeToCells];
	[queueSV display];
	return(self);
}

- pipeLine:(const char *)line
{	int	len = [pipeOutputText textLength];

	[[pipeOutputText setSel:len :len] replaceSel:line];
	return(self);
}

- pipeLine:(int)result line:(const char *)line
{
	return([self pipeLine:line]);
}

- takeUpdatePeriodFrom:sender
{
	[executive setPeriod:[sender doubleValue]];
	return(self);
}

- execute:sender
{	int		result = 0;
	BOOL		runAsync;
	char		s[2048];

	runAsync = [async intValue];
	if ([[commandType selectedCell] tag] == 0)
		result = [executive execute:[command stringValue] async:runAsync];
	else
	{	[pipeOutputWindow makeKeyAndOrderFront:self];
		result = [executive pipe:[command stringValue] to:self
					:((runAsync) ? @selector(pipeLine:line:) : @selector(pipeLine:))
					async:runAsync];
	}
	if (runAsync)
	{	int			insLoc;
	
		sprintf(s,"[%d] %s",result,[command stringValue]);
		[queueMatrix addRow];
		insLoc = [queueMatrix cellCount]-1;
		[[[queueMatrix cellAt:insLoc :0] setStringValue:s] setTag:result];
		[queueMatrix sizeToCells];
		[queueSV display];
	}
	else
	{	NXRunAlertPanel("Sync Command Done",
									(result == 0) ? "No errors" : "However, error %d occurred.",
									"Good",NULL,NULL,result);
	}
	return(self);
}

@end
