// 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_PAGEOBJ_H_
#define CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_

#include "../fxge/fx_ge.h"
#include "fpdf_resource.h"

class CPDF_Path;
class CPDF_ClipPathData;
class CPDF_ClipPath;
class CPDF_ColorStateData;
class CPDF_ColorState;
class CPDF_GraphState;
class CPDF_TextStateData;
class CPDF_TextState;
class CPDF_GeneralStateData;
class CPDF_GeneralState;
class CPDF_ContentMarkItem;
class CPDF_ContentMark;
class CPDF_GraphicStates;
class CPDF_PageObject;
class CPDF_TextObject;
class CPDF_PathObject;
class CPDF_ImageObject;
class CPDF_ShadingObject;
class CPDF_FormObject;
typedef CFX_PathData CPDF_PathData;

class CPDF_Path : public CFX_CountRef<CFX_PathData>
{
public:
    int					GetPointCount()
    {
        return m_pObject->m_PointCount;
    }

    int					GetFlag(int index)
    {
        return m_pObject->m_pPoints[index].m_Flag;
    }

    FX_FLOAT			GetPointX(int index)
    {
        return m_pObject->m_pPoints[index].m_PointX;
    }

    FX_FLOAT			GetPointY(int index)
    {
        return m_pObject->m_pPoints[index].m_PointY;
    }




    FX_PATHPOINT*		GetPoints()
    {
        return m_pObject->m_pPoints;
    }


    CFX_FloatRect		GetBoundingBox() const
    {
        return m_pObject->GetBoundingBox();
    }

    CFX_FloatRect		GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const
    {
        return m_pObject->GetBoundingBox(line_width, miter_limit);
    }

    void				Transform(const CFX_AffineMatrix* pMatrix)
    {
        GetModify()->Transform(pMatrix);
    }

    void				Append(CPDF_Path src, const CFX_AffineMatrix* pMatrix)
    {
        m_pObject->Append(src.m_pObject, pMatrix);
    }

    void				AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top)
    {
        m_pObject->AppendRect(left, bottom, right, top);
    }

    bool				IsRect() const
    {
        return m_pObject->IsRect();
    }
};
class CPDF_ClipPathData
{
public:

    CPDF_ClipPathData();

    CPDF_ClipPathData(const CPDF_ClipPathData&);

    ~CPDF_ClipPathData();

    void				SetCount(int path_count, int text_count);
public:

    int					m_PathCount;

    CPDF_Path*			m_pPathList;

    uint8_t*			m_pTypeList;

    int					m_TextCount;

    CPDF_TextObject**	m_pTextList;
};
class CPDF_ClipPath : public CFX_CountRef<CPDF_ClipPathData>
{
public:

    FX_DWORD			GetPathCount() const
    {
        return m_pObject->m_PathCount;
    }

    CPDF_Path			GetPath(int i) const
    {
        return m_pObject->m_pPathList[i];
    }

    int					GetClipType(int i) const
    {
        return m_pObject->m_pTypeList[i];
    }

    FX_DWORD			GetTextCount() const
    {
        return m_pObject->m_TextCount;
    }

    CPDF_TextObject*	GetText(int i) const
    {
        return m_pObject->m_pTextList[i];
    }

    CFX_FloatRect		GetClipBox() const;

    void				AppendPath(CPDF_Path path, int type, bool bAutoMerge);

    void				DeletePath(int layer_index);

    void				AppendTexts(CPDF_TextObject** pTexts, int count);

    void				Transform(const CFX_AffineMatrix& matrix);
};
class CPDF_ColorStateData
{
public:

    CPDF_ColorStateData(): m_FillRGB(0), m_StrokeRGB(0) {}

    CPDF_ColorStateData(const CPDF_ColorStateData& src);

    void				Default();

    CPDF_Color			m_FillColor;

    FX_DWORD			m_FillRGB;

    CPDF_Color			m_StrokeColor;

    FX_DWORD			m_StrokeRGB;
};
class CPDF_ColorState : public CFX_CountRef<CPDF_ColorStateData>
{
public:

    CPDF_Color*			GetFillColor() const
    {
        return m_pObject ? &m_pObject->m_FillColor : NULL;
    }

