// 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/browser/password_generation_bubble_controller.h"

#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#import "chrome/browser/ui/cocoa/info_bubble_view.h"
#import "chrome/browser/ui/cocoa/info_bubble_window.h"
#include "chrome/browser/ui/cocoa/key_equivalent_constants.h"
#import "chrome/browser/ui/cocoa/styled_text_field_cell.h"
#include "components/autofill/content/common/autofill_messages.h"
#include "components/autofill/core/browser/password_generator.h"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/password_generation_util.h"
#include "content/public/browser/render_view_host.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#import "ui/base/cocoa/tracking_area.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h"

namespace {

// Size of the border in the bubble.
const CGFloat kBorderSize = 9.0;

// Visible size of the textfield.
const CGFloat kTextFieldHeight = 20.0;
const CGFloat kTextFieldWidth = 172.0;

// Frame padding necessary to make the textfield the correct visible size.
const CGFloat kTextFieldTopPadding = 3.0;

// Visible size of the button
const CGFloat kButtonWidth = 63.0;
const CGFloat kButtonHeight = 20.0;

// Padding that is added to the frame around the button to make it the
// correct visible size. Determined via visual inspection.
const CGFloat kButtonHorizontalPadding = 6.0;
const CGFloat kButtonVerticalPadding = 3.0;

// Visible size of the title.
const CGFloat kTitleWidth = 170.0;
const CGFloat kTitleHeight = 15.0;

// Space between the title and the textfield.
const CGFloat kVerticalSpacing = 13.0;

// Space between the textfield and the button.
const CGFloat kHorizontalSpacing = 7.0;

// We don't actually want the border to be kBorderSize on top as there is
// whitespace in the title text that makes it looks substantially bigger.
const CGFloat kTopBorderOffset = 3.0;

const CGFloat kIconSize = 26.0;

}  // namespace

// Customized StyledTextFieldCell to display one button decoration that changes
// on hover.
@interface PasswordGenerationTextFieldCell : StyledTextFieldCell {
 @private
  PasswordGenerationBubbleController* controller_;
  BOOL hovering_;
  base::scoped_nsobject<NSImage> normalImage_;
  base::scoped_nsobject<NSImage> hoverImage_;
}

- (void)setUpWithController:(PasswordGenerationBubbleController*)controller
                normalImage:(NSImage*)normalImage
                 hoverImage:(NSImage*)hoverImage;
- (void)mouseEntered:(NSEvent*)theEvent
              inView:(PasswordGenerationTextField*)controlView;
- (void)mouseExited:(NSEvent*)theEvent
             inView:(PasswordGenerationTextField*)controlView;
- (BOOL)mouseDown:(NSEvent*)theEvent
           inView:(PasswordGenerationTextField*)controlView;
- (void)setUpTrackingAreaInRect:(NSRect)frame
                         ofView:(PasswordGenerationTextField*)controlView;
// Exposed for testing.
- (void)iconClicked;
@end

@implementation PasswordGenerationTextField

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

- (PasswordGenerationTextFieldCell*)cell {
  return base::mac::ObjCCastStrict<PasswordGenerationTextFieldCell>(
      [super cell]);
}

- (id)initWithFrame:(NSRect)frame
     withController:(PasswordGenerationBubbleController*)controller
        normalImage:(NSImage*)normalImage
         hoverImage:(NSImage*)hoverImage {
  self = [super initWithFrame:frame];
  if (self) {
    PasswordGenerationTextFieldCell* cell = [self cell];
    [cell setUpWithController:controller
                  normalImage:normalImage
                   hoverImage:hoverImage];
    [cell setUpTrackingAreaInRect:[self bounds] ofView:self];
  }
  return self;
}

- (void)mouseEntered:(NSEvent*)theEvent {
  [[self cell] mouseEntered:theEvent inView:self];
}

- (void)mouseExited:(NSEvent*)theEvent {
  [[self cell] mouseExited:theEvent inView:self];
}

- (void)mouseDown:(NSEvent*)theEvent {
  // Let the cell handle the click if it's in the decoration.
  if (![[self cell] mouseDown:theEvent inView:self]) {
    if ([self currentEditor]) {
      [[self currentEditor] mouseDown:theEvent];
    } else {
      // We somehow lost focus.
      [super mouseDown:theEvent];
    }
  }
}

- (void)simulateIconClick {
  [[self cell] iconClicked];
}

@end

@implementation PasswordGenerationTextFieldCell

- (void)setUpWithController:(PasswordGenerationBubbleController*)controller
                normalImage:(NSImage*)normalImage
                 hoverImage:(NSImage*)hoverImage {
  controller_ = controller;
  hovering_ = NO;
  normalImage_.reset([normalImage retain]);
  hoverImage_.reset([hoverImage retain]);
  [self setLineBreakMode:NSLineBreakByTruncatingTail];
  [self setTruncatesLastVisibleLine:YES];
}

