// 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/gtk/throbber_gtk.h"

#include "base/logging.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "content/public/browser/notification_source.h"
#include "grit/ui_resources.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/image/cairo_cached_surface.h"

namespace {

// The length of a single cycle of the animation in milliseconds.
const int kThrobberDurationMs = 750;

}  // namespace

ThrobberGtk::ThrobberGtk(GtkThemeService* theme_service)
    : theme_service_(theme_service),
      animation_(this),
      num_frames_(0) {
  DCHECK(theme_service_);
  Init();
}

ThrobberGtk::~ThrobberGtk() {
  widget_.Destroy();
}

void ThrobberGtk::Start() {
  animation_.Show();
}

void ThrobberGtk::Stop() {
  animation_.Reset();
}

void ThrobberGtk::AnimationEnded(const gfx::Animation* animation) {
  animation_.Reset();
  animation_.Show();
}

void ThrobberGtk::AnimationProgressed(const gfx::Animation* animation) {
  gtk_widget_queue_draw(widget_.get());
}

void ThrobberGtk::Observe(int type,
                          const content::NotificationSource& source,
                          const content::NotificationDetails& details) {
  DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
  LoadFrames();
  gtk_widget_queue_draw(widget_.get());
}

gboolean ThrobberGtk::OnExpose(GtkWidget* widget, GdkEventExpose* expose) {
  cairo_t* cairo_context =
      gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget)));
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  cairo_translate(cairo_context, allocation.x, allocation.y);

  gfx::CairoCachedSurface* cairo_frames = frames_.ToCairo();
  const int frame =
      static_cast<int>(animation_.GetCurrentValue() * (num_frames_ - 1));
  const int image_size = cairo_frames->Height();
  const int image_offset = frame * image_size;

  cairo_frames->SetSource(cairo_context, widget, -image_offset, 0);
  cairo_rectangle(cairo_context, 0, 0, image_size, image_size);
  cairo_fill(cairo_context);
  cairo_destroy(cairo_context);

  return TRUE;
}

void ThrobberGtk::Init() {
  animation_.SetSlideDuration(kThrobberDurationMs);
  animation_.SetTweenType(gfx::Tween::LINEAR);
  widget_.Own(gtk_image_new());
  gtk_widget_set_can_focus(widget_.get(), FALSE);
  g_signal_connect(widget_.get(), "expose-event", G_CALLBACK(OnExposeThunk),
                   this);

  theme_service_->InitThemesFor(this);
  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
                 content::Source<ThemeService>(theme_service_));
}

void ThrobberGtk::LoadFrames() {
  frames_ = theme_service_->GetImageNamed(IDR_THROBBER);
  DCHECK(!frames_.IsEmpty());
  const int width = frames_.ToCairo()->Width();
  const int height = frames_.ToCairo()->Height();
  DCHECK_EQ(0, width % height);
  num_frames_ = width / height;

  gtk_widget_set_size_request(widget_.get(), height, height);
}