    CPDF_Color*			GetStrokeColor() const
    {
        return m_pObject ? &m_pObject->m_StrokeColor : NULL;
    }

    void				SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);

    void				SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);

    void				SetFillPattern(CPDF_Pattern* pattern, FX_FLOAT* pValue, int nValues);

    void				SetStrokePattern(CPDF_Pattern* pattern, FX_FLOAT* pValue, int nValues);
private:
    void				SetColor(CPDF_Color& color, FX_DWORD& rgb, CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);
};
typedef CFX_GraphStateData CPDF_GraphStateData;
class CPDF_GraphState : public CFX_CountRef<CFX_GraphStateData>
{
public:
};
class CPDF_TextStateData
{
public:

    CPDF_TextStateData();

    CPDF_TextStateData(const CPDF_TextStateData& src);

    ~CPDF_TextStateData();

    CPDF_Font*			m_pFont;

    CPDF_Document*		m_pDocument;

    FX_FLOAT			m_FontSize;

    FX_FLOAT			m_CharSpace;

    FX_FLOAT			m_WordSpace;

    FX_FLOAT		m_Matrix[4];

    int					m_TextMode;

    FX_FLOAT		m_CTM[4];
};
class CPDF_TextState : public CFX_CountRef<CPDF_TextStateData>
{
public:

    CPDF_Font*			GetFont() const
    {
        return m_pObject->m_pFont;
    }

    void				SetFont(CPDF_Font* pFont);

    FX_FLOAT			GetFontSize() const
    {
        return m_pObject->m_FontSize;
    }

    FX_FLOAT*			GetMatrix() const
    {
        return m_pObject->m_Matrix;
    }



    FX_FLOAT			GetFontSizeV() const;

    FX_FLOAT			GetFontSizeH() const;

    FX_FLOAT			GetBaselineAngle() const;

    FX_FLOAT			GetShearAngle() const;

};
class CPDF_TransferFunc;
class CPDF_GeneralStateData
{
public:

    CPDF_GeneralStateData();

    CPDF_GeneralStateData(const CPDF_GeneralStateData& src);
    ~CPDF_GeneralStateData();

    void				SetBlendMode(const CFX_ByteStringC& blend_mode);

    char				m_BlendMode[16];

    int					m_BlendType;

    CPDF_Object*		m_pSoftMask;

    FX_FLOAT			m_SMaskMatrix[6];

    FX_FLOAT			m_StrokeAlpha;

    FX_FLOAT			m_FillAlpha;

    CPDF_Object*		m_pTR;

    CPDF_TransferFunc*	m_pTransferFunc;

    CFX_Matrix			m_Matrix;

    int					m_RenderIntent;

    bool				m_StrokeAdjust;

    bool				m_AlphaSource;

    bool				m_TextKnockout;

    bool				m_StrokeOP;

    bool				m_FillOP;

    int					m_OPMode;

    CPDF_Object*		m_pBG;

    CPDF_Object*		m_pUCR;

    CPDF_Object*		m_pHT;

    FX_FLOAT			m_Flatness;

    FX_FLOAT			m_Smoothness;
};
class CPDF_GeneralState : public CFX_CountRef<CPDF_GeneralStateData>
{
public:

    void				SetRenderIntent(const CFX_ByteString& ri);

    int					GetBlendType() const
    {
        return m_pObject ? m_pObject->m_BlendType : FXDIB_BLEND_NORMAL;
    }

    int					GetAlpha(bool bStroke) const
    {
        return m_pObject ? FXSYS_round((bStroke ? m_pObject->m_StrokeAlpha : m_pObject->m_FillAlpha) * 255) : 255;
    }
};
class CPDF_ContentMarkItem
{
public:

    typedef enum {
        None,
        PropertiesDict,
        DirectDict,
        MCID
    } ParamType;

    CPDF_ContentMarkItem();

    CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src);

    ~CPDF_ContentMarkItem();

    inline const CFX_ByteString&	GetName() const
    {
        return m_MarkName;
    }

    inline ParamType	GetParamType() const
    {
        return m_ParamType;
    }

    inline void*		GetParam() const
    {
        return m_pParam;
    }

    inline bool		HasMCID() const;

    inline void			SetName(const CFX_ByteString& name)
    {
        m_MarkName = name;
    }

    inline void			SetParam(ParamType type, void* param)
    {
        m_ParamType = type;
        m_pParam = param;
    }
private:

    CFX_ByteString		m_MarkName;

    ParamType			m_ParamType;

    void*				m_pParam;
};
class CPDF_ContentMarkData
{
public:

    CPDF_ContentMarkData() { }

    CPDF_ContentMarkData(const CPDF_ContentMarkData& src);

    inline int			CountItems() const
    {
        return m_Marks.GetSize();
    }

    inline CPDF_ContentMarkItem&	GetItem(int index) const
    {
        return m_Marks[index];
    }

    int					GetMCID() const;

    void				AddMark(const CFX_ByteString& name, CPDF_Dictionary* pDict, bool bDictNeedClone);

    void				DeleteLastMark();
private:

    CFX_ObjectArray<CPDF_ContentMarkItem>	m_Marks;
};
class CPDF_ContentMark : public CFX_CountRef<CPDF_ContentMarkData>
{
public:

    int					GetMCID() const
    {
        return m_pObject ? m_pObject->GetMCID() : -1;
    }

    bool				HasMark(const CFX_ByteStringC& mark) const;

    bool				LookupMark(const CFX_ByteStringC& mark, CPDF_Dictionary*& pDict) const;
};

#define PDFPAGE_TEXT     1
#define PDFPAGE_PATH     2
#define PDFPAGE_IMAGE    3
#define PDFPAGE_SHADING  4
#define PDFPAGE_FORM     5

class CPDF_GraphicStates
{
public:
    void				CopyStates(const CPDF_GraphicStates& src);

    void				DefaultStates();

    CPDF_ClipPath		m_ClipPath;

    CPDF_GraphState		m_GraphState;

    CPDF_ColorState		m_ColorState;

    CPDF_TextState		m_TextState;

    CPDF_GeneralState	m_GeneralState;
};

class CPDF_PageObject : public CPDF_GraphicStates
{
public:
    static CPDF_PageObject* Create(int type);
    virtual ~CPDF_PageObject();

    CPDF_PageObject*	Clone() const;

    void				Copy(const CPDF_PageObject* pSrcObject);

    virtual void Transform(const CFX_AffineMatrix& matrix) = 0;

    void				RemoveClipPath();

    void				AppendClipPath(CPDF_Path path, int type, bool bAutoMerge);

    void				CopyClipPath(CPDF_PageObject* pObj);

    void				TransformClipPath(CFX_AffineMatrix& matrix);

    void				TransformGeneralState(CFX_AffineMatrix& matrix);

    void				SetColorState(CPDF_ColorState state)
    {
        m_ColorState = state;
    }

    FX_RECT				GetBBox(const CFX_AffineMatrix* pMatrix) const;

    int					m_Type;

    FX_FLOAT			m_Left;

    FX_FLOAT			m_Right;

    FX_FLOAT			m_Top;

    FX_FLOAT			m_Bottom;

    CPDF_ContentMark	m_ContentMark;

protected:
    virtual void CopyData(const CPDF_PageObject* pSrcObject) = 0;

    void				RecalcBBox();

    CPDF_PageObject() {}

};

struct CPDF_TextObjectItem {
    FX_DWORD m_CharCode;
    FX_FLOAT m_OriginX;
    FX_FLOAT m_OriginY;
};

class CPDF_TextObject : public CPDF_PageObject
{
public:
    CPDF_TextObject();
    ~CPDF_TextObject() override;

    int CountItems() const
    {
        return m_nChars;
    }

    void GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const;

    int CountChars() const;

    void GetCharInfo(int index, FX_DWORD& charcode, FX_FLOAT& kerning) const;
    void GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const;

    void GetCharRect(int index, CFX_FloatRect& rect) const;

    FX_FLOAT GetCharWidth(FX_DWORD charcode) const;
    FX_FLOAT GetSpaceCharWidth() const;

    FX_FLOAT GetPosX() const
    {
        return m_PosX;
    }

