// 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_tracker.h"
#include "ui/gfx/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()).PassAs<LayerImpl>();
}

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 OcclusionTracker<LayerImpl>& occlusion_tracker,
    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 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());

  // Nothing is opaque here.
  // TODO(danakj): Should we look at the SkBitmaps to determine opaqueness?
  gfx::Rect opaque_rect;
  gfx::Rect visible_rect;
  const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};

  visible_rect =
      occlusion_tracker.UnoccludedContentRect(layer_top_left, draw_transform());
  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);
  }

  visible_rect = occlusion_tracker.UnoccludedContentRect(layer_top_right,
                                                         draw_transform());
  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);
  }

  visible_rect = occlusion_tracker.UnoccludedContentRect(layer_bottom_left,
                                                         draw_transform());
  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);
  }

  visible_rect = occlusion_tracker.UnoccludedContentRect(layer_bottom_right,
                                                         draw_transform());
  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);
  }

  visible_rect =
      occlusion_tracker.UnoccludedContentRect(layer_top, draw_transform());
  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);
  }

  visible_rect =
      occlusion_tracker.UnoccludedContentRect(layer_left, draw_transform());
  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);
  }

  visible_rect =
      occlusion_tracker.UnoccludedContentRect(layer_right, draw_transform());
  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);
  }

  visible_rect =
      occlusion_tracker.UnoccludedContentRect(layer_bottom, draw_transform());
  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);
  }

  if (fill_center_) {
    visible_rect =
        occlusion_tracker.UnoccludedContentRect(layer_center, draw_transform());
    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);
    }
  }
}

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