- (void)splitFrame:(NSRect*)cellFrame toIconFrame:(NSRect*)iconFrame {
  NSDivideRect(*cellFrame, iconFrame, cellFrame,
               kIconSize, NSMaxXEdge);
}

- (NSRect)getIconFrame:(NSRect)cellFrame {
  NSRect iconFrame;
  [self splitFrame:&cellFrame toIconFrame:&iconFrame];
  return iconFrame;
}

- (NSRect)getTextFrame:(NSRect)cellFrame {
  NSRect iconFrame;
  [self splitFrame:&cellFrame toIconFrame:&iconFrame];
  return cellFrame;
}

- (BOOL)eventIsInDecoration:(NSEvent*)theEvent
                     inView:(PasswordGenerationTextField*)controlView {
  NSPoint mouseLocation = [controlView convertPoint:[theEvent locationInWindow]
                                           fromView:nil];
  NSRect cellFrame = [controlView bounds];
  return NSMouseInRect(mouseLocation,
                       [self getIconFrame:cellFrame],
                       [controlView isFlipped]);
}

- (void)mouseEntered:(NSEvent*)theEvent
              inView:(PasswordGenerationTextField*)controlView {
  hovering_ = YES;
  [controlView setNeedsDisplay:YES];
}

- (void)mouseExited:(NSEvent*)theEvent
             inView:(PasswordGenerationTextField*)controlView {
  hovering_ = NO;
  [controlView setNeedsDisplay:YES];
}

- (BOOL)mouseDown:(NSEvent*)theEvent
           inView:(PasswordGenerationTextField*)controlView {
  if ([self eventIsInDecoration:theEvent inView:controlView]) {
    [self iconClicked];
    return YES;
  }
  return NO;
}

- (void)iconClicked {
  [controller_ regeneratePassword];
}

- (NSImage*)getImage {
  if (hovering_)
    return hoverImage_;
  return normalImage_;
}

- (NSRect)adjustFrameForFrame:(NSRect)frame {
  // By default, there appears to be a 2 pixel gap between what is considered
  // part of the textFrame and what is considered part of the icon.
  // TODO(gcasto): This really should be fixed in StyledTextFieldCell, as it
  // looks like the location bar also suffers from this issue.
  frame.size.width += 2;
  return frame;
}

- (NSRect)textFrameForFrame:(NSRect)cellFrame {
  // Baseclass insets the rect by top and bottom offsets.
  NSRect textFrame = [super textFrameForFrame:cellFrame];
  textFrame = [self getTextFrame:textFrame];
  return [self adjustFrameForFrame:textFrame];
}

- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame {
  NSRect textFrame = [self getTextFrame:cellFrame];
  return [self adjustFrameForFrame:textFrame];
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
  NSImage* image = [self getImage];
  NSRect iconFrame = [self getIconFrame:cellFrame];
  // Center the image in the available space. At the moment the image is
  // slightly larger than the frame so we crop it.
  // Offset the full difference on the left hand side since the border on the
  // right takes up some space. Offset half the vertical difference on the
  // bottom so that the image stays vertically centered.
  const CGFloat xOffset = [image size].width - NSWidth(iconFrame);
  const CGFloat yOffset = ([image size].height - (NSHeight(iconFrame))) / 2.0;
  NSRect croppedRect = NSMakeRect(xOffset,
                                  yOffset,
                                  NSWidth(iconFrame),
                                  NSHeight(iconFrame));

  [image drawInRect:iconFrame
           fromRect:croppedRect
          operation:NSCompositeSourceOver
           fraction:1.0
     respectFlipped:YES
              hints:nil];

  [super drawInteriorWithFrame:cellFrame inView:controlView];
}

- (void)setUpTrackingAreaInRect:(NSRect)frame
                         ofView:(PasswordGenerationTextField*)view {
  NSRect iconFrame = [self getIconFrame:frame];
  base::scoped_nsobject<CrTrackingArea> area(
      [[CrTrackingArea alloc] initWithRect:iconFrame
                                   options:NSTrackingMouseEnteredAndExited |
          NSTrackingActiveAlways owner:view userInfo:nil]);
  [view addTrackingArea:area];
}

- (CGFloat)topTextFrameOffset {
  return 1.0;
}

- (CGFloat)bottomTextFrameOffset {
  return 1.0;
}

- (CGFloat)cornerRadius {
  return 4.0;
}

- (BOOL)shouldDrawBezel {
  return YES;
}

@end

