// 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.

#include "ui/views/controls/menu/menu_item_view.h"

#include "base/i18n/case_conversion.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/text_utils.h"
#include "ui/native_theme/common_theme.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/menu/menu_config.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/controls/menu/menu_image_util.h"
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "ui/views/controls/menu/menu_separator.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/widget/widget.h"

namespace views {

namespace {

// EmptyMenuMenuItem ---------------------------------------------------------

// EmptyMenuMenuItem is used when a menu has no menu items. EmptyMenuMenuItem
// is itself a MenuItemView, but it uses a different ID so that it isn't
// identified as a MenuItemView.

class EmptyMenuMenuItem : public MenuItemView {
 public:
  explicit EmptyMenuMenuItem(MenuItemView* parent)
      : MenuItemView(parent, 0, EMPTY) {
    // Set this so that we're not identified as a normal menu item.
    set_id(kEmptyMenuItemViewID);
    SetTitle(l10n_util::GetStringUTF16(IDS_APP_MENU_EMPTY_SUBMENU));
    SetEnabled(false);
  }

  virtual bool GetTooltipText(const gfx::Point& p,
                              base::string16* tooltip) const override {
    // Empty menu items shouldn't have a tooltip.
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(EmptyMenuMenuItem);
};

}  // namespace

// Padding between child views.
static const int kChildXPadding = 8;

// MenuItemView ---------------------------------------------------------------

// static
const int MenuItemView::kMenuItemViewID = 1001;

// static
const int MenuItemView::kEmptyMenuItemViewID =
    MenuItemView::kMenuItemViewID + 1;

// static
int MenuItemView::icon_area_width_ = 0;

// static
int MenuItemView::label_start_;

// static
int MenuItemView::item_right_margin_;

// static
int MenuItemView::pref_menu_height_;

// static
const char MenuItemView::kViewClassName[] = "MenuItemView";

MenuItemView::MenuItemView(MenuDelegate* delegate)
    : delegate_(delegate),
      controller_(NULL),
      canceled_(false),
      parent_menu_item_(NULL),
      type_(SUBMENU),
      selected_(false),
      command_(0),
      submenu_(NULL),
      has_mnemonics_(false),
      show_mnemonics_(false),
      has_icons_(false),
      icon_view_(NULL),
      top_margin_(-1),
      bottom_margin_(-1),
      left_icon_margin_(0),
      right_icon_margin_(0),
      requested_menu_position_(POSITION_BEST_FIT),
      actual_menu_position_(requested_menu_position_),
      use_right_margin_(true) {
  // NOTE: don't check the delegate for NULL, UpdateMenuPartSizes() supplies a
  // NULL delegate.
  Init(NULL, 0, SUBMENU, delegate);
}

void MenuItemView::ChildPreferredSizeChanged(View* child) {
  invalidate_dimensions();
  PreferredSizeChanged();
}

bool MenuItemView::GetTooltipText(const gfx::Point& p,
                                  base::string16* tooltip) const {
  *tooltip = tooltip_;
  if (!tooltip->empty())
    return true;

  if (GetType() == SEPARATOR)
    return false;

  const MenuController* controller = GetMenuController();
  if (!controller || controller->exit_type() != MenuController::EXIT_NONE) {
    // Either the menu has been closed or we're in the process of closing the
    // menu. Don't attempt to query the delegate as it may no longer be valid.
    return false;
  }

  const MenuItemView* root_menu_item = GetRootMenuItem();
  if (root_menu_item->canceled_) {
    // TODO(sky): if |canceled_| is true, controller->exit_type() should be
    // something other than EXIT_NONE, but crash reports seem to indicate
    // otherwise. Figure out why this is needed.
    return false;
  }

  const MenuDelegate* delegate = GetDelegate();
  CHECK(delegate);
  gfx::Point location(p);
  ConvertPointToScreen(this, &location);
  *tooltip = delegate->GetTooltipText(command_, location);
  return !tooltip->empty();
}

void MenuItemView::GetAccessibleState(ui::AXViewState* state) {
  state->role = ui::AX_ROLE_MENU_ITEM;

  base::string16 item_text;
  if (IsContainer()) {
    // The first child is taking over, just use its accessible name instead of
    // |title_|.
    View* child = child_at(0);
    ui::AXViewState state;
    child->GetAccessibleState(&state);
    item_text = state.name;
  } else {
    item_text = title_;
  }
  state->name = GetAccessibleNameForMenuItem(item_text, GetMinorText());

  switch (GetType()) {
    case SUBMENU:
      state->AddStateFlag(ui::AX_STATE_HASPOPUP);
      break;
    case CHECKBOX:
    case RADIO:
      if (GetDelegate()->IsItemChecked(GetCommand()))
        state->AddStateFlag(ui::AX_STATE_CHECKED);
      break;
    case NORMAL:
    case SEPARATOR:
    case EMPTY:
      // No additional accessibility states currently for these menu states.
      break;
  }
}

// static
bool MenuItemView::IsBubble(MenuAnchorPosition anchor) {
  return anchor == MENU_ANCHOR_BUBBLE_LEFT ||
         anchor == MENU_ANCHOR_BUBBLE_RIGHT ||
         anchor == MENU_ANCHOR_BUBBLE_ABOVE ||
         anchor == MENU_ANCHOR_BUBBLE_BELOW;
}

// static
base::string16 MenuItemView::GetAccessibleNameForMenuItem(
      const base::string16& item_text, const base::string16& minor_text) {
  base::string16 accessible_name = item_text;

  // Filter out the "&" for accessibility clients.
  size_t index = 0;
  const base::char16 amp = '&';
  while ((index = accessible_name.find(amp, index)) != base::string16::npos &&
         index + 1 < accessible_name.length()) {
    accessible_name.replace(index, accessible_name.length() - index,
                            accessible_name.substr(index + 1));

    // Special case for "&&" (escaped for "&").
    if (accessible_name[index] == '&')
      ++index;
  }

  // Append subtext.
  if (!minor_text.empty()) {
    accessible_name.push_back(' ');
    accessible_name.append(minor_text);
  }

  return accessible_name;
}

void MenuItemView::Cancel() {
  if (controller_ && !canceled_) {
    canceled_ = true;
    controller_->Cancel(MenuController::EXIT_ALL);
  }
}

MenuItemView* MenuItemView::AddMenuItemAt(
    int index,
    int item_id,
    const base::string16& label,
    const base::string16& sublabel,
    const base::string16& minor_text,
    const gfx::ImageSkia& icon,
    Type type,
    ui::MenuSeparatorType separator_style) {
  DCHECK_NE(type, EMPTY);
  DCHECK_LE(0, index);
  if (!submenu_)
    CreateSubmenu();
  DCHECK_GE(submenu_->child_count(), index);
  if (type == SEPARATOR) {
    submenu_->AddChildViewAt(new MenuSeparator(this, separator_style), index);
    return NULL;
  }
  MenuItemView* item = new MenuItemView(this, item_id, type);
  if (label.empty() && GetDelegate())
    item->SetTitle(GetDelegate()->GetLabel(item_id));
  else
    item->SetTitle(label);
  item->SetSubtitle(sublabel);
  item->SetMinorText(minor_text);
  if (!icon.isNull())
    item->SetIcon(icon);
  if (type == SUBMENU)
    item->CreateSubmenu();
  if (GetDelegate() && !GetDelegate()->IsCommandVisible(item_id))
    item->SetVisible(false);
  submenu_->AddChildViewAt(item, index);
  return item;
}

void MenuItemView::RemoveMenuItemAt(int index) {
  DCHECK(submenu_);
  DCHECK_LE(0, index);
  DCHECK_GT(submenu_->child_count(), index);

  View* item = submenu_->child_at(index);
  DCHECK(item);
  submenu_->RemoveChildView(item);

  // RemoveChildView() does not delete the item, which is a good thing
  // in case a submenu is being displayed while items are being removed.
  // Deletion will be done by ChildrenChanged() or at destruction.
  removed_items_.push_back(item);
}

MenuItemView* MenuItemView::AppendMenuItem(int item_id,
                                           const base::string16& label,
                                           Type type) {
  return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
      gfx::ImageSkia(), type, ui::NORMAL_SEPARATOR);
}

MenuItemView* MenuItemView::AppendSubMenu(int item_id,
                                          const base::string16& label) {
  return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
      gfx::ImageSkia(), SUBMENU, ui::NORMAL_SEPARATOR);
}

