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

#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "cc/base/math_util.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/occlusion.h"
#include "ui/gfx/geometry/rect_f.h"

namespace cc {

NinePatchLayerImpl::NinePatchLayerImpl(LayerTreeImpl* tree_impl, int id)
    : UIResourceLayerImpl(tree_impl, id),
      fill_center_(false),
      nearest_neighbor_(false) {}

NinePatchLayerImpl::~NinePatchLayerImpl() {}

scoped_ptr<LayerImpl> NinePatchLayerImpl::CreateLayerImpl(
    LayerTreeImpl* tree_impl) {
  return NinePatchLayerImpl::Create(tree_impl, id());
}

void NinePatchLayerImpl::PushPropertiesTo(LayerImpl* layer) {
  UIResourceLayerImpl::PushPropertiesTo(layer);
  NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);

  layer_impl->SetLayout(image_aperture_, border_, fill_center_,
                        nearest_neighbor_);
}

static gfx::RectF NormalizedRect(float x,
                                 float y,
                                 float width,
                                 float height,
                                 float total_width,
                                 float total_height) {
  return gfx::RectF(x / total_width,
                    y / total_height,
                    width / total_width,
                    height / total_height);
}

void NinePatchLayerImpl::SetLayout(const gfx::Rect& aperture,
                                   const gfx::Rect& border,
                                   bool fill_center,
                                   bool nearest_neighbor) {
  // This check imposes an ordering on the call sequence.  An UIResource must
  // exist before SetLayout can be called.
  DCHECK(ui_resource_id_);

  if (image_aperture_ == aperture && border_ == border &&
      fill_center_ == fill_center && nearest_neighbor_ == nearest_neighbor)
    return;

  image_aperture_ = aperture;
  border_ = border;
  fill_center_ = fill_center;
  nearest_neighbor_ = nearest_neighbor;

  NoteLayerPropertyChanged();
}

void NinePatchLayerImpl::CheckGeometryLimitations() {
  // |border| is in layer space.  It cannot exceed the bounds of the layer.
  DCHECK_GE(bounds().width(), border_.width());
  DCHECK_GE(bounds().height(), border_.height());

  // Sanity Check on |border|
  DCHECK_LE(border_.x(), border_.width());
  DCHECK_LE(border_.y(), border_.height());
  DCHECK_GE(border_.x(), 0);
  DCHECK_GE(border_.y(), 0);

  // |aperture| is in image space.  It cannot exceed the bounds of the bitmap.
  DCHECK(!image_aperture_.size().IsEmpty());
  DCHECK(gfx::Rect(image_bounds_).Contains(image_aperture_))
      << "image_bounds_ " << gfx::Rect(image_bounds_).ToString()
      << " image_aperture_ " << image_aperture_.ToString();
}

