// 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 "ash/wm/frame_painter.h"

#include <vector>

#include "ash/ash_constants.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace_controller.h"
#include "base/logging.h"  // DCHECK
#include "grit/ash_resources.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/base/animation/slide_animation.h"
#include "ui/base/hit_test.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

using aura::RootWindow;
using aura::Window;
using views::Widget;

namespace {
// TODO(jamescook): Border is specified to be a single pixel overlapping
// the web content and may need to be built into the shadow layers instead.
const int kBorderThickness = 0;
// Space between left edge of window and popup window icon.
const int kIconOffsetX = 9;
// Height and width of window icon.
const int kIconSize = 16;
// Space between the title text and the caption buttons.
const int kTitleLogoSpacing = 5;
// Space between window icon and title text.
const int kTitleIconOffsetX = 5;
// Space between window edge and title text, when there is no icon.
const int kTitleNoIconOffsetX = 8;
// Color for the non-maximized window title text.
const SkColor kNonMaximizedWindowTitleTextColor = SkColorSetRGB(40, 40, 40);
// Color for the maximized window title text.
const SkColor kMaximizedWindowTitleTextColor = SK_ColorWHITE;
// Size of header/content separator line below the header image.
const int kHeaderContentSeparatorSize = 1;
// Color of header bottom edge line.
const SkColor kHeaderContentSeparatorColor = SkColorSetRGB(128, 128, 128);
// Space between close button and right edge of window.
const int kCloseButtonOffsetX = 0;
// Space between close button and top edge of window.
const int kCloseButtonOffsetY = 0;
// The size and close buttons are designed to slightly overlap in order
// to do fancy hover highlighting.
const int kSizeButtonOffsetX = -1;
// In the pre-Ash era the web content area had a frame along the left edge, so
// user-generated theme images for the new tab page assume they are shifted
// right relative to the header.  Now that we have removed the left edge frame
// we need to copy the theme image for the window header from a few pixels
// inset to preserve alignment with the NTP image, or else we'll break a bunch
// of existing themes.  We do something similar on OS X for the same reason.
const int kThemeFrameImageInsetX = 5;
// Duration of crossfade animation for activating and deactivating frame.
const int kActivationCrossfadeDurationMs = 200;
// Alpha/opacity value for fully-opaque headers.
const int kFullyOpaque = 255;

// Tiles an image into an area, rounding the top corners. Samples |image|
// starting |image_inset_x| pixels from the left of the image.
void TileRoundRect(gfx::Canvas* canvas,
                   const gfx::ImageSkia& image,
                   const SkPaint& paint,
                   const gfx::Rect& bounds,
                   int top_left_corner_radius,
                   int top_right_corner_radius,
                   int image_inset_x) {
  SkRect rect = gfx::RectToSkRect(bounds);
  const SkScalar kTopLeftRadius = SkIntToScalar(top_left_corner_radius);
  const SkScalar kTopRightRadius = SkIntToScalar(top_right_corner_radius);
  SkScalar radii[8] = {
      kTopLeftRadius, kTopLeftRadius,  // top-left
      kTopRightRadius, kTopRightRadius,  // top-right
      0, 0,   // bottom-right
      0, 0};  // bottom-left
  SkPath path;
  path.addRoundRect(rect, radii, SkPath::kCW_Direction);
  canvas->DrawImageInPath(image, -image_inset_x, 0, path, paint);
}

// Tiles |frame_image| and |frame_overlay_image| into an area, rounding the top
// corners.
void PaintFrameImagesInRoundRect(gfx::Canvas* canvas,
                                 const gfx::ImageSkia* frame_image,
                                 const gfx::ImageSkia* frame_overlay_image,
                                 const SkPaint& paint,
                                 const gfx::Rect& bounds,
                                 int corner_radius,
                                 int image_inset_x) {
  SkXfermode::Mode normal_mode;
  SkXfermode::AsMode(NULL, &normal_mode);

  // If |paint| is using an unusual SkXfermode::Mode (this is the case while
  // crossfading), we must create a new canvas to overlay |frame_image| and
  // |frame_overlay_image| using |normal_mode| and then paint the result
  // using the unusual mode. We try to avoid this because creating a new
  // browser-width canvas is expensive.
  bool fast_path = (!frame_overlay_image ||
      SkXfermode::IsMode(paint.getXfermode(), normal_mode));
  if (fast_path) {
    TileRoundRect(canvas, *frame_image, paint, bounds, corner_radius,
        corner_radius, image_inset_x);

    if (frame_overlay_image) {
      // Adjust |bounds| such that |frame_overlay_image| is not tiled.
      gfx::Rect overlay_bounds = bounds;
      overlay_bounds.Intersect(
          gfx::Rect(bounds.origin(), frame_overlay_image->size()));
      int top_left_corner_radius = corner_radius;
      int top_right_corner_radius = corner_radius;
      if (overlay_bounds.width() < bounds.width() - corner_radius)
        top_right_corner_radius = 0;
      TileRoundRect(canvas, *frame_overlay_image, paint, overlay_bounds,
          top_left_corner_radius, top_right_corner_radius, 0);
    }
  } else {
    gfx::Canvas temporary_canvas(bounds.size(), canvas->scale_factor(), false);
    temporary_canvas.TileImageInt(*frame_image,
                                  image_inset_x, 0,
                                  0, 0,
                                  bounds.width(), bounds.height());
    temporary_canvas.DrawImageInt(*frame_overlay_image, 0, 0);
    TileRoundRect(canvas, gfx::ImageSkia(temporary_canvas.ExtractImageRep()),
        paint, bounds, corner_radius, corner_radius, 0);
  }
}

// Returns true if |child| and all ancestors are visible. Useful to ensure that
// a window is individually visible and is not part of a hidden workspace.
bool IsVisibleToRoot(Window* child) {
  for (Window* window = child; window; window = window->parent()) {
    // We must use TargetVisibility() because windows animate in and out and
    // IsVisible() also tracks the layer visibility state.
    if (!window->TargetVisibility())
      return false;
  }
  return true;
}

// Returns true if |window| is a "normal" window for purposes of solo window
// computations. Returns false for windows that are:
// * Not drawn (for example, DragDropTracker uses one for mouse capture)
// * Modal alerts (it looks odd for headers to change when an alert opens)
// * Constrained windows (ditto)
bool IsSoloWindowHeaderCandidate(aura::Window* window) {
  return window &&
      window->type() == aura::client::WINDOW_TYPE_NORMAL &&
      window->layer() &&
      window->layer()->type() != ui::LAYER_NOT_DRAWN &&
      window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_NONE &&
      !window->GetProperty(ash::kConstrainedWindowKey);
}

// Returns a list of windows in |root_window|| that potentially could have
// a transparent solo-window header.
std::vector<Window*> GetWindowsForSoloHeaderUpdate(RootWindow* root_window) {
  std::vector<Window*> windows;
  // During shutdown there may not be a workspace controller. In that case
  // we don't care about updating any windows.
  ash::internal::WorkspaceController* workspace_controller =
      ash::GetRootWindowController(root_window)->workspace_controller();
  if (workspace_controller) {
    // Avoid memory allocations for typical window counts.
    windows.reserve(16);
    // Collect windows from the active workspace.
    Window* workspace = workspace_controller->GetActiveWorkspaceWindow();
    windows.insert(windows.end(),
                   workspace->children().begin(),
                   workspace->children().end());
    // Collect "always on top" windows.
    Window* top_container =
        ash::Shell::GetContainer(
            root_window, ash::internal::kShellWindowId_AlwaysOnTopContainer);
    windows.insert(windows.end(),
                   top_container->children().begin(),
                   top_container->children().end());
  }
  return windows;
}
}  // namespace

