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

#include "ash/system/user/user_view.h"

#include <algorithm>

#include "ash/multi_profile_uma.h"
#include "ash/popup_message.h"
#include "ash/session/session_state_delegate.h"
#include "ash/session/user_info.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_popup_label_button.h"
#include "ash/system/tray/tray_popup_label_button_border.h"
#include "ash/system/user/button_from_view.h"
#include "ash/system/user/config.h"
#include "ash/system/user/rounded_image_view.h"
#include "ash/system/user/user_card_view.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/painter.h"
#include "ui/wm/core/shadow_types.h"

namespace ash {
namespace tray {

namespace {

const int kPublicAccountLogoutButtonBorderImagesNormal[] = {
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
};

const int kPublicAccountLogoutButtonBorderImagesHovered[] = {
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
    IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
};

// When a hover border is used, it is starting this many pixels before the icon
// position.
const int kTrayUserTileHoverBorderInset = 10;

// Offsetting the popup message relative to the tray menu.
const int kPopupMessageOffset = 25;

// Switch to a user with the given |user_index|.
void SwitchUser(ash::MultiProfileIndex user_index) {
  // Do not switch users when the log screen is presented.
  if (ash::Shell::GetInstance()
          ->session_state_delegate()
          ->IsUserSessionBlocked())
    return;

  DCHECK(user_index > 0);
  ash::SessionStateDelegate* delegate =
      ash::Shell::GetInstance()->session_state_delegate();
  ash::MultiProfileUMA::RecordSwitchActiveUser(
      ash::MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY);
  delegate->SwitchActiveUser(delegate->GetUserInfo(user_index)->GetUserID());
}

class LogoutButton : public TrayPopupLabelButton {
 public:
  // If |placeholder| is true, button is used as placeholder. That means that
  // button is inactive and is not painted, but consume the same ammount of
  // space, as if it was painted.
  LogoutButton(views::ButtonListener* listener,
               const base::string16& text,
               bool placeholder)
      : TrayPopupLabelButton(listener, text), placeholder_(placeholder) {
    SetEnabled(!placeholder_);
  }

  virtual ~LogoutButton() {}

 private:
  virtual void Paint(gfx::Canvas* canvas,
                     const views::CullSet& cull_set) OVERRIDE {
    // Just skip paint if this button used as a placeholder.
    if (!placeholder_)
      TrayPopupLabelButton::Paint(canvas, cull_set);
  }

  bool placeholder_;
  DISALLOW_COPY_AND_ASSIGN(LogoutButton);
};

class UserViewMouseWatcherHost : public views::MouseWatcherHost {
 public:
  explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area)
      : screen_area_(screen_area) {}
  virtual ~UserViewMouseWatcherHost() {}

  // Implementation of MouseWatcherHost.
  virtual bool Contains(const gfx::Point& screen_point,
                        views::MouseWatcherHost::MouseEventType type) OVERRIDE {
    return screen_area_.Contains(screen_point);
  }

 private:
  gfx::Rect screen_area_;

  DISALLOW_COPY_AND_ASSIGN(UserViewMouseWatcherHost);
};

// The menu item view which gets shown when the user clicks in multi profile
// mode onto the user item.
class AddUserView : public views::View {
 public:
  // The |owner| is the view for which this view gets created.
  AddUserView(ButtonFromView* owner);
  virtual ~AddUserView();

  // Get the anchor view for a message.
  views::View* anchor() { return anchor_; }

 private:
  // Overridden from views::View.
  virtual gfx::Size GetPreferredSize() const OVERRIDE;

  // Create the additional client content for this item.
  void AddContent();

  // This is the content we create and show.
  views::View* add_user_;

  // This is the owner view of this item.
  ButtonFromView* owner_;

  // The anchor view for targetted bubble messages.
  views::View* anchor_;

