// 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 XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
#define XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_

#include <memory>
#include <vector>

#include "core/fxcrt/include/fx_ext.h"
#include "xfa/fde/css/fde_css.h"
#include "xfa/fde/css/fde_csscache.h"
#include "xfa/fde/css/fde_cssdeclaration.h"
#include "xfa/fgas/crt/fgas_memory.h"
#include "xfa/fgas/crt/fgas_system.h"

class CFDE_CSSAccelerator;
class CFDE_CSSComputedStyle;
class CXFA_CSSTagProvider;

class FDE_CSSRuleData : public CFX_Target {
 public:
  FDE_CSSRuleData(CFDE_CSSSelector* pSel,
                  CFDE_CSSDeclaration* pDecl,
                  uint32_t dwPos);

  CFDE_CSSSelector* const pSelector;
  CFDE_CSSDeclaration* const pDeclaration;
  uint32_t dwPriority;
  FDE_CSSRuleData* pNext;
};

class CFDE_CSSRuleCollection : public CFX_Target {
 public:
  CFDE_CSSRuleCollection();
  ~CFDE_CSSRuleCollection() override;

  void AddRulesFrom(const CFDE_CSSStyleSheetArray& sheets,
                    uint32_t dwMediaList,
                    IFGAS_FontMgr* pFontMgr);
  void Clear();

  int32_t CountSelectors() const { return m_iSelectors; }
  FDE_CSSRuleData* GetIDRuleData(uint32_t dwIDHash) {
    void* pData;
    return m_IDRules.Lookup((void*)(uintptr_t)dwIDHash, pData)
               ? (FDE_CSSRuleData*)pData
               : nullptr;
  }
  FDE_CSSRuleData* GetTagRuleData(uint32_t dwTagHasn) {
    void* pData;
    return m_TagRules.Lookup((void*)(uintptr_t)dwTagHasn, pData)
               ? (FDE_CSSRuleData*)pData
               : nullptr;
  }
  FDE_CSSRuleData* GetClassRuleData(uint32_t dwIDHash) {
    void* pData;
    return m_ClassRules.Lookup((void*)(uintptr_t)dwIDHash, pData)
               ? (FDE_CSSRuleData*)pData
               : nullptr;
  }
  FDE_CSSRuleData* GetUniversalRuleData() { return m_pUniversalRules; }
  FDE_CSSRuleData* GetPersudoRuleData() { return m_pPersudoRules; }

  IFX_MemoryAllocator* m_pStaticStore;

 protected:
  void AddRulesFrom(IFDE_CSSStyleSheet* pStyleSheet,
                    IFDE_CSSRule* pRule,
                    uint32_t dwMediaList,
                    IFGAS_FontMgr* pFontMgr);
  void AddRuleTo(CFX_MapPtrToPtr& map,
                 uint32_t dwKey,
                 CFDE_CSSSelector* pSel,
                 CFDE_CSSDeclaration* pDecl);
  FX_BOOL AddRuleTo(FDE_CSSRuleData*& pList, FDE_CSSRuleData* pData);
  FDE_CSSRuleData* NewRuleData(CFDE_CSSSelector* pSel,
                               CFDE_CSSDeclaration* pDecl);
  CFX_MapPtrToPtr m_IDRules;
  CFX_MapPtrToPtr m_TagRules;
  CFX_MapPtrToPtr m_ClassRules;
  FDE_CSSRuleData* m_pUniversalRules;
  FDE_CSSRuleData* m_pPersudoRules;
  int32_t m_iSelectors;
};

class CFDE_CSSStyleSelector : public CFX_Target {
 public:
  explicit CFDE_CSSStyleSelector(IFGAS_FontMgr* pFontMgr);
  ~CFDE_CSSStyleSelector() override;

  void SetDefFontSize(FX_FLOAT fFontSize);

  FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType,
                        IFDE_CSSStyleSheet* pSheet);
  FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType,
                         const CFDE_CSSStyleSheetArray* pArray);
  void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType,
                        FDE_CSSSTYLESHEETPRIORITY ePriority);
  void UpdateStyleIndex(uint32_t dwMediaList);
  CFDE_CSSAccelerator* InitAccelerator();
  IFDE_CSSComputedStyle* CreateComputedStyle(
      IFDE_CSSComputedStyle* pParentStyle);
  int32_t MatchDeclarations(CXFA_CSSTagProvider* pTag,
                            CFDE_CSSDeclarationArray& matchedDecls,
                            FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE);
  void ComputeStyle(CXFA_CSSTagProvider* pTag,
                    const CFDE_CSSDeclaration** ppDeclArray,
                    int32_t iDeclCount,
                    IFDE_CSSComputedStyle* pDestStyle);

 protected:
  void Reset();
  void MatchRules(FDE_CSSTagCache* pCache,
                  FDE_CSSRuleData* pList,
                  FDE_CSSPERSUDO ePersudoType);
  FX_BOOL MatchSelector(FDE_CSSTagCache* pCache,
                        CFDE_CSSSelector* pSel,
                        FDE_CSSPERSUDO ePersudoType);
  void AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
                         const FX_WCHAR* psz,
                         int32_t iLen);
  void ApplyDeclarations(FX_BOOL bPriority,
                         const CFDE_CSSDeclaration** ppDeclArray,
                         int32_t iDeclCount,
                         IFDE_CSSComputedStyle* pDestStyle);
  void ApplyProperty(FDE_CSSPROPERTY eProperty,
                     IFDE_CSSValue* pValue,
                     CFDE_CSSComputedStyle* pComputedStyle);

  FX_FLOAT ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit,
                       FX_FLOAT fValue,
                       FX_FLOAT fPercentBase);
  FX_BOOL SetLengthWithPercent(FDE_CSSLENGTH& width,
                               FDE_CSSPRIMITIVETYPE eType,
                               IFDE_CSSPrimitiveValue* pPrimitive,
                               FX_FLOAT fFontSize);
  FX_FLOAT ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize);
  FDE_CSSDISPLAY ToDisplay(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSTEXTALIGN ToTextAlign(FDE_CSSPROPERTYVALUE eValue);
  uint16_t ToFontWeight(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSFONTSTYLE ToFontStyle(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSBORDERSTYLE ToBorderStyle(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSVERTICALALIGN ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSLISTSTYLETYPE ToListStyleType(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSLISTSTYLEPOSITION ToListStylePosition(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSVISIBILITY ToVisibility(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSWHITESPACE ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue);
  uint32_t ToTextDecoration(IFDE_CSSValueList* pList);
  FDE_CSSTEXTTRANSFORM ToTextTransform(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSFONTVARIANT ToFontVariant(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSFLOAT ToFloat(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSCLEAR ToClear(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSWRITINGMODE ToWritingMode(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSWORDBREAK ToWordBreak(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSPAGEBREAK ToPageBreak(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSOVERFLOW ToOverflow(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSLINEBREAK ToLineBreak(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSTEXTCOMBINE ToTextCombine(FDE_CSSPROPERTYVALUE eValue);
  FX_BOOL ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue,
                             FDE_CSSTEXTEMPHASISMARK& eMark);
  FX_BOOL ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue,
                             FDE_CSSTEXTEMPHASISFILL& eFill);
  FDE_CSSCURSOR ToCursor(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSPOSITION ToPosition(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSCAPTIONSIDE ToCaptionSide(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSBKGREPEAT ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSBKGATTACHMENT ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYALIGN ToRubyAlign(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYOVERHANG ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYPOSITION ToRubyPosition(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYSPAN ToRubySpan(FDE_CSSPROPERTYVALUE eValue);

  IFGAS_FontMgr* const m_pFontMgr;
  FX_FLOAT m_fDefFontSize;
  std::unique_ptr<IFX_MemoryAllocator> m_pRuleDataStore;
  CFDE_CSSStyleSheetArray m_SheetGroups[FDE_CSSSTYLESHEETGROUP_MAX];
  CFDE_CSSRuleCollection m_RuleCollection[FDE_CSSSTYLESHEETGROUP_MAX];
  FDE_CSSSTYLESHEETGROUP m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_MAX];
  std::unique_ptr<IFX_MemoryAllocator> m_pInlineStyleStore;
  std::unique_ptr<IFX_MemoryAllocator> m_pFixedStyleStore;
  std::unique_ptr<CFDE_CSSAccelerator> m_pAccelerator;
  std::vector<FDE_CSSRuleData*> m_MatchedRules;
};

struct FDE_CSSCOUNTERDATA {
 public:
  FDE_CSSCOUNTERDATA() { FXSYS_memset(this, 0, sizeof(FDE_CSSCOUNTERDATA)); }
  FX_BOOL GetCounterIncrement(int32_t& iValue) {
    iValue = m_iIncVal;
    return m_bIncrement;
  }
  FX_BOOL GetCounterReset(int32_t& iValue) {
    iValue = m_iResetVal;
    return m_bReset;
  }

  const FX_WCHAR* m_pszIdent;
  FX_BOOL m_bIncrement;
  FX_BOOL m_bReset;
  int32_t m_iIncVal;
  int32_t m_iResetVal;
};

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

  void SetCounterIncrementList(IFDE_CSSValueList* pList) {
    m_pCounterInc = pList;
    m_bIndexDirty = TRUE;
  }
  void SetCounterResetList(IFDE_CSSValueList* pList) {
    m_pCounterReset = pList;
    m_bIndexDirty = TRUE;
  }
  int32_t CountCounters() {
    UpdateIndex();
    return m_arrCounterData.GetSize();
  }
  FX_BOOL GetCounterIncrement(int32_t index, int32_t& iValue) {
    UpdateIndex();
    return m_arrCounterData.ElementAt(index).GetCounterIncrement(iValue);
  }
  FX_BOOL GetCounterReset(int32_t index, int32_t& iValue) {
    UpdateIndex();
    return m_arrCounterData.ElementAt(index).GetCounterReset(iValue);
  }
  const FX_WCHAR* GetCounterIdentifier(int32_t index) {
    UpdateIndex();
    return m_arrCounterData.ElementAt(index).m_pszIdent;
  }

 protected:
  void UpdateIndex();
  void DoUpdateIndex(IFDE_CSSValueList* pList);
  int32_t FindIndex(const FX_WCHAR* pszIdentifier);

  IFDE_CSSValueList* m_pCounterInc;
  IFDE_CSSValueList* m_pCounterReset;
  CFX_ArrayTemplate<FDE_CSSCOUNTERDATA> m_arrCounterData;
  FX_BOOL m_bIndexDirty;
};

class CFDE_CSSInheritedData {
 public:
  CFDE_CSSInheritedData();

  void Reset();

  const FX_WCHAR* m_pszListStyleImage;
  FDE_CSSLENGTH m_LetterSpacing;
  FDE_CSSLENGTH m_WordSpacing;
  FDE_CSSLENGTH m_TextIndent;
  IFDE_CSSValueList* m_pFontFamily;
  IFDE_CSSValueList* m_pQuotes;
  IFDE_CSSValueList* m_pCursorUris;
  FDE_CSSCURSOR m_eCursor;
  FX_FLOAT m_fFontSize;
  FX_FLOAT m_fLineHeight;
  FX_ARGB m_dwFontColor;
  FX_ARGB m_dwTextEmphasisColor;
  uint16_t m_wFontWeight;
  int32_t m_iWidows;
  int32_t m_iOrphans;
  const FX_WCHAR* m_pszTextEmphasisCustomMark;
  uint32_t m_eFontVariant : 1;
  uint32_t m_eFontStyle : 1;
  uint32_t m_bTextEmphasisColorCurrent : 1;
  uint32_t m_eTextAligh : 2;
  uint32_t m_eVisibility : 2;
  uint32_t m_eWhiteSpace : 3;
  uint32_t m_eTextTransform : 2;
  uint32_t m_eWritingMode : 2;
  uint32_t m_eWordBreak : 2;
  uint32_t m_eLineBreak : 2;
  uint32_t m_eTextEmphasisFill : 1;
  uint32_t m_eTextEmphasisMark : 3;
  uint32_t m_eCaptionSide : 3;
  uint8_t m_eRubyAlign : 4;
  uint8_t m_eRubyOverhang : 2;
  uint8_t m_eRubyPosition : 2;
};

class CFDE_CSSNonInheritedData {
 public:
  CFDE_CSSNonInheritedData();

  void Reset();

  IFDE_CSSValueList* m_pContentList;
  CFDE_CSSCounterStyle* m_pCounterStyle;
  FDE_CSSRECT m_MarginWidth;
  FDE_CSSRECT m_BorderWidth;
  FDE_CSSRECT m_PaddingWidth;
  FDE_CSSSIZE m_BoxSize;
  FDE_CSSSIZE m_MinBoxSize;
  FDE_CSSSIZE m_MaxBoxSize;
  FDE_CSSPOINT m_BKGPosition;
  const FX_WCHAR* m_pszBKGImage;
  FX_ARGB m_dwBKGColor;
  FX_ARGB m_dwBDRLeftColor;
  FX_ARGB m_dwBDRTopColor;
  FX_ARGB m_dwBDRRightColor;
  FX_ARGB m_dwBDRBottomColor;
  IFDE_CSSValue* m_pRubySpan;
  FDE_CSSLENGTH m_ColumnCount;
  FDE_CSSLENGTH m_ColumnGap;
  FDE_CSSLENGTH m_ColumnRuleWidth;
  FDE_CSSLENGTH m_ColumnWidth;
  FX_ARGB m_dwColumnRuleColor;
  FDE_CSSLENGTH m_Top;
  FDE_CSSLENGTH m_Bottom;
  FDE_CSSLENGTH m_Left;
  FDE_CSSLENGTH m_Right;

  FX_FLOAT m_fVerticalAlign;
  FX_FLOAT m_fTextCombineNumber;
  uint32_t m_eBDRLeftStyle : 4;
  uint32_t m_eBDRTopStyle : 4;
  uint32_t m_eBDRRightStyle : 4;
  uint32_t m_eBDRBottomStyle : 4;
  uint32_t m_eDisplay : 5;
  uint32_t m_eVerticalAlign : 4;
  uint32_t m_eListStyleType : 5;
  uint32_t m_eColumnRuleStyle : 4;
  uint32_t m_ePageBreakInside : 3;
  uint32_t m_ePageBreakAfter : 3;
  uint32_t m_ePageBreakBefore : 3;
  uint32_t m_ePosition : 2;
  uint32_t m_eBKGRepeat : 2;
  uint32_t m_eFloat : 2;
  uint32_t m_eClear : 2;
  uint32_t m_eOverflowX : 3;
  uint32_t m_eOverflowY : 3;
  uint32_t m_eListStylePosition : 1;
  uint32_t m_eBKGAttachment : 1;
  uint32_t m_bHasMargin : 1;
  uint32_t m_bHasBorder : 1;
  uint32_t m_bHasPadding : 1;
  uint32_t m_dwTextDecoration : 5;
  uint32_t m_eTextCombine : 1;
  uint32_t m_bColumnRuleColorSame : 1;
  uint32_t m_bHasTextCombineNumber : 1;
};

class CFDE_CSSComputedStyle : public IFDE_CSSComputedStyle,
                              public IFDE_CSSBoundaryStyle,
                              public IFDE_CSSFontStyle,
                              public IFDE_CSSPositionStyle,
                              public IFDE_CSSParagraphStyle,
                              public CFX_Target {
 public:
  CFDE_CSSComputedStyle(IFX_MemoryAllocator* pAlloc);
  ~CFDE_CSSComputedStyle() override;

  // IFX_Retainable
  uint32_t Retain() override;
  uint32_t Release() override;

  // IFDE_CSSComputedStyle
  void Reset() override;
  IFDE_CSSFontStyle* GetFontStyles() override;
  IFDE_CSSBoundaryStyle* GetBoundaryStyles() override;
  IFDE_CSSPositionStyle* GetPositionStyles() override;
  IFDE_CSSParagraphStyle* GetParagraphStyles() override;
  FX_BOOL GetCustomStyle(const CFX_WideStringC& wsName,
                         CFX_WideString& wsValue) const override;

  // IFDE_CSSFontStyle:
  int32_t CountFontFamilies() const override;
  const FX_WCHAR* GetFontFamily(int32_t index) const override;
  uint16_t GetFontWeight() const override;
  FDE_CSSFONTVARIANT GetFontVariant() const override;
  FDE_CSSFONTSTYLE GetFontStyle() const override;
  FX_FLOAT GetFontSize() const override;
  FX_ARGB GetColor() const override;
  void SetFontWeight(uint16_t wFontWeight) override;
  void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant) override;
  void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle) override;
  void SetFontSize(FX_FLOAT fFontSize) override;
  void SetColor(FX_ARGB dwFontColor) override;

  // IFDE_CSSBoundaryStyle:
  const FDE_CSSRECT* GetBorderWidth() const override;
  const FDE_CSSRECT* GetMarginWidth() const override;
  const FDE_CSSRECT* GetPaddingWidth() const override;
  void SetMarginWidth(const FDE_CSSRECT& rect) override;
  void SetPaddingWidth(const FDE_CSSRECT& rect) override;

  // IFDE_CSSPositionStyle:
  FDE_CSSDISPLAY GetDisplay() const override;

  // IFDE_CSSParagraphStyle:
  FX_FLOAT GetLineHeight() const override;
  const FDE_CSSLENGTH& GetTextIndent() const override;
  FDE_CSSTEXTALIGN GetTextAlign() const override;
  FDE_CSSVERTICALALIGN GetVerticalAlign() const override;
  FX_FLOAT GetNumberVerticalAlign() const override;
  uint32_t GetTextDecoration() const override;
  const FDE_CSSLENGTH& GetLetterSpacing() const override;
  void SetLineHeight(FX_FLOAT fLineHeight) override;
  void SetTextIndent(const FDE_CSSLENGTH& textIndent) override;
  void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign) override;
  void SetNumberVerticalAlign(FX_FLOAT fAlign) override;
  void SetTextDecoration(uint32_t dwTextDecoration) override;
  void SetLetterSpacing(const FDE_CSSLENGTH& letterSpacing) override;
  void AddCustomStyle(const CFX_WideString& wsName,
                      const CFX_WideString& wsValue);

  uint32_t m_dwRefCount;
  IFX_MemoryAllocator* const m_pAllocator;
  CFDE_CSSInheritedData m_InheritedData;
  CFDE_CSSNonInheritedData m_NonInheritedData;
  CFX_WideStringArray m_CustomProperties;
};

#endif  // XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
