/*
 *  Author:       Serg Stoyan
 *
 *  Classes:      AppController : NSObject
 *                NSApplication (Forward)
 *
 *  Description:  Application's Controller. Action regarding application
 *                icon, application icon window, application menu.
 *                Manages creation/deletion windows and panels, access
 *                to application defaults (preferences).
 */

#import "AppController.h"

#import <Foundation/NSInvocation.h>

#import <AppKit/NSMenu.h>
#import <AppKit/NSWindow.h>
#import <AppKit/NSPanel.h>

#import "AppDefaults.h"
#import "AppIcon.h"
#import "Info.h"
#import "SessionWindow.h"
#import "SessionPrefs/Panel.h"

@implementation AppController

/*-------------------------------------------------------------------------*
 *  Application delegate methods
 *-------------------------------------------------------------------------*/
- (void) applicationWillFinishLaunching: (NSNotification *)notify
{
  appIcon = [[AppIcon alloc] init];
  [[NSApp iconWindow] setContentView: appIcon];

  [self createMenu];
}

- (void) applicationDidFinishLaunching: (NSNotification *)notify;
{
  appDefaults = [AppDefaults new];
  
  sessionWindow = [SessionWindow new];
  [sessionWindow orderFront: self];
}

- (BOOL) applicationShouldTerminate: (id)sender
{
  RELEASE (appDefaults);
  appDefaults = nil;

  return YES;
}

- (void) createMenu
{
  NSMenu *menu;
  NSMenu *info;
  NSMenu *session;
  NSMenu *edit;
  NSMenu *services;

  SEL action = @selector(method:);

  menu = [NSMenu new];

  [menu addItemWithTitle: @"Info" 
		action: @selector(showInfoPanel:) keyEquivalent: @""];
  [menu addItemWithTitle: @"Session"
    action:action keyEquivalent: @""];
  [menu addItemWithTitle: @"Edit"
    action:action keyEquivalent: @""];
/*  [menu addItemWithTitle: @"Windows"
    action:action keyEquivalent: @""];*/
  [menu addItemWithTitle: @"Services"
    action:action keyEquivalent: @""];
  [menu addItemWithTitle: @"Hide"
    action:@selector(hide:) keyEquivalent: @"h"];
  [menu addItemWithTitle:
    @"Quit" action:@selector(terminate:) keyEquivalent: @"q"];

  info = AUTORELEASE([[NSMenu alloc] init]);
  [menu setSubmenu:info forItem:[menu itemWithTitle:@"Info"]];
  [info addItemWithTitle:@"Info Panel..."
		action:@selector(showInfoPanel:) keyEquivalent:@""];
  [info addItemWithTitle:@"Preferences..." 
		action:@selector(showPrefPanel:) keyEquivalent:@""];
  [info addItemWithTitle:@"Help..." action:action keyEquivalent:@"?"];
  
  session = AUTORELEASE([[NSMenu alloc] init]);
  [session addItemWithTitle:@"New..." 
		   action: @selector(newSession:) keyEquivalent:@"n"];
  [session addItemWithTitle:@"Delete" 
		   action: @selector(deleteSession:) keyEquivalent:@""];
  [session addItemWithTitle:@"Inspector..." 
		   action: @selector(configureSession:) keyEquivalent:@"I"];
  [menu setSubmenu: session forItem: [menu itemWithTitle:@"Session"]];

  edit = AUTORELEASE([[NSMenu alloc] init]);
  [edit addItemWithTitle:@"Cut" action:action keyEquivalent:@"x"];
  [edit addItemWithTitle:@"Copy" action:action keyEquivalent:@"c"];
  [edit addItemWithTitle:@"Paste" action:action keyEquivalent:@"v"];
  [edit addItemWithTitle:@"Delete" action:action keyEquivalent:@""];
  [edit addItemWithTitle:@"Select All" action:action keyEquivalent:@"a"];
  [menu setSubmenu:edit forItem:[menu itemWithTitle:@"Edit"]];

  // Windows
/*  windows = [NSMenu new];
  [windows addItemWithTitle: @"Arrange in Front" 
    action:action keyEquivalent: @""];
  [windows addItemWithTitle: @"Miniaturize Window" 
    action: @selector (miniaturizeKeyWindow:) keyEquivalent: @"m"];
  [windows addItemWithTitle: @"Close Window" 
    action: @selector (closeKeyWindow) keyEquivalent: @"w"];
  [menu setSubmenu: windows forItem: [menu itemWithTitle:@"Windows"]];*/
  
  services = AUTORELEASE([[NSMenu alloc] init]);
  [menu setSubmenu: services forItem:[menu itemWithTitle:@"Services"]];

//  [NSApp setWindowsMenu: windows];
  [NSApp setServicesMenu: services];
  [NSApp setMainMenu: menu];
}