MenuItemView* MenuItemView::AppendSubMenuWithIcon(int item_id,
                                                  const base::string16& label,
                                                  const gfx::ImageSkia& icon) {
  return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
                            icon, SUBMENU, ui::NORMAL_SEPARATOR);
}

MenuItemView* MenuItemView::AppendMenuItemWithLabel(
    int item_id,
    const base::string16& label) {
  return AppendMenuItem(item_id, label, NORMAL);
}

MenuItemView* MenuItemView::AppendDelegateMenuItem(int item_id) {
  return AppendMenuItem(item_id, base::string16(), NORMAL);
}

void MenuItemView::AppendSeparator() {
  AppendMenuItemImpl(0, base::string16(), base::string16(), base::string16(),
                     gfx::ImageSkia(), SEPARATOR, ui::NORMAL_SEPARATOR);
}

MenuItemView* MenuItemView::AppendMenuItemWithIcon(int item_id,
                                                   const base::string16& label,
                                                   const gfx::ImageSkia& icon) {
  return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
                            icon, NORMAL, ui::NORMAL_SEPARATOR);
}

MenuItemView* MenuItemView::AppendMenuItemImpl(
    int item_id,
    const base::string16& label,
    const base::string16& sublabel,
    const base::string16& minor_text,
    const gfx::ImageSkia& icon,
    Type type,
    ui::MenuSeparatorType separator_style) {
  const int index = submenu_ ? submenu_->child_count() : 0;
  return AddMenuItemAt(index, item_id, label, sublabel, minor_text, icon, type,
                       separator_style);
}

