// 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) {}

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_);
}

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) {
  // 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)
    return;

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

  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,
    const Occlusion& occlusion_in_content_space,
    AppendQuadsData* append_quads_data) {
  CheckGeometryLimitations();
  SharedQuadState* shared_quad_state =
      render_pass->CreateAndAppendSharedQuadState();
  PopulateSharedQuadState(shared_quad_state);

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

  if (!ui_resource_id_)
    return;

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

  if (!resource)
    return;

  static const bool flipped = false;
  static const bool nearest_neighbor = 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 =
      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);
  }

  visible_rect =
      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);
  }

  visible_rect =
      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);
  }

  visible_rect =
      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);
  }

  visible_rect = 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);
  }

  visible_rect =
      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);
  }

  visible_rect =
      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);
  }

  visible_rect =
      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);
  }

  if (fill_center_) {
    visible_rect =
        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);
    }
  }
}

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
