// 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 "../fxge/fx_dib.h"
#include "fpdf_parser.h"
#include "fpdf_resource.h"

class CPDF_PageObjects;
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_PageObjects {
 public:
  CPDF_PageObjects(FX_BOOL bReleaseMembers = TRUE);
  ~CPDF_PageObjects();

  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);
  }

  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_AffineMatrix& matrix);

  FX_BOOL BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; }

  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:
  friend class CPDF_ContentParser;
  friend class CPDF_StreamContentParser;
  friend class CPDF_AllStates;

  enum ParseState { CONTENT_NOT_PARSED, CONTENT_PARSING, CONTENT_PARSED };

  void LoadTransInfo();
  void ClearCacheObjects();

  CFX_PtrList m_ObjectList;
  FX_BOOL m_bBackgroundAlphaNeeded;
  FX_BOOL m_bReleaseMembers;
  CPDF_ContentParser* m_pParser;
  ParseState m_ParseState;
};

class CPDF_Page : public CPDF_PageObjects, public CFX_PrivateData {
 public:
  CPDF_Page();

  ~CPDF_Page();

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

  void StartParse(CPDF_ParseOptions* pOptions = NULL, FX_BOOL bReParse = FALSE);

  void ParseContent(CPDF_ParseOptions* pOptions = NULL,
                    FX_BOOL bReParse = FALSE);

  void GetDisplayMatrix(CFX_AffineMatrix& 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_AffineMatrix& GetPageMatrix() const { return m_PageMatrix; }

  CPDF_Object* GetPageAttr(const CFX_ByteStringC& name) const;

  CPDF_PageRenderCache* GetRenderCache() const { return m_pPageRender; }

  void ClearRenderCache();

 protected:
  friend class CPDF_ContentParser;

  FX_FLOAT m_PageWidth;

  FX_FLOAT m_PageHeight;

  CFX_AffineMatrix 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_PageObjects {
 public:
  CPDF_Form(CPDF_Document* pDocument,
            CPDF_Dictionary* pPageResources,
            CPDF_Stream* pFormStream,
            CPDF_Dictionary* pParentResources = NULL);

  ~CPDF_Form();

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

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

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

 protected:
  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);

 private:
  CPDF_Page* m_pPage;
  CPDF_Document* m_pDocument;
  CFX_PtrArray m_pageObjects;
};

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGE_H_