- (AppIcon *) appIcon
{
  return appIcon;
}

- (AppDefaults *) appDefaults
{
  return appDefaults;
}

- (SessionWindow *) sessionWindow
{
  return sessionWindow;
}

- (SessionPrefsPanel *) sessionPrefsPanel
{
  return sessionPrefsPanel;
}

/*-------------------------------------------------------------------------*
 *  Menu action methods
 *-------------------------------------------------------------------------*/
- (void) showInfoPanel: (id)sender
{
  if (infoPanel == nil)
  {
    infoPanel = [InfoPanel new];
  }

  [infoPanel orderFront:self];
}

- (void) showPrefPanel: (id)sender
{
  NSRunAlertPanel(@"Preferences", @"Preferences is not implemented yet",
      @"Ok", nil, nil);
}

- (void) newSession: (id)sender
{
  sessionPrefsPanel = [[SessionPrefsPanel new] 
    openNewSessionWithPrefs: [appDefaults sessionsDict]];
}

- (void) deleteSession: (id)sender
{
  if (NSRunAlertPanel (@"Delete session", 
        @"Do you want to delete session configuration?",
        @"Leave", @"Delete", nil) == 1)
  {
    return;
  }

  if (sessionPrefsPanel != nil)
  {
    [sessionPrefsPanel close];
  }

  [appDefaults removeSessionWithName: [sessionWindow getSelectedSessionName]];

  if (appDefaults != nil)
  {
    [sessionWindow updateSessionsList];
  }
}

- (void) configureSession: (id)sender
{
  if (sessionPrefsPanel == nil && sender != sessionWindow)
  {
    sessionPrefsPanel = [[SessionPrefsPanel new]
      openWithSessionName: [sessionWindow getSelectedSessionName]
      andPrefs: [appDefaults sessionsDict]];
  }
  else
  {
    [sessionPrefsPanel 
      loadPrefsForSession: [sessionWindow getSelectedSessionName]
      andPrefs: [appDefaults sessionsDict]];
  }
}

// Info Panel
- (void) infoPanelWillClose
{
  infoPanel = nil;
}

// Session Preferences
- (void) sessionPrefsPanelWillClose
{
  sessionPrefsPanel = nil;
}

// NSMenuValidation protocol
- (BOOL) validateMenuItem: (NSMenuItem *)aMenuItem
{
  NSString *selectedSessionName;
  NSString *itemTitle;

  selectedSessionName = [sessionWindow getSelectedSessionName];
  itemTitle = [aMenuItem title];

  if ([itemTitle isEqualToString:@"New..."]
      && sessionPrefsPanel != nil)
  {      
    return NO;
  }
  else if ([itemTitle isEqualToString:@"Inspector..."])
  {
    if (sessionPrefsPanel != nil
        || [selectedSessionName isEqualToString: @"No sessions configured"])
    {
      return NO;
    }
  }
  else if ([itemTitle isEqualToString:@"Delete"]
      && (sessionPrefsPanel != nil
      || [selectedSessionName isEqualToString: @"No sessions configured"]))
  {
    return NO;
  }

  return YES;
}

//Windows
- (void) miniaturizeKeyWindow: (id)sender
{
  [[NSApp keyWindow] miniaturize: sender];
}

- (void) closeKeyWindow
{
  [[NSApp keyWindow] close];
}

@end

@implementation NSApplication (Forward)

- (void) forwardInvocation: (NSInvocation *)anInvocation
{
  if ([[self delegate] respondsToSelector: [anInvocation selector]])
  {
    [anInvocation invokeWithTarget: [self delegate]];
  }
  else
  {
    [super forwardInvocation: anInvocation];
  }
}

@end

