// Preferences.h
// Project: Cribbage
// Stephan Wacker
// 93-10-03


#import "Preferences.h"
#import "Cribbage.h"

#import "cribbage.h"


#define APP_NAME	"CribbageBySW"	// name in defaults database

//
// Defaults vector for initializing defaults database
//
static NXDefaultsVector AppDefaults = {
    { LIMIT_DEFAULT_NAME,		LIMIT_DEFAULT_VALUE },
    { BRIEF_DEFAULT_NAME,		BRIEF_DEFAULT_VALUE },
    { EXPLAIN_DEFAULT_NAME,		EXPLAIN_DEFAULT_VALUE },
    { COMP_COLOR_DEFAULT_NAME,		COMP_COLOR_DEFAULT_VALUE },
    { HUMAN_COLOR_DEFAULT_NAME,		HUMAN_COLOR_DEFAULT_VALUE },
    { BACKGROUND_COLOR_DEFAULT_NAME,	BACKGROUND_COLOR_DEFAULT_VALUE },
    { NULL, NULL }
};


@implementation Preferences


- run: sender
{
    [[limitButton window] makeKeyAndOrderFront: self];
    return self;
}

- changeColor: sender
{
    [[NXApp delegate] updatePreferences];
    return self;
}

- changeSwitch: sender
// Always query all switches.
{
    quiet = [self briefMessages];
    explain = [self explainMistakes];
    return self;
}


- freezeLimit
{
    [limitButton setEnabled: NO];
    return self;
}

- unfreezeLimit
{
    [limitButton setEnabled: YES];
    return self;
}


+ initialize
// Register default values after class has been created.
{
    NXRegisterDefaults( APP_NAME, AppDefaults );
    
    // Initialize global variables.
    quiet = [self defaultBriefMessages];
    explain = [self defaultExplainMistakes];
    
    return self;
}



- (int) limit
// Answer current game limit.
{
    return [[[limitPopup itemList] selectedCell] tag];
}

- setLimit: (int) value
// Set new game limit.
{
    // [limitPopup itemList] is a Matrix.
    [[limitPopup itemList] selectCellWithTag: value];
    [limitButton setTitle: [[[limitPopup itemList] selectedCell] title]];
    return self;
}

+ (int) defaultLimit
// Answer default game limit.
{
    int		result;
    const char	*value = NXGetDefaultValue( APP_NAME, LIMIT_DEFAULT_NAME );
    
    result = atoi( value );
    switch( result ) {
      case 61:
      case 121:
	break;
      default:
	result = LIMIT_DEFAULT;		// only if invalid default value
	break;
    }
	
    return result;
}



- (BOOL) briefMessages
// Answer current messages selection.
{
    return [messagesSwitch intValue];
}

- setBriefMessages: (BOOL) value
// Set new messages selection.
{
    [messagesSwitch setIntValue: value];
    return self;
}

+ (BOOL) defaultBriefMessages
// Answer default messages selection.
{
    int		result;
    const char	*value = NXGetDefaultValue( APP_NAME, BRIEF_DEFAULT_NAME );
    
    result = !strcmp( value, "Yes" );
	
    return result;
}



- (BOOL) explainMistakes
// Answer current explanation selection.
{
    return [explainSwitch intValue];
}

- setExplainMistakes: (BOOL) value
// Set new explanation selection.
{
    [explainSwitch setIntValue: value];
    return self;
}

+ (BOOL) defaultExplainMistakes
// Answer default explanation selection.
{
    int		result;
    const char	*value = NXGetDefaultValue( APP_NAME, EXPLAIN_DEFAULT_NAME );
    
    result = !strcmp( value, "Yes" );
	
    return result;
}



- (NXColor) compColor
// Answer current computer peg color.
{
    return [compColorWell color];
}

- setCompColor: (NXColor) color
// Set new computer peg color.
{
    [compColorWell setColor: color];
    return self;
}

