// Copyright (c) 2013 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 "chrome/browser/ui/tabs/tab_audio_indicator.h"

#include "grit/theme_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/animation/animation_container.h"
#include "ui/gfx/animation/linear_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/skia_util.h"

namespace {

// The number of columns to draw for the equalizer graphic.
const size_t kEqualizerColumnCount = 3;

// The equalizer cycles between these frames. An equalizer frame is 2 columns
// where each column ranges from 0 to 4.
const size_t kEqualizerFrames[][kEqualizerColumnCount] = {
   { 1, 1, 1 },
   { 1, 2, 2 },
   { 2, 2, 3 },
   { 3, 3, 2 },
   { 3, 2, 1 },
   { 2, 1, 2 },
   { 1, 2, 3 },
   { 2, 1, 2 },
   { 3, 2, 1 },
   { 3, 2, 1 },
   { 2, 3, 2 },
   { 1, 2, 3 },
   { 2, 1, 2 },
};

// The space between equalizer levels.
const int kEqualizerColumnPadding = 1;

// The duration of each equalizer frame.
const size_t kAnimationCycleDurationMs = 250;

// The duration of the "ending" animation once audio stops playing.
const size_t kAnimationEndingDurationMs = 1000;

// Target frames per second. In reality fewer frames are drawn because the
// equalizer levels change slowly.
const int kFPS = 15;

}  // namespace

TabAudioIndicator::TabAudioIndicator(Delegate* delegate)
    : delegate_(delegate),
      frame_index_(0),
      state_(STATE_NOT_ANIMATING) {
}

TabAudioIndicator::~TabAudioIndicator() {
}

void TabAudioIndicator::SetAnimationContainer(
    gfx::AnimationContainer* animation_container) {
  animation_container_ = animation_container;
}

void TabAudioIndicator::SetIsPlayingAudio(bool is_playing_audio) {
  if (is_playing_audio && state_ != STATE_ANIMATING) {
    state_ = STATE_ANIMATING;
    animation_.reset(
        new gfx::LinearAnimation(kAnimationCycleDurationMs, kFPS, this));
    animation_->SetContainer(animation_container_.get());
    animation_->Start();
  } else if (!is_playing_audio && state_ == STATE_ANIMATING) {
    state_ = STATE_ANIMATION_ENDING;
    animation_.reset(
        new gfx::LinearAnimation(kAnimationEndingDurationMs, kFPS, this));
    animation_->SetContainer(animation_container_.get());
    animation_->Start();
  }
}

bool TabAudioIndicator::IsAnimating() {
  return state_ != STATE_NOT_ANIMATING;
}

void TabAudioIndicator::Paint(gfx::Canvas* canvas, const gfx::Rect& rect) {
  canvas->Save();
  canvas->ClipRect(rect);

  // Draw 3 equalizer columns. |IDR_AUDIO_EQUALIZER_COLUMN| is a column of the
  // equalizer with 4 levels. The current level is between 0 and 4 so the
  // image is shifted down and then drawn.
  if (state_ != STATE_NOT_ANIMATING) {
    ui::ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    gfx::ImageSkia* image(rb.GetImageSkiaNamed(IDR_AUDIO_EQUALIZER_COLUMN));
    int x = rect.right();
    std::vector<int> levels = GetCurrentEqualizerLevels();
    for (int i = levels.size() - 1; i >= 0; --i) {
      x -= image->width();
      if (levels[i] == 0)
        continue;

      // Shift the image down by the level.
      int y = rect.bottom() - levels[i] * 2;
      canvas->DrawImageInt(*image, x, y);

      // Clip the equalizer column so the favicon doesn't obscure it.
      gfx::Rect equalizer_rect(x, y, image->width(), image->height());
      canvas->sk_canvas()->clipRect(
          gfx::RectToSkRect(equalizer_rect), SkRegion::kDifference_Op);

      // Padding is baked into both sides of the icons so overlap the images.
      x += kEqualizerColumnPadding;
    }

    // Cache the levels that were just drawn. This is used to prevent
    // unnecessary drawing when animation progress doesn't result in equalizer
    // levels changing.
    last_displayed_equalizer_levels_ = levels;
  }

  if (!favicon_.isNull()) {
    int dst_x = rect.x() - (favicon_.width() - rect.width()) / 2;
    int dst_y = rect.y() - (favicon_.height()- rect.height()) / 2;
    canvas->DrawImageInt(favicon_, dst_x, dst_y);
  }

  canvas->Restore();
}

void TabAudioIndicator::AnimationProgressed(const gfx::Animation* animation) {
  std::vector<int> levels = GetCurrentEqualizerLevels();
  if (last_displayed_equalizer_levels_ != levels)
    delegate_->ScheduleAudioIndicatorPaint();
}

void TabAudioIndicator::AnimationEnded(const gfx::Animation* animation) {
  if (state_ == STATE_ANIMATING) {
    // The current equalizer frame animation has finished. Start animating the
    // next frame.
    frame_index_ = (frame_index_ + 1) % arraysize(kEqualizerFrames);
    animation_->Start();
  } else if (state_ == STATE_ANIMATION_ENDING) {
    // The "ending" animation has stopped. Update the tab state so that the UI
    // can update the tab icon.
    state_ = STATE_NOT_ANIMATING;
    delegate_->ScheduleAudioIndicatorPaint();
  }
}

std::vector<int> TabAudioIndicator::GetCurrentEqualizerLevels() const {
  int next_frame_index = (frame_index_ + 1) % arraysize(kEqualizerFrames);
  std::vector<int> levels;
  // For all 2 columsn of the equalizer, tween between the current equalizer
  // level and the target equalizer level.
  for (size_t i = 0; i < kEqualizerColumnCount; ++i) {
    int start = kEqualizerFrames[frame_index_][i];
    int end = state_ == STATE_ANIMATION_ENDING
              ? 0
              : kEqualizerFrames[next_frame_index][i];
    levels.push_back(animation_->CurrentValueBetween(start, end));
  }
  return levels;
}