SubmenuView* MenuItemView::CreateSubmenu() {
  if (!submenu_)
    submenu_ = new SubmenuView(this);
  return submenu_;
}

bool MenuItemView::HasSubmenu() const {
  return (submenu_ != NULL);
}

SubmenuView* MenuItemView::GetSubmenu() const {
  return submenu_;
}

void MenuItemView::SetTitle(const base::string16& title) {
  title_ = title;
  invalidate_dimensions();  // Triggers preferred size recalculation.
}

void MenuItemView::SetSubtitle(const base::string16& subtitle) {
  subtitle_ = subtitle;
  invalidate_dimensions();  // Triggers preferred size recalculation.
}

void MenuItemView::SetMinorText(const base::string16& minor_text) {
  minor_text_ = minor_text;
  invalidate_dimensions();  // Triggers preferred size recalculation.
}

void MenuItemView::SetSelected(bool selected) {
  selected_ = selected;
  SchedulePaint();
}

void MenuItemView::SetTooltip(const base::string16& tooltip, int item_id) {
  MenuItemView* item = GetMenuItemByID(item_id);
  DCHECK(item);
  item->tooltip_ = tooltip;
}

void MenuItemView::SetIcon(const gfx::ImageSkia& icon, int item_id) {
  MenuItemView* item = GetMenuItemByID(item_id);
  DCHECK(item);
  item->SetIcon(icon);
}

void MenuItemView::SetIcon(const gfx::ImageSkia& icon) {
  if (icon.isNull()) {
    SetIconView(NULL);
    return;
  }

  ImageView* icon_view = new ImageView();
  icon_view->SetImage(&icon);
  SetIconView(icon_view);
}

void MenuItemView::SetIconView(View* icon_view) {
  if (icon_view_) {
    RemoveChildView(icon_view_);
    delete icon_view_;
    icon_view_ = NULL;
  }
  if (icon_view) {
    AddChildView(icon_view);
    icon_view_ = icon_view;
  }
  Layout();
  SchedulePaint();
}

void MenuItemView::OnPaint(gfx::Canvas* canvas) {
  PaintButton(canvas, PB_NORMAL);
}

gfx::Size MenuItemView::GetPreferredSize() const {
  const MenuItemDimensions& dimensions(GetDimensions());
  return gfx::Size(dimensions.standard_width + dimensions.children_width,
                   dimensions.height);
}

int MenuItemView::GetHeightForWidth(int width) const {
  // If this isn't a container, we can just use the preferred size's height.
  if (!IsContainer())
    return GetPreferredSize().height();

  int height = child_at(0)->GetHeightForWidth(width);
  if (!icon_view_ && GetRootMenuItem()->has_icons())
    height = std::max(height, GetMenuConfig().check_height);
  height += GetBottomMargin() + GetTopMargin();

  return height;
}

const MenuItemView::MenuItemDimensions& MenuItemView::GetDimensions() const {
  if (!is_dimensions_valid())
    dimensions_ = CalculateDimensions();
  DCHECK(is_dimensions_valid());
  return dimensions_;
}

MenuController* MenuItemView::GetMenuController() {
  return GetRootMenuItem()->controller_;
}

const MenuController* MenuItemView::GetMenuController() const {
  return GetRootMenuItem()->controller_;
}

