/*
 * 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.
 */

#ifndef PrintContext_h
#define PrintContext_h

#include "core/CoreExport.h"
#include "platform/heap/Handle.h"
#include "platform/wtf/Forward.h"
#include "platform/wtf/HashMap.h"
#include "platform/wtf/Vector.h"
#include "platform/wtf/text/WTFString.h"

namespace blink {

class Element;
class FloatSize;
class GraphicsContext;
class IntRect;
class LocalFrame;
class Node;

class CORE_EXPORT PrintContext
    : public GarbageCollectedFinalized<PrintContext> {
 public:
  // By shrinking to a width of 75%, we will render the correct physical
  // dimensions in paged media (i.e. cm, pt,). The shrinkage used
  // to be 80% to match other browsers - they have since moved on.
  // Wide pages will be scaled down more than this.
  // This value is the percentage inverted.
  static constexpr float kPrintingMinimumShrinkFactor = 1.33333333f;

  // 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).
  // TODO(rhogan): Decide if this quirk is still required.
  static constexpr float kPrintingMaximumShrinkFactor = 2;

  explicit PrintContext(LocalFrame*);
  virtual ~PrintContext();

  LocalFrame* GetFrame() const { return 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 BeginPrintMode(). That's probably
  // not always desirable.
  virtual void ComputePageRects(const FloatSize& print_size);

  // Deprecated. Page size computation is already in this class, clients
  // shouldn't be copying it.
  virtual void ComputePageRectsWithPageSize(
      const FloatSize& page_size_in_pixels);

  // These are only valid after page rects are computed.
  size_t PageCount() const { return page_rects_.size(); }
  const IntRect& PageRect(size_t page_number) const {
    return page_rects_[page_number];
  }
  const Vector<IntRect>& PageRects() const { return page_rects_; }

  // 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.
  virtual void BeginPrintMode(float width, float height = 0);

  // Return to screen mode.
  virtual void EndPrintMode();

  // The following static methods are used by layout tests:

  // Returns -1 if page isn't found.
  static int PageNumberForElement(Element*,
                                  const FloatSize& page_size_in_pixels);
  static String PageProperty(LocalFrame*,
                             const char* property_name,
                             int page_number);
  static bool IsPageBoxVisible(LocalFrame*, int page_number);
  static String PageSizeAndMarginsInPixels(LocalFrame*,
                                           int page_number,
                                           int width,
                                           int height,
                                           int margin_top,
                                           int margin_right,
                                           int margin_bottom,
                                           int margin_left);
  static int NumberOfPages(LocalFrame*, const FloatSize& page_size_in_pixels);

  virtual void Trace(blink::Visitor*);

 protected:
  friend class PrintContextTest;

  void OutputLinkedDestinations(GraphicsContext&, const IntRect& page_rect);

  Member<LocalFrame> frame_;
  Vector<IntRect> page_rects_;

 private:
  void ComputePageRectsWithPageSizeInternal(
      const FloatSize& page_size_in_pixels);
  void CollectLinkedDestinations(Node*);
  bool IsFrameValid() const;

  // Used to prevent misuses of BeginPrintMode() and EndPrintMode() (e.g., call
  // EndPrintMode() without BeginPrintMode()).
  bool is_printing_;

  HeapHashMap<String, Member<Element>> linked_destinations_;
  bool linked_destinations_valid_;
};

class ScopedPrintContext {
  STACK_ALLOCATED();

 public:
  explicit ScopedPrintContext(LocalFrame*);
  ~ScopedPrintContext();

  PrintContext* operator->() const { return context_.Get(); }

 private:
  Member<PrintContext> context_;

  DISALLOW_COPY_AND_ASSIGN(ScopedPrintContext);
};

}  // namespace blink

#endif
