// Copyright 2016 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/display/touch_calibrator_view.h"

#include <memory>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shell.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/linear_animation.h"
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/controls/label.h"
#include "ui/views/widget/widget.h"

namespace ash {

namespace {

constexpr char kWidgetName[] = "TouchCalibratorOverlay";

constexpr int kAnimationFrameRate = 100;
constexpr auto kFadeDuration = base::TimeDelta::FromMilliseconds(150);
constexpr auto kPointMoveDuration = base::TimeDelta::FromMilliseconds(400);
constexpr auto kPointMoveDurationLong = base::TimeDelta::FromMilliseconds(500);

const SkColor kExitLabelColor = SkColorSetARGB(255, 138, 138, 138);
constexpr int kExitLabelWidth = 300;
constexpr int kExitLabelHeight = 20;

const SkColor kTapHereLabelColor = SK_ColorWHITE;

constexpr int kHintBoxWidth = 298;
constexpr int kHintBoxHeight = 180;
constexpr int kHintBoxLabelTextSize = 5;
constexpr int kHintBoxSublabelTextSize = 3;

constexpr int kThrobberCircleViewWidth = 64;
constexpr float kThrobberCircleRadiusFactor = 3.f / 8.f;

constexpr auto kFinalMessageTransitionDuration =
    base::TimeDelta::FromMilliseconds(200);
constexpr int kCompleteMessageViewWidth = 427;
constexpr int kCompleteMessageViewHeight = kThrobberCircleViewWidth;
constexpr int kCompleteMessageTextSize = 16;

constexpr int kTouchPointViewOffset = 100;

constexpr int kTapLabelHeight = 48;
constexpr int kTapLabelWidth = 80;

const SkColor kHintLabelTextColor = SK_ColorBLACK;
const SkColor kHintSublabelTextColor = SkColorSetARGB(255, 161, 161, 161);

const SkColor kInnerCircleColor = SK_ColorWHITE;
const SkColor kOuterCircleColor = SkColorSetA(kInnerCircleColor, 255 * 0.2);

constexpr int kCircleAnimationDurationMs = 900;

constexpr int kHintRectBorderRadius = 4;

constexpr float kBackgroundFinalOpacity = 0.75f;

constexpr int kTouchTargetWidth = 64;
constexpr int kTouchTargetHeight = kTouchTargetWidth + kTouchTargetWidth / 2;

constexpr float kTouchTargetVerticalOffsetFactor = 11.f / 24.f;

const SkColor kTouchTargetInnerCircleColor = SkColorSetARGB(255, 66, 133, 244);
const SkColor kTouchTargetOuterCircleColor =
    SkColorSetA(kTouchTargetInnerCircleColor, 255 * 0.2);
const SkColor kHandIconColor = SkColorSetARGB(255, 201, 201, 201);
constexpr float kHandIconHorizontalOffsetFactor = 7.f / 32.f;

// Returns the initialization params for the widget that contains the touch
// calibrator view.
views::Widget::InitParams GetWidgetParams(aura::Window* root_window) {
  views::Widget::InitParams params;
  params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
  params.name = kWidgetName;
  params.keep_on_top = true;
  params.accept_events = true;
  params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.parent =
      Shell::GetContainer(root_window, kShellWindowId_OverlayContainer);
  return params;
}

// Returns the size of bounding box required for |text| of given |font_list|.
gfx::Size GetSizeForString(const base::string16& text,
                           const gfx::FontList& font_list) {
  int height = 0, width = 0;
  gfx::Canvas::SizeStringInt(text, font_list, &width, &height, 0, 0);
  return gfx::Size(width, height);
}

void AnimateLayerToPosition(views::View* view,
                            base::TimeDelta duration,
                            gfx::Point end_position,
                            float opacity = 1.f) {
  ui::ScopedLayerAnimationSettings slide_settings(view->layer()->GetAnimator());
  slide_settings.SetPreemptionStrategy(
      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
  slide_settings.SetTransitionDuration(duration);
  view->SetBoundsRect(gfx::Rect(end_position, view->size()));
  view->layer()->SetOpacity(opacity);
}

}  // namespace

// Creates a throbbing animated view with two concentric circles. The radius of
// the inner circle is fixed while that of the outer circle oscillates between a
// min and max radius. The animation takes |animation_duration| milliseconds
// to complete. The center of these circles are at the center of the view
// element.
class CircularThrobberView : public views::View, public gfx::AnimationDelegate {
 public:
  CircularThrobberView(int width,
                       const SkColor& inner_circle_color,
                       const SkColor& outer_circle_color,
                       int animation_duration);
  ~CircularThrobberView() override;