  DISALLOW_COPY_AND_ASSIGN(AddUserView);
};

AddUserView::AddUserView(ButtonFromView* owner)
    : add_user_(NULL), owner_(owner), anchor_(NULL) {
  AddContent();
  owner_->ForceBorderVisible(true);
}

AddUserView::~AddUserView() {
  owner_->ForceBorderVisible(false);
}

gfx::Size AddUserView::GetPreferredSize() const {
  return owner_->bounds().size();
}

void AddUserView::AddContent() {
  SetLayoutManager(new views::FillLayout());
  set_background(views::Background::CreateSolidBackground(kBackgroundColor));

  add_user_ = new views::View;
  add_user_->SetBorder(views::Border::CreateEmptyBorder(
      0, kTrayUserTileHoverBorderInset, 0, 0));

  add_user_->SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems));
  AddChildViewAt(add_user_, 0);

  // Add the [+] icon which is also the anchor for messages.
  RoundedImageView* icon = new RoundedImageView(kTrayAvatarCornerRadius, true);
  anchor_ = icon;
  icon->SetImage(*ui::ResourceBundle::GetSharedInstance()
                      .GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER)
                      .ToImageSkia(),
                 gfx::Size(kTrayAvatarSize, kTrayAvatarSize));
  add_user_->AddChildView(icon);

  // Add the command text.
  views::Label* command_label = new views::Label(
      l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT));
  command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  add_user_->AddChildView(command_label);
}

}  // namespace

UserView::UserView(SystemTrayItem* owner,
                   user::LoginStatus login,
                   MultiProfileIndex index,
                   bool for_detailed_view)
    : multiprofile_index_(index),
      user_card_view_(NULL),
      owner_(owner),
      is_user_card_button_(false),
      logout_button_(NULL),
      add_user_disabled_(false),
      for_detailed_view_(for_detailed_view) {
  CHECK_NE(user::LOGGED_IN_NONE, login);
  if (!index) {
    // Only the logged in user will have a background. All other users will have
    // to allow the TrayPopupContainer highlighting the menu line.
    set_background(views::Background::CreateSolidBackground(
        login == user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor
                                        : kBackgroundColor));
  }
  SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems));
  // The logout button must be added before the user card so that the user card
  // can correctly calculate the remaining available width.
  // Note that only the current multiprofile user gets a button.
  if (!multiprofile_index_)
    AddLogoutButton(login);
  AddUserCard(login);
}

UserView::~UserView() {}

void UserView::MouseMovedOutOfHost() {
  popup_message_.reset();
  mouse_watcher_.reset();
  add_menu_option_.reset();
}

TrayUser::TestState UserView::GetStateForTest() const {
  if (add_menu_option_.get()) {
    return add_user_disabled_ ? TrayUser::ACTIVE_BUT_DISABLED
                              : TrayUser::ACTIVE;
  }

  if (!is_user_card_button_)
    return TrayUser::SHOWN;

  return static_cast<ButtonFromView*>(user_card_view_)->is_hovered_for_test()
             ? TrayUser::HOVERED
             : TrayUser::SHOWN;
}

gfx::Rect UserView::GetBoundsInScreenOfUserButtonForTest() {
  DCHECK(user_card_view_);
  return user_card_view_->GetBoundsInScreen();
}

gfx::Size UserView::GetPreferredSize() const {
  gfx::Size size = views::View::GetPreferredSize();
  // Only the active user panel will be forced to a certain height.
  if (!multiprofile_index_) {
    size.set_height(
        std::max(size.height(), kTrayPopupItemHeight + GetInsets().height()));
  }
  return size;
}

int UserView::GetHeightForWidth(int width) const {
  return GetPreferredSize().height();
}