MenuDelegate* MenuItemView::GetDelegate() {
  return GetRootMenuItem()->delegate_;
}

const MenuDelegate* MenuItemView::GetDelegate() const {
  return GetRootMenuItem()->delegate_;
}

MenuItemView* MenuItemView::GetRootMenuItem() {
  return const_cast<MenuItemView*>(
      static_cast<const MenuItemView*>(this)->GetRootMenuItem());
}

const MenuItemView* MenuItemView::GetRootMenuItem() const {
  const MenuItemView* item = this;
  for (const MenuItemView* parent = GetParentMenuItem(); parent;
       parent = item->GetParentMenuItem())
    item = parent;
  return item;
}

base::char16 MenuItemView::GetMnemonic() {
  if (!GetRootMenuItem()->has_mnemonics_)
    return 0;

  size_t index = 0;
  do {
    index = title_.find('&', index);
    if (index != base::string16::npos) {
      if (index + 1 != title_.size() && title_[index + 1] != '&') {
        base::char16 char_array[] = { title_[index + 1], 0 };
        // TODO(jshin): What about Turkish locale? See http://crbug.com/81719.
        // If the mnemonic is capital I and the UI language is Turkish,
        // lowercasing it results in 'small dotless i', which is different
        // from a 'dotted i'. Similar issues may exist for az and lt locales.
        return base::i18n::ToLower(char_array)[0];
      }
      index++;
    }
  } while (index != base::string16::npos);
  return 0;
}

MenuItemView* MenuItemView::GetMenuItemByID(int id) {
  if (GetCommand() == id)
    return this;
  if (!HasSubmenu())
    return NULL;
  for (int i = 0; i < GetSubmenu()->child_count(); ++i) {
    View* child = GetSubmenu()->child_at(i);
    if (child->id() == MenuItemView::kMenuItemViewID) {
      MenuItemView* result = static_cast<MenuItemView*>(child)->
          GetMenuItemByID(id);
      if (result)
        return result;
    }
  }
  return NULL;
}

void MenuItemView::ChildrenChanged() {
  MenuController* controller = GetMenuController();
  if (controller) {
    // Handles the case where we were empty and are no longer empty.
    RemoveEmptyMenus();

    // Handles the case where we were not empty, but now are.
    AddEmptyMenus();

    controller->MenuChildrenChanged(this);

    if (submenu_) {
      // Force a paint and layout. This handles the case of the top
      // level window's size remaining the same, resulting in no
      // change to the submenu's size and no layout.
      submenu_->Layout();
      submenu_->SchedulePaint();
      // Update the menu selection after layout.
      controller->UpdateSubmenuSelection(submenu_);
    }
  }

  STLDeleteElements(&removed_items_);
}

void MenuItemView::Layout() {
  if (!has_children())
    return;

  if (IsContainer()) {
    View* child = child_at(0);
    gfx::Size size = child->GetPreferredSize();
    child->SetBounds(0, GetTopMargin(), size.width(), size.height());
  } else {
    // Child views are laid out right aligned and given the full height. To
    // right align start with the last view and progress to the first.
    int x = width() - (use_right_margin_ ? item_right_margin_ : 0);
    for (int i = child_count() - 1; i >= 0; --i) {
      View* child = child_at(i);
      if (icon_view_ && (icon_view_ == child))
        continue;
      int width = child->GetPreferredSize().width();
      child->SetBounds(x - width, 0, width, height());
      x -= width - kChildXPadding;
    }
    // Position |icon_view|.
    const MenuConfig& config = GetMenuConfig();
    if (icon_view_) {
      icon_view_->SizeToPreferredSize();
      gfx::Size size = icon_view_->GetPreferredSize();
      int x = config.item_left_margin + left_icon_margin_ +
              (icon_area_width_ - size.width()) / 2;
      if (type_ == CHECKBOX || type_ == RADIO)
        x = label_start_;
      int y =
          (height() + GetTopMargin() - GetBottomMargin() - size.height()) / 2;
      icon_view_->SetPosition(gfx::Point(x, y));
    }
  }
}

void MenuItemView::SetMargins(int top_margin, int bottom_margin) {
  top_margin_ = top_margin;
  bottom_margin_ = bottom_margin;

  invalidate_dimensions();
}

const MenuConfig& MenuItemView::GetMenuConfig() const {
  const MenuController* controller = GetMenuController();
  if (controller)
    return controller->menu_config_;
  return MenuConfig::instance(NULL);
}

