/*
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2007-2019 Apple Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "PrintContext.h"

#include "ElementTraversal.h"
#include "GraphicsContext.h"
#include "Frame.h"
#include "FrameView.h"
#include "LengthBox.h"
#include "RenderView.h"
#include "RuntimeEnabledFeatures.h"
#include "StyleInheritedData.h"
#include "StyleResolver.h"
#include "StyleScope.h"
#include <wtf/text/StringConcatenateNumbers.h>

namespace WebCore {

PrintContext::PrintContext(Frame* frame)
    : FrameDestructionObserver(frame)
{
}

PrintContext::~PrintContext()
{
    if (m_isPrinting)
        end();
}

void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight, bool allowHorizontalTiling)
{
    if (!frame())
        return;

    auto& frame = *this->frame();
    m_pageRects.clear();
    outPageHeight = 0;

    if (!frame.document() || !frame.view() || !frame.document()->renderView())
        return;

    if (userScaleFactor <= 0) {
        LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
        return;
    }

    RenderView* view = frame.document()->renderView();
    const IntRect& documentRect = view->documentRect();
    FloatSize pageSize = frame.resizePageRectsKeepingRatio(FloatSize(printRect.width(), printRect.height()), FloatSize(documentRect.width(), documentRect.height()));
    float pageWidth = pageSize.width();
    float pageHeight = pageSize.height();

    outPageHeight = pageHeight; // this is the height of the page adjusted by margins
    pageHeight -= headerHeight + footerHeight;

    if (pageHeight <= 0) {
        LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
        return;
    }

    computePageRectsWithPageSizeInternal(FloatSize(pageWidth / userScaleFactor, pageHeight / userScaleFactor), allowHorizontalTiling);
}

FloatBoxExtent PrintContext::computedPageMargin(FloatBoxExtent printMargin)
{
    if (!frame() || !frame()->document())
        return printMargin;
    if (!RuntimeEnabledFeatures::sharedFeatures().pageAtRuleSupportEnabled())
        return printMargin;
    // FIXME Currently no pseudo class is supported.
    auto style = frame()->document()->styleScope().resolver().styleForPage(0);

    float pixelToPointScaleFactor = 1 / CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(CSSPrimitiveValue::CSS_PT);
    return { style->marginTop().isAuto() ? printMargin.top() : style->marginTop().value() * pixelToPointScaleFactor,
        style->marginRight().isAuto() ? printMargin.right() : style->marginRight().value() * pixelToPointScaleFactor,
        style->marginBottom().isAuto() ? printMargin.bottom() : style->marginBottom().value() * pixelToPointScaleFactor,
        style->marginLeft().isAuto() ? printMargin.left() : style->marginLeft().value() * pixelToPointScaleFactor };
}

FloatSize PrintContext::computedPageSize(FloatSize pageSize, FloatBoxExtent printMargin)
{
    auto computedMargin = computedPageMargin(printMargin);
    if (computedMargin == printMargin)
        return pageSize;

    auto horizontalMarginDelta = (printMargin.left() - computedMargin.left()) + (printMargin.right() - computedMargin.right()); 
    auto verticalMarginDelta = (printMargin.top() - computedMargin.top()) + (printMargin.bottom() - computedMargin.bottom());
    return { pageSize.width() + horizontalMarginDelta, pageSize.height() + verticalMarginDelta };
}

void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling)
{
    m_pageRects.clear();
    computePageRectsWithPageSizeInternal(pageSizeInPixels, allowHorizontalTiling);
}

void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowInlineDirectionTiling)
{
    if (!frame())
        return;

    auto& frame = *this->frame();
    if (!frame.document() || !frame.view() || !frame.document()->renderView())
        return;

    RenderView* view = frame.document()->renderView();

    IntRect docRect = view->documentRect();

    int pageWidth = pageSizeInPixels.width();
    int pageHeight = pageSizeInPixels.height();

    bool isHorizontal = view->style().isHorizontalWritingMode();

    int docLogicalHeight = isHorizontal ? docRect.height() : docRect.width();
    int pageLogicalHeight = isHorizontal ? pageHeight : pageWidth;
    int pageLogicalWidth = isHorizontal ? pageWidth : pageHeight;

    int inlineDirectionStart;
    int inlineDirectionEnd;
    int blockDirectionStart;
    int blockDirectionEnd;
    if (isHorizontal) {
        if (view->style().isFlippedBlocksWritingMode()) {
            blockDirectionStart = docRect.maxY();
            blockDirectionEnd = docRect.y();
        } else {
            blockDirectionStart = docRect.y();
            blockDirectionEnd = docRect.maxY();
        }
        inlineDirectionStart = view->style().isLeftToRightDirection() ? docRect.x() : docRect.maxX();
        inlineDirectionEnd = view->style().isLeftToRightDirection() ? docRect.maxX() : docRect.x();
    } else {
        if (view->style().isFlippedBlocksWritingMode()) {
            blockDirectionStart = docRect.maxX();
            blockDirectionEnd = docRect.x();
        } else {
            blockDirectionStart = docRect.x();
            blockDirectionEnd = docRect.maxX();
        }
        inlineDirectionStart = view->style().isLeftToRightDirection() ? docRect.y() : docRect.maxY();
        inlineDirectionEnd = view->style().isLeftToRightDirection() ? docRect.maxY() : docRect.y();
    }

    unsigned pageCount = ceilf((float)docLogicalHeight / pageLogicalHeight);
    for (unsigned i = 0; i < pageCount; ++i) {
        int pageLogicalTop = blockDirectionEnd > blockDirectionStart ?
                                blockDirectionStart + i * pageLogicalHeight : 
                                blockDirectionStart - (i + 1) * pageLogicalHeight;
        if (allowInlineDirectionTiling) {
            for (int currentInlinePosition = inlineDirectionStart;
                 inlineDirectionEnd > inlineDirectionStart ? currentInlinePosition < inlineDirectionEnd : currentInlinePosition > inlineDirectionEnd;
                 currentInlinePosition += (inlineDirectionEnd > inlineDirectionStart ? pageLogicalWidth : -pageLogicalWidth)) {
                int pageLogicalLeft = inlineDirectionEnd > inlineDirectionStart ? currentInlinePosition : currentInlinePosition - pageLogicalWidth;
                IntRect pageRect(pageLogicalLeft, pageLogicalTop, pageLogicalWidth, pageLogicalHeight);
                if (!isHorizontal)
                    pageRect = pageRect.transposedRect();
                m_pageRects.append(pageRect);
            }
        } else {
            int pageLogicalLeft = inlineDirectionEnd > inlineDirectionStart ? inlineDirectionStart : inlineDirectionStart - pageLogicalWidth;
            IntRect pageRect(pageLogicalLeft, pageLogicalTop, pageLogicalWidth, pageLogicalHeight);
            if (!isHorizontal)
                pageRect = pageRect.transposedRect();
            m_pageRects.append(pageRect);
        }
    }
}

void PrintContext::begin(float width, float height)
{
    if (!frame())
        return;

    auto& frame = *this->frame();
    // This function can be called multiple times to adjust printing parameters without going back to screen mode.
    m_isPrinting = true;

    FloatSize originalPageSize = FloatSize(width, height);
    FloatSize minLayoutSize = frame.resizePageRectsKeepingRatio(originalPageSize, FloatSize(width * minimumShrinkFactor(), height * minimumShrinkFactor()));

    // This changes layout, so callers need to make sure that they don't paint to screen while in printing mode.
    frame.setPrinting(true, minLayoutSize, originalPageSize, maximumShrinkFactor() / minimumShrinkFactor(), AdjustViewSize);
}

float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
{
    if (!frame())
        return 1;

    auto& frame = *this->frame();
    if (!frame.view())
        return 1;

    bool useViewWidth = true;
    if (frame.document() && frame.document()->renderView())
        useViewWidth = frame.document()->renderView()->style().isHorizontalWritingMode();

    float viewLogicalWidth = useViewWidth ? frame.view()->contentsWidth() : frame.view()->contentsHeight();
    if (viewLogicalWidth < 1)
        return 1;

    float maxShrinkToFitScaleFactor = 1 / maximumShrinkFactor();
    float shrinkToFitScaleFactor = (useViewWidth ? availablePaperSize.width() : availablePaperSize.height()) / viewLogicalWidth;
    return std::max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
}

void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
{
    if (!frame())
        return;

    auto& frame = *this->frame();
    // FIXME: Not correct for vertical text.
    IntRect pageRect = m_pageRects[pageNumber];
    float scale = width / pageRect.width();

    ctx.save();
    ctx.scale(scale);
    ctx.translate(-pageRect.x(), -pageRect.y());
    ctx.clip(pageRect);
    frame.view()->paintContents(ctx, pageRect);
    outputLinkedDestinations(ctx, *frame.document(), pageRect);
    ctx.restore();
}

void PrintContext::spoolRect(GraphicsContext& ctx, const IntRect& rect)
{
    if (!frame())
        return;

    auto& frame = *this->frame();
    // FIXME: Not correct for vertical text.
    ctx.save();
    ctx.translate(-rect.x(), -rect.y());
    ctx.clip(rect);
    frame.view()->paintContents(ctx, rect);
    outputLinkedDestinations(ctx, *frame.document(), rect);
    ctx.restore();
}

void PrintContext::end()
{
    if (!frame())
        return;

    auto& frame = *this->frame();
    ASSERT(m_isPrinting);
    m_isPrinting = false;
    frame.setPrinting(false, FloatSize(), FloatSize(), 0, AdjustViewSize);
    m_linkedDestinations = nullptr;
}

static inline RenderBoxModelObject* enclosingBoxModelObject(RenderElement* renderer)
{
    while (renderer && !is<RenderBoxModelObject>(*renderer))
        renderer = renderer->parent();
    return downcast<RenderBoxModelObject>(renderer);
}

int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSizeInPixels)
{
    // Make sure the element is not freed during the layout.
    RefPtr<Element> elementRef(element);
    element->document().updateLayout();

    auto* box = enclosingBoxModelObject(element->renderer());
    if (!box)
        return -1;

    Frame* frame = element->document().frame();
    FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
    PrintContext printContext(frame);
    printContext.begin(pageRect.width(), pageRect.height());
    FloatSize scaledPageSize = pageSizeInPixels;
    scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
    printContext.computePageRectsWithPageSize(scaledPageSize, false);

    int top = roundToInt(box->offsetTop());
    int left = roundToInt(box->offsetLeft());
    size_t pageNumber = 0;
    for (; pageNumber < printContext.pageCount(); pageNumber++) {
        const IntRect& page = printContext.pageRect(pageNumber);
        if (page.x() <= left && left < page.maxX() && page.y() <= top && top < page.maxY())
            return pageNumber;
    }
    return -1;
}

void PrintContext::collectLinkedDestinations(Document& document)
{
    for (Element* child = document.documentElement(); child; child = ElementTraversal::next(*child)) {
        String outAnchorName;
        if (Element* element = child->findAnchorElementForLink(outAnchorName))
            m_linkedDestinations->add(outAnchorName, *element);
    }
}

void PrintContext::outputLinkedDestinations(GraphicsContext& graphicsContext, Document& document, const IntRect& pageRect)
{
    if (!graphicsContext.supportsInternalLinks())
        return;

    if (!m_linkedDestinations) {
        m_linkedDestinations = makeUnique<HashMap<String, Ref<Element>>>();
        collectLinkedDestinations(document);
    }

    for (const auto& it : *m_linkedDestinations) {
        RenderElement* renderer = it.value->renderer();
        if (!renderer)
            continue;

        FloatPoint point = renderer->absoluteAnchorRect().minXMinYCorner();
        point = point.expandedTo(FloatPoint());

        if (!pageRect.contains(roundedIntPoint(point)))
            continue;

        graphicsContext.addDestinationAtPoint(it.key, point);
    }
}

String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pageNumber)
{
    ASSERT(frame);
    ASSERT(frame->document());

    Ref<Frame> protectedFrame(*frame);

    auto& document = *frame->document();
    PrintContext printContext(frame);
    printContext.begin(800); // Any width is OK here.
    document.updateLayout();
    auto style = document.styleScope().resolver().styleForPage(pageNumber);

    // Implement formatters for properties we care about.
    if (!strcmp(propertyName, "margin-left")) {
        if (style->marginLeft().isAuto())
            return "auto"_s;
        return String::number(style->marginLeft().value());
    }
    if (!strcmp(propertyName, "line-height"))
        return String::number(style->lineHeight().value());
    if (!strcmp(propertyName, "font-size"))
        return String::number(style->fontDescription().computedPixelSize());
    if (!strcmp(propertyName, "font-family"))
        return style->fontDescription().firstFamily();
    if (!strcmp(propertyName, "size"))
        return makeString(style->pageSize().width.value(), ' ', style->pageSize().height.value());

    return makeString("pageProperty() unimplemented for: ", propertyName);
}

bool PrintContext::isPageBoxVisible(Frame* frame, int pageNumber)
{
    return frame->document()->isPageBoxVisible(pageNumber);
}

String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
{
    IntSize pageSize(width, height);
    frame->document()->pageSizeAndMarginsInPixels(pageNumber, pageSize, marginTop, marginRight, marginBottom, marginLeft);

    return makeString('(', pageSize.width(), ", ", pageSize.height(), ") ", marginTop, ' ', marginRight, ' ', marginBottom, ' ', marginLeft);
}

bool PrintContext::beginAndComputePageRectsWithPageSize(Frame& frame, const FloatSize& pageSizeInPixels)
{
    if (!frame.document() || !frame.view() || !frame.document()->renderView())
        return false;

    frame.document()->updateLayout();

    begin(pageSizeInPixels.width(), pageSizeInPixels.height());
    // Account for shrink-to-fit.
    FloatSize scaledPageSize = pageSizeInPixels;
    scaledPageSize.scale(frame.view()->contentsSize().width() / pageSizeInPixels.width());
    computePageRectsWithPageSize(scaledPageSize, false);

    return true;
}

int PrintContext::numberOfPages(Frame& frame, const FloatSize& pageSizeInPixels)
{
    Ref<Frame> protectedFrame(frame);

    PrintContext printContext(&frame);
    if (!printContext.beginAndComputePageRectsWithPageSize(frame, pageSizeInPixels))
        return -1;

    return printContext.pageCount();
}

void PrintContext::spoolAllPagesWithBoundaries(Frame& frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
{
    Ref<Frame> protectedFrame(frame);

    PrintContext printContext(&frame);
    if (!printContext.beginAndComputePageRectsWithPageSize(frame, pageSizeInPixels))
        return;

    const float pageWidth = pageSizeInPixels.width();
    const Vector<IntRect>& pageRects = printContext.pageRects();
    int totalHeight = pageRects.size() * (pageSizeInPixels.height() + 1) - 1;

    // Fill the whole background by white.
    graphicsContext.setFillColor(Color(255, 255, 255));
    graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight));

    graphicsContext.save();

    int currentHeight = 0;
    for (size_t pageIndex = 0; pageIndex < pageRects.size(); pageIndex++) {
        // Draw a line for a page boundary if this isn't the first page.
        if (pageIndex > 0) {
#if PLATFORM(COCOA)
            int boundaryLineY = currentHeight;
#else
            int boundaryLineY = currentHeight - 1;
#endif
            graphicsContext.save();
            graphicsContext.setStrokeColor(Color(0, 0, 255));
            graphicsContext.setFillColor(Color(0, 0, 255));
            graphicsContext.drawLine(IntPoint(0, boundaryLineY), IntPoint(pageWidth, boundaryLineY));
            graphicsContext.restore();
        }

        graphicsContext.save();
        graphicsContext.translate(0, currentHeight);
        printContext.spoolPage(graphicsContext, pageIndex, pageWidth);
        graphicsContext.restore();

        currentHeight += pageSizeInPixels.height() + 1;
    }

    graphicsContext.restore();
}

}
