
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#import "SkOptionsTableView.h"
#import "SkTextFieldCell.h"
@implementation SkOptionItem
@synthesize fCell, fItem;
- (void)dealloc {
    [fCell release];
    [super dealloc];
}
@end

@implementation SkOptionsTableView
@synthesize fItems;

- (id)initWithCoder:(NSCoder*)coder {
    if ((self = [super initWithCoder:coder])) {
        self.dataSource = self;
        self.delegate = self;
        fMenus = NULL;
        fShowKeys = YES;
        [self setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
        self.fItems = [NSMutableArray array];
    }
    return self;
}

- (void)dealloc {
    self.fItems = nil;
    [super dealloc];
}

- (void) view:(SkNSView*)view didAddMenu:(const SkOSMenu*)menu {}
- (void) view:(SkNSView*)view didUpdateMenu:(const SkOSMenu*)menu {
    [self updateMenu:menu];
}

- (IBAction)toggleKeyEquivalents:(id)sender {
    fShowKeys = !fShowKeys;
    NSMenuItem* item = (NSMenuItem*)sender;
    [item setState:fShowKeys];
    [self reloadData];
}

- (void)registerMenus:(const SkTDArray<SkOSMenu*>*)menus {
    fMenus = menus;
    for (int i = 0; i < fMenus->count(); ++i) {
        [self loadMenu:(*fMenus)[i]];
    }
}

- (void)updateMenu:(const SkOSMenu*)menu {
    // the first menu is always assumed to be the static, the second is
    // repopulated every time over and over again

    // seems pretty weird that we have to get rid of the const'ness here,
    // but trying to propagate the const'ness through all the way to the fMenus
    // vector was a non-starter.

    int menuIndex = fMenus->find(const_cast<SkOSMenu *>(menu));
    if (menuIndex >= 0 && menuIndex < fMenus->count()) {
        NSUInteger first = 0;
        for (int i = 0; i < menuIndex; ++i) {
            first += (*fMenus)[i]->getCount();
        }
        [fItems removeObjectsInRange:NSMakeRange(first, [fItems count] - first)];
        [self loadMenu:menu];
    }
    [self reloadData];
}

- (NSCellStateValue)triStateToNSState:(SkOSMenu::TriState)state {
    if (SkOSMenu::kOnState == state)
        return NSOnState;
    else if (SkOSMenu::kOffState == state)
        return NSOffState;
    else
        return NSMixedState;
}

- (void)loadMenu:(const SkOSMenu*)menu {
    const SkOSMenu::Item* menuitems[menu->getCount()];
    menu->getItems(menuitems);
    for (int i = 0; i < menu->getCount(); ++i) {
        const SkOSMenu::Item* item = menuitems[i];
        SkOptionItem* option = [[SkOptionItem alloc] init];
        option.fItem = item;

        if (SkOSMenu::kList_Type == item->getType()) {
            int index = 0, count = 0;
            SkOSMenu::FindListItemCount(*item->getEvent(), &count);
            NSMutableArray* optionstrs = [[NSMutableArray alloc] initWithCapacity:count];
            SkAutoTDeleteArray<SkString> ada(new SkString[count]);
            SkString* options = ada.get();
            SkOSMenu::FindListItems(*item->getEvent(), options);
            for (int i = 0; i < count; ++i)
                [optionstrs addObject:[NSString stringWithUTF8String:options[i].c_str()]];
            SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &index);
            option.fCell = [self createList:optionstrs current:index];
            [optionstrs release];
        }
        else {
            bool state = false;
            SkString str;
            SkOSMenu::TriState tristate;
            switch (item->getType()) {
                case SkOSMenu::kAction_Type:
                    option.fCell = [self createAction];
                    break;
                case SkOSMenu::kSlider_Type:
                    SkScalar min, max, value;
                    SkOSMenu::FindSliderValue(*item->getEvent(), item->getSlotName(), &value);
                    SkOSMenu::FindSliderMin(*item->getEvent(), &min);
                    SkOSMenu::FindSliderMax(*item->getEvent(), &max);
                    option.fCell = [self createSlider:value
                                                  min:min
                                                  max:max];
                    break;
                case SkOSMenu::kSwitch_Type:
                    SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state);
                    option.fCell = [self createSwitch:(BOOL)state];
                    break;
                case SkOSMenu::kTriState_Type:
                    SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate);
                    option.fCell = [self createTriState:[self triStateToNSState:tristate]];
                    break;
                case SkOSMenu::kTextField_Type:
                    SkOSMenu::FindText(*item->getEvent(),item->getSlotName(), &str);
                    option.fCell = [self createTextField:[NSString stringWithUTF8String:str.c_str()]];
                    break;
                default:
                    break;
            }
        }
        [fItems addObject:option];
        [option release];
    }
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    return [self.fItems count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
    if (columnIndex == 0) {
        const SkOSMenu::Item* item = ((SkOptionItem*)[fItems objectAtIndex:row]).fItem;
        NSString* label = [NSString stringWithUTF8String:item->getLabel()];
        if (fShowKeys)
            return [NSString stringWithFormat:@"%@ (%c)", label, item->getKeyEquivalent()];
        else
            return label;
    }
    else
        return nil;
}

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    if (tableColumn) {
        NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
        if (columnIndex == 1)
            return [((SkOptionItem*)[fItems objectAtIndex:row]).fCell copy];
        else
            return [[[SkTextFieldCell alloc] init] autorelease];
    }
    return nil;
}

- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
    if (columnIndex == 1) {
        SkOptionItem* option = (SkOptionItem*)[self.fItems objectAtIndex:row];
        NSCell* storedCell = option.fCell;
        const SkOSMenu::Item* item = option.fItem;
        switch (item->getType()) {
            case SkOSMenu::kAction_Type:
                break;
            case SkOSMenu::kList_Type:
                [cell selectItemAtIndex:[(NSPopUpButtonCell*)storedCell indexOfSelectedItem]];
                break;
            case SkOSMenu::kSlider_Type:
                [cell setFloatValue:[storedCell floatValue]];
                break;
            case SkOSMenu::kSwitch_Type:
                [cell setState:[(NSButtonCell*)storedCell state]];
                break;
            case SkOSMenu::kTextField_Type:
                if ([[storedCell stringValue] length] > 0)
                    [cell setStringValue:[storedCell stringValue]];
                break;
            case SkOSMenu::kTriState_Type:
                [cell setState:[(NSButtonCell*)storedCell state]];
                break;
            default:
                break;
        }
    }
    else {
        [(SkTextFieldCell*)cell setEditable:NO];
    }
}

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
    if (columnIndex == 1) {
        SkOptionItem* option = (SkOptionItem*)[self.fItems objectAtIndex:row];
        NSCell* cell = option.fCell;
        const SkOSMenu::Item* item = option.fItem;
        switch (item->getType()) {
            case SkOSMenu::kAction_Type:
                item->postEvent();
                break;
            case SkOSMenu::kList_Type:
                [(NSPopUpButtonCell*)cell selectItemAtIndex:[anObject intValue]];
                item->setInt([anObject intValue]);
                break;
            case SkOSMenu::kSlider_Type:
                [cell setFloatValue:[anObject floatValue]];
                item->setScalar([anObject floatValue]);
                break;
            case SkOSMenu::kSwitch_Type:
                [cell setState:[anObject boolValue]];
                item->setBool([anObject boolValue]);
                break;
            case SkOSMenu::kTextField_Type:
                if ([anObject length] > 0) {
                    [cell setStringValue:anObject];
                    item->setString([anObject UTF8String]);
                }
                break;
            case SkOSMenu::kTriState_Type:
                [cell setState:[anObject intValue]];
                item->setTriState((SkOSMenu::TriState)[anObject intValue]);
                break;
            default:
                break;
        }
        item->postEvent();
    }
}

- (NSCell*)createAction{
    NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease];
    [cell setTitle:@""];
    [cell setButtonType:NSMomentaryPushInButton];
    [cell setBezelStyle:NSSmallSquareBezelStyle];
    return cell;
}

- (NSCell*)createList:(NSArray*)items current:(int)index {
    NSPopUpButtonCell* cell = [[[NSPopUpButtonCell alloc] init] autorelease];
    [cell addItemsWithTitles:items];
    [cell selectItemAtIndex:index];
    [cell setArrowPosition:NSPopUpArrowAtBottom];
    [cell setBezelStyle:NSSmallSquareBezelStyle];
    return cell;
}

- (NSCell*)createSlider:(float)value min:(float)min max:(float)max {
    NSSliderCell* cell = [[[NSSliderCell alloc] init] autorelease];
    [cell setFloatValue:value];
    [cell setMinValue:min];
    [cell setMaxValue:max];
    return cell;
}

- (NSCell*)createSwitch:(BOOL)state {
    NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease];
    [cell setState:state];
    [cell setTitle:@""];
    [cell setButtonType:NSSwitchButton];
    return cell;
}

- (NSCell*)createTextField:(NSString*)placeHolder {
    SkTextFieldCell* cell = [[[SkTextFieldCell alloc] init] autorelease];
    [cell setEditable:YES];
    [cell setStringValue:@""];
    [cell setPlaceholderString:placeHolder];
    return cell;
}

- (NSCell*)createTriState:(NSCellStateValue)state {
    NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease];
    [cell setAllowsMixedState:TRUE];
    [cell setTitle:@""];
    [cell setState:(NSInteger)state];
    [cell setButtonType:NSSwitchButton];
    return cell;
}
@end