  // views::View overrides:
  void OnPaint(gfx::Canvas* canvas) override;

  // gfx::AnimationDelegate overrides:
  void AnimationProgressed(const gfx::Animation* animation) override;

 private:
  // Radius of the inner circle.
  const int inner_radius_;

  // Current radius of the outer circle.
  int outer_radius_;

  // Minimum radius for outer animated circle.
  const int smallest_radius_animated_circle_;

  // Maximum radius for outer animated circle.
  const int largest_radius_animated_circle_;

  cc::PaintFlags inner_circle_flags_;
  cc::PaintFlags outer_circle_flags_;

  std::unique_ptr<gfx::ThrobAnimation> animation_;

  // Center of the concentric circles.
  const gfx::Point center_;

  DISALLOW_COPY_AND_ASSIGN(CircularThrobberView);
};

CircularThrobberView::CircularThrobberView(int width,
                                           const SkColor& inner_circle_color,
                                           const SkColor& outer_circle_color,
                                           int animation_duration)
    : inner_radius_(width / 4),
      outer_radius_(inner_radius_),
      smallest_radius_animated_circle_(width * kThrobberCircleRadiusFactor),
      largest_radius_animated_circle_(width / 2),
      center_(gfx::Point(width / 2, width / 2)) {
  SetSize(gfx::Size(width, width));

  inner_circle_flags_.setColor(inner_circle_color);
  inner_circle_flags_.setAntiAlias(true);
  inner_circle_flags_.setStyle(cc::PaintFlags::kFill_Style);

  outer_circle_flags_.setColor(outer_circle_color);
  outer_circle_flags_.setAntiAlias(true);
  outer_circle_flags_.setStyle(cc::PaintFlags::kFill_Style);

  animation_.reset(new gfx::ThrobAnimation(this));
  animation_->SetThrobDuration(animation_duration);
  animation_->StartThrobbing(-1);

  SchedulePaint();
}

CircularThrobberView::~CircularThrobberView() = default;

void CircularThrobberView::OnPaint(gfx::Canvas* canvas) {
  canvas->DrawCircle(center_, outer_radius_, outer_circle_flags_);
  canvas->DrawCircle(center_, inner_radius_, inner_circle_flags_);
}

void CircularThrobberView::AnimationProgressed(
    const gfx::Animation* animation) {
  if (animation != animation_.get())
    return;
  outer_radius_ = animation->CurrentValueBetween(
      smallest_radius_animated_circle_, largest_radius_animated_circle_);
  SchedulePaint();
}

class TouchTargetThrobberView : public CircularThrobberView {
 public:
  TouchTargetThrobberView(const gfx::Rect& bounds,
                          const SkColor& inner_circle_color,
                          const SkColor& outer_circle_color,
                          const SkColor& hand_icon_color,
                          int animation_duration);
  ~TouchTargetThrobberView() override;

  // views::View overrides:
  void OnPaint(gfx::Canvas* canvas) override;

 private:
  const int horizontal_offset_;

  const int icon_width_;

  gfx::ImageSkia hand_icon_;

  DISALLOW_COPY_AND_ASSIGN(TouchTargetThrobberView);
};

TouchTargetThrobberView::TouchTargetThrobberView(
    const gfx::Rect& bounds,
    const SkColor& inner_circle_color,
    const SkColor& outer_circle_color,
    const SkColor& hand_icon_color,
    int animation_duration)
    : CircularThrobberView(bounds.width(),
                           inner_circle_color,
                           outer_circle_color,
                           animation_duration),
      horizontal_offset_(bounds.width() * kHandIconHorizontalOffsetFactor),
      icon_width_(bounds.width() * 0.5f) {
  SetBoundsRect(bounds);

  hand_icon_ = gfx::CreateVectorIcon(kTouchCalibrationHandIcon, kHandIconColor);
}

TouchTargetThrobberView::~TouchTargetThrobberView() = default;

void TouchTargetThrobberView::OnPaint(gfx::Canvas* canvas) {
  CircularThrobberView::OnPaint(canvas);
  canvas->DrawImageInt(hand_icon_, horizontal_offset_, icon_width_);
}

//   Circular      _________________________________
//   Throbber     |                                 |
//     View       |                                 |
//  ___________   |                                 |
// |           |  |                                 |
// |           |  |                                 |
// |     .     |  |            Hint Box             |
// |           |  |                                 |
// |___________|  |                                 |
//                |                                 |
//                |                                 |
//                |_________________________________|
//
// This view is set next to the throbber circle view such that their centers
// align. The hint box has a label text and a sublabel text to assist the
// user by informing them about the next step in the calibration process.
class HintBox : public views::View {
 public:
  HintBox(const gfx::Rect& bounds, int border_radius);
  ~HintBox() override;

