/*
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/page/drag_image.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "skia/ext/image_operations.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_metrics.h"
#include "third_party/blink/renderer/platform/fonts/string_truncator.h"
#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_point.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/bidi_text_run.h"
#include "third_party/blink/renderer/platform/text/text_run.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

namespace blink {

namespace {

const float kDragLabelBorderX = 4;
// Keep border_y in synch with DragController::LinkDragBorderInset.
const float kDragLabelBorderY = 2;
const float kLabelBorderYOffset = 2;

const float kMaxDragLabelWidth = 300;
const float kMaxDragLabelStringWidth =
    (kMaxDragLabelWidth - 2 * kDragLabelBorderX);

const float kDragLinkLabelFontSize = 11;
const float kDragLinkUrlFontSize = 10;

}  // anonymous namespace

FloatSize DragImage::ClampedImageScale(const IntSize& image_size,
                                       const IntSize& size,
                                       const IntSize& max_size) {
  // Non-uniform scaling for size mapping.
  FloatSize image_scale(
      static_cast<float>(size.Width()) / image_size.Width(),
      static_cast<float>(size.Height()) / image_size.Height());

  // Uniform scaling for clamping.
  const float clamp_scale_x =
      size.Width() > max_size.Width()
          ? static_cast<float>(max_size.Width()) / size.Width()
          : 1;
  const float clamp_scale_y =
      size.Height() > max_size.Height()
          ? static_cast<float>(max_size.Height()) / size.Height()
          : 1;
  image_scale.Scale(std::min(clamp_scale_x, clamp_scale_y));

  return image_scale;
}

std::unique_ptr<DragImage> DragImage::Create(
    Image* image,
    RespectImageOrientationEnum should_respect_image_orientation,
    float device_scale_factor,
    InterpolationQuality interpolation_quality,
    float opacity,
    FloatSize image_scale) {
  if (!image)
    return nullptr;

  PaintImage paint_image = image->PaintImageForCurrentFrame();
  if (!paint_image)
    return nullptr;

  ImageOrientation orientation;
  auto* bitmap_image = DynamicTo<BitmapImage>(image);
  if (should_respect_image_orientation == kRespectImageOrientation &&
      bitmap_image)
    orientation = bitmap_image->CurrentFrameOrientation();

  SkBitmap bm;
  paint_image = Image::ResizeAndOrientImage(
      paint_image, orientation, image_scale, opacity, interpolation_quality);
  if (!paint_image || !paint_image.GetSwSkImage()->asLegacyBitmap(&bm))
    return nullptr;

  return base::WrapUnique(
      new DragImage(bm, device_scale_factor, interpolation_quality));
}

static Font DeriveDragLabelFont(int size,
                                FontSelectionValue font_weight,
                                const FontDescription& system_font) {
  FontDescription description = system_font;
  description.SetWeight(font_weight);
  description.SetSpecifiedSize(size);
  description.SetComputedSize(size);
  Font result(description);
  return result;
}

std::unique_ptr<DragImage> DragImage::Create(const KURL& url,
                                             const String& in_label,
                                             const FontDescription& system_font,
                                             float device_scale_factor) {
  const Font label_font = DeriveDragLabelFont(kDragLinkLabelFontSize,
                                              BoldWeightValue(), system_font);
  const SimpleFontData* label_font_data = label_font.PrimaryFont();
  DCHECK(label_font_data);
  const Font url_font = DeriveDragLabelFont(kDragLinkUrlFontSize,
                                            NormalWeightValue(), system_font);
  const SimpleFontData* url_font_data = url_font.PrimaryFont();
  DCHECK(url_font_data);

  if (!label_font_data || !url_font_data)
    return nullptr;

  FontCachePurgePreventer font_cache_purge_preventer;

  bool draw_url_string = true;
  bool clip_url_string = false;
  bool clip_label_string = false;
  float max_drag_label_string_width_dip =
      kMaxDragLabelStringWidth / device_scale_factor;

  String url_string = url.GetString();
  String label = in_label.StripWhiteSpace();
  if (label.IsEmpty()) {
    draw_url_string = false;
    label = url_string;
  }

  // First step is drawing the link drag image width.
  TextRun label_run(label.Impl());
  TextRun url_run(url_string.Impl());
  IntSize label_size(label_font.Width(label_run),
                     label_font_data->GetFontMetrics().Ascent() +
                         label_font_data->GetFontMetrics().Descent());

  if (label_size.Width() > max_drag_label_string_width_dip) {
    label_size.SetWidth(max_drag_label_string_width_dip);
    clip_label_string = true;
  }

  IntSize url_string_size;
  IntSize image_size(label_size.Width() + kDragLabelBorderX * 2,
                     label_size.Height() + kDragLabelBorderY * 2);

  if (draw_url_string) {
    url_string_size.SetWidth(url_font.Width(url_run));
    url_string_size.SetHeight(url_font_data->GetFontMetrics().Ascent() +
                              url_font_data->GetFontMetrics().Descent());
    image_size.SetHeight(image_size.Height() + url_string_size.Height());
    if (url_string_size.Width() > max_drag_label_string_width_dip) {
      image_size.SetWidth(max_drag_label_string_width_dip);
      clip_url_string = true;
    } else {
      image_size.SetWidth(
          std::max(label_size.Width(), url_string_size.Width()) +
          kDragLabelBorderX * 2);
    }
  }

  // We now know how big the image needs to be, so we create and
  // fill the background
  IntSize scaled_image_size = image_size;
  scaled_image_size.Scale(device_scale_factor);
  // TODO(fserb): are we sure this should be software?
  std::unique_ptr<CanvasResourceProvider> resource_provider(
      CanvasResourceProvider::CreateBitmapProvider(
          scaled_image_size, kLow_SkFilterQuality, CanvasResourceParams(),
          CanvasResourceProvider::ShouldInitialize::kNo));
  if (!resource_provider)
    return nullptr;

  resource_provider->Canvas()->scale(device_scale_factor, device_scale_factor);

  const float kDragLabelRadius = 5;

  IntRect rect(IntPoint(), image_size);
  PaintFlags background_paint;
  background_paint.setColor(SkColorSetRGB(140, 140, 140));
  background_paint.setAntiAlias(true);
  SkRRect rrect;
  rrect.setRectXY(SkRect::MakeWH(image_size.Width(), image_size.Height()),
                  kDragLabelRadius, kDragLabelRadius);
  resource_provider->Canvas()->drawRRect(rrect, background_paint);

  // Draw the text
  PaintFlags text_paint;
  if (draw_url_string) {
    if (clip_url_string)
      url_string = StringTruncator::CenterTruncate(
          url_string, image_size.Width() - (kDragLabelBorderX * 2.0f),
          url_font);
    FloatPoint text_pos(
        kDragLabelBorderX,
        image_size.Height() -
            (kLabelBorderYOffset + url_font_data->GetFontMetrics().Descent()));
    TextRun text_run(url_string);
    url_font.DrawText(resource_provider->Canvas(), TextRunPaintInfo(text_run),
                      text_pos, device_scale_factor, text_paint);
  }

  if (clip_label_string)
    label = StringTruncator::RightTruncate(
        label, image_size.Width() - (kDragLabelBorderX * 2.0f), label_font);

  bool has_strong_directionality;
  TextRun text_run =
      TextRunWithDirectionality(label, &has_strong_directionality);
  IntPoint text_pos(
      kDragLabelBorderX,
      kDragLabelBorderY + label_font.GetFontDescription().ComputedPixelSize());
  if (has_strong_directionality &&
      text_run.Direction() == TextDirection::kRtl) {
    float text_width = label_font.Width(text_run);
    int available_width = image_size.Width() - kDragLabelBorderX * 2;
    text_pos.SetX(available_width - ceilf(text_width));
  }
  label_font.DrawBidiText(resource_provider->Canvas(),
                          TextRunPaintInfo(text_run), FloatPoint(text_pos),
                          Font::kDoNotPaintIfFontNotReady, device_scale_factor,
                          text_paint);

  scoped_refptr<StaticBitmapImage> image = resource_provider->Snapshot();
  return DragImage::Create(image.get(), kRespectImageOrientation,
                           device_scale_factor);
}

DragImage::DragImage(const SkBitmap& bitmap,
                     float resolution_scale,
                     InterpolationQuality interpolation_quality)
    : bitmap_(bitmap),
      resolution_scale_(resolution_scale),
      interpolation_quality_(interpolation_quality) {}

DragImage::~DragImage() = default;

void DragImage::Scale(float scale_x, float scale_y) {
  skia::ImageOperations::ResizeMethod resize_method =
      interpolation_quality_ == kInterpolationNone
          ? skia::ImageOperations::RESIZE_BOX
          : skia::ImageOperations::RESIZE_LANCZOS3;
  int image_width = scale_x * bitmap_.width();
  int image_height = scale_y * bitmap_.height();
  bitmap_ = skia::ImageOperations::Resize(bitmap_, resize_method, image_width,
                                          image_height);
}

}  // namespace blink
