// 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 = SkColorSetARGBInline(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 = SkColorSetARGBInline(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 =
    SkColorSetARGBInline(255, 66, 133, 244);
const SkColor kTouchTargetOuterCircleColor =
    SkColorSetA(kTouchTargetInnerCircleColor, 255 * 0.2);
const SkColor kHandIconColor = SkColorSetARGBInline(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
