// Copyright 2014 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/passwords/manage_passwords_view_controller.h"

#include <cmath>

#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/ui/chrome_style.h"
#import "chrome/browser/ui/cocoa/passwords/passwords_bubble_utils.h"
#import "chrome/browser/ui/cocoa/passwords/passwords_list_view_controller.h"
#include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
#include "grit/components_strings.h"
#include "grit/generated_resources.h"
#include "skia/ext/skia_utils_mac.h"
#import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
#include "ui/base/l10n/l10n_util.h"

@implementation NoPasswordsView
- (id)initWithWidth:(CGFloat)width {
  if ((self = [super initWithFrame:NSZeroRect])) {
    [self setEditable:NO];
    [self setSelectable:NO];
    [self setDrawsBackground:NO];
    [self setBezeled:NO];
    [self setStringValue:l10n_util::GetNSString(
        IDS_MANAGE_PASSWORDS_NO_PASSWORDS)];
    [self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
    [[self cell] setWraps:YES];
    [self setFrameSize:NSMakeSize(width, MAXFLOAT)];
    [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:self];
  }
  return self;
}
@end

@interface ManagePasswordsViewController ()
- (void)onDoneClicked:(id)sender;
- (void)onManageClicked:(id)sender;
@end

@implementation ManagePasswordsViewController

- (void)loadView {
  base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]);

  // -----------------------------------
  // |  Title                          |
  // |                                 |
  // |    username   password      x   |
  // |    username   password      x   |
  // |    username   password      x   |
  // |                                 |
  // |  Manage                 [Done]  |
  // -----------------------------------

  // The bubble should be wide enough to fit the title row, the username and
  // password rows, and the buttons row on one line each, but not smaller than
  // kDesiredBubbleWidth.

  // Create the elements and add them to the view.
  NSTextField* titleLabel =
      [self addTitleLabel:base::SysUTF16ToNSString(self.model->title())
                   toView:view];

  // Content. If we have a list of passwords to store for the current site, we
  // display them to the user for management. Otherwise, we show a "No passwords
  // for this site" message.
  NSView* contentView = nil;
  if (self.model->local_credentials().empty()) {
    const CGFloat noPasswordsWidth = std::max(
        kDesiredBubbleWidth - 2 * kFramePadding, NSWidth([titleLabel frame]));
    noPasswordsView_.reset(
        [[NoPasswordsView alloc] initWithWidth:noPasswordsWidth]);
    contentView = noPasswordsView_.get();
  } else {
    passwordsListController_.reset([[PasswordsListViewController alloc]
        initWithModel:self.model
                forms:self.model->local_credentials().get()]);
    contentView = [passwordsListController_ view];
  }
  [view addSubview:contentView];

  // Wrap the title if necessary to match the width of the content view.
  if (NSWidth([titleLabel frame]) > NSWidth([contentView frame])) {
    [titleLabel setFrameSize:NSMakeSize(NSWidth([contentView frame]), 0)];
    [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:titleLabel];
  }

  // Done button.
  doneButton_.reset([[self addButton:l10n_util::GetNSString(IDS_DONE)
                              toView:view
                              target:self
                              action:@selector(onDoneClicked:)] retain]);

  // Manage button.
  manageButton_.reset([[NSButton alloc] initWithFrame:NSZeroRect]);
  base::scoped_nsobject<HyperlinkButtonCell> cell([[HyperlinkButtonCell alloc]
      initTextCell:base::SysUTF16ToNSString(self.model->manage_link())]);
  [cell setControlSize:NSSmallControlSize];
  [cell setTextColor:skia::SkColorToCalibratedNSColor(
      chrome_style::GetLinkColor())];
  [manageButton_ setCell:cell.get()];
  [manageButton_ sizeToFit];
  [manageButton_ setTarget:self];
  [manageButton_ setAction:@selector(onManageClicked:)];
  [view addSubview:manageButton_];

  // Layout the elements, starting at the bottom and moving up.

  // The Done button goes in the bottom-right corner.
  const CGFloat width = 2 * kFramePadding + NSWidth([contentView frame]);
  CGFloat curX = width - kFramePadding - NSWidth([doneButton_ frame]);
  CGFloat curY = kFramePadding;
  [doneButton_ setFrameOrigin:NSMakePoint(curX, curY)];

  // The Manage button goes in the bottom-left corner, centered vertically with
  // the Done button.
  curX = kFramePadding;
  const CGFloat diffY = std::ceil(
      (NSHeight([doneButton_ frame]) - NSHeight([manageButton_ frame])) / 2.0);
  [manageButton_ setFrameOrigin:NSMakePoint(curX, curY + diffY)];

  // The content goes above the button row.
  curX = kFramePadding;
  curY = NSMaxY([doneButton_ frame]) + kUnrelatedControlVerticalPadding;
  [contentView setFrameOrigin:NSMakePoint(curX, curY)];

  // The title goes above the content.
  curY = NSMaxY([contentView frame]) + kUnrelatedControlVerticalPadding;
  [titleLabel setFrameOrigin:NSMakePoint(curX, curY)];

  curX = NSMaxX([contentView frame]) + kFramePadding;
  curY = NSMaxY([titleLabel frame]) + kFramePadding;
  DCHECK_EQ(width, curX);
  [view setFrameSize:NSMakeSize(curX, curY)];

  [self setView:view];
}

- (void)onDoneClicked:(id)sender {
  if (self.model)
    self.model->OnDoneClicked();
  [self.delegate viewShouldDismiss];
}

- (void)onManageClicked:(id)sender {
  if (self.model)
    self.model->OnManageLinkClicked();
  [self.delegate viewShouldDismiss];
}

- (ManagePasswordsBubbleModel*)model {
  return [self.delegate model];
}

- (NSButton*)defaultButton {
  return doneButton_;
}

@end

@implementation ManagePasswordsViewController (Testing)

- (NSButton*)doneButton {
  return doneButton_.get();
}

- (NSButton*)manageButton {
  return manageButton_.get();
}

- (NoPasswordsView*)noPasswordsView {
  return noPasswordsView_.get();
}

- (PasswordsListViewController*)passwordsListController {
  return passwordsListController_.get();
}

@end