// 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
#define PDF_CONTENT_NOT_PARSED	0
#define PDF_CONTENT_PARSING		1
#define PDF_CONTENT_PARSED		2
class CPDF_PageObjects
{
public:

    CPDF_PageObjects(FX_BOOL bReleaseMembers = TRUE);

    ~CPDF_PageObjects();




    void				ContinueParse(IFX_Pause* pPause);

    int					GetParseState() const
    {
        return m_ParseState;
    }

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

    int					EstimateParseProgress() const;




    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;

    CFX_PtrList			m_ObjectList;

    FX_BOOL				m_bBackgroundAlphaNeeded;

    FX_BOOL				m_bReleaseMembers;
    void				LoadTransInfo();
    void                ClearCacheObjects();

    CPDF_ContentParser*	m_pParser;

    FX_BOOL				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_
