// 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 "ash/system/tray_accessibility.h"

#include "ash/accessibility_delegate.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/shell.h"
#include "ash/system/tray/hover_highlight_view.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_details_view.h"
#include "ash/system/tray/tray_item_more.h"
#include "ash/system/tray/tray_notification_view.h"
#include "ash/system/tray/tray_popup_label_button.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/gfx/image/image.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace internal {

namespace {

enum AccessibilityState {
  A11Y_NONE             = 0,
  A11Y_SPOKEN_FEEDBACK  = 1 << 0,
  A11Y_HIGH_CONTRAST    = 1 << 1,
  A11Y_SCREEN_MAGNIFIER = 1 << 2,
  A11Y_LARGE_CURSOR     = 1 << 3,
  A11Y_AUTOCLICK        = 1 << 4,
};

uint32 GetAccessibilityState() {
  AccessibilityDelegate* delegate =
      Shell::GetInstance()->accessibility_delegate();
  uint32 state = A11Y_NONE;
  if (delegate->IsSpokenFeedbackEnabled())
    state |= A11Y_SPOKEN_FEEDBACK;
  if (delegate->IsHighContrastEnabled())
    state |= A11Y_HIGH_CONTRAST;
  if (delegate->IsMagnifierEnabled())
    state |= A11Y_SCREEN_MAGNIFIER;
  if (delegate->IsLargeCursorEnabled())
    state |= A11Y_LARGE_CURSOR;
  if (delegate->IsAutoclickEnabled())
    state |= A11Y_AUTOCLICK;
  return state;
}

user::LoginStatus GetCurrentLoginStatus() {
  return Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus();
}

}  // namespace

namespace tray {

class DefaultAccessibilityView : public TrayItemMore {
 public:
  explicit DefaultAccessibilityView(SystemTrayItem* owner)
      : TrayItemMore(owner, true) {
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK).
                    ToImageSkia());
    base::string16 label = bundle.GetLocalizedString(
        IDS_ASH_STATUS_TRAY_ACCESSIBILITY);
    SetLabel(label);
    SetAccessibleName(label);
  }

  virtual ~DefaultAccessibilityView() {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DefaultAccessibilityView);
};

class AccessibilityPopupView : public TrayNotificationView {
 public:
  AccessibilityPopupView(SystemTrayItem* owner)
      : TrayNotificationView(owner, IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK) {
    InitView(GetLabel());
  }

 private:
  views::Label* GetLabel() {
    views::Label* label = new views::Label(
        l10n_util::GetStringUTF16(
            IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_ENABLED_BUBBLE));
    label->SetMultiLine(true);
    label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    return label;
  }

  DISALLOW_COPY_AND_ASSIGN(AccessibilityPopupView);
};

////////////////////////////////////////////////////////////////////////////////
// ash::internal::tray::AccessibilityDetailedView

AccessibilityDetailedView::AccessibilityDetailedView(
    SystemTrayItem* owner, user::LoginStatus login) :
        TrayDetailsView(owner),
        spoken_feedback_view_(NULL),
        high_contrast_view_(NULL),
        screen_magnifier_view_(NULL),
        large_cursor_view_(NULL),
        help_view_(NULL),
        settings_view_(NULL),
        autoclick_view_(NULL),
        spoken_feedback_enabled_(false),
        high_contrast_enabled_(false),
        screen_magnifier_enabled_(false),
        large_cursor_enabled_(false),
        autoclick_enabled_(false),
        login_(login) {

  Reset();

  AppendAccessibilityList();
  AppendHelpEntries();
  CreateSpecialRow(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TITLE, this);

  Layout();
}

void AccessibilityDetailedView::AppendAccessibilityList() {
  CreateScrollableList();
  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();

  AccessibilityDelegate* delegate =
      Shell::GetInstance()->accessibility_delegate();
  spoken_feedback_enabled_ = delegate->IsSpokenFeedbackEnabled();
  spoken_feedback_view_ = AddScrollListItem(
      bundle.GetLocalizedString(
          IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SPOKEN_FEEDBACK),
      spoken_feedback_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
      spoken_feedback_enabled_);

  // Large Cursor item is shown only in Login screen.
  if (login_ == user::LOGGED_IN_NONE) {
    large_cursor_enabled_ = delegate->IsLargeCursorEnabled();
    large_cursor_view_ = AddScrollListItem(
        bundle.GetLocalizedString(
            IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LARGE_CURSOR),
        large_cursor_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
        large_cursor_enabled_);
  }

  high_contrast_enabled_ = delegate->IsHighContrastEnabled();
  high_contrast_view_ = AddScrollListItem(
      bundle.GetLocalizedString(
          IDS_ASH_STATUS_TRAY_ACCESSIBILITY_HIGH_CONTRAST_MODE),
      high_contrast_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
      high_contrast_enabled_);
  screen_magnifier_enabled_ = delegate->IsMagnifierEnabled();
  screen_magnifier_view_ = AddScrollListItem(
      bundle.GetLocalizedString(
          IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SCREEN_MAGNIFIER),
      screen_magnifier_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
      screen_magnifier_enabled_);

  // Don't show autoclick option at login screen.
  if (login_ != user::LOGGED_IN_NONE) {
    autoclick_enabled_ = delegate->IsAutoclickEnabled();
    autoclick_view_ = AddScrollListItem(
        bundle.GetLocalizedString(
            IDS_ASH_STATUS_TRAY_ACCESSIBILITY_AUTOCLICK),
        autoclick_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
        autoclick_enabled_);
  }
}

