/*
	Copyright (C) 1994 Sean Luke

	COWSSystemLibrary.h
	Version 1.0
	Sean Luke
	
*/

#import "COWSSystemLibrary.h"
#import <time.h>
#import <appkit/appkit.h>
#define COWSSYSTEMLIBRARY_BIGENOUGHREGISTRATION	300

@implementation COWSSystemLibrary


- loadLibrary:sender
	{
	[sender addLibraryFunction:"beep"
			selector:@selector(beep:)
			target:self];
	[sender addLibraryFunction:"user-name"
			selector:@selector(userName:)
			target:self];
	[sender addLibraryFunction:"ping"
			selector:@selector(ping:)
			target:self];
	[sender addLibraryFunction:"alert"
			selector:@selector(alert:)
			target:self];
	[sender addLibraryFunction:"set-default"
			selector:@selector(setDefault:)
			target:self];
	[sender addLibraryFunction:"default"
			selector:@selector(getDefault:)
			target:self];
	[sender addLibraryFunction:"remove-default"
			selector:@selector(removeDefault:)
			target:self];
	/*[sender addLibraryFunction:"register-defaults"
			selector:@selector(registerDefaults:)
			target:self];*/
	[sender addLibraryFunction:"app-name"
			selector:@selector(appName:)
			target:self];
	[sender addLibraryFunction:"language"
			selector:@selector(language:)
			target:self];
	[sender addLibraryFunction:"time"
			selector:@selector(time:)
			target:self];
	[sender addLibraryFunction:"sleep"
			selector:@selector(sleep:)
			target:self];
	[sender addLibraryFunction:"execute"
			selector:@selector(execute:)
			target:self];
	interpreter=sender;
	return self;
	}


// functions
- beep:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	NXBeep();
	[ret setBooleanVal:TRUE];
	return ret;
	}
	
- userName:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	[ret setString:NXUserName()];
	return ret;
	}

- ping:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	NXPing();
	[ret setBooleanVal:TRUE];
	return ret;
	}

- alert:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	const char* title;
	const char* msg;
	const char* defaultButton;
	const char* alternateButton=NULL;	// quiets warnings
	const char* otherButton=NULL;		// likewise
	int answer;
	
	if ([interpreter canPause])	[interpreter pauseInterpreting];
	// Modal panels are reentrant and start up events again, so we must
	// be careful that the interpreter doesn't go merrily on its timed-entry
	// way before this library call gets a chance to respond.
	
	[arg_list first];
	
	if (![arg_list now])
		{
		[ret setString:"Alert: No Title"];
		[ret setError:YES];
		return ret;
		}
	title=[[arg_list now] string];

	if (![arg_list next])
		{
		[ret setString:"Alert: No Message"];
		[ret setError:YES];
		return ret;
		}
	msg=[[arg_list now] string];
		
	// set up OKAY button
	if ([arg_list next]) defaultButton=[[arg_list now] string];
	else defaultButton="Okay";
	// set up other buttons
	if ([arg_list next]) alternateButton=[[arg_list now] string];
	if ([arg_list next]) otherButton=[[arg_list now] string];

	answer=NXRunAlertPanel
		(title,msg,defaultButton,alternateButton,otherButton);	

	if (answer==NX_ALERTDEFAULT) [ret setBooleanVal:TRUE];
	if (answer==NX_ALERTALTERNATE) [ret setBooleanVal:FALSE];
	if (answer==NX_ALERTOTHER) [ret setString:"other"];
	if (answer==NX_ALERTERROR) [ret setString:"error"];

	if ([interpreter canPause]) [interpreter resumeInterpreting];
	return ret;
	}


// defaults
- setDefault:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	char owner[COWSSYSTEMLIBRARY_BIGENOUGHREGISTRATION];
	const char* key;
	const char* value;
	
	[arg_list first];
	
	if (![arg_list now])
		{
		[ret setString:"set-default: no key value"];
		[ret setError:YES];
		return ret;
		}
	key=[[arg_list now] string];
	
	if (![arg_list next])
		{
		[ret setString:"set-default: no value"];
		[ret setError:YES];
		return ret;
		}
	value=[[arg_list now] string];
	
	sprintf(owner,"%s(COWS)",[NXApp appName]);
	if (NXWriteDefault(owner,key,value)) [ret setBooleanVal:TRUE];
	else [ret setBooleanVal:FALSE];
		
	return ret;
	}

- getDefault:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	char owner[COWSSYSTEMLIBRARY_BIGENOUGHREGISTRATION];
	const char* key;
	const char* value;
		
	[arg_list first];
	
	if (![arg_list now])
		{
		[ret setString:"get-default: no key value"];
		[ret setError:YES];
		return ret;
		}
	key=[[arg_list now] string];
		
	sprintf(owner,"%s(COWS)",[NXApp appName]);
	if (value=NXGetDefaultValue(owner,key)) [ret setString:value];
	else [ret setString:""];
		
	return ret;
	}

- removeDefault:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	char owner[COWSSYSTEMLIBRARY_BIGENOUGHREGISTRATION];
	const char* key;
		
	[arg_list first];
	
	if (![arg_list now])
		{
		[ret setString:"remove-default: no key value"];
		[ret setError:YES];
		return ret;
		}
	key=[[arg_list now] string];
		
	sprintf(owner,"%s(COWS)",[NXApp appName]);
	if (NXRemoveDefault(owner,key)) [ret setBooleanVal:TRUE];
	else [ret setBooleanVal:FALSE];
		
	return ret;
	}


// application
- appName:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	[ret setString:[NXApp appName]];
	return ret;
	}

- language:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	const char* const* x=[NXApp systemLanguages];
	if (x[1]) [ret setString: x[1]];
	else [ret setString:""];
	return ret;
	}
			// systemLanguages

// time
- time:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	time_t tm=time(NULL);
	[ret setString:ctime(&tm)];
	return ret;
	}


- sleep:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	double x;
	[arg_list first];
	if (![arg_list now])
		{
		[ret setString:"sleep: no value"];
		[ret setError:YES];
		return ret;
		}
	x=[[arg_list now] doubleVal];
	if (x>0) usleep(x);
	[ret setBooleanVal:TRUE];
	return ret;
	}

- execute:arg_list
	{
	id ret=[[COWSStringNode alloc] init];
	[arg_list first];
	if (![arg_list now])
		{
		[ret setString:"execute: no value"];
		[ret setError:YES];
		return ret;
		}
	[ret setIntVal:system([[arg_list now] string])];
	return ret;
	}


@end