// 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 "chrome/browser/ui/tabs/tab_utils.h"

#include "base/strings/string16.h"
#include "chrome/browser/media/audio_stream_indicator.h"
#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/media_stream_capture_indicator.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/animation/multi_animation.h"

namespace chrome {

namespace {

// Interval between frame updates of the tab indicator animations.  This is not
// the usual 60 FPS because a trade-off must be made between tab UI animation
// smoothness and media recording/playback performance on low-end hardware.
const int kIndicatorFrameIntervalMs = 50;  // 20 FPS

// Fade-in/out duration for the tab indicator animations.  Fade-in is quick to
// immediately notify the user.  Fade-out is more gradual, so that the user has
// a chance of finding a tab that has quickly "blipped" on and off.
const int kIndicatorFadeInDurationMs = 200;
const int kIndicatorFadeOutDurationMs = 1000;

// Animation that throbs in (towards 1.0) and out (towards 0.0), and ends in the
// "in" state.
class TabRecordingIndicatorAnimation : public gfx::MultiAnimation {
 public:
  virtual ~TabRecordingIndicatorAnimation() {}

  // Overridden to provide alternating "towards in" and "towards out" behavior.
  virtual double GetCurrentValue() const OVERRIDE;

  static scoped_ptr<TabRecordingIndicatorAnimation> Create();

 private:
  TabRecordingIndicatorAnimation(const gfx::MultiAnimation::Parts& parts,
                                 const base::TimeDelta interval)
      : MultiAnimation(parts, interval) {}

