//
//  ECSegmentGeneratorPanelController.m
//  Etokicho
//
//  Created by 二鏡 on 11/11/19.
//  Copyright 2011年 二鏡庵. All rights reserved.
//

#import "ECSegmentGeneratorPanelController.h"
#import "ConfigurationManager.h"
#import "MainController.h"
#import "ECTransitionMenuItem.h"

static NSString *oSelectedIndexContext = @"selection";

@interface ECSegmentGeneratorPanelController ()
- (void)updateMenuItems:(NSArray*)transitions;
- (void)selectMenuItem:(NSManagedObject*)obj
         ofTransitions:(NSArray*)transitions;
- (void)_returnMenuSelection;
- (void)changeDefaultItem:(NSUInteger)idx;
@end

static id _si = nil;

#pragma mark -
@implementation ECSegmentGeneratorPanelController
@synthesize selection,menuItems,isRegularSelection, currentDuration;
+ (id)sharedPanel
{
    if(_si == nil)
    {
        _si = [[self alloc] initWithWindowNibName: @"SegmentGeneratorPanel"];
        [_si window];
    }
    return _si;
}
- (void)awakeFromNib
{
    id cm = [[NSApp delegate] configurationManager];
    id defaultItem = [cm currentTransition];
    id transitions = [cm transitions]; // all
    [self updateMenuItems: transitions];
    [self selectMenuItem: defaultItem
           ofTransitions: transitions];
    
    [self addObserver: self
           forKeyPath: oSelectedIndexContext
              options: NSKeyValueObservingOptionOld | NSKeyValueObservingOptionInitial
              context: oSelectedIndexContext];
    [self setWindowFrameAutosaveName: @"SegmentGeneratorPanelFrame"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if(context == oSelectedIndexContext)
    {
        oldIndex = [[change objectForKey: NSKeyValueChangeOldKey] firstIndex];
        NSUInteger idx = [menuItemsController selectionIndex];
        [self changeDefaultItem: idx];
        self.isRegularSelection = (idx != 0 && idx != [menuItems count]-1);
        return ;
    }
    
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}

#pragma mark Menu Items
- (void)updateMenuItems:(NSArray*)transitions
{
    id result = [NSMutableArray array];
    
    [result addObject: [ECTransitionMenuItem noneItem]];
    for(id aTransition in transitions)
    {
        ECTransitionMenuItem *item = [[ECTransitionMenuItem alloc] init];
        item.name = [aTransition valueForKey: @"name"];
        item.objectID = [aTransition objectID];
        [result addObject: item];
        [item release];
    }
    [result addObject: [ECTransitionMenuItem makeItem]];
    
    self.menuItems = result;
}

- (void)selectMenuItem:(NSManagedObject*)obj
         ofTransitions:(NSArray*)transitions
{
    if(obj == nil)
    {
        [menuItemsController setSelectionIndexes: [NSIndexSet indexSetWithIndex: 0]];
    }
    else
    {
        NSUInteger idx = [transitions indexOfObject: obj];
        if(idx == NSNotFound)
            [menuItemsController setSelectionIndexes: [NSIndexSet indexSetWithIndex: 0]];
        else
            [menuItemsController setSelectionIndexes: [NSIndexSet indexSetWithIndex: idx+1]];
        // 先頭はnoneなのでメニュー上のindexは一つシフトする
    }
}

- (void)_returnMenuSelection
{
    // cancel時にメニューアイテムの場所を戻す
    
    // newItemを指している場合は巻き戻し
    NSUInteger idx = [menuItemsController selectionIndex];
    if(idx == [menuItems count] -1)
    {
        [menuItemsController setSelectionIndexes: 
         [NSIndexSet indexSetWithIndex: oldIndex]];
    }
    else
    {
        // 動作の対称性のためidxを書き直す
        [menuItemsController setSelectionIndexes: 
         [NSIndexSet indexSetWithIndex: idx]];
    }    
}

#pragma mark Setting Update
- (void)changeDefaultItem:(NSUInteger)idx
{
    id item = [menuItems objectAtIndex: idx];
    ConfigurationManager *cm = [[NSApp delegate] configurationManager];
    id currentObj = [cm fetchItem: item];
    [cm setCurrentTransition: currentObj];
    self.currentDuration = [[currentObj valueForKey: @"duration"] integerValue];
    id error;
    [cm save: &error];
}

#pragma mark Action
- (IBAction)popupChanged:(id)sender
{
    // 下でoldを記憶し、現在のselectionはindexでとることができる
    NSUInteger selectionIndex = [menuItemsController selectionIndex];
    if(selectionIndex == [menuItems count]-1)
    {
        [self performSelector: @selector(showTransitionPanel:) 
                   withObject: nil
                   afterDelay: 0.0];        
    }
}

- (IBAction)remove:(id)sender
{
    id error;
    NSUInteger selectionIndex = [menuItemsController selectionIndex];
    id item = [menuItems objectAtIndex: selectionIndex];
    ConfigurationManager *cm = [[NSApp delegate] configurationManager];
    [cm deleteItem: item];
    [[cm context] processPendingChanges];
    if([cm save: &error] == NO)
        [NSApp presentError: error];
    
    [self updateMenuItems: [cm transitions]];
    
    // 削除後は一つ上を選択
    [menuItemsController setSelectionIndexes:
     [NSIndexSet indexSetWithIndex: selectionIndex-1]];
}

- (IBAction)edit:(id)sender
{
    NSUInteger selectionIndex = [menuItemsController selectionIndex];
    id item = [menuItems objectAtIndex: selectionIndex];
    id cm = [[NSApp delegate] configurationManager];
    id obj = [cm fetchItem: item];
    [self performSelector: @selector(showTransitionPanel:) 
               withObject: obj
               afterDelay: 0.0];
}

#pragma mark Panel Main Routine
- (void)showTransitionPanel:(NSManagedObject*)obj
{
    ECTransitionEditorPanelController *editor = [ECTransitionEditorPanelController sharedTransitionEditor];
    
    if(obj == nil) 
    {
        // 新規
        [editor loadInitialState];
    }
    else
    {
        // load current parameter
        editor.name = [obj valueForKey: @"name"];
        editor.compositionID = [obj valueForKey: @"identifier"];
        editor.flipHorizontal = [[obj valueForKey: @"flipHorizontal"] boolValue];
        editor.parameters = [obj valueForKey: @"parameters"];
        editor.duration = [[obj valueForKey: @"duration"] integerValue]; 
        [editor loadCompositionWithParameters];
    }
    
    NSUInteger result = [editor startModal];
    
    if(result != NSOKButton)
    {
        [self _returnMenuSelection];
        return;
    }
    
    id name = editor.name;
    id identifier = editor.compositionID;
    id parameters = editor.parameters;
    BOOL isFlipped = editor.flipHorizontal;
    NSInteger duration = editor.duration;
    
    // test
    if([name length] == 0 || [identifier length] == 0)
    {
        // 無効と見なす
        [self _returnMenuSelection];
        return ;
    }
    
    // 新規と編集で挙動が違う。
    if(obj == nil)
    {
        // 新しいmanagedObjectを挿入
        id configuration = [[NSApp delegate] configurationManager];
        obj = [configuration insertNewTransition];
    }
    
    // objのパラメータを書き換える
    [obj setValue: name forKey: @"name"];
    [obj setValue: identifier forKey: @"identifier"];
    [obj setValue: parameters forKey: @"parameters"];
    [obj setValue: [NSNumber numberWithBool: isFlipped] forKey: @"flipHorizontal"];
    [obj setValue: [NSNumber numberWithInteger: duration] forKey: @"duration"];
    id error;
    ConfigurationManager *cm = [[NSApp delegate] configurationManager];
    [cm setCurrentTransition: obj];
    
    // objectIDを正規化するためにsaveが必要
    [cm save: &error];
    
    id transitions = [cm transitions]; // all
    [self updateMenuItems: transitions];
    [self selectMenuItem: obj
           ofTransitions: transitions];
}

@end
