/*
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2007 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.
 */

#pragma once

#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>

namespace WebCore {

class Document;
class Element;
class Frame;
class FloatRect;
class FloatSize;
class GraphicsContext;
class IntRect;
class Node;

class PrintContext {
public:
    WEBCORE_EXPORT explicit PrintContext(Frame*);
    WEBCORE_EXPORT ~PrintContext();

    Frame* frame() const { return m_frame; }

    // Break up a page into rects without relayout.
    // FIXME: This means that CSS page breaks won't be on page boundary if the size is different than what was passed to begin(). That's probably not always desirable.
    // FIXME: Header and footer height should be applied before layout, not after.
    // FIXME: The printRect argument is only used to determine page aspect ratio, it would be better to pass a FloatSize with page dimensions instead.
    WEBCORE_EXPORT void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight, bool allowHorizontalTiling = false);

    // Deprecated. Page size computation is already in this class, clients shouldn't be copying it.
    WEBCORE_EXPORT void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling);

    // These are only valid after page rects are computed.
    size_t pageCount() const { return m_pageRects.size(); }
    const IntRect& pageRect(size_t pageNumber) const { return m_pageRects[pageNumber]; }
    const Vector<IntRect>& pageRects() const { return m_pageRects; }

    WEBCORE_EXPORT float computeAutomaticScaleFactor(const FloatSize& availablePaperSize);

    // Enter print mode, updating layout for new page size.
    // This function can be called multiple times to apply new print options without going back to screen mode.
    WEBCORE_EXPORT void begin(float width, float height = 0);

    // FIXME: eliminate width argument.
    WEBCORE_EXPORT void spoolPage(GraphicsContext& ctx, int pageNumber, float width);

    WEBCORE_EXPORT void spoolRect(GraphicsContext& ctx, const IntRect&);

    // Return to screen mode.
    WEBCORE_EXPORT void end();

    // Used by layout tests.
    WEBCORE_EXPORT static int pageNumberForElement(Element*, const FloatSize& pageSizeInPixels); // Returns -1 if page isn't found.
    WEBCORE_EXPORT static String pageProperty(Frame*, const char* propertyName, int pageNumber);
    WEBCORE_EXPORT static bool isPageBoxVisible(Frame*, int pageNumber);
    WEBCORE_EXPORT static String pageSizeAndMarginsInPixels(Frame*, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
    WEBCORE_EXPORT static int numberOfPages(Frame&, const FloatSize& pageSizeInPixels);
    // Draw all pages into a graphics context with lines which mean page boundaries.
    // The height of the graphics context should be
    // (pageSizeInPixels.height() + 1) * number-of-pages - 1
    WEBCORE_EXPORT static void spoolAllPagesWithBoundaries(Frame&, GraphicsContext&, const FloatSize& pageSizeInPixels);
    
    // By imaging to a width a little wider than the available pixels,
    // thin pages will be scaled down a little, matching the way they
    // print in IE and Camino. This lets them use fewer sheets than they
    // would otherwise, which is presumably why other browsers do this.
    // Wide pages will be scaled down more than this.
    static constexpr float minimumShrinkFactor() { return 1.25; }

    // This number determines how small we are willing to reduce the page content
    // in order to accommodate the widest line. If the page would have to be
    // reduced smaller to make the widest line fit, we just clip instead (this
    // behavior matches MacIE and Mozilla, at least)
    static constexpr float maximumShrinkFactor() { return 2; }

protected:
    Frame* m_frame;
    Vector<IntRect> m_pageRects;

private:
    void computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling);
    bool beginAndComputePageRectsWithPageSize(Frame&, const FloatSize& pageSizeInPixels);
    void collectLinkedDestinations(Document&);
    void outputLinkedDestinations(GraphicsContext&, Document&, const IntRect& pageRect);

    // Used to prevent misuses of begin() and end() (e.g., call end without begin).
    bool m_isPrinting { false };

    std::unique_ptr<HashMap<String, Ref<Element>>> m_linkedDestinations;
};

} // namespace WebCore