+ (NXColor) defaultCompColor
// Answer default computer peg color.
{
    NXColor	result;
    float	r, g, b;
    const char	*value = NXGetDefaultValue( APP_NAME, COMP_COLOR_DEFAULT_NAME );
    
    if( sscanf( value, "(%f,%f,%f)", &r, &g, &b ) < 3 ) {
	result = COMP_COLOR_DEFAULT;
    } else {
	result = NXConvertRGBToColor( r, g, b );
    }
	
    return result;
}



- (NXColor) humanColor
// Answer current human peg color.
{
    return [humanColorWell color];
}

- setHumanColor: (NXColor) color
// Set new human peg color.
{
    [humanColorWell setColor: color];
    return self;
}

+ (NXColor) defaultHumanColor
// Answer default human peg color.
{
    NXColor	result;
    float	r, g, b;
    const char	*value = NXGetDefaultValue( APP_NAME, HUMAN_COLOR_DEFAULT_NAME );
    
    if( sscanf( value, "(%f,%f,%f)", &r, &g, &b ) < 3 ) {
	result = HUMAN_COLOR_DEFAULT;
    } else {
	result = NXConvertRGBToColor( r, g, b );
    }
	
    return result;
}



- (NXColor) backgroundColor
// Answer current background peg color.
{
    return [backgroundColorWell color];
}

- setBackgroundColor: (NXColor) color
// Set new background peg color.
{
    [backgroundColorWell setColor: color];
    return self;
}

+ (NXColor) defaultBackgroundColor
// Answer default background peg color.
{
    NXColor	result;
    float	r, g, b;
    const char	*value = NXGetDefaultValue( APP_NAME, BACKGROUND_COLOR_DEFAULT_NAME );
    
    if( sscanf( value, "(%f,%f,%f)", &r, &g, &b ) < 3 ) {
	result = BACKGROUND_COLOR_DEFAULT;
    } else {
	result = NXConvertRGBToColor( r, g, b );
    }
	
    return result;
}



- awakeFromNib;
// Initialize yourself after nib file has been loaded.
{
    // Find popup list of limit button.
    limitPopup = [limitButton target];
    
    [self setLimit: [[self class] defaultLimit]];
    [self setBriefMessages: [[self class] defaultBriefMessages]];
    [self setExplainMistakes: [[self class] defaultExplainMistakes]];
    [self setCompColor: [[self class] defaultCompColor]];
    [self setHumanColor: [[self class] defaultHumanColor]];
    [self setBackgroundColor: [[self class] defaultBackgroundColor]];
    
    return self;
}


- save: sender
// Save preferences in database.
{
    static NXDefaultsVector newDefaults = {
	{ LIMIT_DEFAULT_NAME,			NULL },
	{ BRIEF_DEFAULT_NAME,			NULL },
	{ EXPLAIN_DEFAULT_NAME,			NULL },
	{ COMP_COLOR_DEFAULT_NAME,		NULL },
	{ HUMAN_COLOR_DEFAULT_NAME,		NULL },
	{ BACKGROUND_COLOR_DEFAULT_NAME,	NULL },
	{ NULL, NULL }
    };
    
    int		i;
    float	r, g, b;
    
    
    if( !newDefaults[0].value )			// allocate default values
	for( i = 0; newDefaults[i].name != NULL; i++ ) {
	    newDefaults[i].value = malloc( 60 );	// max length = 59
	}
    
    
    i = 0;
    
    sprintf( newDefaults[i++].value, "%d", [self limit] );

    sprintf( newDefaults[i++].value, "%s",
	     [self briefMessages] ? "Yes" : "No" );
    
    sprintf( newDefaults[i++].value, "%s",
	     [self explainMistakes] ? "Yes" : "No" );
    
    NXConvertColorToRGB( [self compColor], &r, &g, &b );
    sprintf( newDefaults[i++].value, "(%f,%f,%f)", r, g, b );
    
    NXConvertColorToRGB( [self humanColor], &r, &g, &b );
    sprintf( newDefaults[i++].value, "(%f,%f,%f)", r, g, b );
    
    NXConvertColorToRGB( [self backgroundColor], &r, &g, &b );
    sprintf( newDefaults[i++].value, "(%f,%f,%f)", r, g, b );
    
    
    NXWriteDefaults( APP_NAME, newDefaults );
    
    return self;
}


@end	// Preferences