    FX_FLOAT GetPosY() const
    {
        return m_PosY;
    }

    void GetTextMatrix(CFX_AffineMatrix* pMatrix) const;

    CPDF_Font* GetFont() const
    {
        return m_TextState.GetFont();
    }

    FX_FLOAT GetFontSize() const
    {
        return m_TextState.GetFontSize();
    }

    void SetEmpty();

    void SetText(const CFX_ByteString& text);

    void SetText(CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs);

    void SetText(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pKernings);

    void SetPosition(FX_FLOAT x, FX_FLOAT y);

    void SetTextState(CPDF_TextState TextState);

    // CPDF_PageObject:
    void Transform(const CFX_AffineMatrix& matrix) override;

    void CalcCharPos(FX_FLOAT* pPosArray) const;

    void SetData(int nChars,
                 FX_DWORD* pCharCodes,
                 FX_FLOAT* pCharPos,
                 FX_FLOAT x,
                 FX_FLOAT y);

    void GetData(int& nChars, FX_DWORD*& pCharCodes, FX_FLOAT*& pCharPos)
    {
        nChars = m_nChars;
        pCharCodes = m_pCharCodes;
        pCharPos = m_pCharPos;
    }


    void RecalcPositionData()
    {
        CalcPositionData(nullptr, nullptr, 1);
    }

protected:
    friend class CPDF_RenderStatus;
    friend class CPDF_StreamContentParser;
    friend class CPDF_TextRenderer;
    friend class CTextPage;

    // CPDF_PageObject:
    void CopyData(const CPDF_PageObject* pSrcObject) override;

    void SetSegments(const CFX_ByteString* pStrs,
                     FX_FLOAT* pKerning,
                     int nSegs);

    void CalcPositionData(FX_FLOAT* pTextAdvanceX,
                          FX_FLOAT* pTextAdvanceY,
                          FX_FLOAT horz_scale,
                          int level = 0);

    FX_FLOAT m_PosX;
    FX_FLOAT m_PosY;

    int m_nChars;

    FX_DWORD* m_pCharCodes;

    FX_FLOAT* m_pCharPos;
};

class CPDF_PathObject : public CPDF_PageObject
{
public:
    CPDF_PathObject()
    {
        m_Type = PDFPAGE_PATH;
    }

    virtual ~CPDF_PathObject() {}
    void Transform(const CFX_AffineMatrix& maxtrix) override;

    void				SetGraphState(CPDF_GraphState GraphState);

    CPDF_Path			m_Path;

    int					m_FillType;

    bool				m_bStroke;

    CFX_AffineMatrix	m_Matrix;


    void				CalcBoundingBox();

protected:
    void CopyData(const CPDF_PageObject* pSrcObject) override;
};

class CPDF_ImageObject : public CPDF_PageObject
{
public:
    CPDF_ImageObject();

    virtual ~CPDF_ImageObject();
    void Transform(const CFX_AffineMatrix& matrix) override;

    CPDF_Image*			m_pImage;

    CFX_AffineMatrix	m_Matrix;

    void				CalcBoundingBox();

private:
    void CopyData(const CPDF_PageObject* pSrcObject) override;
};

class CPDF_ShadingObject : public CPDF_PageObject
{
public:
    CPDF_ShadingObject();

    virtual ~CPDF_ShadingObject();

    CPDF_ShadingPattern*	m_pShading;

    CFX_AffineMatrix	m_Matrix;

    void Transform(const CFX_AffineMatrix& matrix) override;

    void				CalcBoundingBox();

protected:
    void CopyData(const CPDF_PageObject* pSrcObject) override;
};

class CPDF_FormObject : public CPDF_PageObject
{
public:
    CPDF_FormObject()
    {
        m_Type = PDFPAGE_FORM;
        m_pForm = NULL;
    }

    virtual ~CPDF_FormObject();
    void Transform(const CFX_AffineMatrix& matrix) override;

    CPDF_Form*			m_pForm;

    CFX_AffineMatrix	m_FormMatrix;

    void				CalcBoundingBox();

protected:
    void CopyData(const CPDF_PageObject* pSrcObject) override;
};

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