MenuItemView::MenuItemView(MenuItemView* parent,
                           int command,
                           MenuItemView::Type type)
    : delegate_(NULL),
      controller_(NULL),
      canceled_(false),
      parent_menu_item_(parent),
      type_(type),
      selected_(false),
      command_(command),
      submenu_(NULL),
      has_mnemonics_(false),
      show_mnemonics_(false),
      has_icons_(false),
      icon_view_(NULL),
      top_margin_(-1),
      bottom_margin_(-1),
      left_icon_margin_(0),
      right_icon_margin_(0),
      requested_menu_position_(POSITION_BEST_FIT),
      actual_menu_position_(requested_menu_position_),
      use_right_margin_(true) {
  Init(parent, command, type, NULL);
}

MenuItemView::~MenuItemView() {
  delete submenu_;
  STLDeleteElements(&removed_items_);
}

const char* MenuItemView::GetClassName() const {
  return kViewClassName;
}

// Calculates all sizes that we can from the OS.
//
// This is invoked prior to Running a menu.
void MenuItemView::UpdateMenuPartSizes() {
  const MenuConfig& config = GetMenuConfig();

  item_right_margin_ = config.label_to_arrow_padding + config.arrow_width +
                       config.arrow_to_edge_padding;
  icon_area_width_ = config.check_width;
  if (has_icons_)
    icon_area_width_ = std::max(icon_area_width_, GetMaxIconViewWidth());

  label_start_ = config.item_left_margin + icon_area_width_;
  int padding = 0;
  if (config.always_use_icon_to_label_padding) {
    padding = config.icon_to_label_padding;
  } else if (config.render_gutter) {
    padding = config.item_left_margin;
  } else {
    padding = (has_icons_ || HasChecksOrRadioButtons()) ?
        config.icon_to_label_padding : 0;
  }
  label_start_ += padding;

  if (config.render_gutter)
    label_start_ += config.gutter_width + config.gutter_to_label;

  EmptyMenuMenuItem menu_item(this);
  menu_item.set_controller(GetMenuController());
  pref_menu_height_ = menu_item.GetPreferredSize().height();
}

void MenuItemView::Init(MenuItemView* parent,
                        int command,
                        MenuItemView::Type type,
                        MenuDelegate* delegate) {
  delegate_ = delegate;
  controller_ = NULL;
  canceled_ = false;
  parent_menu_item_ = parent;
  type_ = type;
  selected_ = false;
  command_ = command;
  submenu_ = NULL;
  show_mnemonics_ = false;
  // Assign our ID, this allows SubmenuItemView to find MenuItemViews.
  set_id(kMenuItemViewID);
  has_icons_ = false;

  // Don't request enabled status from the root menu item as it is just
  // a container for real items.  EMPTY items will be disabled.
  MenuDelegate* root_delegate = GetDelegate();
  if (parent && type != EMPTY && root_delegate)
    SetEnabled(root_delegate->IsCommandEnabled(command));
}

void MenuItemView::PrepareForRun(bool is_first_menu,
                                 bool has_mnemonics,
                                 bool show_mnemonics) {
  // Currently we only support showing the root.
  DCHECK(!parent_menu_item_);

  // Force us to have a submenu.
  CreateSubmenu();
  actual_menu_position_ = requested_menu_position_;
  canceled_ = false;

  has_mnemonics_ = has_mnemonics;
  show_mnemonics_ = has_mnemonics && show_mnemonics;

  AddEmptyMenus();

  if (is_first_menu) {
    // Only update the menu size if there are no menus showing, otherwise
    // things may shift around.
    UpdateMenuPartSizes();
  }
}

int MenuItemView::GetDrawStringFlags() {
  int flags = 0;
  if (base::i18n::IsRTL())
    flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
  else
    flags |= gfx::Canvas::TEXT_ALIGN_LEFT;

  if (GetRootMenuItem()->has_mnemonics_) {
    if (GetMenuConfig().show_mnemonics || GetRootMenuItem()->show_mnemonics_) {
      flags |= gfx::Canvas::SHOW_PREFIX;
    } else {
      flags |= gfx::Canvas::HIDE_PREFIX;
    }
  }
  return flags;
}

const gfx::FontList& MenuItemView::GetFontList() const {
  const MenuDelegate* delegate = GetDelegate();
  if (delegate) {
    const gfx::FontList* font_list = delegate->GetLabelFontList(GetCommand());
    if (font_list)
      return *font_list;
  }
  return GetMenuConfig().font_list;
}

