/*
 * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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 "core/layout/shapes/ShapeOutsideInfo.h"

#include "core/inspector/ConsoleMessage.h"
#include "core/layout/FloatingObjects.h"
#include "core/layout/LayoutBlockFlow.h"
#include "core/layout/LayoutBox.h"
#include "core/layout/LayoutImage.h"
#include "core/layout/api/LineLayoutBlockFlow.h"
#include "platform/LengthFunctions.h"
#include "public/platform/Platform.h"
#include "wtf/AutoReset.h"
#include <memory>

namespace blink {

CSSBoxType referenceBox(const ShapeValue& shapeValue) {
  if (shapeValue.cssBox() == BoxMissing)
    return MarginBox;
  return shapeValue.cssBox();
}

void ShapeOutsideInfo::setReferenceBoxLogicalSize(
    LayoutSize newReferenceBoxLogicalSize) {
  bool isHorizontalWritingMode =
      m_layoutBox.containingBlock()->style()->isHorizontalWritingMode();
  switch (referenceBox(*m_layoutBox.style()->shapeOutside())) {
    case MarginBox:
      if (isHorizontalWritingMode)
        newReferenceBoxLogicalSize.expand(m_layoutBox.marginWidth(),
                                          m_layoutBox.marginHeight());
      else
        newReferenceBoxLogicalSize.expand(m_layoutBox.marginHeight(),
                                          m_layoutBox.marginWidth());
      break;
    case BorderBox:
      break;
    case PaddingBox:
      if (isHorizontalWritingMode)
        newReferenceBoxLogicalSize.shrink(m_layoutBox.borderWidth(),
                                          m_layoutBox.borderHeight());
      else
        newReferenceBoxLogicalSize.shrink(m_layoutBox.borderHeight(),
                                          m_layoutBox.borderWidth());
      break;
    case ContentBox:
      if (isHorizontalWritingMode)
        newReferenceBoxLogicalSize.shrink(m_layoutBox.borderAndPaddingWidth(),
                                          m_layoutBox.borderAndPaddingHeight());
      else
        newReferenceBoxLogicalSize.shrink(m_layoutBox.borderAndPaddingHeight(),
                                          m_layoutBox.borderAndPaddingWidth());
      break;
    case BoxMissing:
      ASSERT_NOT_REACHED();
      break;
  }

  newReferenceBoxLogicalSize.clampNegativeToZero();

  if (m_referenceBoxLogicalSize == newReferenceBoxLogicalSize)
    return;
  markShapeAsDirty();
  m_referenceBoxLogicalSize = newReferenceBoxLogicalSize;
}

static bool checkShapeImageOrigin(Document& document,
                                  const StyleImage& styleImage) {
  if (styleImage.isGeneratedImage())
    return true;

  ASSERT(styleImage.cachedImage());
  ImageResourceContent& imageResource = *(styleImage.cachedImage());
  if (imageResource.isAccessAllowed(document.getSecurityOrigin()))
    return true;

  const KURL& url = imageResource.url();
  String urlString = url.isNull() ? "''" : url.elidedString();
  document.addConsoleMessage(
      ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel,
                             "Unsafe attempt to load URL " + urlString + "."));

  return false;
}

static LayoutRect getShapeImageMarginRect(
    const LayoutBox& layoutBox,
    const LayoutSize& referenceBoxLogicalSize) {
  LayoutPoint marginBoxOrigin(
      -layoutBox.marginLogicalLeft() - layoutBox.borderAndPaddingLogicalLeft(),
      -layoutBox.marginBefore() - layoutBox.borderBefore() -
          layoutBox.paddingBefore());
  LayoutSize marginBoxSizeDelta(
      layoutBox.marginLogicalWidth() + layoutBox.borderAndPaddingLogicalWidth(),
      layoutBox.marginLogicalHeight() +
          layoutBox.borderAndPaddingLogicalHeight());
  LayoutSize marginRectSize(referenceBoxLogicalSize + marginBoxSizeDelta);
  marginRectSize.clampNegativeToZero();
  return LayoutRect(marginBoxOrigin, marginRectSize);
}

static bool isValidRasterShapeRect(const LayoutRect& rect) {
  static double maxImageSizeBytes = 0;
  if (!maxImageSizeBytes) {
    size_t size32MaxBytes =
        0xFFFFFFFF / 4;  // Some platforms don't limit maxDecodedImageBytes.
    maxImageSizeBytes =
        std::min(size32MaxBytes, Platform::current()->maxDecodedImageBytes());
  }
  return (rect.width().toFloat() * rect.height().toFloat() * 4.0) <
         maxImageSizeBytes;
}

std::unique_ptr<Shape> ShapeOutsideInfo::createShapeForImage(
    StyleImage* styleImage,
    float shapeImageThreshold,
    WritingMode writingMode,
    float margin) const {
  const LayoutSize& imageSize =
      styleImage->imageSize(m_layoutBox, m_layoutBox.style()->effectiveZoom(),
                            m_referenceBoxLogicalSize);

  const LayoutRect& marginRect =
      getShapeImageMarginRect(m_layoutBox, m_referenceBoxLogicalSize);
  const LayoutRect& imageRect =
      (m_layoutBox.isLayoutImage())
          ? toLayoutImage(m_layoutBox).replacedContentRect()
          : LayoutRect(LayoutPoint(), imageSize);

  if (!isValidRasterShapeRect(marginRect) ||
      !isValidRasterShapeRect(imageRect)) {
    m_layoutBox.document().addConsoleMessage(
        ConsoleMessage::create(RenderingMessageSource, ErrorMessageLevel,
                               "The shape-outside image is too large."));
    return Shape::createEmptyRasterShape(writingMode, margin);
  }

  ASSERT(!styleImage->isPendingImage());
  RefPtr<Image> image =
      styleImage->image(m_layoutBox, flooredIntSize(imageSize),
                        m_layoutBox.style()->effectiveZoom());

  return Shape::createRasterShape(image.get(), shapeImageThreshold, imageRect,
                                  marginRect, writingMode, margin);
}

const Shape& ShapeOutsideInfo::computedShape() const {
  if (Shape* shape = m_shape.get())
    return *shape;

  AutoReset<bool> isInComputingShape(&m_isComputingShape, true);

  const ComputedStyle& style = *m_layoutBox.style();
  ASSERT(m_layoutBox.containingBlock());
  const ComputedStyle& containingBlockStyle =
      *m_layoutBox.containingBlock()->style();

  WritingMode writingMode = containingBlockStyle.getWritingMode();
  // Make sure contentWidth is not negative. This can happen when containing
  // block has a vertical scrollbar and its content is smaller than the
  // scrollbar width.
  LayoutUnit maximumValue =
      m_layoutBox.containingBlock()
          ? std::max(LayoutUnit(),
                     m_layoutBox.containingBlock()->contentWidth())
          : LayoutUnit();
  float margin = floatValueForLength(m_layoutBox.style()->shapeMargin(),
                                     maximumValue.toFloat());

  float shapeImageThreshold = style.shapeImageThreshold();
  ASSERT(style.shapeOutside());
  const ShapeValue& shapeValue = *style.shapeOutside();

  switch (shapeValue.type()) {
    case ShapeValue::Shape:
      ASSERT(shapeValue.shape());
      m_shape = Shape::createShape(
          shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
      break;
    case ShapeValue::Image:
      ASSERT(shapeValue.isImageValid());
      m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold,
                                    writingMode, margin);
      break;
    case ShapeValue::Box: {
      const FloatRoundedRect& shapeRect = style.getRoundedBorderFor(
          LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize),
          m_layoutBox.view());
      m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin);
      break;
    }
  }

  ASSERT(m_shape);
  return *m_shape;
}

inline LayoutUnit borderBeforeInWritingMode(const LayoutBox& layoutBox,
                                            WritingMode writingMode) {
  switch (writingMode) {
    case WritingMode::HorizontalTb:
      return LayoutUnit(layoutBox.borderTop());
    case WritingMode::VerticalLr:
      return LayoutUnit(layoutBox.borderLeft());
    case WritingMode::VerticalRl:
      return LayoutUnit(layoutBox.borderRight());
  }

  ASSERT_NOT_REACHED();
  return LayoutUnit(layoutBox.borderBefore());
}

inline LayoutUnit borderAndPaddingBeforeInWritingMode(
    const LayoutBox& layoutBox,
    WritingMode writingMode) {
  switch (writingMode) {
    case WritingMode::HorizontalTb:
      return layoutBox.borderTop() + layoutBox.paddingTop();
    case WritingMode::VerticalLr:
      return layoutBox.borderLeft() + layoutBox.paddingLeft();
    case WritingMode::VerticalRl:
      return layoutBox.borderRight() + layoutBox.paddingRight();
  }

  ASSERT_NOT_REACHED();
  return layoutBox.borderAndPaddingBefore();
}

LayoutUnit ShapeOutsideInfo::logicalTopOffset() const {
  switch (referenceBox(*m_layoutBox.style()->shapeOutside())) {
    case MarginBox:
      return -m_layoutBox.marginBefore(m_layoutBox.containingBlock()->style());
    case BorderBox:
      return LayoutUnit();
    case PaddingBox:
      return borderBeforeInWritingMode(
          m_layoutBox,
          m_layoutBox.containingBlock()->style()->getWritingMode());
    case ContentBox:
      return borderAndPaddingBeforeInWritingMode(
          m_layoutBox,
          m_layoutBox.containingBlock()->style()->getWritingMode());
    case BoxMissing:
      break;
  }

  ASSERT_NOT_REACHED();
  return LayoutUnit();
}

inline LayoutUnit borderStartWithStyleForWritingMode(
    const LayoutBox& layoutBox,
    const ComputedStyle* style) {
  if (style->isHorizontalWritingMode()) {
    if (style->isLeftToRightDirection())
      return LayoutUnit(layoutBox.borderLeft());

    return LayoutUnit(layoutBox.borderRight());
  }
  if (style->isLeftToRightDirection())
    return LayoutUnit(layoutBox.borderTop());

  return LayoutUnit(layoutBox.borderBottom());
}

inline LayoutUnit borderAndPaddingStartWithStyleForWritingMode(
    const LayoutBox& layoutBox,
    const ComputedStyle* style) {
  if (style->isHorizontalWritingMode()) {
    if (style->isLeftToRightDirection())
      return layoutBox.borderLeft() + layoutBox.paddingLeft();

    return layoutBox.borderRight() + layoutBox.paddingRight();
  }
  if (style->isLeftToRightDirection())
    return layoutBox.borderTop() + layoutBox.paddingTop();

  return layoutBox.borderBottom() + layoutBox.paddingBottom();
}

LayoutUnit ShapeOutsideInfo::logicalLeftOffset() const {
  switch (referenceBox(*m_layoutBox.style()->shapeOutside())) {
    case MarginBox:
      return -m_layoutBox.marginStart(m_layoutBox.containingBlock()->style());
    case BorderBox:
      return LayoutUnit();
    case PaddingBox:
      return borderStartWithStyleForWritingMode(
          m_layoutBox, m_layoutBox.containingBlock()->style());
    case ContentBox:
      return borderAndPaddingStartWithStyleForWritingMode(
          m_layoutBox, m_layoutBox.containingBlock()->style());
    case BoxMissing:
      break;
  }

  ASSERT_NOT_REACHED();
  return LayoutUnit();
}

bool ShapeOutsideInfo::isEnabledFor(const LayoutBox& box) {
  ShapeValue* shapeValue = box.style()->shapeOutside();
  if (!box.isFloating() || !shapeValue)
    return false;

  switch (shapeValue->type()) {
    case ShapeValue::Shape:
      return shapeValue->shape();
    case ShapeValue::Image:
      return shapeValue->isImageValid() &&
             checkShapeImageOrigin(box.document(), *(shapeValue->image()));
    case ShapeValue::Box:
      return true;
  }

  return false;
}

ShapeOutsideDeltas ShapeOutsideInfo::computeDeltasForContainingBlockLine(
    const LineLayoutBlockFlow& containingBlock,
    const FloatingObject& floatingObject,
    LayoutUnit lineTop,
    LayoutUnit lineHeight) {
  ASSERT(lineHeight >= 0);

  LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(floatingObject) +
                            containingBlock.marginBeforeForChild(m_layoutBox);
  LayoutUnit borderBoxLineTop = lineTop - borderBoxTop;

  if (isShapeDirty() ||
      !m_shapeOutsideDeltas.isForLine(borderBoxLineTop, lineHeight)) {
    LayoutUnit referenceBoxLineTop = borderBoxLineTop - logicalTopOffset();
    LayoutUnit floatMarginBoxWidth = std::max(
        containingBlock.logicalWidthForFloat(floatingObject), LayoutUnit());

    if (computedShape().lineOverlapsShapeMarginBounds(referenceBoxLineTop,
                                                      lineHeight)) {
      LineSegment segment = computedShape().getExcludedInterval(
          (borderBoxLineTop - logicalTopOffset()),
          std::min(lineHeight, shapeLogicalBottom() - borderBoxLineTop));
      if (segment.isValid) {
        LayoutUnit logicalLeftMargin =
            containingBlock.style()->isLeftToRightDirection()
                ? containingBlock.marginStartForChild(m_layoutBox)
                : containingBlock.marginEndForChild(m_layoutBox);
        LayoutUnit rawLeftMarginBoxDelta(
            segment.logicalLeft + logicalLeftOffset() + logicalLeftMargin);
        LayoutUnit leftMarginBoxDelta = clampTo<LayoutUnit>(
            rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth);

        LayoutUnit logicalRightMargin =
            containingBlock.style()->isLeftToRightDirection()
                ? containingBlock.marginEndForChild(m_layoutBox)
                : containingBlock.marginStartForChild(m_layoutBox);
        LayoutUnit rawRightMarginBoxDelta(
            segment.logicalRight + logicalLeftOffset() -
            containingBlock.logicalWidthForChild(m_layoutBox) -
            logicalRightMargin);
        LayoutUnit rightMarginBoxDelta = clampTo<LayoutUnit>(
            rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());

        m_shapeOutsideDeltas =
            ShapeOutsideDeltas(leftMarginBoxDelta, rightMarginBoxDelta, true,
                               borderBoxLineTop, lineHeight);
        return m_shapeOutsideDeltas;
      }
    }

    // Lines that do not overlap the shape should act as if the float
    // wasn't there for layout purposes. So we set the deltas to remove the
    // entire width of the float.
    m_shapeOutsideDeltas =
        ShapeOutsideDeltas(floatMarginBoxWidth, -floatMarginBoxWidth, false,
                           borderBoxLineTop, lineHeight);
  }

  return m_shapeOutsideDeltas;
}

LayoutRect ShapeOutsideInfo::computedShapePhysicalBoundingBox() const {
  LayoutRect physicalBoundingBox =
      computedShape().shapeMarginLogicalBoundingBox();
  physicalBoundingBox.setX(physicalBoundingBox.x() + logicalLeftOffset());

  if (m_layoutBox.style()->isFlippedBlocksWritingMode())
    physicalBoundingBox.setY(m_layoutBox.logicalHeight() -
                             physicalBoundingBox.maxY());
  else
    physicalBoundingBox.setY(physicalBoundingBox.y() + logicalTopOffset());

  if (!m_layoutBox.style()->isHorizontalWritingMode())
    physicalBoundingBox = physicalBoundingBox.transposedRect();
  else
    physicalBoundingBox.setY(physicalBoundingBox.y() + logicalTopOffset());

  return physicalBoundingBox;
}

FloatPoint ShapeOutsideInfo::shapeToLayoutObjectPoint(FloatPoint point) const {
  FloatPoint result = FloatPoint(point.x() + logicalLeftOffset(),
                                 point.y() + logicalTopOffset());
  if (m_layoutBox.style()->isFlippedBlocksWritingMode())
    result.setY(m_layoutBox.logicalHeight() - result.y());
  if (!m_layoutBox.style()->isHorizontalWritingMode())
    result = result.transposedPoint();
  return result;
}

FloatSize ShapeOutsideInfo::shapeToLayoutObjectSize(FloatSize size) const {
  if (!m_layoutBox.style()->isHorizontalWritingMode())
    return size.transposedSize();
  return size;
}

}  // namespace blink