namespace ash {

// static
int FramePainter::kActiveWindowOpacity = 255;  // 1.0
int FramePainter::kInactiveWindowOpacity = 255;  // 1.0
int FramePainter::kSoloWindowOpacity = 77;  // 0.3

///////////////////////////////////////////////////////////////////////////////
// FramePainter, public:

FramePainter::FramePainter()
    : frame_(NULL),
      window_icon_(NULL),
      size_button_(NULL),
      close_button_(NULL),
      window_(NULL),
      button_separator_(NULL),
      top_left_corner_(NULL),
      top_edge_(NULL),
      top_right_corner_(NULL),
      header_left_edge_(NULL),
      header_right_edge_(NULL),
      previous_theme_frame_id_(0),
      previous_theme_frame_overlay_id_(0),
      previous_opacity_(0),
      crossfade_theme_frame_id_(0),
      crossfade_theme_frame_overlay_id_(0),
      crossfade_opacity_(0),
      size_button_behavior_(SIZE_BUTTON_MAXIMIZES) {}

FramePainter::~FramePainter() {
  // Sometimes we are destroyed before the window closes, so ensure we clean up.
  if (window_) {
    window_->RemoveObserver(this);
  }
}

void FramePainter::Init(views::Widget* frame,
                        views::View* window_icon,
                        views::ImageButton* size_button,
                        views::ImageButton* close_button,
                        SizeButtonBehavior behavior) {
  DCHECK(frame);
  // window_icon may be NULL.
  DCHECK(size_button);
  DCHECK(close_button);
  frame_ = frame;
  window_icon_ = window_icon;
  size_button_ = size_button;
  close_button_ = close_button;
  size_button_behavior_ = behavior;

  // Window frame image parts.
  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  button_separator_ =
      rb.GetImageNamed(IDR_AURA_WINDOW_BUTTON_SEPARATOR).ToImageSkia();
  top_left_corner_ =
      rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP_LEFT).ToImageSkia();
  top_edge_ =
      rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP).ToImageSkia();
  top_right_corner_ =
      rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP_RIGHT).ToImageSkia();
  header_left_edge_ =
      rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_LEFT).ToImageSkia();
  header_right_edge_ =
      rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_RIGHT).ToImageSkia();

  window_ = frame->GetNativeWindow();
  gfx::Insets mouse_insets = gfx::Insets(-kResizeOutsideBoundsSize,
                                         -kResizeOutsideBoundsSize,
                                         -kResizeOutsideBoundsSize,
                                         -kResizeOutsideBoundsSize);
  gfx::Insets touch_insets = mouse_insets.Scale(
      kResizeOutsideBoundsScaleForTouch);
  // Ensure we get resize cursors for a few pixels outside our bounds.
  window_->SetHitTestBoundsOverrideOuter(mouse_insets, touch_insets);
  // Ensure we get resize cursors just inside our bounds as well.
  window_->set_hit_test_bounds_override_inner(mouse_insets);

  // Watch for maximize/restore/fullscreen state changes.  Observer removes
  // itself in OnWindowDestroying() below, or in the destructor if we go away
  // before the window.
  window_->AddObserver(this);

  // Solo-window header updates are handled by the workspace controller when
  // this window is added to the active workspace.
}