void MenuItemView::AddEmptyMenus() {
  DCHECK(HasSubmenu());
  if (!submenu_->has_children()) {
    submenu_->AddChildViewAt(new EmptyMenuMenuItem(this), 0);
  } else {
    for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count;
         ++i) {
      MenuItemView* child = submenu_->GetMenuItemAt(i);
      if (child->HasSubmenu())
        child->AddEmptyMenus();
    }
  }
}

void MenuItemView::RemoveEmptyMenus() {
  DCHECK(HasSubmenu());
  // Iterate backwards as we may end up removing views, which alters the child
  // view count.
  for (int i = submenu_->child_count() - 1; i >= 0; --i) {
    View* child = submenu_->child_at(i);
    if (child->id() == MenuItemView::kMenuItemViewID) {
      MenuItemView* menu_item = static_cast<MenuItemView*>(child);
      if (menu_item->HasSubmenu())
        menu_item->RemoveEmptyMenus();
    } else if (child->id() == EmptyMenuMenuItem::kEmptyMenuItemViewID) {
      submenu_->RemoveChildView(child);
      delete child;
      child = NULL;
    }
  }
}

void MenuItemView::AdjustBoundsForRTLUI(gfx::Rect* rect) const {
  rect->set_x(GetMirroredXForRect(*rect));
}

void MenuItemView::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) {
  const MenuConfig& config = GetMenuConfig();
  bool render_selection =
      (mode == PB_NORMAL && IsSelected() &&
       parent_menu_item_->GetSubmenu()->GetShowSelection(this) &&
       (NonIconChildViewsCount() == 0));

  MenuDelegate *delegate = GetDelegate();
  // Render the background. As MenuScrollViewContainer draws the background, we
  // only need the background when we want it to look different, as when we're
  // selected.
  ui::NativeTheme* native_theme = GetNativeTheme();
  SkColor override_color;
  if (delegate && delegate->GetBackgroundColor(GetCommand(),
                                               render_selection,
                                               &override_color)) {
    canvas->DrawColor(override_color);
  } else if (render_selection) {
    gfx::Rect item_bounds(0, 0, width(), height());
    AdjustBoundsForRTLUI(&item_bounds);

    native_theme->Paint(canvas->sk_canvas(),
                        ui::NativeTheme::kMenuItemBackground,
                        ui::NativeTheme::kHovered,
                        item_bounds,
                        ui::NativeTheme::ExtraParams());
  }

  const int icon_x = config.item_left_margin + left_icon_margin_;
  const int top_margin = GetTopMargin();
  const int bottom_margin = GetBottomMargin();
  const int available_height = height() - top_margin - bottom_margin;

  // Render the check.
  if (type_ == CHECKBOX && delegate->IsItemChecked(GetCommand())) {
    gfx::ImageSkia check = GetMenuCheckImage(render_selection);
    // Don't use config.check_width here as it's padded
    // to force more padding (AURA).
    gfx::Rect check_bounds(icon_x,
                           top_margin + (available_height - check.height()) / 2,
                           check.width(),
                           check.height());
    AdjustBoundsForRTLUI(&check_bounds);
    canvas->DrawImageInt(check, check_bounds.x(), check_bounds.y());
  } else if (type_ == RADIO) {
    gfx::ImageSkia image =
        GetRadioButtonImage(delegate->IsItemChecked(GetCommand()));
    gfx::Rect radio_bounds(icon_x,
                           top_margin + (available_height - image.height()) / 2,
                           image.width(),
                           image.height());
    AdjustBoundsForRTLUI(&radio_bounds);
    canvas->DrawImageInt(image, radio_bounds.x(), radio_bounds.y());
  }

  // Render the foreground.
  ui::NativeTheme::ColorId color_id;
  if (enabled()) {
    color_id = render_selection ?
        ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor:
        ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor;
  } else {
    bool emphasized = delegate &&
                      delegate->GetShouldUseDisabledEmphasizedForegroundColor(
                          GetCommand());
    color_id = emphasized ?
        ui::NativeTheme::kColorId_DisabledEmphasizedMenuItemForegroundColor :
        ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor;
  }
  SkColor fg_color = native_theme->GetSystemColor(color_id);
  SkColor override_foreground_color;
  if (delegate && delegate->GetForegroundColor(GetCommand(),
                                               render_selection,
                                               &override_foreground_color))
    fg_color = override_foreground_color;

  const gfx::FontList& font_list = GetFontList();
  int accel_width = parent_menu_item_->GetSubmenu()->max_minor_text_width();
  int label_start = GetLabelStartForThisItem();

  int width = this->width() - label_start - accel_width -
      (!delegate ||
       delegate->ShouldReserveSpaceForSubmenuIndicator() ?
           item_right_margin_ : config.arrow_to_edge_padding);
  gfx::Rect text_bounds(label_start, top_margin, width,
                        subtitle_.empty() ? available_height
                                          : available_height / 2);
  text_bounds.set_x(GetMirroredXForRect(text_bounds));
  int flags = GetDrawStringFlags();
  if (mode == PB_FOR_DRAG)
    flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING;
  canvas->DrawStringRectWithFlags(title(), font_list, fg_color, text_bounds,
                                  flags);
  if (!subtitle_.empty()) {
    canvas->DrawStringRectWithFlags(
        subtitle_,
        font_list,
        GetNativeTheme()->GetSystemColor(
            ui::NativeTheme::kColorId_ButtonDisabledColor),
        text_bounds + gfx::Vector2d(0, font_list.GetHeight()),
        flags);
  }

  PaintMinorText(canvas, render_selection);

  // Render the submenu indicator (arrow).
  if (HasSubmenu()) {
    gfx::ImageSkia arrow = GetSubmenuArrowImage(render_selection);
    gfx::Rect arrow_bounds(this->width() - config.arrow_width -
                               config.arrow_to_edge_padding,
                           top_margin + (available_height - arrow.height()) / 2,
                           config.arrow_width,
                           arrow.height());
    AdjustBoundsForRTLUI(&arrow_bounds);
    canvas->DrawImageInt(arrow, arrow_bounds.x(), arrow_bounds.y());
  }
}

