// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"

#include "base/logging.h"
#import "chrome/browser/ui/cocoa/browser_command_executor.h"
#import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
#include "chrome/browser/global_keyboard_shortcuts_mac.h"
#import "content/public/browser/render_widget_host_view_mac_base.h"

typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);

@interface ChromeEventProcessingWindow ()
// Duplicate the given key event, but changing the associated window.
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
@end

@implementation ChromeEventProcessingWindow

- (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event fromTable:
    (KeyToCommandMapper)commandForKeyboardShortcut {
  // Extract info from |event|.
  NSUInteger modifers = [event modifierFlags];
  const bool cmdKey = modifers & NSCommandKeyMask;
  const bool shiftKey = modifers & NSShiftKeyMask;
  const bool cntrlKey = modifers & NSControlKeyMask;
  const bool optKey = modifers & NSAlternateKeyMask;
  const unichar keyCode = [event keyCode];
  const unichar keyChar = KeyCharacterForEvent(event);

  int cmdNum = commandForKeyboardShortcut(cmdKey, shiftKey, cntrlKey, optKey,
      keyCode, keyChar);

  if (cmdNum != -1) {
    id executor = [self delegate];
    // A bit of sanity.
    DCHECK([executor conformsToProtocol:@protocol(BrowserCommandExecutor)]);
    DCHECK([executor respondsToSelector:@selector(executeCommand:)]);
    [executor executeCommand:cmdNum];
    return YES;
  }
  return NO;
}

- (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event {
  return [self handleExtraKeyboardShortcut:event
                                 fromTable:CommandForWindowKeyboardShortcut];
}

- (BOOL)handleDelayedWindowKeyboardShortcut:(NSEvent*)event {
  return [self handleExtraKeyboardShortcut:event
                         fromTable:CommandForDelayedWindowKeyboardShortcut];
}

- (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event {
  return [self handleExtraKeyboardShortcut:event
                                 fromTable:CommandForBrowserKeyboardShortcut];
}

- (BOOL)performKeyEquivalent:(NSEvent*)event {
  if (redispatchingEvent_)
    return NO;

  NSWindow* window = event.window;
  if (window) {
    BrowserWindowController* controller = [window windowController];
    if ([controller respondsToSelector:@selector(handledByExtensionCommand:)]) {
      if ([controller handledByExtensionCommand:event])
        return YES;
    }
  }

  // Give the web site a chance to handle the event. If it doesn't want to
  // handle it, it will call us back with one of the |handle*| methods above.
  NSResponder* r = [self firstResponder];
  if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
    return [r performKeyEquivalent:event];

  // If the delegate does not implement the BrowserCommandExecutor protocol,
  // then we don't need to handle browser specific shortcut keys.
  if (![[self delegate] conformsToProtocol:@protocol(BrowserCommandExecutor)])
    return [super performKeyEquivalent:event];

  // Handle per-window shortcuts like cmd-1, but do not handle browser-level
  // shortcuts like cmd-left (else, cmd-left would do history navigation even
  // if e.g. the Omnibox has focus).
  if ([self handleExtraWindowKeyboardShortcut:event])
    return YES;

  if ([super performKeyEquivalent:event])
    return YES;

  // Handle per-window shortcuts like Esc after giving everybody else a chance
  // to handle them
  return [self handleDelayedWindowKeyboardShortcut:event];
}

- (BOOL)redispatchKeyEvent:(NSEvent*)event {
  DCHECK(event);
  NSEventType eventType = [event type];
  if (eventType != NSKeyDown &&
      eventType != NSKeyUp &&
      eventType != NSFlagsChanged) {
    NOTREACHED();
    return YES;  // Pretend it's been handled in an effort to limit damage.
  }

  // Ordinarily, the event's window should be this window. However, when
  // switching between normal and fullscreen mode, we switch out the window, and
  // the event's window might be the previous window (or even an earlier one if
  // the renderer is running slowly and several mode switches occur). In this
  // rare case, we synthesize a new key event so that its associate window
  // (number) is our own.
  if ([event window] != self)
    event = [self keyEventForWindow:self fromKeyEvent:event];

  // Redispatch the event.
  eventHandled_ = YES;
  redispatchingEvent_ = YES;
  [NSApp sendEvent:event];
  redispatchingEvent_ = NO;

  // If the event was not handled by [NSApp sendEvent:], the sendEvent:
  // method below will be called, and because |redispatchingEvent_| is YES,
  // |eventHandled_| will be set to NO.
  return eventHandled_;
}

- (void)sendEvent:(NSEvent*)event {
  if (!redispatchingEvent_)
    [super sendEvent:event];
  else
    eventHandled_ = NO;
}

- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
  NSEventType eventType = [event type];

  // Convert the event's location from the original window's coordinates into
  // our own.
  NSPoint eventLoc = [event locationInWindow];
  eventLoc = [[event window] convertBaseToScreen:eventLoc];
  eventLoc = [self convertScreenToBase:eventLoc];

  // Various things *only* apply to key down/up.
  BOOL eventIsARepeat = NO;
  NSString* eventCharacters = nil;
  NSString* eventUnmodCharacters = nil;
  if (eventType == NSKeyDown || eventType == NSKeyUp) {
    eventIsARepeat = [event isARepeat];
    eventCharacters = [event characters];
    eventUnmodCharacters = [event charactersIgnoringModifiers];
  }

  // This synthesis may be slightly imperfect: we provide nil for the context,
  // since I (viettrungluu) am sceptical that putting in the original context
  // (if one is given) is valid.
  return [NSEvent keyEventWithType:eventType
                          location:eventLoc
                     modifierFlags:[event modifierFlags]
                         timestamp:[event timestamp]
                      windowNumber:[window windowNumber]
                           context:nil
                        characters:eventCharacters
       charactersIgnoringModifiers:eventUnmodCharacters
                         isARepeat:eventIsARepeat
                           keyCode:[event keyCode]];
}

@end  // ChromeEventProcessingWindow
