// Copyright (c) 2011 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/menu_button.h"

#include "base/logging.h"
#import "chrome/browser/ui/cocoa/clickhold_button_cell.h"
#import "chrome/browser/ui/cocoa/nsview_additions.h"

@interface MenuButton (Private)
- (void)showMenu:(BOOL)isDragging;
- (void)clickShowMenu:(id)sender;
- (void)dragShowMenu:(id)sender;
@end  // @interface MenuButton (Private)

@implementation MenuButton

@synthesize openMenuOnClick = openMenuOnClick_;
@synthesize openMenuOnRightClick = openMenuOnRightClick_;

// Overrides:

+ (Class)cellClass {
  return [ClickHoldButtonCell class];
}

- (id)init {
  if ((self = [super init]))
    [self configureCell];
  return self;
}

- (id)initWithCoder:(NSCoder*)decoder {
  if ((self = [super initWithCoder:decoder]))
    [self configureCell];
  return self;
}

- (id)initWithFrame:(NSRect)frameRect {
  if ((self = [super initWithFrame:frameRect]))
    [self configureCell];
  return self;
}

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

- (void)awakeFromNib {
  [self configureCell];
}

- (void)setCell:(NSCell*)cell {
  [super setCell:cell];
  [self configureCell];
}

- (void)rightMouseDown:(NSEvent*)theEvent {
  if (!openMenuOnRightClick_) {
    [super rightMouseDown:theEvent];
    return;
  }

  [self clickShowMenu:self];
}

// Accessors and mutators:

- (NSMenu*)attachedMenu {
  return attachedMenu_.get();
}

- (void)setAttachedMenu:(NSMenu*)menu {
  attachedMenu_.reset([menu retain]);
  [[self cell] setEnableClickHold:(menu != nil)];
}

- (void)setOpenMenuOnClick:(BOOL)enabled {
  openMenuOnClick_ = enabled;
  if (enabled) {
    [[self cell] setClickHoldTimeout:0.0];  // Make menu trigger immediately.
    [[self cell] setAction:@selector(clickShowMenu:)];
    [[self cell] setTarget:self];
  } else {
    [[self cell] setClickHoldTimeout:0.25];  // Default value.
  }
}

- (void)setOpenMenuOnRightClick:(BOOL)enabled {
  openMenuOnRightClick_ = enabled;
}

- (NSRect)menuRect {
  return [self bounds];
}

@end  // @implementation MenuButton

@implementation MenuButton (Private)

// Reset various settings of the button and its associated |ClickHoldButtonCell|
// to the standard state which provides reasonable defaults.
- (void)configureCell {
  ClickHoldButtonCell* cell = [self cell];
  DCHECK([cell isKindOfClass:[ClickHoldButtonCell class]]);
  [cell setClickHoldAction:@selector(dragShowMenu:)];
  [cell setClickHoldTarget:self];
  [cell setEnableClickHold:([self attachedMenu] != nil)];
}

// Actually show the menu (in the correct location). |isDragging| indicates
// whether the mouse button is still down or not.
- (void)showMenu:(BOOL)isDragging {
  if (![self attachedMenu]) {
    LOG(WARNING) << "No menu available.";
    if (isDragging) {
      // If we're dragging, wait for mouse up.
      [NSApp nextEventMatchingMask:NSLeftMouseUpMask
                         untilDate:[NSDate distantFuture]
                            inMode:NSEventTrackingRunLoopMode
                           dequeue:YES];
    }
    return;
  }

  // TODO(viettrungluu): We have some fudge factors below to make things line up
  // (approximately). I wish I knew how to get rid of them. (Note that our view
  // is flipped, and that frame should be in our coordinates.) The y/height is
  // very odd, since it doesn't seem to respond to changes the way that it
  // should. I don't understand it.
  NSRect frame = [self menuRect];
  frame.origin.x -= 2.0;
  frame.size.height += 10.0;

  // Make our pop-up button cell and set things up. This is, as of 10.5, the
  // official Apple-recommended hack. Later, perhaps |-[NSMenu
  // popUpMenuPositioningItem:atLocation:inView:]| may be a better option.
  // However, using a pulldown has the benefit that Cocoa automatically places
  // the menu correctly even when we're at the edge of the screen (including
  // "dragging upwards" when the button is close to the bottom of the screen).
  // A |scoped_nsobject| local variable cannot be used here because
  // Accessibility on 10.5 grabs the NSPopUpButtonCell without retaining it, and
  // uses it later. (This is fixed in 10.6.)
  if (!popUpCell_.get()) {
    popUpCell_.reset([[NSPopUpButtonCell alloc] initTextCell:@""
                                                   pullsDown:YES]);
  }
  DCHECK(popUpCell_.get());
  [popUpCell_ setMenu:[self attachedMenu]];
  [popUpCell_ selectItem:nil];
  [popUpCell_ attachPopUpWithFrame:frame inView:self];
  [popUpCell_ performClickWithFrame:frame inView:self];

  // Once the menu is dismissed send a mouseExited event if necessary. If the
  // menu action caused the super view to resize then we won't automatically
  // get a mouseExited event so we need to do this manually.
  // See http://crbug.com/82456
  if (![self cr_isMouseInView]) {
    if ([[self cell] respondsToSelector:@selector(mouseExited:)])
      [[self cell] mouseExited:nil];
  }
}

// Called when the button is clicked and released. (Shouldn't happen with
// timeout of 0, though there may be some strange pointing devices out there.)
- (void)clickShowMenu:(id)sender {
  // This should only be called if openMenuOnClick has been set (which hooks
  // up this target-action).
  DCHECK(openMenuOnClick_ || openMenuOnRightClick_);
  [self showMenu:NO];
}

// Called when the button is clicked and dragged/held.
- (void)dragShowMenu:(id)sender {
  // We shouldn't get here unless the menu is enabled.
  DCHECK([self attachedMenu]);
  [self showMenu:YES];
}

@end  // @implementation MenuButton (Private)