  // views::View overrides:
  void OnPaint(gfx::Canvas* canvas) override;

  void SetLabel(const base::string16& text, const SkColor& color);
  void SetSubLabel(const base::string16& text, const SkColor& color);

 private:
  void UpdateWidth(int updated_width);

  base::string16 label_text_;
  base::string16 sublabel_text_;

  SkColor label_color_;
  SkColor sublabel_color_;

  const int border_radius_;

  int base_border_;

  int arrow_width_;

  int horizontal_offset_;

  gfx::Rect rounded_rect_bounds_;

  gfx::FontList label_font_list_;
  gfx::FontList sublabel_font_list_;

  gfx::Rect label_text_bounds_;
  gfx::Rect sublabel_text_bounds_;

  cc::PaintFlags flags_;

  DISALLOW_COPY_AND_ASSIGN(HintBox);
};

HintBox::HintBox(const gfx::Rect& bounds, int border_radius)
    : border_radius_(border_radius) {
  SetBorder(std::make_unique<views::BubbleBorder>(
      base::i18n::IsRTL() ? views::BubbleBorder::RIGHT_CENTER
                          : views::BubbleBorder::LEFT_CENTER,
      views::BubbleBorder::NO_SHADOW_OPAQUE_BORDER, SK_ColorWHITE));

  arrow_width_ = (GetInsets().right() - GetInsets().left()) *
                 (base::i18n::IsRTL() ? 1 : -1);

  // Border on all sides are the same except on the side of the arrow, in which
  // case the width of the arrow is additional.
  base_border_ = base::i18n::IsRTL() ? GetInsets().left() : GetInsets().right();

  SetBounds(bounds.x(), bounds.y() - base_border_,
            bounds.width() + 2 * base_border_ + arrow_width_,
            bounds.height() + 2 * base_border_);

  rounded_rect_bounds_ = GetLocalBounds();
  rounded_rect_bounds_.Inset(GetInsets());

  flags_.setColor(SK_ColorWHITE);
  flags_.setStyle(cc::PaintFlags::kFill_Style);
  flags_.setAntiAlias(true);

  horizontal_offset_ =
      arrow_width_ + base_border_ + rounded_rect_bounds_.width() * 0.08f;
  int top_offset = horizontal_offset_;
  int line_gap = rounded_rect_bounds_.height() * 0.018f;
  int label_height = rounded_rect_bounds_.height() * 0.11f;

  label_text_bounds_.SetRect(horizontal_offset_, top_offset, 0, label_height);

  top_offset += label_text_bounds_.height() + line_gap;

  sublabel_text_bounds_.SetRect(horizontal_offset_, top_offset, 0,
                                label_height);
}

HintBox::~HintBox() = default;

void HintBox::UpdateWidth(int updated_width) {
  SetSize(gfx::Size(updated_width + 2 * base_border_ + arrow_width_, height()));
  rounded_rect_bounds_ = GetLocalBounds();
  rounded_rect_bounds_.Inset(GetInsets());
}

void HintBox::SetLabel(const base::string16& text, const SkColor& color) {
  label_text_ = text;
  label_color_ = color;

  label_font_list_ =
      ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
          kHintBoxLabelTextSize, gfx::Font::FontStyle::NORMAL,
          gfx::Font::Weight::NORMAL);

  // Adjust size of label bounds based on text and font.
  gfx::Size size = GetSizeForString(label_text_, label_font_list_);
  label_text_bounds_.set_size(
      gfx::Size(size.width(), label_text_bounds_.height()));

