// 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_CSSSTYLESHEET_H_
#define XFA_FDE_CSS_FDE_CSSSTYLESHEET_H_

#include <memory>
#include <unordered_map>

#include "core/fxcrt/include/fx_ext.h"
#include "xfa/fde/css/fde_cssdeclaration.h"

class CFDE_CSSSyntaxParser;

class CFDE_CSSSelector : public CFX_Target {
 public:
  CFDE_CSSSelector(FDE_CSSSELECTORTYPE eType,
                   const FX_WCHAR* psz,
                   int32_t iLen,
                   bool bIgnoreCase);

  virtual FDE_CSSSELECTORTYPE GetType() const;
  virtual uint32_t GetNameHash() const;
  virtual CFDE_CSSSelector* GetNextSelector() const;

  static CFDE_CSSSelector* FromString(IFX_MemoryAllocator* pStaticStore,
                                      const FX_WCHAR* psz,
                                      int32_t iLen);

  void SetNext(CFDE_CSSSelector* pNext) { m_pNext = pNext; }

 protected:
  void SetType(FDE_CSSSELECTORTYPE eType) { m_eType = eType; }

  FDE_CSSSELECTORTYPE m_eType;
  uint32_t m_dwHash;
  CFDE_CSSSelector* m_pNext;
};

class CFDE_CSSStyleRule : public IFDE_CSSStyleRule, public CFX_Target {
 public:
  CFDE_CSSStyleRule();

  // IFDE_CSSStyleRule
  int32_t CountSelectorLists() const override;
  CFDE_CSSSelector* GetSelectorList(int32_t index) const override;
  CFDE_CSSDeclaration* GetDeclaration() override;

  CFDE_CSSDeclaration& GetDeclImp() { return m_Declaration; }
  void SetSelector(IFX_MemoryAllocator* pStaticStore,
                   const CFX_ArrayTemplate<CFDE_CSSSelector*>& list);

 protected:
  CFDE_CSSDeclaration m_Declaration;
  CFDE_CSSSelector** m_ppSelector;
  int32_t m_iSelectors;
};

class CFDE_CSSMediaRule : public IFDE_CSSMediaRule, public CFX_Target {
 public:
  explicit CFDE_CSSMediaRule(uint32_t dwMediaList);
  ~CFDE_CSSMediaRule() override;

  // IFDE_CSSMediaRule
  uint32_t GetMediaList() const override;
  int32_t CountRules() const override;
  IFDE_CSSRule* GetRule(int32_t index) override;

  CFX_MassArrayTemplate<IFDE_CSSRule*>& GetArray() { return m_RuleArray; }

 protected:
  uint32_t m_dwMediaList;
  CFX_MassArrayTemplate<IFDE_CSSRule*> m_RuleArray;
};

class CFDE_CSSFontFaceRule : public IFDE_CSSFontFaceRule, public CFX_Target {
 public:
  // IFDE_CSSFontFaceRule
  CFDE_CSSDeclaration* GetDeclaration() override;

  CFDE_CSSDeclaration& GetDeclImp() { return m_Declaration; }

 protected:
  CFDE_CSSDeclaration m_Declaration;
};

#define FDE_CSSSWITCHDEFAULTS()     \
  case FDE_CSSSYNTAXSTATUS_EOS:     \
    return FDE_CSSSYNTAXSTATUS_EOS; \
  case FDE_CSSSYNTAXSTATUS_Error:   \
  default:                          \
    return FDE_CSSSYNTAXSTATUS_Error;

class CFDE_CSSStyleSheet : public IFDE_CSSStyleSheet, public CFX_Target {
 public:
  CFDE_CSSStyleSheet(uint32_t dwMediaList);
  ~CFDE_CSSStyleSheet() override;

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

  // IFDE_CSSStyleSheet:
  FX_BOOL GetUrl(CFX_WideString& szUrl) override;
  uint32_t GetMediaList() const override;
  uint16_t GetCodePage() const override;
  int32_t CountRules() const override;
  IFDE_CSSRule* GetRule(int32_t index) override;

  FX_BOOL LoadFromStream(const CFX_WideString& szUrl,
                         IFX_Stream* pStream,
                         uint16_t wCodePage);
  FX_BOOL LoadFromBuffer(const CFX_WideString& szUrl,
                         const FX_WCHAR* pBuffer,
                         int32_t iBufSize,
                         uint16_t wCodePage);

 protected:
  void Reset();
  FX_BOOL LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax);
  FDE_CSSSYNTAXSTATUS LoadStyleRule(
      CFDE_CSSSyntaxParser* pSyntax,
      CFX_MassArrayTemplate<IFDE_CSSRule*>& ruleArray);
  FDE_CSSSYNTAXSTATUS LoadImportRule(CFDE_CSSSyntaxParser* pSyntax);
  FDE_CSSSYNTAXSTATUS LoadPageRule(CFDE_CSSSyntaxParser* pSyntax);
  FDE_CSSSYNTAXSTATUS LoadMediaRule(CFDE_CSSSyntaxParser* pSyntax);
  FDE_CSSSYNTAXSTATUS LoadFontFaceRule(
      CFDE_CSSSyntaxParser* pSyntax,
      CFX_MassArrayTemplate<IFDE_CSSRule*>& ruleArray);
  FDE_CSSSYNTAXSTATUS SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax);
  uint16_t m_wCodePage;
  uint16_t m_wRefCount;
  uint32_t m_dwMediaList;
  std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
  CFX_MassArrayTemplate<IFDE_CSSRule*> m_RuleArray;
  CFX_WideString m_szUrl;
  CFX_ArrayTemplate<CFDE_CSSSelector*> m_Selectors;
  std::unordered_map<uint32_t, FX_WCHAR*> m_StringCache;
};

#endif  // XFA_FDE_CSS_FDE_CSSSTYLESHEET_H_