void UserView::Layout() {
  gfx::Rect contents_area(GetContentsBounds());
  if (user_card_view_ && logout_button_) {
    // Give the logout button the space it requests.
    gfx::Rect logout_area = contents_area;
    logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize());
    logout_area.set_x(contents_area.right() - logout_area.width());

    // Give the remaining space to the user card.
    gfx::Rect user_card_area = contents_area;
    int remaining_width = contents_area.width() - logout_area.width();
    if (IsMultiProfileSupportedAndUserActive() ||
        IsMultiAccountSupportedAndUserActive()) {
      // In multiprofile/multiaccount case |user_card_view_| and
      // |logout_button_| have to have the same height.
      int y = std::min(user_card_area.y(), logout_area.y());
      int height = std::max(user_card_area.height(), logout_area.height());
      logout_area.set_y(y);
      logout_area.set_height(height);
      user_card_area.set_y(y);
      user_card_area.set_height(height);

      // In multiprofile mode we have also to increase the size of the card by
      // the size of the border to make it overlap with the logout button.
      user_card_area.set_width(std::max(0, remaining_width + 1));

      // To make the logout button symmetrical with the user card we also make
      // the button longer by the same size the hover area in front of the icon
      // got inset.
      logout_area.set_width(logout_area.width() +
                            kTrayUserTileHoverBorderInset);
    } else {
      // In all other modes we have to make sure that there is enough spacing
      // between the two.
      remaining_width -= kTrayPopupPaddingBetweenItems;
    }
    user_card_area.set_width(remaining_width);
    user_card_view_->SetBoundsRect(user_card_area);
    logout_button_->SetBoundsRect(logout_area);
  } else if (user_card_view_) {
    user_card_view_->SetBoundsRect(contents_area);
  } else if (logout_button_) {
    logout_button_->SetBoundsRect(contents_area);
  }
}

void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) {
  if (sender == logout_button_) {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        ash::UMA_STATUS_AREA_SIGN_OUT);
    Shell::GetInstance()->system_tray_delegate()->SignOut();
  } else if (sender == user_card_view_ && !multiprofile_index_ &&
             IsMultiAccountSupportedAndUserActive()) {
    owner_->TransitionDetailedView();
  } else if (sender == user_card_view_ &&
             IsMultiProfileSupportedAndUserActive()) {
    if (!multiprofile_index_) {
      ToggleAddUserMenuOption();
    } else {
      SwitchUser(multiprofile_index_);
      // Since the user list is about to change the system menu should get
      // closed.
      owner_->system_tray()->CloseSystemBubble();
    }
  } else if (add_menu_option_.get() &&
             sender == add_menu_option_->GetContentsView()) {
    // Let the user add another account to the session.
    MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY);
    Shell::GetInstance()->system_tray_delegate()->ShowUserLogin();
    owner_->system_tray()->CloseSystemBubble();
  } else {
    NOTREACHED();
  }
}

void UserView::AddLogoutButton(user::LoginStatus login) {
  const base::string16 title =
      user::GetLocalizedSignOutStringForStatus(login, true);
  TrayPopupLabelButton* logout_button =
      new LogoutButton(this, title, for_detailed_view_);
  logout_button->SetAccessibleName(title);
  logout_button_ = logout_button;
  // In public account mode, the logout button border has a custom color.
  if (login == user::LOGGED_IN_PUBLIC) {
    scoped_ptr<TrayPopupLabelButtonBorder> border(
        new TrayPopupLabelButtonBorder());
    border->SetPainter(false,
                       views::Button::STATE_NORMAL,
                       views::Painter::CreateImageGridPainter(
                           kPublicAccountLogoutButtonBorderImagesNormal));
    border->SetPainter(false,
                       views::Button::STATE_HOVERED,
                       views::Painter::CreateImageGridPainter(
                           kPublicAccountLogoutButtonBorderImagesHovered));
    border->SetPainter(false,
                       views::Button::STATE_PRESSED,
                       views::Painter::CreateImageGridPainter(
                           kPublicAccountLogoutButtonBorderImagesHovered));
    logout_button_->SetBorder(border.PassAs<views::Border>());
  }
  AddChildView(logout_button_);
}