  // Check if the width of hint box needs to be updated.
  int minimum_expected_width =
      size.width() + 2 * horizontal_offset_ - arrow_width_;
  if (minimum_expected_width > rounded_rect_bounds_.width())
    UpdateWidth(minimum_expected_width);
}

void HintBox::SetSubLabel(const base::string16& text, const SkColor& color) {
  sublabel_text_ = text;
  sublabel_color_ = color;

  sublabel_font_list_ =
      ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
          kHintBoxSublabelTextSize, gfx::Font::FontStyle::NORMAL,
          gfx::Font::Weight::NORMAL);

  // Adjust size of sublabel label bounds based on text and font.
  gfx::Size size = GetSizeForString(sublabel_text_, sublabel_font_list_);
  sublabel_text_bounds_.set_size(
      gfx::Size(size.width(), sublabel_text_bounds_.height()));

  // Check if the width of hint box needs to be updated.
  int minimum_expected_width =
      size.width() + 2 * horizontal_offset_ - arrow_width_;
  if (minimum_expected_width > rounded_rect_bounds_.width())
    UpdateWidth(minimum_expected_width);
}

void HintBox::OnPaint(gfx::Canvas* canvas) {
  views::View::OnPaint(canvas);
  canvas->DrawRoundRect(rounded_rect_bounds_, border_radius_, flags_);
  canvas->DrawStringRectWithFlags(label_text_, label_font_list_, label_color_,
                                  label_text_bounds_, gfx::Canvas::NO_ELLIPSIS);
  canvas->DrawStringRectWithFlags(sublabel_text_, sublabel_font_list_,
                                  sublabel_color_, sublabel_text_bounds_,
                                  gfx::Canvas::NO_ELLIPSIS);
}

class CompletionMessageView : public views::View {
 public:
  CompletionMessageView(const gfx::Rect& bounds, const base::string16& message);
  ~CompletionMessageView() override;

  // views::View overrides:
  void OnPaint(gfx::Canvas* canvas) override;

 private:
  const base::string16 message_;
  gfx::FontList font_list_;

  gfx::Rect text_bounds_;

  gfx::ImageSkia check_icon_;

  cc::PaintFlags flags_;

  DISALLOW_COPY_AND_ASSIGN(CompletionMessageView);
};

CompletionMessageView::CompletionMessageView(const gfx::Rect& bounds,
                                             const base::string16& message)
    : message_(message) {
  SetBoundsRect(bounds);

  int x_offset = height() * 5.f / 4.f;
  text_bounds_.SetRect(x_offset, 0, width() - x_offset, height());

  font_list_ = ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
      kCompleteMessageTextSize, gfx::Font::FontStyle::NORMAL,
      gfx::Font::Weight::NORMAL);

  // crbug/676513 moves this file to src/ash which will require an ash icon
  // file.
  check_icon_ =
      gfx::CreateVectorIcon(kTouchCalibrationCompleteCheckIcon, SK_ColorWHITE);

  flags_.setColor(SK_ColorWHITE);
  flags_.setStyle(cc::PaintFlags::kFill_Style);
  flags_.setAntiAlias(true);
}

CompletionMessageView::~CompletionMessageView() = default;

void CompletionMessageView::OnPaint(gfx::Canvas* canvas) {
  canvas->DrawImageInt(check_icon_, 0, 0);

  // TODO(malaykeshav): Work with elizabethchiu@ to get better UX for RTL.
  canvas->DrawStringRectWithFlags(
      message_, font_list_, flags_.getColor(), text_bounds_,
      gfx::Canvas::TEXT_ALIGN_LEFT | gfx::Canvas::NO_SUBPIXEL_RENDERING);
}

TouchCalibratorView::TouchCalibratorView(const display::Display& target_display,
                                         bool is_primary_view)
    : display_(target_display),
      is_primary_view_(is_primary_view),
      exit_label_(nullptr),
      tap_label_(nullptr),
      throbber_circle_(nullptr),
      hint_box_view_(nullptr),
      touch_point_view_(nullptr) {
  aura::Window* root = Shell::GetRootWindowForDisplayId(display_.id());
  widget_.reset(new views::Widget);
  widget_->Init(GetWidgetParams(root));
  widget_->SetContentsView(this);
  widget_->SetBounds(display_.bounds());
  widget_->Show();
  set_owned_by_client();

  animator_.reset(
      new gfx::LinearAnimation(kFadeDuration, kAnimationFrameRate, this));

  InitViewContents();
  AdvanceToNextState();
}

