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

#include "grit/ui_resources.h"
#include "skia/ext/image_operations.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/dip_util.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/size_conversions.h"
#include "ui/views/corewm/shadow_types.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace internal {

namespace {
using views::Widget;

Widget* CreateDragWidget(gfx::NativeView context) {
  Widget* drag_widget = new Widget;
  Widget::InitParams params;
  params.type = Widget::InitParams::TYPE_TOOLTIP;
  params.keep_on_top = true;
  params.context = context;
  params.accept_events = false;
  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
  drag_widget->Init(params);
  drag_widget->SetOpacity(0xFF);
  drag_widget->GetNativeWindow()->set_owned_by_parent(false);
  drag_widget->GetNativeWindow()->SetName("DragWidget");
  SetShadowType(drag_widget->GetNativeView(), views::corewm::SHADOW_TYPE_NONE);
  return drag_widget;
}
}

DragImageView::DragImageView(gfx::NativeView context,
                             ui::DragDropTypes::DragEventSource event_source)
    : views::ImageView(),
      drag_event_source_(event_source),
      touch_drag_operation_(ui::DragDropTypes::DRAG_NONE) {
  widget_.reset(CreateDragWidget(context));
  widget_->SetContentsView(this);
  widget_->SetAlwaysOnTop(true);

  // We are owned by the DragDropController.
  set_owned_by_client();
}

DragImageView::~DragImageView() {
  widget_->Hide();
}

void DragImageView::SetBoundsInScreen(const gfx::Rect& bounds) {
  widget_->SetBounds(bounds);
  widget_size_ = bounds.size();
}

void DragImageView::SetScreenPosition(const gfx::Point& position) {
  widget_->SetBounds(gfx::Rect(position, widget_size_));
}

gfx::Rect DragImageView::GetBoundsInScreen() const {
  return widget_->GetWindowBoundsInScreen();
}

void DragImageView::SetWidgetVisible(bool visible) {
  if (visible != widget_->IsVisible()) {
    if (visible)
      widget_->Show();
    else
      widget_->Hide();
  }
}

void DragImageView::SetTouchDragOperationHintOff() {
  // Simply set the drag type to non-touch so that no hint is drawn.
  drag_event_source_ = ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
  SchedulePaint();
}

void DragImageView::SetTouchDragOperation(int operation) {
  if (touch_drag_operation_ == operation)
    return;
  touch_drag_operation_ = operation;
  SchedulePaint();
}

void DragImageView::SetTouchDragOperationHintPosition(
    const gfx::Point& position) {
  if (touch_drag_operation_indicator_position_ == position)
    return;
  touch_drag_operation_indicator_position_ = position;
  SchedulePaint();
}

void DragImageView::SetOpacity(float visibility) {
  DCHECK_GE(visibility, 0.0f);
  DCHECK_LE(visibility, 1.0f);
  widget_->SetOpacity(static_cast<int>(0xff * visibility));
}

void DragImageView::OnPaint(gfx::Canvas* canvas) {
  if (GetImage().isNull())
    return;

  // |widget_size_| is in DIP. ImageSkia::size() also returns the size in DIP.
  if (GetImage().size() == widget_size_) {
    canvas->DrawImageInt(GetImage(), 0, 0);
  } else {
    float device_scale = 1;
    if (widget_->GetNativeView() && widget_->GetNativeView()->layer()) {
      device_scale = ui::GetDeviceScaleFactor(
          widget_->GetNativeView()->layer());
    }
    // The drag image already has device scale factor applied. But
    // |widget_size_| is in DIP units.
    gfx::Size scaled_widget_size = gfx::ToRoundedSize(
        gfx::ScaleSize(widget_size_, device_scale));
    gfx::ImageSkiaRep image_rep = GetImage().GetRepresentation(device_scale);
    if (image_rep.is_null())
      return;
    SkBitmap scaled = skia::ImageOperations::Resize(
        image_rep.sk_bitmap(), skia::ImageOperations::RESIZE_LANCZOS3,
        scaled_widget_size.width(), scaled_widget_size.height());
    gfx::ImageSkia image_skia(gfx::ImageSkiaRep(scaled, device_scale));
    canvas->DrawImageInt(image_skia, 0, 0);
  }

  if (drag_event_source_ != ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH)
    return;

  // Select appropriate drag hint.
  gfx::Image* drag_hint =
      &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
      IDR_TOUCH_DRAG_TIP_NODROP);
  if (touch_drag_operation_ & ui::DragDropTypes::DRAG_COPY) {
    drag_hint = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_TOUCH_DRAG_TIP_COPY);
  } else if (touch_drag_operation_ & ui::DragDropTypes::DRAG_MOVE) {
    drag_hint = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_TOUCH_DRAG_TIP_MOVE);
  } else if (touch_drag_operation_ & ui::DragDropTypes::DRAG_LINK) {
    drag_hint = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_TOUCH_DRAG_TIP_LINK);
  }
  if (!drag_hint->IsEmpty()) {
    gfx::Size drag_hint_size = drag_hint->Size();

    // Enlarge widget if required to fit the drag hint image.
    if (drag_hint_size.width() > widget_size_.width() ||
        drag_hint_size.height() > widget_size_.height()) {
      gfx::Size new_widget_size = widget_size_;
      new_widget_size.SetToMax(drag_hint_size);
      widget_->SetSize(new_widget_size);
    }

    // Make sure drag hint image is positioned within the widget.
    gfx::Point drag_hint_position = touch_drag_operation_indicator_position_;
    drag_hint_position.Offset(-drag_hint_size.width() / 2, 0);
    gfx::Rect drag_hint_bounds(drag_hint_position, drag_hint_size);
    drag_hint_bounds.AdjustToFit(gfx::Rect(widget_size_));

    // Draw image.
    canvas->DrawImageInt(*(drag_hint->ToImageSkia()),
        drag_hint_bounds.x(), drag_hint_bounds.y());
  }
}

}  // namespace internal
}  // namespace ash
