
#import "app.h"

#define GRAPH_NAME	"MyGraph3"


void aTimerProc(DPSTimedEntry teNumber, double now, char *userdata)
{
	[(id)userdata doYourThing: now];
}


@implementation GraphityAPIDemo3

- reportError: (const char *)message;
{
	NXRunAlertPanel("Problem!", message, "OK", NULL, NULL);
	return self;
}

- initSpeaker;
{
	port_t aPort;
	
	if(theSpeaker == nil) 
		theSpeaker = [[Graphity_APISpeaker allocFromZone:[self zone]]
					init];
	
	if([theSpeaker sendPort] != PORT_NULL) return self;
	
	aPort = NXPortFromName("Graphity", NULL);
	if(aPort == PORT_NULL) {
		[self reportError: "Could not launch Graphity!"];
		return nil;
	}
	[theSpeaker setSendPort:aPort];
	return self;
}

- newDocument:sender
{
	int x, error;
	const char *name = [theNameField stringValue];
	
	if([self initSpeaker] == nil)
		return nil;
		
	x = [theSpeaker API_newDocument: (char *)name error:&error];
	if(x != 0) {
		[self reportError: "Communication problem!"];
		return nil;
	}
	
	if(error != GRAPHITY_OK) {
		[self reportError: "Graphity could not create new doc!"];
		return nil;
	}
	
	[self shapeDocument:nil];
	[theNameField setEnabled:NO];
	[theAddButton setEnabled:YES];
	
    	return self; 
}

- addGraph:sender
{
	int x, error;
	const char *name = GRAPH_NAME;
	const char *docname = [theNameField stringValue];
	
	if([self initSpeaker] == nil)
		return nil;
		
	x = [theSpeaker API_addGraph: GRAPHITY_BAR_GRAPH
			with: (char *)name
			in: (char *)docname 
			error:&error];
	if(x != 0) {
		[self reportError: "Communication problem!"];
		return nil;
	}
	
	if(error != GRAPHITY_OK) {
		[self reportError: "Graphity could not create new graph!"];
		return nil;
	}

	[theSpeaker API_redisplay:(char *)name
			in: (char *)docname 
			error:&error];
	
	[theStartButton setEnabled:YES];
	
    	return self;
}


- shapeDocument:sender
{
	int a, error;
	const char *docname = [theNameField stringValue];
	float x = 0;
	float y = 0;
	float w = 550;
	float h = 700;
	
	if([self initSpeaker] == nil)
		return nil;
		
	a = [theSpeaker API_shapeDocument:(char *)docname
		    x:x
		    y: y
		    width:w
		    height:h
		    error: &error];
	if(a != 0) {
		[self reportError: "Communication problem!"];
		return nil;
	}
	
	if(error != GRAPHITY_OK) {
		[self reportError: "Graphity could not shape document!"];
		return nil;
	}
	
    	return self;
}

- graphData:sender
{
	int x, error;
	const char *name = GRAPH_NAME;
	const char *docname = [theNameField stringValue];
	const char *tmpFile = "/tmp/GraphityDemo3.data";	// ugly
	const char *aScript = [theScript stringValue];	
	int rowCount = -1;
	int serieCount = -1;
	char aBuf[512];
	
    // run shell script and place output in tmpFile
    
	sprintf(aBuf, "%s > %s", aScript, tmpFile);
	system(aBuf);
	
    // init speaker
    
	if([self initSpeaker] == nil)
		return nil;
		
    // tell Graphity to parse data in tmpFile
    
	x = [theSpeaker API_readDataFrom:(char *)tmpFile
			graph:(char *)name
			in:(char *)docname
			error: &error];
	if(x != 0) {
		[self reportError: "Communication problem!"];
		return nil;
	}
	
	if(error != GRAPHITY_OK) {
		[self reportError: "Graphity could not parse data file!"];
		return nil;
	}
	
    // get the size of the data
    
	[theSpeaker API_getGraphSize:(char *)name
		in:(char *)docname
		rowCount: &rowCount
		serieCount: &serieCount
		error: &error];
	[[theSizeForm findCellWithTag: 1] setIntValue: serieCount];
	[[theSizeForm findCellWithTag: 0] setIntValue: rowCount];
	
    	return self;
}

- startTimer:sender;
{
	[self startTheTimer:YES];
	[theStopButton setEnabled:YES];
	[theStartButton setEnabled:NO];
	[self doYourThing:0];
	return self;
}

- stopTimer:sender;
{
	[self startTheTimer:NO];
	[theStopButton setEnabled:NO];
	[theStartButton setEnabled:YES];
	return self;
}

- startTheTimer:(BOOL)flag;
{
	double period = [theFreq doubleValue];
	
	if(!flag) {
		if(theTimer != NULL)
			DPSRemoveTimedEntry(theTimer);
		theTimer = (DPSTimedEntry)NULL;	
		return self;
	}
	if(theTimer != NULL)
			DPSRemoveTimedEntry(theTimer);
	theTimer = DPSAddTimedEntry(period, 
				(DPSTimedEntryProc)aTimerProc,
				(void *)self, NX_BASETHRESHOLD);
	return self;
}

- doYourThing:(double)now;
{
	[theMessage setStringValue: "Sending data to Graphity..."];
	NXPing();
	[self graphData:nil];
	[theMessage setStringValue: ""];
	return self;
}

@end