// static
void FramePainter::UpdateSoloWindowHeader(RootWindow* root_window) {
  // Use a separate function here so callers outside of FramePainter don't need
  // to know about "ignorable_window".
  UpdateSoloWindowInRoot(root_window, NULL /* ignorable_window */);
}

gfx::Rect FramePainter::GetBoundsForClientView(
    int top_height,
    const gfx::Rect& window_bounds) const {
  return gfx::Rect(
      kBorderThickness,
      top_height,
      std::max(0, window_bounds.width() - (2 * kBorderThickness)),
      std::max(0, window_bounds.height() - top_height - kBorderThickness));
}

gfx::Rect FramePainter::GetWindowBoundsForClientBounds(
    int top_height,
    const gfx::Rect& client_bounds) const {
  return gfx::Rect(std::max(0, client_bounds.x() - kBorderThickness),
                   std::max(0, client_bounds.y() - top_height),
                   client_bounds.width() + (2 * kBorderThickness),
                   client_bounds.height() + top_height + kBorderThickness);
}

int FramePainter::NonClientHitTest(views::NonClientFrameView* view,
                                   const gfx::Point& point) {
  gfx::Rect expanded_bounds = view->bounds();
  int outside_bounds = kResizeOutsideBoundsSize;

  if (aura::Env::GetInstance()->is_touch_down())
    outside_bounds *= kResizeOutsideBoundsScaleForTouch;
  expanded_bounds.Inset(-outside_bounds, -outside_bounds);

  if (!expanded_bounds.Contains(point))
    return HTNOWHERE;

  // No avatar button.

  // Check the frame first, as we allow a small area overlapping the contents
  // to be used for resize handles.
  bool can_ever_resize = frame_->widget_delegate() ?
      frame_->widget_delegate()->CanResize() :
      false;
  // Don't allow overlapping resize handles when the window is maximized or
  // fullscreen, as it can't be resized in those states.
  int resize_border =
      frame_->IsMaximized() || frame_->IsFullscreen() ? 0 :
      kResizeInsideBoundsSize;
  int frame_component = view->GetHTComponentForFrame(point,
                                                     resize_border,
                                                     resize_border,
                                                     kResizeAreaCornerSize,
                                                     kResizeAreaCornerSize,
                                                     can_ever_resize);
  if (frame_component != HTNOWHERE)
    return frame_component;

  int client_component = frame_->client_view()->NonClientHitTest(point);
  if (client_component != HTNOWHERE)
    return client_component;

  // Then see if the point is within any of the window controls.
  if (close_button_->visible() &&
      close_button_->GetMirroredBounds().Contains(point))
    return HTCLOSE;
  if (size_button_->visible() &&
      size_button_->GetMirroredBounds().Contains(point))
    return HTMAXBUTTON;

  // Caption is a safe default.
  return HTCAPTION;
}

