// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_INCLUDE_FPDFAPI_FPDF_PAGE_H_
#define CORE_INCLUDE_FPDFAPI_FPDF_PAGE_H_

#include <memory>

#include "core/include/fpdfapi/fpdf_parser.h"
#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_dib.h"

class CPDF_Page;
class CPDF_Form;
class CPDF_ParseOptions;
class CPDF_PageObject;
class CPDF_PageRenderCache;
class CPDF_StreamFilter;
class CPDF_AllStates;
class CPDF_ContentParser;
class CPDF_StreamContentParser;
#define PDFTRANS_GROUP 0x0100
#define PDFTRANS_ISOLATED 0x0200
#define PDFTRANS_KNOCKOUT 0x0400

class CPDF_PageObjectList {
 public:
  CPDF_PageObjectList();
  ~CPDF_PageObjectList();

  void ContinueParse(IFX_Pause* pPause);

  FX_BOOL IsParsed() const { return m_ParseState == CONTENT_PARSED; }

  FX_POSITION GetFirstObjectPosition() const {
    return m_ObjectList.GetHeadPosition();
  }

  FX_POSITION GetLastObjectPosition() const {
    return m_ObjectList.GetTailPosition();
  }

  CPDF_PageObject* GetNextObject(FX_POSITION& pos) const {
    return (CPDF_PageObject*)m_ObjectList.GetNext(pos);
  }

  CPDF_PageObject* GetPrevObject(FX_POSITION& pos) const {
    return (CPDF_PageObject*)m_ObjectList.GetPrev(pos);
  }

  CPDF_PageObject* GetObjectAt(FX_POSITION pos) const {
    return (CPDF_PageObject*)m_ObjectList.GetAt(pos);
  }

  void AddTail(CPDF_PageObject* obj) { m_ObjectList.AddTail(obj); }
  FX_DWORD CountObjects() const { return m_ObjectList.GetCount(); }

  int GetObjectIndex(CPDF_PageObject* pObj) const;

  CPDF_PageObject* GetObjectByIndex(int index) const;

  FX_POSITION InsertObject(FX_POSITION posInsertAfter,
                           CPDF_PageObject* pNewObject);

  void Transform(const CFX_Matrix& matrix);

  FX_BOOL BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; }
  void SetBackgroundAlphaNeeded(FX_BOOL needed) {
    m_bBackgroundAlphaNeeded = needed;
  }

  FX_BOOL HasImageMask() const { return m_bHasImageMask; }
  void SetHasImageMask(FX_BOOL value) { m_bHasImageMask = value; }
  CFX_FloatRect CalcBoundingBox() const;

  CPDF_Dictionary* m_pFormDict;
  CPDF_Stream* m_pFormStream;
  CPDF_Document* m_pDocument;
  CPDF_Dictionary* m_pPageResources;
  CPDF_Dictionary* m_pResources;
  CFX_FloatRect m_BBox;
  int m_Transparency;

 protected:
  enum ParseState { CONTENT_NOT_PARSED, CONTENT_PARSING, CONTENT_PARSED };

  void LoadTransInfo();

  FX_BOOL m_bBackgroundAlphaNeeded;
  FX_BOOL m_bHasImageMask;
  ParseState m_ParseState;
  std::unique_ptr<CPDF_ContentParser> m_pParser;
  CFX_PtrList m_ObjectList;
};

class CPDF_Page : public CPDF_PageObjectList, public CFX_PrivateData {
 public:
  CPDF_Page();
  ~CPDF_Page();

  void Load(CPDF_Document* pDocument,
            CPDF_Dictionary* pPageDict,
            FX_BOOL bPageCache = TRUE);

  void ParseContent(CPDF_ParseOptions* pOptions);

  void GetDisplayMatrix(CFX_Matrix& matrix,
                        int xPos,
                        int yPos,
                        int xSize,
                        int ySize,
                        int iRotate) const;

  FX_FLOAT GetPageWidth() const { return m_PageWidth; }
  FX_FLOAT GetPageHeight() const { return m_PageHeight; }
  CFX_FloatRect GetPageBBox() const { return m_BBox; }
  const CFX_Matrix& GetPageMatrix() const { return m_PageMatrix; }
  CPDF_Object* GetPageAttr(const CFX_ByteStringC& name) const;
  CPDF_PageRenderCache* GetRenderCache() const { return m_pPageRender; }

 protected:
  friend class CPDF_ContentParser;
  void StartParse(CPDF_ParseOptions* pOptions);

  FX_FLOAT m_PageWidth;
  FX_FLOAT m_PageHeight;
  CFX_Matrix m_PageMatrix;
  CPDF_PageRenderCache* m_pPageRender;
};
class CPDF_ParseOptions {
 public:
  CPDF_ParseOptions();

  FX_BOOL m_bTextOnly;

  FX_BOOL m_bMarkedContent;

  FX_BOOL m_bSeparateForm;

  FX_BOOL m_bDecodeInlineImage;
};
class CPDF_Form : public CPDF_PageObjectList {
 public:
  CPDF_Form(CPDF_Document* pDocument,
            CPDF_Dictionary* pPageResources,
            CPDF_Stream* pFormStream,
            CPDF_Dictionary* pParentResources = NULL);

  ~CPDF_Form();

  void StartParse(CPDF_AllStates* pGraphicStates,
                  CFX_Matrix* pParentMatrix,
                  CPDF_Type3Char* pType3Char,
                  CPDF_ParseOptions* pOptions,
                  int level = 0);

  void ParseContent(CPDF_AllStates* pGraphicStates,
                    CFX_Matrix* pParentMatrix,
                    CPDF_Type3Char* pType3Char,
                    CPDF_ParseOptions* pOptions,
                    int level = 0);

  CPDF_Form* Clone() const;
};
class CPDF_PageContentGenerator {
 public:
  CPDF_PageContentGenerator(CPDF_Page* pPage);
  ~CPDF_PageContentGenerator();
  FX_BOOL InsertPageObject(CPDF_PageObject* pPageObject);
  void GenerateContent();
  void TransformContent(CFX_Matrix& matrix);

 private:
  void ProcessImage(CFX_ByteTextBuf& buf, CPDF_ImageObject* pImageObj);
  void ProcessForm(CFX_ByteTextBuf& buf,
                   const uint8_t* data,
                   FX_DWORD size,
                   CFX_Matrix& matrix);
  CFX_ByteString RealizeResource(CPDF_Object* pResourceObj,
                                 const FX_CHAR* szType);

  CPDF_Page* m_pPage;
  CPDF_Document* m_pDocument;
  CFX_ArrayTemplate<CPDF_PageObject*> m_pageObjects;
};

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGE_H_
