/*
 Oaxaca: Useful Cocoa Library
 Copyright (C) 2005, Niko Matsakis (niko@alum.mit.edu)
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#import "OAKeyboardLayout.h"

#define SUCCESS 0

@implementation OAKeyboardLayout

- initWithKeyboardLayoutRef:(KeyboardLayoutRef)ref
{
    if ((self = [super init])) {
        _ref = ref;
        const void **lnarg = (const void**)&_localizedName;
        if (KLGetKeyboardLayoutProperty(_ref, kKLLocalizedName, lnarg) != SUCCESS) {
            [self release];
            return nil;
        }
        [_localizedName retain];
        
        const void **narg = (const void**)&_name;
        if (KLGetKeyboardLayoutProperty(_ref, kKLName, narg) != SUCCESS) {
            [self release];
            return nil;
        }
        [_name retain];
    }
    return self;
}

- (void) dealloc 
{
    [_localizedName release];
    [_name release];
    [super dealloc];
}

+ (NSArray*) allKeyboardLayouts
{
    CFIndex cnt;
    KeyboardLayoutRef klref;
    
    if (KLGetKeyboardLayoutCount (&cnt) != 0) {
        // error?  return an empty array
        return [NSArray array];
    }
    
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:cnt];
    
    for (int i = 0; i < cnt; i++) {
        if (KLGetKeyboardLayoutAtIndex (i, &klref) == SUCCESS) {
            OAKeyboardLayout *layout = [[OAKeyboardLayout alloc] initWithKeyboardLayoutRef:klref];
            if (layout)
                [result addObject:layout];
        }
    }
    
    return result;
}

+ (OAKeyboardLayout*) currentKeyboardLayout
{
    KeyboardLayoutRef klref;
    if (KLGetCurrentKeyboardLayout (&klref) == SUCCESS) {
        return [[[OAKeyboardLayout alloc] initWithKeyboardLayoutRef:klref] autorelease];
    }
    return nil;
}

+ (OAKeyboardLayout*) keyboardLayoutWithName:(NSString*)name
{
    KeyboardLayoutRef klref;
    if (KLGetKeyboardLayoutWithName ((CFStringRef)name, &klref) == SUCCESS) {
        return [[[OAKeyboardLayout alloc] initWithKeyboardLayoutRef:klref] autorelease];
    }
    return nil;
}

- (NSString *) localizedName
{
    return _localizedName;
}

- (NSString *) name
{
    return _name;
}

- (BOOL) set
{
    SInt32 scriptCode;
    if (KLGetKeyboardLayoutProperty( _ref, kKLGroupIdentifier, (const void**)&scriptCode ) != SUCCESS)
        return NO;
    KeyScript( scriptCode | smKeyForceKeyScriptMask );
    if (KLSetCurrentKeyboardLayout( _ref ) != SUCCESS)
        return NO;
    // workaround... not sure if this is necessary or not
    if ( scriptCode == smUnicodeScript )
        KeyScript( scriptCode | smKeyForceKeyScriptMask );
    
    return YES;
}

@end