gfx::Size FramePainter::GetMinimumSize(views::NonClientFrameView* view) {
  gfx::Size min_size = frame_->client_view()->GetMinimumSize();
  // Ensure we can display the top of the caption area.
  gfx::Rect client_bounds = view->GetBoundsForClientView();
  min_size.Enlarge(0, client_bounds.y());
  // Ensure we have enough space for the window icon and buttons.  We allow
  // the title string to collapse to zero width.
  int title_width = GetTitleOffsetX() +
      size_button_->width() + kSizeButtonOffsetX +
      close_button_->width() + kCloseButtonOffsetX;
  if (title_width > min_size.width())
    min_size.set_width(title_width);
  return min_size;
}

gfx::Size FramePainter::GetMaximumSize(views::NonClientFrameView* view) {
  return frame_->client_view()->GetMaximumSize();
}

int FramePainter::GetRightInset() const {
  gfx::Size close_size = close_button_->GetPreferredSize();
  gfx::Size size_button_size = size_button_->GetPreferredSize();
  int inset = close_size.width() + kCloseButtonOffsetX +
      size_button_size.width() + kSizeButtonOffsetX;
  return inset;
}

int FramePainter::GetThemeBackgroundXInset() const {
  return kThemeFrameImageInsetX;
}

bool FramePainter::ShouldUseMinimalHeaderStyle(Themed header_themed) const {
  // Use the minimalistic header style whenever |frame_| is maximized or
  // fullscreen EXCEPT:
  // - If the user has installed a theme with custom images for the header.
  // - For windows whose workspace is not tracked by the workspace code (which
  //   are used for tab dragging).
  // - When the user is cycling through workspaces.
  return ((frame_->IsMaximized() || frame_->IsFullscreen()) &&
      header_themed == THEMED_NO &&
      GetTrackedByWorkspace(frame_->GetNativeWindow()));
}