void NinePatchLayerImpl::AppendQuads(
    RenderPass* render_pass,
    AppendQuadsData* append_quads_data) {
  CheckGeometryLimitations();
  SharedQuadState* shared_quad_state =
      render_pass->CreateAndAppendSharedQuadState();
  PopulateSharedQuadState(shared_quad_state);

  AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
                        append_quads_data);

  if (!ui_resource_id_)
    return;

  ResourceId resource =
      layer_tree_impl()->ResourceIdForUIResource(ui_resource_id_);

  if (!resource)
    return;

  static const bool flipped = false;
  static const bool premultiplied_alpha = true;

  DCHECK(!bounds().IsEmpty());

  // NinePatch border widths in layer space.
  int layer_left_width = border_.x();
  int layer_top_height = border_.y();
  int layer_right_width = border_.width() - layer_left_width;
  int layer_bottom_height = border_.height() - layer_top_height;

  int layer_middle_width = bounds().width() - border_.width();
  int layer_middle_height = bounds().height() - border_.height();

  // Patch positions in layer space
  gfx::Rect layer_top_left(0, 0, layer_left_width, layer_top_height);
  gfx::Rect layer_top_right(bounds().width() - layer_right_width,
                            0,
                            layer_right_width,
                            layer_top_height);
  gfx::Rect layer_bottom_left(0,
                              bounds().height() - layer_bottom_height,
                              layer_left_width,
                              layer_bottom_height);
  gfx::Rect layer_bottom_right(layer_top_right.x(),
                               layer_bottom_left.y(),
                               layer_right_width,
                               layer_bottom_height);
  gfx::Rect layer_top(
      layer_top_left.right(), 0, layer_middle_width, layer_top_height);
  gfx::Rect layer_left(
      0, layer_top_left.bottom(), layer_left_width, layer_middle_height);
  gfx::Rect layer_right(layer_top_right.x(),
                        layer_top_right.bottom(),
                        layer_right_width,
                        layer_left.height());
  gfx::Rect layer_bottom(layer_top.x(),
                         layer_bottom_left.y(),
                         layer_top.width(),
                         layer_bottom_height);
  gfx::Rect layer_center(layer_left_width,
                         layer_top_height,
                         layer_middle_width,
                         layer_middle_height);

  // Note the following values are in image (bitmap) space.
  float image_width = image_bounds_.width();
  float image_height = image_bounds_.height();

  int image_aperture_left_width = image_aperture_.x();
  int image_aperture_top_height = image_aperture_.y();
  int image_aperture_right_width = image_width - image_aperture_.right();
  int image_aperture_bottom_height = image_height - image_aperture_.bottom();
  // Patch positions in bitmap UV space (from zero to one)
  gfx::RectF uv_top_left = NormalizedRect(0,
                                          0,
                                          image_aperture_left_width,
                                          image_aperture_top_height,
                                          image_width,
                                          image_height);
  gfx::RectF uv_top_right =
      NormalizedRect(image_width - image_aperture_right_width,
                     0,
                     image_aperture_right_width,
                     image_aperture_top_height,
                     image_width,
                     image_height);
  gfx::RectF uv_bottom_left =
      NormalizedRect(0,
                     image_height - image_aperture_bottom_height,
                     image_aperture_left_width,
                     image_aperture_bottom_height,
                     image_width,
                     image_height);
  gfx::RectF uv_bottom_right =
      NormalizedRect(image_width - image_aperture_right_width,
                     image_height - image_aperture_bottom_height,
                     image_aperture_right_width,
                     image_aperture_bottom_height,
                     image_width,
                     image_height);
  gfx::RectF uv_top(
      uv_top_left.right(),
      0,
      (image_width - image_aperture_left_width - image_aperture_right_width) /
          image_width,
      (image_aperture_top_height) / image_height);
  gfx::RectF uv_left(0,
                     uv_top_left.bottom(),
                     image_aperture_left_width / image_width,
                     (image_height - image_aperture_top_height -
                      image_aperture_bottom_height) /
                         image_height);
  gfx::RectF uv_right(uv_top_right.x(),
                      uv_top_right.bottom(),
                      image_aperture_right_width / image_width,
                      uv_left.height());
  gfx::RectF uv_bottom(uv_top.x(),
                       uv_bottom_left.y(),
                       uv_top.width(),
                       image_aperture_bottom_height / image_height);
  gfx::RectF uv_center(uv_top_left.right(),
                       uv_top_left.bottom(),
                       uv_top.width(),
                       uv_left.height());

  gfx::Rect opaque_rect;
  gfx::Rect visible_rect;
  const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
  const bool opaque = layer_tree_impl()->IsUIResourceOpaque(ui_resource_id_);

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_top_left);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_top_left, opaque_rect, visible_rect,
                 resource, premultiplied_alpha, uv_top_left.origin(),
                 uv_top_left.bottom_right(), SK_ColorTRANSPARENT,
                 vertex_opacity, flipped, nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_top_right);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_top_right, opaque_rect, visible_rect,
                 resource, premultiplied_alpha, uv_top_right.origin(),
                 uv_top_right.bottom_right(), SK_ColorTRANSPARENT,
                 vertex_opacity, flipped, nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_bottom_left);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_bottom_left, opaque_rect,
                 visible_rect, resource, premultiplied_alpha,
                 uv_bottom_left.origin(), uv_bottom_left.bottom_right(),
                 SK_ColorTRANSPARENT, vertex_opacity, flipped,
                 nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_bottom_right);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_bottom_right, opaque_rect,
                 visible_rect, resource, premultiplied_alpha,
                 uv_bottom_right.origin(), uv_bottom_right.bottom_right(),
                 SK_ColorTRANSPARENT, vertex_opacity, flipped,
                 nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_top);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_top, opaque_rect, visible_rect,
                 resource, premultiplied_alpha, uv_top.origin(),
                 uv_top.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity,
                 flipped, nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_left);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_left, opaque_rect, visible_rect,
                 resource, premultiplied_alpha, uv_left.origin(),
                 uv_left.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity,
                 flipped, nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_right);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_right, opaque_rect, layer_right,
                 resource, premultiplied_alpha, uv_right.origin(),
                 uv_right.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity,
                 flipped, nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  visible_rect =
      draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
          layer_bottom);
  opaque_rect = opaque ? visible_rect : gfx::Rect();
  if (!visible_rect.IsEmpty()) {
    TextureDrawQuad* quad =
        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
    quad->SetNew(shared_quad_state, layer_bottom, opaque_rect, visible_rect,
                 resource, premultiplied_alpha, uv_bottom.origin(),
                 uv_bottom.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity,
                 flipped, nearest_neighbor_);
    ValidateQuadResources(quad);
  }

  if (fill_center_) {
    visible_rect =
        draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
            layer_center);
    opaque_rect = opaque ? visible_rect : gfx::Rect();
    if (!visible_rect.IsEmpty()) {
      TextureDrawQuad* quad =
          render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
      quad->SetNew(shared_quad_state, layer_center, opaque_rect, visible_rect,
                   resource, premultiplied_alpha, uv_center.origin(),
                   uv_center.bottom_right(), SK_ColorTRANSPARENT,
                   vertex_opacity, flipped, nearest_neighbor_);
      ValidateQuadResources(quad);
    }
  }
}

const char* NinePatchLayerImpl::LayerTypeAsString() const {
  return "cc::NinePatchLayerImpl";
}

base::DictionaryValue* NinePatchLayerImpl::LayerTreeAsJson() const {
  base::DictionaryValue* result = LayerImpl::LayerTreeAsJson();

  base::ListValue* list = new base::ListValue;
  list->AppendInteger(image_aperture_.origin().x());
  list->AppendInteger(image_aperture_.origin().y());
  list->AppendInteger(image_aperture_.size().width());
  list->AppendInteger(image_aperture_.size().height());
  result->Set("ImageAperture", list);

  list = new base::ListValue;
  list->AppendInteger(image_bounds_.width());
  list->AppendInteger(image_bounds_.height());
  result->Set("ImageBounds", list);

  result->Set("Border", MathUtil::AsValue(border_).release());

  result->SetBoolean("FillCenter", fill_center_);

  return result;
}

}  // namespace cc
