// Copyright 2016 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 "cc/layers/painted_overlay_scrollbar_layer.h"

#include <algorithm>

#include "base/auto_reset.h"
#include "cc/base/math_util.h"
#include "cc/layers/painted_overlay_scrollbar_layer_impl.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSize.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/skia_util.h"

namespace cc {

std::unique_ptr<LayerImpl> PaintedOverlayScrollbarLayer::CreateLayerImpl(
    LayerTreeImpl* tree_impl) {
  return PaintedOverlayScrollbarLayerImpl::Create(
      tree_impl, id(), scrollbar_->Orientation(),
      scrollbar_->IsLeftSideVerticalScrollbar());
}

scoped_refptr<PaintedOverlayScrollbarLayer>
PaintedOverlayScrollbarLayer::Create(std::unique_ptr<Scrollbar> scrollbar,
                                     ElementId scroll_element_id) {
  return base::WrapRefCounted(new PaintedOverlayScrollbarLayer(
      std::move(scrollbar), scroll_element_id));
}

PaintedOverlayScrollbarLayer::PaintedOverlayScrollbarLayer(
    std::unique_ptr<Scrollbar> scrollbar,
    ElementId scroll_element_id)
    : scrollbar_(std::move(scrollbar)),
      scroll_element_id_(scroll_element_id),
      thumb_thickness_(scrollbar_->ThumbThickness()),
      thumb_length_(scrollbar_->ThumbLength()) {
  DCHECK(scrollbar_->UsesNinePatchThumbResource());
}

PaintedOverlayScrollbarLayer::~PaintedOverlayScrollbarLayer() = default;

void PaintedOverlayScrollbarLayer::SetScrollElementId(ElementId element_id) {
  if (element_id == scroll_element_id_)
    return;

  scroll_element_id_ = element_id;
  SetNeedsCommit();
}

bool PaintedOverlayScrollbarLayer::OpacityCanAnimateOnImplThread() const {
  return scrollbar_->IsOverlay();
}

void PaintedOverlayScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
  Layer::PushPropertiesTo(layer);

  PaintedOverlayScrollbarLayerImpl* scrollbar_layer =
      static_cast<PaintedOverlayScrollbarLayerImpl*>(layer);

  scrollbar_layer->SetScrollElementId(scroll_element_id_);

  scrollbar_layer->SetThumbThickness(thumb_thickness_);
  scrollbar_layer->SetThumbLength(thumb_length_);
  if (scrollbar_->Orientation() == HORIZONTAL) {
    scrollbar_layer->SetTrackStart(track_rect_.x() - location_.x());
    scrollbar_layer->SetTrackLength(track_rect_.width());
  } else {
    scrollbar_layer->SetTrackStart(track_rect_.y() - location_.y());
    scrollbar_layer->SetTrackLength(track_rect_.height());
  }

  if (thumb_resource_.get()) {
    scrollbar_layer->SetImageBounds(
        layer_tree_host()->GetUIResourceManager()->GetUIResourceSize(
            thumb_resource_->id()));
    scrollbar_layer->SetAperture(aperture_);
    scrollbar_layer->set_thumb_ui_resource_id(thumb_resource_->id());
  } else {
    scrollbar_layer->SetImageBounds(gfx::Size());
    scrollbar_layer->SetAperture(gfx::Rect());
    scrollbar_layer->set_thumb_ui_resource_id(0);
  }
}

ScrollbarLayerInterface* PaintedOverlayScrollbarLayer::ToScrollbarLayer() {
  return this;
}

void PaintedOverlayScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
  // When the LTH is set to null or has changed, then this layer should remove
  // all of its associated resources.
  if (host != layer_tree_host())
    thumb_resource_ = nullptr;

  Layer::SetLayerTreeHost(host);
}

gfx::Rect PaintedOverlayScrollbarLayer::OriginThumbRectForPainting() const {
  return gfx::Rect(gfx::Point(), scrollbar_->NinePatchThumbCanvasSize());
}

bool PaintedOverlayScrollbarLayer::Update() {
  bool updated = false;
  updated |= Layer::Update();

  DCHECK(scrollbar_->HasThumb());
  DCHECK(scrollbar_->IsOverlay());
  DCHECK(scrollbar_->UsesNinePatchThumbResource());
  updated |= UpdateProperty(scrollbar_->TrackRect(), &track_rect_);
  updated |= UpdateProperty(scrollbar_->Location(), &location_);
  updated |= UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_);
  updated |= UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_);
  updated |= PaintThumbIfNeeded();

  return updated;
}

bool PaintedOverlayScrollbarLayer::PaintThumbIfNeeded() {
  if (!scrollbar_->NeedsPaintPart(THUMB) && thumb_resource_)
    return false;

  gfx::Rect paint_rect = OriginThumbRectForPainting();
  aperture_ = scrollbar_->NinePatchThumbAperture();

  DCHECK(!paint_rect.size().IsEmpty());
  DCHECK(paint_rect.origin().IsOrigin());

  SkBitmap skbitmap;
  skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height());
  SkiaPaintCanvas canvas(skbitmap);

  SkRect content_skrect = RectToSkRect(paint_rect);
  PaintFlags flags;
  flags.setAntiAlias(false);
  flags.setBlendMode(SkBlendMode::kClear);
  canvas.drawRect(content_skrect, flags);
  canvas.clipRect(content_skrect);

  scrollbar_->PaintPart(&canvas, THUMB, paint_rect);
  // Make sure that the pixels are no longer mutable to unavoid unnecessary
  // allocation and copying.
  skbitmap.setImmutable();

  thumb_resource_ = ScopedUIResource::Create(
      layer_tree_host()->GetUIResourceManager(), UIResourceBitmap(skbitmap));

  SetNeedsPushProperties();

  return true;
}

}  // namespace cc
