// Copyright (c) 2010 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.

#ifndef PDF_PDFIUM_PDFIUM_PAGE_H_
#define PDF_PDFIUM_PDFIUM_PAGE_H_

#include <string>
#include <vector>

#include "base/strings/string16.h"
#include "ppapi/cpp/rect.h"
#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdf_formfill.h"
#include "third_party/pdfium/public/fpdf_text.h"

namespace base {
class Value;
}

namespace chrome_pdf {

class PDFiumEngine;

// Wrapper around a page from the document.
class PDFiumPage {
 public:
  PDFiumPage(PDFiumEngine* engine,
             int i,
             const pp::Rect& r,
             bool available);
  ~PDFiumPage();

  // Unloads the PDFium data for this page from memory.
  void Unload();
  // Gets the FPDF_PAGE for this page, loading and parsing it if necessary.
  FPDF_PAGE GetPage();
  // Get the FPDF_PAGE for printing.
  FPDF_PAGE GetPrintPage();
  // Close the printing page.
  void ClosePrintPage();

  // Returns FPDF_TEXTPAGE for the page, loading and parsing it if necessary.
  FPDF_TEXTPAGE GetTextPage();

  // Returns a DictionaryValue version of the page.
  base::Value* GetAccessibleContentAsValue(int rotation);

  enum Area {
    NONSELECTABLE_AREA,
    TEXT_AREA,
    WEBLINK_AREA,  // Area is a hyperlink.
    DOCLINK_AREA,  // Area is a link to a different part of the same document.
  };

  struct LinkTarget {
    // We are using std::string here which have a copy contructor.
    // That prevents us from using union here.
    std::string url;  // Valid for WEBLINK_AREA only.
    int page;         // Valid for DOCLINK_AREA only.
  };

  // Given a point in the document that's in this page, returns its character
  // index if it's near a character, and also the type of text.
  // Target is optional. It will be filled in for WEBLINK_AREA or
  // DOCLINK_AREA only.
  Area GetCharIndex(const pp::Point& point, int rotation, int* char_index,
                    int* form_type, LinkTarget* target);

  // Gets the character at the given index.
  base::char16 GetCharAtIndex(int index);

  // Gets the number of characters in the page.
  int GetCharCount();

  // Converts from page coordinates to screen coordinates.
  pp::Rect PageToScreen(const pp::Point& offset,
                        double zoom,
                        double left,
                        double top,
                        double right,
                        double bottom,
                        int rotation) const;

  int index() const { return index_; }
  pp::Rect rect() const { return rect_; }
  void set_rect(const pp::Rect& r) { rect_ = r; }
  bool available() const { return available_; }
  void set_available(bool available) { available_ = available; }
  void set_calculated_links(bool calculated_links) {
     calculated_links_ = calculated_links;
  }

 private:
  // Returns a link index if the given character index is over a link, or -1
  // otherwise.
  int GetLink(int char_index, LinkTarget* target);
  // Returns the link indices if the given rect intersects a link rect, or an
  // empty vector otherwise.
  std::vector<int> GetLinks(pp::Rect text_area,
                            std::vector<LinkTarget>* targets);
  // Calculate the locations of any links on the page.
  void CalculateLinks();
  // Returns link type and target associated with a link. Returns
  // NONSELECTABLE_AREA if link detection failed.
  Area GetLinkTarget(FPDF_LINK link, LinkTarget* target) const;
  // Returns target associated with a destination.
  Area GetDestinationTarget(FPDF_DEST destination, LinkTarget* target) const;

  class ScopedLoadCounter {
   public:
    explicit ScopedLoadCounter(PDFiumPage* page);
    ~ScopedLoadCounter();

   private:
    PDFiumPage* const page_;
  };

  struct Link {
    Link();
    ~Link();

    std::string url;
    // Bounding rectangles of characters.
    std::vector<pp::Rect> rects;
  };

  PDFiumEngine* engine_;
  FPDF_PAGE page_;
  FPDF_TEXTPAGE text_page_;
  int index_;
  int loading_count_;
  pp::Rect rect_;
  bool calculated_links_;
  std::vector<Link> links_;
  bool available_;
};

}  // namespace chrome_pdf

#endif  // PDF_PDFIUM_PDFIUM_PAGE_H_