TouchCalibratorView::~TouchCalibratorView() {
  state_ = UNKNOWN;
  widget_->Hide();
  animator_->End();
}

void TouchCalibratorView::InitViewContents() {
  // Initialize the background rect.
  background_rect_ =
      gfx::RectF(0, 0, display_.bounds().width(), display_.bounds().height());

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  // Initialize exit label that informs the user how to exit the touch
  // calibration setup.
  exit_label_ = new views::Label(
      rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_EXIT_LABEL),
      {rb.GetFontListWithDelta(8, gfx::Font::FontStyle::NORMAL,
                               gfx::Font::Weight::NORMAL)});
  exit_label_->SetBounds((display_.bounds().width() - kExitLabelWidth) / 2,
                         display_.bounds().height() * 3.f / 4, kExitLabelWidth,
                         kExitLabelHeight);
  exit_label_->SetAutoColorReadabilityEnabled(false);
  exit_label_->SetEnabledColor(kExitLabelColor);
  exit_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
  exit_label_->SetSubpixelRenderingEnabled(false);
  exit_label_->SetVisible(false);

  AddChildView(exit_label_);

  // If this is not the screen that is being calibrated, then this is all we
  // need to display.
  if (!is_primary_view_)
    return;

  // Initialize the touch point view that contains the animated circle that the
  // user needs to tap.
  const int kTouchPointViewHeight = kThrobberCircleViewWidth + kTapLabelHeight;
  const int kThrobberCircleViewHorizontalOffset =
      (kTapLabelWidth - kThrobberCircleViewWidth) / 2;

  throbber_circle_ =
      new CircularThrobberView(kThrobberCircleViewWidth, kInnerCircleColor,
                               kOuterCircleColor, kCircleAnimationDurationMs);
  throbber_circle_->SetPosition(
      gfx::Point(kThrobberCircleViewHorizontalOffset, 0));

  // Initialize the tap label.
  tap_label_ = new views::Label(
      rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_TAP_HERE_LABEL),
      {rb.GetFontListWithDelta(6, gfx::Font::FontStyle::NORMAL,
                               gfx::Font::Weight::NORMAL)});
  tap_label_->SetBounds(0, kThrobberCircleViewWidth, kTapLabelWidth,
                        kTapLabelHeight);
  tap_label_->SetEnabledColor(kTapHereLabelColor);
  tap_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
  tap_label_->SetAutoColorReadabilityEnabled(false);
  tap_label_->SetSubpixelRenderingEnabled(false);
  tap_label_->SetVisible(false);

  touch_point_view_ = new views::View;
  touch_point_view_->SetBounds(kTouchPointViewOffset, kTouchPointViewOffset,
                               kTapLabelWidth, kTouchPointViewHeight);
  touch_point_view_->SetVisible(false);
  touch_point_view_->SetPaintToLayer();
  touch_point_view_->layer()->SetFillsBoundsOpaquely(false);
  touch_point_view_->layer()->GetAnimator()->AddObserver(this);
  touch_point_view_->SetBackground(
      views::CreateSolidBackground(SK_ColorTRANSPARENT));

  touch_point_view_->AddChildView(throbber_circle_);
  touch_point_view_->AddChildView(tap_label_);

  AddChildView(touch_point_view_);

  // Initialize the Hint Box view.
  base::string16 hint_label_text =
      rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_LABEL_TEXT);
  base::string16 hint_sublabel_text =
      rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_HINT_SUBLABEL_TEXT);

  int tpv_width = touch_point_view_->width();

  gfx::Size size(kHintBoxWidth, kHintBoxHeight);

  gfx::Point position(touch_point_view_->x() + tpv_width * 1.2f,
                      touch_point_view_->y() +
                          (kThrobberCircleViewWidth / 2.f) -
                          (size.height() / 2.f));

  HintBox* hint_box =
      new HintBox(gfx::Rect(position, size), kHintRectBorderRadius);
  hint_box->SetVisible(false);
  hint_box->SetLabel(hint_label_text, kHintLabelTextColor);
  hint_box->SetSubLabel(hint_sublabel_text, kHintSublabelTextColor);
  hint_box_view_ = hint_box;

  AddChildView(hint_box_view_);

  // Initialize the animated hint box throbber view.
  TouchTargetThrobberView* target_view = new TouchTargetThrobberView(
      gfx::Rect((hint_box->width() - kTouchTargetWidth) / 2,
                hint_box->height() * kTouchTargetVerticalOffsetFactor,
                kTouchTargetWidth, kTouchTargetHeight),
      kTouchTargetInnerCircleColor, kTouchTargetOuterCircleColor,
      kHandIconColor, kCircleAnimationDurationMs);
  target_view->SetVisible(true);

  hint_box_view_->AddChildView(target_view);

  // Initialize the view that contains the calibration complete message which
  // will be displayed at the end.
  base::string16 finish_msg_text =
      rb.GetLocalizedString(IDS_DISPLAY_TOUCH_CALIBRATION_FINISH_LABEL);

  gfx::Rect msg_view_bounds(
      (display_.bounds().width() - kCompleteMessageViewWidth) / 2,
      display_.bounds().height() / 3, kCompleteMessageViewWidth,
      kCompleteMessageViewHeight);
  completion_message_view_ =
      new CompletionMessageView(msg_view_bounds, finish_msg_text);
  completion_message_view_->SetVisible(false);
  completion_message_view_->SetPaintToLayer();
  completion_message_view_->layer()->SetFillsBoundsOpaquely(false);
  completion_message_view_->layer()->GetAnimator()->AddObserver(this);
  completion_message_view_->SetBackground(
      views::CreateSolidBackground(SK_ColorTRANSPARENT));

  AddChildView(completion_message_view_);
}

