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

#include "base/time/time.h"
#include "grit/ash_resources.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/wm/core/image_grid.h"

namespace {

// Final opacity for resize effect.
const float kShadowTargetOpacity = 0.25f;
// Animation time for resize effect in milliseconds.
const int kShadowAnimationDurationMs = 100;

// Sets up a layer as invisible and fully transparent, without animating.
void InitLayer(ui::Layer* layer) {
  layer->SetVisible(false);
  layer->SetOpacity(0.f);
}

// Triggers an opacity animation that will make |layer| become |visible|.
void ShowLayer(ui::Layer* layer, bool visible) {
  ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
  settings.SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
  layer->SetOpacity(visible ? kShadowTargetOpacity : 0.f);
  // Sets the layer visibility after a delay, which will be identical to the
  // opacity animation duration.
  layer->SetVisible(visible);
}

}  // namespace

namespace ash {

ResizeShadow::ResizeShadow() : last_hit_test_(HTNOWHERE) {}

ResizeShadow::~ResizeShadow() {}

void ResizeShadow::Init(aura::Window* window) {
  // Set up our image grid and images.
  ResourceBundle& res = ResourceBundle::GetSharedInstance();
  image_grid_.reset(new ::wm::ImageGrid);
  image_grid_->SetImages(
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP_LEFT),
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP),
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP_RIGHT),
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_LEFT),
      NULL,
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_RIGHT),
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM_LEFT),
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM),
      &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM_RIGHT));
  // Initialize all layers to invisible/transparent.
  InitLayer(image_grid_->top_left_layer());
  InitLayer(image_grid_->top_layer());
  InitLayer(image_grid_->top_right_layer());
  InitLayer(image_grid_->left_layer());
  InitLayer(image_grid_->right_layer());
  InitLayer(image_grid_->bottom_left_layer());
  InitLayer(image_grid_->bottom_layer());
  InitLayer(image_grid_->bottom_right_layer());
  // Add image grid as a child of the window's layer so it follows the window
  // as it moves.
  window->layer()->Add(image_grid_->layer());
}

void ResizeShadow::ShowForHitTest(int hit) {
  // Don't start animations unless something changed.
  if (hit == last_hit_test_)
    return;
  last_hit_test_ = hit;

  // Show affected corners.
  ShowLayer(image_grid_->top_left_layer(), hit == HTTOPLEFT);
  ShowLayer(image_grid_->top_right_layer(), hit == HTTOPRIGHT);
  ShowLayer(image_grid_->bottom_left_layer(), hit == HTBOTTOMLEFT);
  ShowLayer(image_grid_->bottom_right_layer(), hit == HTBOTTOMRIGHT);

  // Show affected edges.
  ShowLayer(image_grid_->top_layer(),
            hit == HTTOPLEFT || hit == HTTOP || hit == HTTOPRIGHT);
  ShowLayer(image_grid_->left_layer(),
            hit == HTTOPLEFT || hit == HTLEFT || hit == HTBOTTOMLEFT);
  ShowLayer(image_grid_->right_layer(),
            hit == HTTOPRIGHT || hit == HTRIGHT || hit == HTBOTTOMRIGHT);
  ShowLayer(image_grid_->bottom_layer(),
            hit == HTBOTTOMLEFT || hit == HTBOTTOM || hit == HTBOTTOMRIGHT);
}

void ResizeShadow::Hide() {
  ShowForHitTest(HTNOWHERE);
}

void ResizeShadow::Layout(const gfx::Rect& content_bounds) {
  gfx::Rect local_bounds(content_bounds.size());
  image_grid_->SetContentBounds(local_bounds);
}

}  // namespace ash