  // Number of times to "toggle throb" the recording and tab capture indicators
  // when they first appear.
  static const int kCaptureIndicatorThrobCycles = 5;
};

double TabRecordingIndicatorAnimation::GetCurrentValue() const {
  return current_part_index() % 2 ?
      1.0 - MultiAnimation::GetCurrentValue() :
      MultiAnimation::GetCurrentValue();
}

scoped_ptr<TabRecordingIndicatorAnimation>
TabRecordingIndicatorAnimation::Create() {
  MultiAnimation::Parts parts;
  COMPILE_ASSERT(kCaptureIndicatorThrobCycles % 2 != 0,
                 must_be_odd_so_animation_finishes_in_showing_state);
  for (int i = 0; i < kCaptureIndicatorThrobCycles; ++i) {
    parts.push_back(MultiAnimation::Part(
        i % 2 ? kIndicatorFadeOutDurationMs : kIndicatorFadeInDurationMs,
        gfx::Tween::EASE_IN));
  }
  const base::TimeDelta interval =
      base::TimeDelta::FromMilliseconds(kIndicatorFrameIntervalMs);
  scoped_ptr<TabRecordingIndicatorAnimation> animation(
      new TabRecordingIndicatorAnimation(parts, interval));
  animation->set_continuous(false);
  return animation.Pass();
}

}  // namespace

bool ShouldTabShowFavicon(int capacity,
                          bool is_pinned_tab,
                          bool is_active_tab,
                          bool has_favicon,
                          TabMediaState media_state) {
  if (!has_favicon)
    return false;
  int required_capacity = 1;
  if (ShouldTabShowCloseButton(capacity, is_pinned_tab, is_active_tab))
    ++required_capacity;
  if (ShouldTabShowMediaIndicator(
          capacity, is_pinned_tab, is_active_tab, has_favicon, media_state)) {
    ++required_capacity;
  }
  return capacity >= required_capacity;
}

bool ShouldTabShowMediaIndicator(int capacity,
                                 bool is_pinned_tab,
                                 bool is_active_tab,
                                 bool has_favicon,
                                 TabMediaState media_state) {
  if (media_state == TAB_MEDIA_STATE_NONE)
    return false;
  if (ShouldTabShowCloseButton(capacity, is_pinned_tab, is_active_tab))
    return capacity >= 2;
  return capacity >= 1;
}

bool ShouldTabShowCloseButton(int capacity,
                              bool is_pinned_tab,
                              bool is_active_tab) {
  if (is_pinned_tab)
    return false;
  else if (is_active_tab)
    return true;
  else
    return capacity >= 3;
}

bool IsPlayingAudio(content::WebContents* contents) {
  AudioStreamIndicator* audio_indicator =
      MediaCaptureDevicesDispatcher::GetInstance()->GetAudioStreamIndicator()
          .get();
  return audio_indicator && audio_indicator->IsPlayingAudio(contents);
}

TabMediaState GetTabMediaStateForContents(content::WebContents* contents) {
  if (!contents)
    return TAB_MEDIA_STATE_NONE;

  scoped_refptr<MediaStreamCaptureIndicator> indicator =
      MediaCaptureDevicesDispatcher::GetInstance()->
          GetMediaStreamCaptureIndicator();
  if (indicator) {
    if (indicator->IsBeingMirrored(contents))
      return TAB_MEDIA_STATE_CAPTURING;
    if (indicator->IsCapturingUserMedia(contents))
      return TAB_MEDIA_STATE_RECORDING;
  }

  if (IsPlayingAudio(contents))
    return TAB_MEDIA_STATE_AUDIO_PLAYING;

  return TAB_MEDIA_STATE_NONE;
}

const gfx::Image& GetTabMediaIndicatorImage(TabMediaState media_state) {
  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  switch (media_state) {
    case TAB_MEDIA_STATE_AUDIO_PLAYING:
      return rb.GetNativeImageNamed(IDR_TAB_AUDIO_INDICATOR);
    case TAB_MEDIA_STATE_RECORDING:
      return rb.GetNativeImageNamed(IDR_TAB_RECORDING_INDICATOR);
    case TAB_MEDIA_STATE_CAPTURING:
      return rb.GetNativeImageNamed(IDR_TAB_CAPTURE_INDICATOR);
    case TAB_MEDIA_STATE_NONE:
      break;
  }
  NOTREACHED();
  return rb.GetNativeImageNamed(IDR_SAD_FAVICON);
}

scoped_ptr<gfx::Animation> CreateTabMediaIndicatorFadeAnimation(
    TabMediaState media_state) {
  if (media_state == TAB_MEDIA_STATE_RECORDING ||
      media_state == TAB_MEDIA_STATE_CAPTURING) {
    return TabRecordingIndicatorAnimation::Create().PassAs<gfx::Animation>();
  }

  // Note: While it seems silly to use a one-part MultiAnimation, it's the only
  // gfx::Animation implementation that lets us control the frame interval.
  gfx::MultiAnimation::Parts parts;
  const bool is_for_fade_in = (media_state != TAB_MEDIA_STATE_NONE);
  parts.push_back(gfx::MultiAnimation::Part(
      is_for_fade_in ? kIndicatorFadeInDurationMs : kIndicatorFadeOutDurationMs,
      gfx::Tween::EASE_IN));
  const base::TimeDelta interval =
      base::TimeDelta::FromMilliseconds(kIndicatorFrameIntervalMs);
  scoped_ptr<gfx::MultiAnimation> animation(
      new gfx::MultiAnimation(parts, interval));
  animation->set_continuous(false);
  return animation.PassAs<gfx::Animation>();
}

base::string16 AssembleTabTooltipText(const base::string16& title,
                                      TabMediaState media_state) {
  if (media_state == TAB_MEDIA_STATE_NONE)
    return title;

  base::string16 result = title;
  if (!result.empty())
    result.append(1, '\n');
  switch (media_state) {
    case TAB_MEDIA_STATE_AUDIO_PLAYING:
      result.append(
          l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_MEDIA_STATE_AUDIO_PLAYING));
      break;
    case TAB_MEDIA_STATE_RECORDING:
      result.append(
          l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_MEDIA_STATE_RECORDING));
      break;
    case TAB_MEDIA_STATE_CAPTURING:
      result.append(
          l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_MEDIA_STATE_CAPTURING));
      break;
    case TAB_MEDIA_STATE_NONE:
      NOTREACHED();
      break;
  }
  return result;
}

}  // namespace chrome