void AccessibilityDetailedView::AppendHelpEntries() {
  // Currently the help page requires a browser window.
  // TODO(yoshiki): show this even on login/lock screen. crbug.com/158286
  if (login_ == user::LOGGED_IN_NONE ||
      login_ == user::LOGGED_IN_LOCKED)
    return;

  views::View* bottom_row = new View();
  views::BoxLayout* layout = new
      views::BoxLayout(views::BoxLayout::kHorizontal,
                       kTrayMenuBottomRowPadding,
                       kTrayMenuBottomRowPadding,
                       kTrayMenuBottomRowPaddingBetweenItems);
  layout->set_spread_blank_space(true);
  bottom_row->SetLayoutManager(layout);

  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();

  TrayPopupLabelButton* help = new TrayPopupLabelButton(
      this,
      bundle.GetLocalizedString(
          IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LEARN_MORE));
  bottom_row->AddChildView(help);
  help_view_ = help;

  TrayPopupLabelButton* settings = new TrayPopupLabelButton(
      this,
      bundle.GetLocalizedString(
          IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SETTINGS));
  bottom_row->AddChildView(settings);
  settings_view_ = settings;

  AddChildView(bottom_row);
}

HoverHighlightView* AccessibilityDetailedView::AddScrollListItem(
    const base::string16& text,
    gfx::Font::FontStyle style,
    bool checked) {
  HoverHighlightView* container = new HoverHighlightView(this);
  container->AddCheckableLabel(text, style, checked);
  scroll_content()->AddChildView(container);
  return container;
}

void AccessibilityDetailedView::OnViewClicked(views::View* sender) {
  AccessibilityDelegate* delegate =
      Shell::GetInstance()->accessibility_delegate();
  if (sender == footer()->content()) {
    TransitionToDefaultView();
  } else if (sender == spoken_feedback_view_) {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        delegate->IsSpokenFeedbackEnabled() ?
            ash::UMA_STATUS_AREA_DISABLE_SPOKEN_FEEDBACK :
            ash::UMA_STATUS_AREA_ENABLE_SPOKEN_FEEDBACK);
    delegate->ToggleSpokenFeedback(ash::A11Y_NOTIFICATION_NONE);
  } else if (sender == high_contrast_view_) {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        delegate->IsHighContrastEnabled() ?
            ash::UMA_STATUS_AREA_DISABLE_HIGH_CONTRAST :
            ash::UMA_STATUS_AREA_ENABLE_HIGH_CONTRAST);
    delegate->ToggleHighContrast();
  } else if (sender == screen_magnifier_view_) {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        delegate->IsMagnifierEnabled() ?
            ash::UMA_STATUS_AREA_DISABLE_MAGNIFIER :
            ash::UMA_STATUS_AREA_ENABLE_MAGNIFIER);
    delegate->SetMagnifierEnabled(!delegate->IsMagnifierEnabled());
  } else if (large_cursor_view_ && sender == large_cursor_view_) {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        delegate->IsLargeCursorEnabled() ?
            ash::UMA_STATUS_AREA_DISABLE_LARGE_CURSOR :
            ash::UMA_STATUS_AREA_ENABLE_LARGE_CURSOR);
    delegate->SetLargeCursorEnabled(!delegate->IsLargeCursorEnabled());
  } else if (autoclick_view_ && sender == autoclick_view_) {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        delegate->IsAutoclickEnabled() ?
            ash::UMA_STATUS_AREA_DISABLE_AUTO_CLICK :
            ash::UMA_STATUS_AREA_ENABLE_AUTO_CLICK);
    delegate->SetAutoclickEnabled(!delegate->IsAutoclickEnabled());
  }
}

