// 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_FXCRT_CSS_CFX_CSSDECLARATION_H_
#define CORE_FXCRT_CSS_CFX_CSSDECLARATION_H_

#include <memory>
#include <utility>
#include <vector>

#include "core/fxcrt/css/cfx_cssdatatable.h"

class CFX_CSSPropertyHolder;
class CFX_CSSCustomProperty;

class CFX_CSSDeclaration {
 public:
  using const_prop_iterator =
      std::vector<std::unique_ptr<CFX_CSSPropertyHolder>>::const_iterator;
  using const_custom_iterator =
      std::vector<std::unique_ptr<CFX_CSSCustomProperty>>::const_iterator;

  static bool ParseCSSString(const wchar_t* pszValue,
                             int32_t iValueLen,
                             int32_t* iOffset,
                             int32_t* iLength);
  static bool ParseCSSColor(const wchar_t* pszValue,
                            int32_t iValueLen,
                            FX_ARGB* dwColor);

  CFX_CSSDeclaration();
  ~CFX_CSSDeclaration();

  CFX_RetainPtr<CFX_CSSValue> GetProperty(CFX_CSSProperty eProperty,
                                          bool* bImportant) const;

  const_prop_iterator begin() const { return properties_.begin(); }
  const_prop_iterator end() const { return properties_.end(); }

  const_custom_iterator custom_begin() const {
    return custom_properties_.begin();
  }
  const_custom_iterator custom_end() const { return custom_properties_.end(); }

  bool empty() const { return properties_.empty(); }

  void AddProperty(const CFX_CSSPropertyTable* pTable,
                   const CFX_WideStringC& value);
  void AddProperty(const CFX_WideString& prop, const CFX_WideString& value);

  size_t PropertyCountForTesting() const;

  FX_ARGB ParseColorForTest(const wchar_t* pszValue,
                            int32_t iValueLen,
                            FX_ARGB* dwColor) const;

 private:
  void ParseFontProperty(const wchar_t* pszValue,
                         int32_t iValueLen,
                         bool bImportant);
  bool ParseBorderProperty(const wchar_t* pszValue,
                           int32_t iValueLen,
                           CFX_RetainPtr<CFX_CSSValue>& pWidth) const;
  void ParseValueListProperty(const CFX_CSSPropertyTable* pTable,
                              const wchar_t* pszValue,
                              int32_t iValueLen,
                              bool bImportant);
  void Add4ValuesProperty(const std::vector<CFX_RetainPtr<CFX_CSSValue>>& list,
                          bool bImportant,
                          CFX_CSSProperty eLeft,
                          CFX_CSSProperty eTop,
                          CFX_CSSProperty eRight,
                          CFX_CSSProperty eBottom);
  CFX_RetainPtr<CFX_CSSValue> ParseNumber(const wchar_t* pszValue,
                                          int32_t iValueLen);
  CFX_RetainPtr<CFX_CSSValue> ParseEnum(const wchar_t* pszValue,
                                        int32_t iValueLen);
  CFX_RetainPtr<CFX_CSSValue> ParseColor(const wchar_t* pszValue,
                                         int32_t iValueLen);
  CFX_RetainPtr<CFX_CSSValue> ParseString(const wchar_t* pszValue,
                                          int32_t iValueLen);
  void AddPropertyHolder(CFX_CSSProperty eProperty,
                         CFX_RetainPtr<CFX_CSSValue> pValue,
                         bool bImportant);

  std::vector<std::unique_ptr<CFX_CSSPropertyHolder>> properties_;
  std::vector<std::unique_ptr<CFX_CSSCustomProperty>> custom_properties_;
};

#endif  // CORE_FXCRT_CSS_CFX_CSSDECLARATION_H_