void TouchCalibratorView::OnPaint(gfx::Canvas* canvas) {
  OnPaintBackground(canvas);
}

void TouchCalibratorView::OnPaintBackground(gfx::Canvas* canvas) {
  float opacity;

  // If current state is a fade in or fade out state then update opacity
  // based on how far the animation has progressed.
  if (animator_ && (state_ == TouchCalibratorView::BACKGROUND_FADING_OUT ||
                    state_ == TouchCalibratorView::BACKGROUND_FADING_IN)) {
    opacity = static_cast<float>(animator_->CurrentValueBetween(
        start_opacity_value_, end_opacity_value_));
  } else {
    opacity = state_ == BACKGROUND_FADING_OUT ? 0.f : kBackgroundFinalOpacity;
  }

  flags_.setColor(SkColorSetA(SK_ColorBLACK,
                              std::numeric_limits<uint8_t>::max() * opacity));
  canvas->DrawRect(background_rect_, flags_);
}

void TouchCalibratorView::AnimationProgressed(const gfx::Animation* animation) {
  if (!is_primary_view_) {
    SchedulePaint();
    return;
  }
}

void TouchCalibratorView::AnimationCanceled(const gfx::Animation* animation) {
  AnimationEnded(animation);
}

void TouchCalibratorView::AnimationEnded(const gfx::Animation* animation) {
  switch (state_) {
    case BACKGROUND_FADING_IN:
      exit_label_->SetVisible(true);
      state_ = is_primary_view_ ? DISPLAY_POINT_1 : CALIBRATION_COMPLETE;
      if (is_primary_view_) {
        touch_point_view_->SetVisible(true);
        hint_box_view_->SetVisible(true);
      }
      break;
    case BACKGROUND_FADING_OUT:
      exit_label_->SetVisible(false);
      if (is_primary_view_)
        completion_message_view_->SetVisible(false);
      widget_->Hide();
      break;
    default:
      break;
  }
}

void TouchCalibratorView::OnLayerAnimationStarted(
    ui::LayerAnimationSequence* sequence) {}

void TouchCalibratorView::OnLayerAnimationEnded(
    ui::LayerAnimationSequence* sequence) {
  switch (state_) {
    case ANIMATING_1_TO_2:
      state_ = DISPLAY_POINT_2;
      tap_label_->SetVisible(true);
      break;
    case ANIMATING_2_TO_3:
      state_ = DISPLAY_POINT_3;
      break;
    case ANIMATING_3_TO_4:
      state_ = DISPLAY_POINT_4;
      break;
    case ANIMATING_FINAL_MESSAGE:
      state_ = CALIBRATION_COMPLETE;
      break;
    default:
      break;
  }
}

void TouchCalibratorView::OnLayerAnimationAborted(
    ui::LayerAnimationSequence* sequence) {
  OnLayerAnimationEnded(sequence);
}

void TouchCalibratorView::OnLayerAnimationScheduled(
    ui::LayerAnimationSequence* sequence) {}