void AccessibilityDetailedView::ButtonPressed(views::Button* sender,
                                              const ui::Event& event) {
  SystemTrayDelegate* tray_delegate =
      Shell::GetInstance()->system_tray_delegate();
  if (sender == help_view_)
    tray_delegate->ShowAccessibilityHelp();
  else if (sender == settings_view_)
    tray_delegate->ShowAccessibilitySettings();
}

}  // namespace tray

////////////////////////////////////////////////////////////////////////////////
// ash::internal::TrayAccessibility

TrayAccessibility::TrayAccessibility(SystemTray* system_tray)
    : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_ACCESSIBILITY),
      default_(NULL),
      detailed_popup_(NULL),
      detailed_menu_(NULL),
      request_popup_view_(false),
      tray_icon_visible_(false),
      login_(GetCurrentLoginStatus()),
      previous_accessibility_state_(GetAccessibilityState()),
      show_a11y_menu_on_lock_screen_(true) {
  DCHECK(Shell::GetInstance()->delegate());
  DCHECK(system_tray);
  Shell::GetInstance()->system_tray_notifier()->AddAccessibilityObserver(this);
}

TrayAccessibility::~TrayAccessibility() {
  Shell::GetInstance()->system_tray_notifier()->
      RemoveAccessibilityObserver(this);
}

void TrayAccessibility::SetTrayIconVisible(bool visible) {
  if (tray_view())
    tray_view()->SetVisible(visible);
  tray_icon_visible_ = visible;
}

tray::AccessibilityDetailedView* TrayAccessibility::CreateDetailedMenu() {
  return new tray::AccessibilityDetailedView(this, login_);
}

bool TrayAccessibility::GetInitialVisibility() {
  // Shows accessibility icon if any accessibility feature is enabled.
  // Otherwise, doen't show it.
  return GetAccessibilityState() != A11Y_NONE;
}

views::View* TrayAccessibility::CreateDefaultView(user::LoginStatus status) {
  CHECK(default_ == NULL);

  // Shows accessibility menu if:
  // - on login screen (not logged in);
  // - "Enable accessibility menu" on chrome://settings is checked;
  // - or any of accessibility features is enabled
  // Otherwise, not shows it.
  AccessibilityDelegate* delegate =
      Shell::GetInstance()->accessibility_delegate();
  if (login_ != user::LOGGED_IN_NONE &&
      !delegate->ShouldShowAccessibilityMenu() &&
      // On login screen, keeps the initial visibility of the menu.
      (status != user::LOGGED_IN_LOCKED || !show_a11y_menu_on_lock_screen_))
    return NULL;

  CHECK(default_ == NULL);
  default_ = new tray::DefaultAccessibilityView(this);

  return default_;
}

views::View* TrayAccessibility::CreateDetailedView(user::LoginStatus status) {
  CHECK(detailed_popup_ == NULL);
  CHECK(detailed_menu_ == NULL);

  if (request_popup_view_) {
    detailed_popup_ = new tray::AccessibilityPopupView(this);
    request_popup_view_ = false;
    return detailed_popup_;
  } else {
    Shell::GetInstance()->metrics()->RecordUserMetricsAction(
        ash::UMA_STATUS_AREA_DETAILED_ACCESSABILITY);
    detailed_menu_ = CreateDetailedMenu();
    return detailed_menu_;
  }
}

void TrayAccessibility::DestroyDefaultView() {
  default_ = NULL;
}

void TrayAccessibility::DestroyDetailedView() {
  detailed_popup_ = NULL;
  detailed_menu_ = NULL;
}

void TrayAccessibility::UpdateAfterLoginStatusChange(user::LoginStatus status) {
  // Stores the a11y feature status on just entering the lock screen.
  if (login_ != user::LOGGED_IN_LOCKED && status == user::LOGGED_IN_LOCKED)
    show_a11y_menu_on_lock_screen_ = (GetAccessibilityState() != A11Y_NONE);

  login_ = status;
  SetTrayIconVisible(GetInitialVisibility());
}

void TrayAccessibility::OnAccessibilityModeChanged(
    AccessibilityNotificationVisibility notify) {
  SetTrayIconVisible(GetInitialVisibility());

  uint32 accessibility_state = GetAccessibilityState();
  if ((notify == ash::A11Y_NOTIFICATION_SHOW) &&
      !(previous_accessibility_state_ & A11Y_SPOKEN_FEEDBACK) &&
      (accessibility_state & A11Y_SPOKEN_FEEDBACK)) {
    // Shows popup if |notify| is true and the spoken feedback is being enabled.
    request_popup_view_ = true;
    PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
  } else {
    if (detailed_popup_)
      detailed_popup_->GetWidget()->Close();
    if (detailed_menu_)
      detailed_menu_->GetWidget()->Close();
  }

  previous_accessibility_state_ = accessibility_state;
}

}  // namespace internal
}  // namespace ash