void FramePainter::PaintHeader(views::NonClientFrameView* view,
                               gfx::Canvas* canvas,
                               HeaderMode header_mode,
                               int theme_frame_id,
                               int theme_frame_overlay_id) {
  bool initial_paint = (previous_theme_frame_id_ == 0);
  if (!initial_paint &&
      (previous_theme_frame_id_ != theme_frame_id ||
       previous_theme_frame_overlay_id_ != theme_frame_overlay_id)) {
    aura::Window* parent = frame_->GetNativeWindow()->parent();
    // Don't animate the header if the parent (a workspace) is already
    // animating. Doing so results in continually painting during the animation
    // and gives a slower frame rate.
    // TODO(sky): expose a better way to determine this rather than assuming
    // the parent is a workspace.
    bool parent_animating = parent &&
        (parent->layer()->GetAnimator()->IsAnimatingProperty(
            ui::LayerAnimationElement::OPACITY) ||
         parent->layer()->GetAnimator()->IsAnimatingProperty(
             ui::LayerAnimationElement::VISIBILITY));
    if (!parent_animating) {
      crossfade_animation_.reset(new ui::SlideAnimation(this));
      crossfade_theme_frame_id_ = previous_theme_frame_id_;
      crossfade_theme_frame_overlay_id_ = previous_theme_frame_overlay_id_;
      crossfade_opacity_ = previous_opacity_;
      crossfade_animation_->SetSlideDuration(kActivationCrossfadeDurationMs);
      crossfade_animation_->Show();
    } else {
      crossfade_animation_.reset();
    }
  }

  int opacity =
      GetHeaderOpacity(header_mode, theme_frame_id, theme_frame_overlay_id);
  ui::ThemeProvider* theme_provider = frame_->GetThemeProvider();
  gfx::ImageSkia* theme_frame = theme_provider->GetImageSkiaNamed(
      theme_frame_id);
  gfx::ImageSkia* theme_frame_overlay = NULL;
  if (theme_frame_overlay_id != 0) {
    theme_frame_overlay = theme_provider->GetImageSkiaNamed(
        theme_frame_overlay_id);
  }
  header_frame_bounds_ = gfx::Rect(0, 0, view->width(), theme_frame->height());

  const int kCornerRadius = 2;
  SkPaint paint;

  if (crossfade_animation_.get() && crossfade_animation_->is_animating()) {
    gfx::ImageSkia* crossfade_theme_frame =
        theme_provider->GetImageSkiaNamed(crossfade_theme_frame_id_);
    gfx::ImageSkia* crossfade_theme_frame_overlay = NULL;
    if (crossfade_theme_frame_overlay_id_ != 0) {
      crossfade_theme_frame_overlay = theme_provider->GetImageSkiaNamed(
          crossfade_theme_frame_overlay_id_);
    }
    if (!crossfade_theme_frame ||
        (crossfade_theme_frame_overlay_id_ != 0 &&
         !crossfade_theme_frame_overlay)) {
      // Reset the animation. This case occurs when the user switches the theme
      // that they are using.
      crossfade_animation_.reset();
      paint.setAlpha(opacity);
    } else {
      double current_value = crossfade_animation_->GetCurrentValue();
      int old_alpha = (1 - current_value) * crossfade_opacity_;
      int new_alpha = current_value * opacity;

      // Draw the old header background, clipping the corners to be rounded.
      paint.setAlpha(old_alpha);
      paint.setXfermodeMode(SkXfermode::kPlus_Mode);
      PaintFrameImagesInRoundRect(canvas,
                                  crossfade_theme_frame,
                                  crossfade_theme_frame_overlay,
                                  paint,
                                  header_frame_bounds_,
                                  kCornerRadius,
                                  GetThemeBackgroundXInset());

      paint.setAlpha(new_alpha);
    }
  } else {
    paint.setAlpha(opacity);
  }

  // Draw the header background, clipping the corners to be rounded.
  PaintFrameImagesInRoundRect(canvas,
                              theme_frame,
                              theme_frame_overlay,
                              paint,
                              header_frame_bounds_,
                              kCornerRadius,
                              GetThemeBackgroundXInset());

  previous_theme_frame_id_ = theme_frame_id;
  previous_theme_frame_overlay_id_ = theme_frame_overlay_id;
  previous_opacity_ = opacity;

  // Separator between the maximize and close buttons.  It overlaps the left
  // edge of the close button.
  gfx::Rect divider(close_button_->x(), close_button_->y(),
                    button_separator_->width(), close_button_->height());
  canvas->DrawImageInt(*button_separator_,
                       view->GetMirroredXForRect(divider),
                       close_button_->y());

  // We don't need the extra lightness in the edges when we're at the top edge
  // of the screen or maximized. We have the maximized check as during
  // animations the bounds may not be at 0, but the border shouldn't be drawn.
  //
  // TODO(sky): this isn't quite right. What we really want is a method that
  // returns bounds ignoring transforms on certain windows (such as workspaces)
  // and is relative to the root.
  if (frame_->GetNativeWindow()->bounds().y() == 0 ||
      frame_->IsMaximized() ||
      frame_->IsFullscreen())
    return;

  // Draw the top corners and edge.
  int top_left_height = top_left_corner_->height();
  canvas->DrawImageInt(*top_left_corner_,
                       0, 0, top_left_corner_->width(), top_left_height,
                       0, 0, top_left_corner_->width(), top_left_height,
                       false);
  canvas->TileImageInt(*top_edge_,
      top_left_corner_->width(),
      0,
      view->width() - top_left_corner_->width() - top_right_corner_->width(),
      top_edge_->height());
  int top_right_height = top_right_corner_->height();
  canvas->DrawImageInt(*top_right_corner_,
                       0, 0,
                       top_right_corner_->width(), top_right_height,
                       view->width() - top_right_corner_->width(), 0,
                       top_right_corner_->width(), top_right_height,
                       false);

  // Header left edge.
  int header_left_height = theme_frame->height() - top_left_height;
  canvas->TileImageInt(*header_left_edge_,
                       0, top_left_height,
                       header_left_edge_->width(), header_left_height);

  // Header right edge.
  int header_right_height = theme_frame->height() - top_right_height;
  canvas->TileImageInt(*header_right_edge_,
                       view->width() - header_right_edge_->width(),
                       top_right_height,
                       header_right_edge_->width(),
                       header_right_height);

  // We don't draw edges around the content area.  Web content goes flush
  // to the edge of the window.
}

void FramePainter::PaintHeaderContentSeparator(views::NonClientFrameView* view,
                                               gfx::Canvas* canvas) {
  // Paint the line just above the content area.
  gfx::Rect client_bounds = view->GetBoundsForClientView();
  canvas->FillRect(gfx::Rect(client_bounds.x(),
                             client_bounds.y() - kHeaderContentSeparatorSize,
                             client_bounds.width(),
                             kHeaderContentSeparatorSize),
                   kHeaderContentSeparatorColor);
}

int FramePainter::HeaderContentSeparatorSize() const {
  return kHeaderContentSeparatorSize;
}

void FramePainter::PaintTitleBar(views::NonClientFrameView* view,
                                 gfx::Canvas* canvas,
                                 const gfx::Font& title_font) {
  // The window icon is painted by its own views::View.
  views::WidgetDelegate* delegate = frame_->widget_delegate();
  if (delegate && delegate->ShouldShowWindowTitle()) {
    gfx::Rect title_bounds = GetTitleBounds(title_font);
    SkColor title_color = frame_->IsMaximized() ?
        kMaximizedWindowTitleTextColor : kNonMaximizedWindowTitleTextColor;
    canvas->DrawStringInt(delegate->GetWindowTitle(),
                          title_font,
                          title_color,
                          view->GetMirroredXForRect(title_bounds),
                          title_bounds.y(),
                          title_bounds.width(),
                          title_bounds.height(),
                          gfx::Canvas::NO_SUBPIXEL_RENDERING);
  }
}