void MenuItemView::PaintMinorText(gfx::Canvas* canvas,
                                  bool render_selection) {
  base::string16 minor_text = GetMinorText();
  if (minor_text.empty())
    return;

  int available_height = height() - GetTopMargin() - GetBottomMargin();
  int max_accel_width =
      parent_menu_item_->GetSubmenu()->max_minor_text_width();
  const MenuConfig& config = GetMenuConfig();
  int accel_right_margin = config.align_arrow_and_shortcut ?
                           config.arrow_to_edge_padding :  item_right_margin_;
  gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width,
                         GetTopMargin(), max_accel_width, available_height);
  accel_bounds.set_x(GetMirroredXForRect(accel_bounds));
  int flags = GetDrawStringFlags();
  flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT);
  if (base::i18n::IsRTL())
    flags |= gfx::Canvas::TEXT_ALIGN_LEFT;
  else
    flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
  canvas->DrawStringRectWithFlags(
      minor_text,
      GetFontList(),
      GetNativeTheme()->GetSystemColor(render_selection ?
          ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor :
          ui::NativeTheme::kColorId_ButtonDisabledColor),
      accel_bounds,
      flags);
}

void MenuItemView::DestroyAllMenuHosts() {
  if (!HasSubmenu())
    return;

  submenu_->Close();
  for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count;
       ++i) {
    submenu_->GetMenuItemAt(i)->DestroyAllMenuHosts();
  }
}

int MenuItemView::GetTopMargin() const {
  if (top_margin_ >= 0)
    return top_margin_;

  const MenuItemView* root = GetRootMenuItem();
  return root && root->has_icons_
      ? GetMenuConfig().item_top_margin :
        GetMenuConfig().item_no_icon_top_margin;
}

int MenuItemView::GetBottomMargin() const {
  if (bottom_margin_ >= 0)
    return bottom_margin_;

  const MenuItemView* root = GetRootMenuItem();
  return root && root->has_icons_
      ? GetMenuConfig().item_bottom_margin :
        GetMenuConfig().item_no_icon_bottom_margin;
}

gfx::Size MenuItemView::GetChildPreferredSize() const {
  if (!has_children())
    return gfx::Size();

  if (IsContainer())
    return child_at(0)->GetPreferredSize();

  int width = 0;
  for (int i = 0; i < child_count(); ++i) {
    const View* child = child_at(i);
    if (icon_view_ && (icon_view_ == child))
      continue;
    if (i)
      width += kChildXPadding;
    width += child->GetPreferredSize().width();
  }
  int height = 0;
  if (icon_view_)
    height = icon_view_->GetPreferredSize().height();

  // If there is no icon view it returns a height of 0 to indicate that
  // we should use the title height instead.
  return gfx::Size(width, height);
}