@implementation PasswordGenerationBubbleController

@synthesize textField = textField_;

- (id)initWithWindow:(NSWindow*)parentWindow
          anchoredAt:(NSPoint)point
      renderViewHost:(content::RenderViewHost*)renderViewHost
     passwordManager:(PasswordManager*)passwordManager
      usingGenerator:(autofill::PasswordGenerator*)passwordGenerator
             forForm:(const autofill::PasswordForm&)form {
  CGFloat width = (kBorderSize*2 +
                   kTextFieldWidth +
                   kHorizontalSpacing +
                   kButtonWidth);
  CGFloat height = (kBorderSize*2 +
                    kTextFieldHeight +
                    kVerticalSpacing +
                    kTitleHeight -
                    kTopBorderOffset +
                    info_bubble::kBubbleArrowHeight);
  NSRect contentRect = NSMakeRect(0, 0, width, height);
  base::scoped_nsobject<InfoBubbleWindow> window(
      [[InfoBubbleWindow alloc] initWithContentRect:contentRect
                                          styleMask:NSBorderlessWindowMask
                                            backing:NSBackingStoreBuffered
                                              defer:NO]);
  if (self = [super initWithWindow:window
                      parentWindow:parentWindow
                        anchoredAt:point]) {
    passwordGenerator_ = passwordGenerator;
    renderViewHost_ = renderViewHost;
    passwordManager_ = passwordManager;
    form_ = form;
    [[self bubble] setArrowLocation:info_bubble::kTopLeft];
    [self performLayout];
  }

  return self;
}

- (void)performLayout {
  NSView* contentView = [[self window] contentView];
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();

  textField_ = [[[PasswordGenerationTextField alloc]
      initWithFrame:NSMakeRect(kBorderSize,
                               kBorderSize,
                               kTextFieldWidth,
                               kTextFieldHeight + kTextFieldTopPadding)
     withController:self
        normalImage:rb.GetNativeImageNamed(IDR_RELOAD_DIMMED).ToNSImage()
         hoverImage:rb.GetNativeImageNamed(IDR_RELOAD)
             .ToNSImage()] autorelease];
  gfx::Font smallBoldFont =
      rb.GetFont(ResourceBundle::SmallFont).DeriveFont(0, gfx::Font::BOLD);
  [textField_ setFont:smallBoldFont.GetNativeFont()];
  [textField_
    setStringValue:base::SysUTF8ToNSString(passwordGenerator_->Generate())];
  [textField_ setDelegate:self];
  [contentView addSubview:textField_];

  CGFloat buttonX = (NSMaxX([textField_ frame]) +
                     kHorizontalSpacing -
                     kButtonHorizontalPadding);
  CGFloat buttonY = kBorderSize - kButtonVerticalPadding;
  NSButton* button =
      [[NSButton alloc] initWithFrame:NSMakeRect(
            buttonX,
            buttonY,
            kButtonWidth + 2 * kButtonHorizontalPadding,
            kButtonHeight + 2 * kButtonVerticalPadding)];
  [button setBezelStyle:NSRoundedBezelStyle];
  [button setTitle:l10n_util::GetNSString(IDS_PASSWORD_GENERATION_BUTTON_TEXT)];
  [button setTarget:self];
  [button setAction:@selector(fillPassword:)];
  [contentView addSubview:button];

  base::scoped_nsobject<NSTextField> title([[NSTextField alloc] initWithFrame:
          NSMakeRect(kBorderSize,
                     kBorderSize + kTextFieldHeight + kVerticalSpacing,
                     kTitleWidth,
                     kTitleHeight)]);
  [title setEditable:NO];
  [title setBordered:NO];
  [title setStringValue:l10n_util::GetNSString(
        IDS_PASSWORD_GENERATION_BUBBLE_TITLE)];
  [contentView addSubview:title];
}

- (IBAction)fillPassword:(id)sender {
  if (renderViewHost_) {
    renderViewHost_->Send(
        new AutofillMsg_GeneratedPasswordAccepted(
            renderViewHost_->GetRoutingID(),
            base::SysNSStringToUTF16([textField_ stringValue])));
  }
  if (passwordManager_)
    passwordManager_->SetFormHasGeneratedPassword(form_);

  actions_.password_accepted = true;
  [self close];
}

- (void)regeneratePassword {
  [textField_
    setStringValue:base::SysUTF8ToNSString(passwordGenerator_->Generate())];
  actions_.password_regenerated = true;
}

- (void)controlTextDidChange:(NSNotification*)notification {
  actions_.password_edited = true;
}

- (void)windowWillClose:(NSNotification*)notification {
  autofill::password_generation::LogUserActions(actions_);
  [super windowWillClose:notification];
}

@end