void TouchCalibratorView::AdvanceToNextState() {
  // Stop any previous animations and skip them to the end.
  SkipCurrentAnimation();

  switch (state_) {
    case UNKNOWN:
    case BACKGROUND_FADING_IN:
      state_ = BACKGROUND_FADING_IN;
      start_opacity_value_ = 0.f;
      end_opacity_value_ = kBackgroundFinalOpacity;

      flags_.setStyle(cc::PaintFlags::kFill_Style);
      animator_->SetDuration(kFadeDuration);
      animator_->Start();
      return;
    case DISPLAY_POINT_1:
      state_ = ANIMATING_1_TO_2;

      // The touch point has to be animated from the top left corner of the
      // screen to the top right corner.
      AnimateLayerToPosition(
          touch_point_view_, kPointMoveDuration,
          gfx::Point(display_.bounds().width() - kTouchPointViewOffset -
                         touch_point_view_->width(),
                     touch_point_view_->y()));
      hint_box_view_->SetVisible(false);
      return;
    case DISPLAY_POINT_2:
      state_ = ANIMATING_2_TO_3;

      // The touch point has to be animated from the top right corner of the
      // screen to the bottom left corner.
      AnimateLayerToPosition(
          touch_point_view_, kPointMoveDurationLong,
          gfx::Point(kTouchPointViewOffset, display_.bounds().height() -
                                                kTouchPointViewOffset -
                                                touch_point_view_->height()));
      return;
    case DISPLAY_POINT_3:
      state_ = ANIMATING_3_TO_4;

      // The touch point has to be animated from the bottom left corner of the
      // screen to the bottom right corner.
      AnimateLayerToPosition(
          touch_point_view_, kPointMoveDuration,
          gfx::Point(display_.bounds().width() - kTouchPointViewOffset -
                         touch_point_view_->width(),
                     touch_point_view_->y()));
      return;
    case DISPLAY_POINT_4:
      state_ = ANIMATING_FINAL_MESSAGE;
      completion_message_view_->layer()->SetOpacity(0.f);
      completion_message_view_->SetVisible(true);

      touch_point_view_->SetVisible(false);

      AnimateLayerToPosition(completion_message_view_,
                             kFinalMessageTransitionDuration,
                             gfx::Point(completion_message_view_->x(),
                                        display_.bounds().height() / 2));
      return;
    case CALIBRATION_COMPLETE:
      state_ = BACKGROUND_FADING_OUT;
      if (is_primary_view_) {
        // In case of primary view, we also need to fade out the calibration
        // complete message view.
        AnimateLayerToPosition(
            completion_message_view_, kFadeDuration,
            gfx::Point(completion_message_view_->x(),
                       completion_message_view_->y() +
                           2 * completion_message_view_->height()),
            0.f);
      }

      start_opacity_value_ = kBackgroundFinalOpacity;
      end_opacity_value_ = 0.f;

      flags_.setStyle(cc::PaintFlags::kFill_Style);
      animator_->SetDuration(kFadeDuration);
      animator_->Start();
      return;
    default:
      return;
  }
}

bool TouchCalibratorView::GetDisplayPointLocation(gfx::Point* location) {
  DCHECK(location);
  if (!is_primary_view_)
    return false;

  if (state_ != DISPLAY_POINT_1 && state_ != DISPLAY_POINT_2 &&
      state_ != DISPLAY_POINT_3 && state_ != DISPLAY_POINT_4) {
    return false;
  }

  if (!touch_point_view_ || !throbber_circle_)
    return false;
  // TODO(malaykeshav): Can use views::ConvertPointToScreen()
  location->SetPoint(touch_point_view_->x() + touch_point_view_->width() / 2.f,
                     touch_point_view_->y() + touch_point_view_->width() / 2.f);
  return true;
}

void TouchCalibratorView::SkipToFinalState() {
  state_ = CALIBRATION_COMPLETE;

  exit_label_->SetVisible(false);

  if (is_primary_view_) {
    touch_point_view_->SetVisible(false);
    hint_box_view_->SetVisible(false);
  }

  AdvanceToNextState();
}

void TouchCalibratorView::SkipCurrentAnimation() {
  if (animator_->is_animating())
    animator_->End();
  if (touch_point_view_ &&
      touch_point_view_->layer()->GetAnimator()->is_animating()) {
    touch_point_view_->layer()->GetAnimator()->StopAnimating();
  }
}

}  // namespace ash
