// Copyright 1991, 1994 Scott Hess.  Permission to use, copy,
// modify, and distribute this software and its documentation for
// any purpose and without fee is hereby granted, provided that
// this copyright notice appear in all copies.
// 
// Scott Hess makes no representations about the suitability of
// this software for any purpose.  It is provided "as is" without
// express or implied warranty.
//
#import "AppDefaults.h"

@implementation Application (AppDefaults)
int appDefaultsReference=0;
-(const char *)default:(const char *)defName default:(const char *)defValue
{
	// If the default name is bogus, there's no way to get a
	// real value.
    if( !defName || !defName[ 0]) {
	return defValue;
	
	// Get the real value and return it if non-NULL, otherwise
	// return defValue.  I use NXGetDefaultValue() here, though
	// sometimes it's desirable to change that to NXReadDefault().
	// As of yet, I've not determined which is saner.
	// NXReadDefault() may be in light of the -defaultAs*:default:
	// methods, which allow the specification of the default
	// value to be moved from NXRegisterDefaults() to the point
	// of use.
    } else {
	const char *value=NXGetDefaultValue( [self appName], defName);
	return value ? value : defValue;
    }
}
-(int)defaultAsInt:(const char *)defName default:(int)defValue
{
    const char *value=[self default:defName default:NULL];
    int ret;
	// Attempt to find an integer in value.
    if( sscanf( value, "%d", &ret)) {
	return ret;
    }
    return defValue;
}
-(BOOL)defaultAsBOOL:(const char *)defName default:(BOOL)defValue
{
    const char *value=[self default:defName default:NULL];
	// If it's NULL, return the default value.
    if( !value) {
	return defValue;
	
	// Explicit "YES" and "NO" are simple to handle.
    } else if( !NXOrderStrings( value, "YES", NO, -1, NULL)) {
	return YES;
    } else if( !NXOrderStrings( value, "NO", NO, -1, NULL)) {
	return NO;
	
	// Otherwise, see if it's an integer and return that value
	// if found.
    } else {
	int ret;
	if( sscanf( value, "%d", &ret)) {
	    return ret;
	}
	return defValue;
    }
}
-(float)defaultAsFloat:(const char *)defName default:(float)defValue
{
    const char *value=[self default:defName default:NULL];
    float ret;
	// Attempt to find a float in value.
    if( sscanf( value, "%f", &ret)) {
	return ret;
    }
    return defValue;
}
-(NXColor)defaultAsColor:(const char *)defName default:(NXColor)defValue
{
    const char *value=[self default:defName default:NULL];
	// If there's a value, attempt to parse out rgba components
	// and put them together into a color.
    if( value) {
	float r, g, b, a=NX_NOALPHA;
	if( sscanf( value, "%f %f %f %f", &r, &g, &b, &a)>=3) {
	    return NXConvertRGBAToColor ( r, g, b, a);
	}
    }
    return defValue;
}

    // Call the corrosponding -default*:default: method with sane
    // default values.
- (const char *)default:(const char *)defName
{
    return [self default:defName default:NULL];
}
-(int)defaultAsInt:(const char *)defName
{
    return [self defaultAsInt:defName default:0];
}
-(BOOL)defaultAsBOOL:(const char *)defName
{
    return [self defaultAsBOOL:defName default:NO];
}
-(float)defaultAsFloat:(const char *)defName
{
    return [self defaultAsFloat:defName default:0.0];
}
-(NXColor)defaultAsColor:(const char *)defName
{
    return [self defaultAsColor:defName default:NX_COLORWHITE];
}

- default:(const char *)defName as:(const char *)defValue
{
	// Cannot write if the default name is bogus.
    if( !defName || !defName[ 0]) {
	return nil;
    }
	// Also note if we fail to write.
    if( !NXWriteDefault( [self appName], defName, defValue)) {
	return nil;
    }
    return self;
}
static char buffer[ 32];
- default:(const char *)defName asInt:(int)defValue
{
    sprintf( buffer, "%d", defValue);
    return [self default:defName as:buffer];
}
- default:(const char *)defName asFloat:(float)defValue
{
    sprintf( buffer, "%f", defValue);
    return [self default:defName as:buffer];
}
- default:(const char *)defName asBOOL:(BOOL)defValue
{
    return [self default:defName as:defValue ? "YES" : "NO"];
}
- default:(const char *)defName asColor:(NXColor)defValue
{
    float r, g, b, a;
    NXConvertColorToRGBA( defValue, &r, &g, &b, &a);
    sprintf( buffer, "%f %f %f %f", r, g, b, a);
    return [self default:defName as:buffer];
}

-(BOOL)cmpDefault:(const char *)defName with:(const char *)cmp
{
    const char *value=[self default:defName];
	// Only attempt a comparison if the strings both exist.
    if( value && cmp) {
	return !NXOrderStrings( value, cmp, YES, -1, NULL);
	
	// If value && !cmp, not equal.
    } else if( value) {
	return NO;
    
	// If !value && cmp, not equal.
    } else if( cmp) {
	return NO;
	
	// If !value && !cmp, equal.
    } else {
	return YES;
    }
}
-(BOOL)cmpDefault:(const char *)defName caseWith:(const char *)cmp
{
    const char *value=[self default:defName];
	// Only attempt a comparison if the strings both exist.
    if( value && cmp) {
	return !NXOrderStrings( value, cmp, NO, -1, NULL);
	
	// If value && !cmp, not equal.
    } else if( value) {
	return NO;
    
	// If !value && cmp, not equal.
    } else if( cmp) {
	return NO;
	
	// If !value && !cmp, equal.
    } else {
	return YES;
    }
}
@end