void FramePainter::LayoutHeader(views::NonClientFrameView* view,
                                bool shorter_layout) {
  // The new assets only make sense if the window is actually maximized or
  // fullscreen.
  if (shorter_layout &&
      (frame_->IsMaximized() || frame_->IsFullscreen()) &&
      GetTrackedByWorkspace(frame_->GetNativeWindow())) {
    SetButtonImages(close_button_,
                    IDR_AURA_WINDOW_MAXIMIZED_CLOSE2,
                    IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_H,
                    IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_P);
    // The chat window cannot be restored but only minimized.
    if (size_button_behavior_ == SIZE_BUTTON_MINIMIZES) {
      SetButtonImages(size_button_,
                      IDR_AURA_WINDOW_MINIMIZE_SHORT,
                      IDR_AURA_WINDOW_MINIMIZE_SHORT_H,
                      IDR_AURA_WINDOW_MINIMIZE_SHORT_P);
    } else {
      SetButtonImages(size_button_,
                      IDR_AURA_WINDOW_MAXIMIZED_RESTORE2,
                      IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_H,
                      IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_P);
    }
  } else if (shorter_layout) {
    SetButtonImages(close_button_,
                    IDR_AURA_WINDOW_MAXIMIZED_CLOSE,
                    IDR_AURA_WINDOW_MAXIMIZED_CLOSE_H,
                    IDR_AURA_WINDOW_MAXIMIZED_CLOSE_P);
    // The chat window cannot be restored but only minimized.
    if (size_button_behavior_ == SIZE_BUTTON_MINIMIZES) {
      SetButtonImages(size_button_,
                      IDR_AURA_WINDOW_MINIMIZE_SHORT,
                      IDR_AURA_WINDOW_MINIMIZE_SHORT_H,
                      IDR_AURA_WINDOW_MINIMIZE_SHORT_P);
    } else {
      SetButtonImages(size_button_,
                      IDR_AURA_WINDOW_MAXIMIZED_RESTORE,
                      IDR_AURA_WINDOW_MAXIMIZED_RESTORE_H,
                      IDR_AURA_WINDOW_MAXIMIZED_RESTORE_P);
    }
  } else {
    SetButtonImages(close_button_,
                    IDR_AURA_WINDOW_CLOSE,
                    IDR_AURA_WINDOW_CLOSE_H,
                    IDR_AURA_WINDOW_CLOSE_P);
    SetButtonImages(size_button_,
                    IDR_AURA_WINDOW_MAXIMIZE,
                    IDR_AURA_WINDOW_MAXIMIZE_H,
                    IDR_AURA_WINDOW_MAXIMIZE_P);
  }

  gfx::Size close_size = close_button_->GetPreferredSize();
  close_button_->SetBounds(
      view->width() - close_size.width() - kCloseButtonOffsetX,
      kCloseButtonOffsetY,
      close_size.width(),
      close_size.height());

  gfx::Size size_button_size = size_button_->GetPreferredSize();
  size_button_->SetBounds(
      close_button_->x() - size_button_size.width() - kSizeButtonOffsetX,
      close_button_->y(),
      size_button_size.width(),
      size_button_size.height());

  if (window_icon_) {
    // Vertically center the window icon with respect to the close button.
    int icon_offset_y = GetCloseButtonCenterY() - window_icon_->height() / 2;
    window_icon_->SetBounds(kIconOffsetX, icon_offset_y, kIconSize, kIconSize);
  }
}

void FramePainter::SchedulePaintForTitle(const gfx::Font& title_font) {
  frame_->non_client_view()->SchedulePaintInRect(GetTitleBounds(title_font));
}

void FramePainter::OnThemeChanged() {
  // We do not cache the images for |previous_theme_frame_id_| and
  // |previous_theme_frame_overlay_id_|. Changing the theme changes the images
  // returned from ui::ThemeProvider for |previous_theme_frame_id_|
  // and |previous_theme_frame_overlay_id_|. Reset the image ids to prevent
  // starting a crossfade animation with these images.
  previous_theme_frame_id_ = 0;
  previous_theme_frame_overlay_id_ = 0;

  if (crossfade_animation_.get() && crossfade_animation_->is_animating()) {
    crossfade_animation_.reset();
    frame_->non_client_view()->SchedulePaintInRect(header_frame_bounds_);
  }
}

///////////////////////////////////////////////////////////////////////////////
// aura::WindowObserver overrides:

void FramePainter::OnWindowPropertyChanged(aura::Window* window,
                                           const void* key,
                                           intptr_t old) {
  // When 'kWindowTrackedByWorkspaceKey' changes, we are going to paint the
  // header differently. Schedule a paint to ensure everything is updated
  // correctly.
  if (key == internal::kWindowTrackedByWorkspaceKey &&
      GetTrackedByWorkspace(window)) {
    frame_->non_client_view()->SchedulePaint();
  }

  if (key != aura::client::kShowStateKey)
    return;

  // Maximized and fullscreen windows don't want resize handles overlapping the
  // content area, because when the user moves the cursor to the right screen
  // edge we want them to be able to hit the scroll bar.
  if (ash::wm::IsWindowMaximized(window) ||
      ash::wm::IsWindowFullscreen(window)) {
    window->set_hit_test_bounds_override_inner(gfx::Insets());
  } else {
    window->set_hit_test_bounds_override_inner(
        gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize,
                    kResizeInsideBoundsSize, kResizeInsideBoundsSize));
  }
}

void FramePainter::OnWindowVisibilityChanged(aura::Window* window,
                                             bool visible) {
  // Window visibility change may trigger the change of window solo-ness in a
  // different window.
  UpdateSoloWindowInRoot(window_->GetRootWindow(), visible ? NULL : window_);
}

void FramePainter::OnWindowDestroying(aura::Window* destroying) {
  DCHECK_EQ(window_, destroying);

  // Must be removed here and not in the destructor, as the aura::Window is
  // already destroyed when our destructor runs.
  window_->RemoveObserver(this);

  // If we have two or more windows open and we close this one, we might trigger
  // the solo window appearance for another window.
  UpdateSoloWindowInRoot(window_->GetRootWindow(), window_);

  window_ = NULL;
}

void FramePainter::OnWindowBoundsChanged(aura::Window* window,
                                         const gfx::Rect& old_bounds,
                                         const gfx::Rect& new_bounds) {
  // TODO(sky): this isn't quite right. What we really want is a method that
  // returns bounds ignoring transforms on certain windows (such as workspaces).
  if ((!frame_->IsMaximized() && !frame_->IsFullscreen()) &&
      ((old_bounds.y() == 0 && new_bounds.y() != 0) ||
       (old_bounds.y() != 0 && new_bounds.y() == 0))) {
    SchedulePaintForHeader();
  }
}

void FramePainter::OnWindowAddedToRootWindow(aura::Window* window) {
  // Needs to trigger the window appearance change if the window moves across
  // root windows and a solo window is already in the new root.
  UpdateSoloWindowInRoot(window->GetRootWindow(), NULL /* ignore_window */);
}

void FramePainter::OnWindowRemovingFromRootWindow(aura::Window* window) {
  // Needs to trigger the window appearance change if the window moves across
  // root windows and only one window is left in the previous root.  Because
  // |window| is not yet moved, |window| has to be ignored.
  UpdateSoloWindowInRoot(window->GetRootWindow(), window);
}

///////////////////////////////////////////////////////////////////////////////
// ui::AnimationDelegate overrides:

void FramePainter::AnimationProgressed(const ui::Animation* animation) {
  frame_->non_client_view()->SchedulePaintInRect(header_frame_bounds_);
}

///////////////////////////////////////////////////////////////////////////////
// FramePainter, private:

void FramePainter::SetButtonImages(views::ImageButton* button,
                                   int normal_image_id,
                                   int hot_image_id,
                                   int pushed_image_id) {
  ui::ThemeProvider* theme_provider = frame_->GetThemeProvider();
  button->SetImage(views::CustomButton::STATE_NORMAL,
                   theme_provider->GetImageSkiaNamed(normal_image_id));
  button->SetImage(views::CustomButton::STATE_HOVERED,
                   theme_provider->GetImageSkiaNamed(hot_image_id));
  button->SetImage(views::CustomButton::STATE_PRESSED,
                   theme_provider->GetImageSkiaNamed(pushed_image_id));
}

void FramePainter::SetToggledButtonImages(views::ToggleImageButton* button,
                                          int normal_image_id,
                                          int hot_image_id,
                                          int pushed_image_id) {
  ui::ThemeProvider* theme_provider = frame_->GetThemeProvider();
  button->SetToggledImage(views::CustomButton::STATE_NORMAL,
                          theme_provider->GetImageSkiaNamed(normal_image_id));
  button->SetToggledImage(views::CustomButton::STATE_HOVERED,
                          theme_provider->GetImageSkiaNamed(hot_image_id));
  button->SetToggledImage(views::CustomButton::STATE_PRESSED,
                          theme_provider->GetImageSkiaNamed(pushed_image_id));
}

