// 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/launcher/overflow_button.h"

#include "ash/ash_switches.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_widget.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/base/animation/throb_animation.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace internal {

namespace {

const int kButtonHoverAlpha = 150;

const int kButtonCornerRadius = 2;

const int kButtonHoverSize = 28;

const int kBackgroundOffset = (48 - kButtonHoverSize) / 2;

// Padding from the inner edge of the shelf (towards center of display) to
// the edge of the background image of the overflow button.
const int kImagePaddingFromShelf = 5;

}  // namesapce

OverflowButton::OverflowButton(views::ButtonListener* listener)
    : CustomButton(listener),
      bottom_image_(NULL) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  bottom_image_ = rb.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW).ToImageSkia();


  set_accessibility_focusable(true);
  SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME));
}

OverflowButton::~OverflowButton() {}

void OverflowButton::OnShelfAlignmentChanged() {
  SchedulePaint();
}

void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) {
  gfx::Rect bounds(GetContentsBounds());
  gfx::Rect rect(0, 0, kButtonHoverSize, kButtonHoverSize);
  ShelfLayoutManager* shelf =
      ShelfLayoutManager::ForLauncher(GetWidget()->GetNativeView());

  // Nudge the background a little to line up right.
  if (shelf->IsHorizontalAlignment()) {
    rect.set_origin(gfx::Point(
        bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1,
        bounds.y() + kBackgroundOffset - 1));

  } else {
    rect.set_origin(gfx::Point(
        bounds.x() + kBackgroundOffset - 1,
        bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) - 1));
  }

  SkPaint paint;
  paint.setAntiAlias(true);
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(SkColorSetARGB(
      kButtonHoverAlpha * hover_animation_->GetCurrentValue(),
      0, 0, 0));

  const SkScalar radius = SkIntToScalar(kButtonCornerRadius);
  SkPath path;
  path.addRoundRect(gfx::RectToSkRect(rect), radius, radius);
  canvas->DrawPath(path, paint);
}

void OverflowButton::OnPaint(gfx::Canvas* canvas) {
  ShelfLayoutManager* layout_manager = ShelfLayoutManager::ForLauncher(
      GetWidget()->GetNativeView());
  ShelfAlignment alignment = layout_manager->GetAlignment();

  gfx::Rect bounds(GetContentsBounds());
  if (ash::switches::UseAlternateShelfLayout()) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    int background_image_id = 0;
    if (layout_manager->shelf_widget()->launcher()->IsShowingOverflowBubble())
      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
    else if(layout_manager->shelf_widget()->GetDimsShelf())
      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
    else
      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;

    const gfx::ImageSkia* background =
        rb.GetImageNamed(background_image_id).ToImageSkia();
    if (alignment == SHELF_ALIGNMENT_LEFT) {
      bounds = gfx::Rect(
          bounds.right() - background->width() - kImagePaddingFromShelf,
          bounds.y() + (bounds.height() - background->height()) / 2,
          background->width(), background->height());
    } else if (alignment == SHELF_ALIGNMENT_RIGHT) {
      bounds = gfx::Rect(
          bounds.x() + kImagePaddingFromShelf,
          bounds.y() + (bounds.height() - background->height()) / 2,
          background->width(), background->height());
    } else {
      bounds = gfx::Rect(
          bounds.x() + (bounds.width() - background->width()) / 2,
          bounds.y() + kImagePaddingFromShelf,
          background->width(), background->height());
    }
    canvas->DrawImageInt(*background, bounds.x(), bounds.y());
  } else {
    if (alignment == SHELF_ALIGNMENT_BOTTOM) {
      bounds = gfx::Rect(
          bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1,
          bounds.y() + kBackgroundOffset - 1,
          kButtonHoverSize, kButtonHoverSize);
    } else {
      bounds = gfx::Rect(
          bounds.x() + kBackgroundOffset -1,
          bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) -1,
          kButtonHoverSize, kButtonHoverSize);
    }
    if (hover_animation_->is_animating()) {
      PaintBackground(
          canvas,
          kButtonHoverAlpha * hover_animation_->GetCurrentValue());
    } else if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
      PaintBackground(canvas, kButtonHoverAlpha);
    }
  }

  if (height() < kButtonHoverSize)
    return;

  const gfx::ImageSkia* image = NULL;

  switch(alignment) {
    case SHELF_ALIGNMENT_LEFT:
      if (left_image_.isNull()) {
        left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
            *bottom_image_, SkBitmapOperations::ROTATION_90_CW);
      }
      image = &left_image_;
      break;
    case SHELF_ALIGNMENT_RIGHT:
      if (right_image_.isNull()) {
        right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
            *bottom_image_, SkBitmapOperations::ROTATION_270_CW);
      }
      image = &right_image_;
      break;
    default:
      image = bottom_image_;
      break;
  }

  canvas->DrawImageInt(*image,
                       bounds.x() + ((bounds.width() - image->width()) / 2),
                       bounds.y() + ((bounds.height() - image->height()) / 2));
}

}  // namespace internal
}  // namespace ash