void UserView::AddUserCard(user::LoginStatus login) {
  // Add padding around the panel.
  SetBorder(views::Border::CreateEmptyBorder(kTrayPopupUserCardVerticalPadding,
                                             kTrayPopupPaddingHorizontal,
                                             kTrayPopupUserCardVerticalPadding,
                                             kTrayPopupPaddingHorizontal));

  views::TrayBubbleView* bubble_view =
      owner_->system_tray()->GetSystemBubble()->bubble_view();
  int max_card_width =
      bubble_view->GetMaximumSize().width() -
      (2 * kTrayPopupPaddingHorizontal + kTrayPopupPaddingBetweenItems);
  if (logout_button_)
    max_card_width -= logout_button_->GetPreferredSize().width();
  user_card_view_ =
      new UserCardView(login, max_card_width, multiprofile_index_);
  bool clickable = IsMultiProfileSupportedAndUserActive() ||
                   IsMultiAccountSupportedAndUserActive();
  if (clickable) {
    // To allow the border to start before the icon, reduce the size before and
    // add an inset to the icon to get the spacing.
    if (!multiprofile_index_) {
      SetBorder(views::Border::CreateEmptyBorder(
          kTrayPopupUserCardVerticalPadding,
          kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset,
          kTrayPopupUserCardVerticalPadding,
          kTrayPopupPaddingHorizontal));
      user_card_view_->SetBorder(views::Border::CreateEmptyBorder(
          0, kTrayUserTileHoverBorderInset, 0, 0));
    }
    if (!for_detailed_view_) {
      user_card_view_ =
          new ButtonFromView(user_card_view_, this, !multiprofile_index_);
    } else {
      // We want user card for detailed view to have exactly the same look
      // as user card for default view. That's why we wrap it in a button
      // without click listener and special hover behaviour.
      user_card_view_ = new ButtonFromView(user_card_view_, NULL, false);
    }
    is_user_card_button_ = true;
  }
  AddChildViewAt(user_card_view_, 0);
  // Card for locally managed user can consume more space than currently
  // available. In that case we should increase system bubble's width.
  if (login == user::LOGGED_IN_PUBLIC)
    bubble_view->SetWidth(GetPreferredSize().width());
}

void UserView::ToggleAddUserMenuOption() {
  if (add_menu_option_.get()) {
    popup_message_.reset();
    mouse_watcher_.reset();
    add_menu_option_.reset();
    return;
  }

  // Note: We do not need to install a global event handler to delete this
  // item since it will destroyed automatically before the menu / user menu item
  // gets destroyed..
  add_menu_option_.reset(new views::Widget);
  views::Widget::InitParams params;
  params.type = views::Widget::InitParams::TYPE_TOOLTIP;
  params.keep_on_top = true;
  params.context = this->GetWidget()->GetNativeWindow();
  params.accept_events = true;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  add_menu_option_->Init(params);
  add_menu_option_->SetOpacity(0xFF);
  add_menu_option_->GetNativeWindow()->set_owned_by_parent(false);
  SetShadowType(add_menu_option_->GetNativeView(), wm::SHADOW_TYPE_NONE);

  // Position it below our user card.
  gfx::Rect bounds = user_card_view_->GetBoundsInScreen();
  bounds.set_y(bounds.y() + bounds.height());
  add_menu_option_->SetBounds(bounds);

  // Show the content.
  add_menu_option_->SetAlwaysOnTop(true);
  add_menu_option_->Show();

  AddUserView* add_user_view =
      new AddUserView(static_cast<ButtonFromView*>(user_card_view_));

  const SessionStateDelegate* delegate =
      Shell::GetInstance()->session_state_delegate();
  add_user_disabled_ = delegate->NumberOfLoggedInUsers() >=
                       delegate->GetMaximumNumberOfLoggedInUsers();
  ButtonFromView* button = add_user_disabled_
                               ? new ButtonFromView(add_user_view, NULL, false)
                               : new ButtonFromView(add_user_view, this, true);
  button->ForceBorderVisible(true);
  add_menu_option_->SetContentsView(button);

  if (add_user_disabled_) {
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    popup_message_.reset(new PopupMessage(
        bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER),
        bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER),
        PopupMessage::ICON_WARNING,
        add_user_view->anchor(),
        views::BubbleBorder::TOP_LEFT,
        gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0),
        2 * kPopupMessageOffset));
  }
  // Find the screen area which encloses both elements and sets then a mouse
  // watcher which will close the "menu".
  gfx::Rect area = user_card_view_->GetBoundsInScreen();
  area.set_height(2 * area.height());
  mouse_watcher_.reset(
      new views::MouseWatcher(new UserViewMouseWatcherHost(area), this));
  mouse_watcher_->Start();
}

}  // namespace tray
}  // namespace ash