int FramePainter::GetTitleOffsetX() const {
  return window_icon_ ?
      window_icon_->bounds().right() + kTitleIconOffsetX :
      kTitleNoIconOffsetX;
}

int FramePainter::GetCloseButtonCenterY() const {
  return close_button_->y() + close_button_->height() / 2;
}

int FramePainter::GetHeaderOpacity(
    HeaderMode header_mode,
    int theme_frame_id,
    int theme_frame_overlay_id) const {
  // User-provided themes are painted fully opaque.
  ui::ThemeProvider* theme_provider = frame_->GetThemeProvider();
  if (theme_provider->HasCustomImage(theme_frame_id) ||
      (theme_frame_overlay_id != 0 &&
       theme_provider->HasCustomImage(theme_frame_overlay_id))) {
    return kFullyOpaque;
  }

  // The header is fully opaque when using the minimalistic header style.
  if (ShouldUseMinimalHeaderStyle(THEMED_NO))
    return kFullyOpaque;

  // Single browser window is very transparent.
  if (UseSoloWindowHeader())
    return kSoloWindowOpacity;

  // Otherwise, change transparency based on window activation status.
  if (header_mode == ACTIVE)
    return kActiveWindowOpacity;
  return kInactiveWindowOpacity;
}

bool FramePainter::UseSoloWindowHeader() const {
  // Don't use transparent headers for panels, pop-ups, etc.
  if (!IsSoloWindowHeaderCandidate(window_))
    return false;
  aura::RootWindow* root = window_->GetRootWindow();
  if (!root || root->GetProperty(internal::kIgnoreSoloWindowFramePainterPolicy))
    return false;
  // Don't recompute every time, as it would require many window property
  // lookups.
  return root->GetProperty(internal::kSoloWindowHeaderKey);
}

// static
bool FramePainter::UseSoloWindowHeaderInRoot(RootWindow* root_window,
                                             Window* ignore_window) {
  int visible_window_count = 0;
  std::vector<Window*> windows = GetWindowsForSoloHeaderUpdate(root_window);
  for (std::vector<Window*>::const_iterator it = windows.begin();
       it != windows.end();
       ++it) {
    Window* window = *it;
    // Various sorts of windows "don't count" for this computation.
    if (ignore_window == window ||
        !IsSoloWindowHeaderCandidate(window) ||
        !IsVisibleToRoot(window))
      continue;
    if (wm::IsWindowMaximized(window))
      return false;
    ++visible_window_count;
    if (visible_window_count > 1)
      return false;
  }
  // Count must be tested because all windows might be "don't count" windows
  // in the loop above.
  return visible_window_count == 1;
}

// static
void FramePainter::UpdateSoloWindowInRoot(RootWindow* root,
                                          Window* ignore_window) {
#if defined(OS_WIN)
  // Non-Ash Windows doesn't do solo-window counting for transparency effects,
  // as the desktop background and window frames are managed by the OS.
  if (!ash::Shell::HasInstance())
    return;
#endif
  if (!root)
    return;
  bool old_solo_header = root->GetProperty(internal::kSoloWindowHeaderKey);
  bool new_solo_header = UseSoloWindowHeaderInRoot(root, ignore_window);
  if (old_solo_header == new_solo_header)
    return;
  root->SetProperty(internal::kSoloWindowHeaderKey, new_solo_header);
  // Invalidate all the window frames in the active workspace. There should
  // only be a few.
  std::vector<Window*> windows = GetWindowsForSoloHeaderUpdate(root);
  for (std::vector<Window*>::const_iterator it = windows.begin();
       it != windows.end();
       ++it) {
    Widget* widget = Widget::GetWidgetForNativeWindow(*it);
    if (widget && widget->non_client_view())
      widget->non_client_view()->SchedulePaint();
  }
}

void FramePainter::SchedulePaintForHeader() {
  int top_left_height = top_left_corner_->height();
  int top_right_height = top_right_corner_->height();
  frame_->non_client_view()->SchedulePaintInRect(
      gfx::Rect(0, 0, frame_->non_client_view()->width(),
                std::max(top_left_height, top_right_height)));
}

gfx::Rect FramePainter::GetTitleBounds(const gfx::Font& title_font) {
  int title_x = GetTitleOffsetX();
  // Center the text with respect to the close button. This way it adapts to
  // the caption height and aligns exactly with the window icon. Don't use
  // |window_icon_| for this computation as it may be NULL.
  int title_y = GetCloseButtonCenterY() - title_font.GetHeight() / 2;
  return gfx::Rect(
      title_x,
      std::max(0, title_y),
      std::max(0, size_button_->x() - kTitleLogoSpacing - title_x),
      title_font.GetHeight());
}

}  // namespace ash