MenuItemView::MenuItemDimensions MenuItemView::CalculateDimensions() const {
  gfx::Size child_size = GetChildPreferredSize();

  MenuItemDimensions dimensions;
  // Get the container height.
  dimensions.children_width = child_size.width();
  dimensions.height = child_size.height();
  // Adjust item content height if menu has both items with and without icons.
  // This way all menu items will have the same height.
  if (!icon_view_ && GetRootMenuItem()->has_icons()) {
    dimensions.height = std::max(dimensions.height,
                                 GetMenuConfig().check_height);
  }
  dimensions.height += GetBottomMargin() + GetTopMargin();

  // In case of a container, only the container size needs to be filled.
  if (IsContainer())
    return dimensions;

  // Determine the length of the label text.
  const gfx::FontList& font_list = GetFontList();

  // Get Icon margin overrides for this particular item.
  const MenuDelegate* delegate = GetDelegate();
  if (delegate) {
    delegate->GetHorizontalIconMargins(command_,
                                       icon_area_width_,
                                       &left_icon_margin_,
                                       &right_icon_margin_);
  } else {
    left_icon_margin_ = 0;
    right_icon_margin_ = 0;
  }
  int label_start = GetLabelStartForThisItem();

  int string_width = gfx::GetStringWidth(title_, font_list);
  if (!subtitle_.empty()) {
    string_width = std::max(string_width,
                            gfx::GetStringWidth(subtitle_, font_list));
  }

  dimensions.standard_width = string_width + label_start +
      item_right_margin_;
  // Determine the length of the right-side text.
  base::string16 minor_text = GetMinorText();
  dimensions.minor_text_width =
      minor_text.empty() ? 0 : gfx::GetStringWidth(minor_text, font_list);

  // Determine the height to use.
  dimensions.height =
      std::max(dimensions.height,
               (subtitle_.empty() ? 0 : font_list.GetHeight()) +
               font_list.GetHeight() + GetBottomMargin() + GetTopMargin());
  dimensions.height = std::max(dimensions.height,
                               GetMenuConfig().item_min_height);
  return dimensions;
}

int MenuItemView::GetLabelStartForThisItem() const {
  int label_start = label_start_ + left_icon_margin_ + right_icon_margin_;
  if ((type_ == CHECKBOX || type_ == RADIO) && icon_view_) {
    label_start += icon_view_->size().width() +
        GetMenuConfig().icon_to_label_padding;
  }
  return label_start;
}

base::string16 MenuItemView::GetMinorText() const {
  if (id() == kEmptyMenuItemViewID) {
    // Don't query the delegate for menus that represent no children.
    return base::string16();
  }

  ui::Accelerator accelerator;
  if (GetMenuConfig().show_accelerators && GetDelegate() && GetCommand() &&
          GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) {
    return accelerator.GetShortcutText();
  }

  return minor_text_;
}

bool MenuItemView::IsContainer() const {
  // Let the first child take over |this| when we only have one child and no
  // title.
  return (NonIconChildViewsCount() == 1) && title_.empty();
}

int MenuItemView::NonIconChildViewsCount() const {
  // Note that what child_count() returns is the number of children,
  // not the number of menu items.
  return child_count() - (icon_view_ ? 1 : 0);
}

int MenuItemView::GetMaxIconViewWidth() const {
  int width = 0;
  for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) {
    MenuItemView* menu_item = submenu_->GetMenuItemAt(i);
    int temp_width = 0;
    if (menu_item->GetType() == CHECKBOX ||
        menu_item->GetType() == RADIO) {
      // If this item has a radio or checkbox, the icon will not affect
      // alignment of other items.
      continue;
    } else if (menu_item->HasSubmenu()) {
      temp_width = menu_item->GetMaxIconViewWidth();
    } else if (menu_item->icon_view()) {
      temp_width = menu_item->icon_view()->GetPreferredSize().width();
    }
    width = std::max(width, temp_width);
  }
  return width;
}

bool MenuItemView::HasChecksOrRadioButtons() const {
  for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) {
    MenuItemView* menu_item = submenu_->GetMenuItemAt(i);
    if (menu_item->HasSubmenu()) {
      if (menu_item->HasChecksOrRadioButtons())
        return true;
    } else {
      const Type& type = menu_item->GetType();
      if (type == CHECKBOX || type == RADIO)
        return true;
    }
  }
  return false;
}

}  // namespace views
