#import "PreferencesController.h"

static NSString *_serverPortKey = @"serverPort";

@implementation PreferencesController

+ (void)initialize {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:8001] forKey:_serverPortKey];
    [defaults registerDefaults:appDefaults];
}

- (void)displayError:(NSString *)msg {
    NSBeginAlertSheet(@"Please verify your entry", nil, nil, nil, _preferencesPanel,
                      nil, nil, nil, nil, msg);
}

- (BOOL)isValidPositiveInteger:(NSString *)str upToDigits:(unsigned int)digits {
    unsigned int strLength = [str length];
    if (strLength == 0 || strLength > digits) {
        return FALSE;
    }
    unsigned int digitCount = 0;
    unichar c;
    unsigned int i;
    for (i = 0; i < strLength; ++i) {
        c = [str characterAtIndex:i];
        if (c < '0' || c > '9') {
            return FALSE;
        }
        if (c != '0' || digitCount > 0) {
            ++digitCount;
            if (digitCount > digits) {
                return FALSE;
            }
        }
    }
    return TRUE;
}

- (void)correctSettings {
    if (_serverPort < 0 || _serverPort > 65535) {
        _serverPort = 8001;
    }
}

- (void)initPreferences {
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    _serverPort = [def integerForKey:_serverPortKey];
    [self correctSettings];
    [_serverPortField setIntValue:_serverPort];
}

- (BOOL)validatePreferences {
    NSString *serverPortString = [[_serverPortField stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    int serverPort = -1;
    if ([self isValidPositiveInteger:serverPortString upToDigits:5]) {
        serverPort = [serverPortString intValue];
    }
    if (serverPort < 0 || serverPort > 65535) {
        [self displayError:@"The server port must be a number between 0 and 65535."];
        return FALSE;
    }
    
    if (_serverPort != serverPort) {
        [self willChangeValueForKey:@"serverPort"];
        _serverPort = serverPort;
        [self didChangeValueForKey:@"serverPort"];
    } else {
        _serverPort = serverPort;
    }
    [self correctSettings];
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    [def setInteger:_serverPort forKey:_serverPortKey];
    [self initPreferences];
    return TRUE;
}

- (void)cancelChanges {
    [_serverPortField validateEditing];
    [self initPreferences];
}

- (void)windowWillClose:(NSNotification *)notification {
    [_serverPortField validateEditing];
    [self initPreferences];
}

- (void)windowDidBecomeKey:(NSNotification *)notification {
    [_preferencesPanel center];
}

- (IBAction)cancel:(id)sender {
    [self cancelChanges];
    [_preferencesPanel orderOut:nil];
}

- (IBAction)ok:(id)sender {
    if ([self validatePreferences]) {
        [_preferencesPanel orderOut:nil];
    }
}

- (int)serverPort {
    return _serverPort;
}

@end
