// Copyright 2017 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

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

#include "core/fxcrt/css/cfx_cssstringvalue.h"
#include "core/fxcrt/css/cfx_cssvaluelist.h"

CFX_CSSComputedStyle::CFX_CSSComputedStyle() = default;

CFX_CSSComputedStyle::~CFX_CSSComputedStyle() = default;

bool CFX_CSSComputedStyle::GetCustomStyle(const WideString& wsName,
                                          WideString* pValue) const {
  for (auto iter = m_CustomProperties.rbegin();
       iter != m_CustomProperties.rend(); ++iter) {
    if (wsName == iter->name()) {
      *pValue = iter->value();
      return true;
    }
  }
  return false;
}

size_t CFX_CSSComputedStyle::CountFontFamilies() const {
  return m_InheritedData.m_pFontFamily
             ? m_InheritedData.m_pFontFamily->values().size()
             : 0;
}

const WideString CFX_CSSComputedStyle::GetFontFamily(size_t index) const {
  return m_InheritedData.m_pFontFamily->values()[index]
      .As<CFX_CSSStringValue>()
      ->Value();
}

uint16_t CFX_CSSComputedStyle::GetFontWeight() const {
  return m_InheritedData.m_wFontWeight;
}

CFX_CSSFontVariant CFX_CSSComputedStyle::GetFontVariant() const {
  return m_InheritedData.m_eFontVariant;
}

CFX_CSSFontStyle CFX_CSSComputedStyle::GetFontStyle() const {
  return m_InheritedData.m_eFontStyle;
}

float CFX_CSSComputedStyle::GetFontSize() const {
  return m_InheritedData.m_fFontSize;
}

FX_ARGB CFX_CSSComputedStyle::GetColor() const {
  return m_InheritedData.m_dwFontColor;
}

void CFX_CSSComputedStyle::SetFontWeight(uint16_t wFontWeight) {
  m_InheritedData.m_wFontWeight = wFontWeight;
}

void CFX_CSSComputedStyle::SetFontVariant(CFX_CSSFontVariant eFontVariant) {
  m_InheritedData.m_eFontVariant = eFontVariant;
}

void CFX_CSSComputedStyle::SetFontStyle(CFX_CSSFontStyle eFontStyle) {
  m_InheritedData.m_eFontStyle = eFontStyle;
}

void CFX_CSSComputedStyle::SetFontSize(float fFontSize) {
  m_InheritedData.m_fFontSize = fFontSize;
}

void CFX_CSSComputedStyle::SetColor(FX_ARGB dwFontColor) {
  m_InheritedData.m_dwFontColor = dwFontColor;
}

const CFX_CSSRect* CFX_CSSComputedStyle::GetBorderWidth() const {
  return m_NonInheritedData.m_bHasBorder ? &(m_NonInheritedData.m_BorderWidth)
                                         : nullptr;
}

const CFX_CSSRect* CFX_CSSComputedStyle::GetMarginWidth() const {
  return m_NonInheritedData.m_bHasMargin ? &(m_NonInheritedData.m_MarginWidth)
                                         : nullptr;
}

const CFX_CSSRect* CFX_CSSComputedStyle::GetPaddingWidth() const {
  return m_NonInheritedData.m_bHasPadding ? &(m_NonInheritedData.m_PaddingWidth)
                                          : nullptr;
}

void CFX_CSSComputedStyle::SetMarginWidth(const CFX_CSSRect& rect) {
  m_NonInheritedData.m_MarginWidth = rect;
  m_NonInheritedData.m_bHasMargin = true;
}

void CFX_CSSComputedStyle::SetPaddingWidth(const CFX_CSSRect& rect) {
  m_NonInheritedData.m_PaddingWidth = rect;
  m_NonInheritedData.m_bHasPadding = true;
}

CFX_CSSDisplay CFX_CSSComputedStyle::GetDisplay() const {
  return m_NonInheritedData.m_eDisplay;
}

float CFX_CSSComputedStyle::GetLineHeight() const {
  return m_InheritedData.m_fLineHeight;
}

const CFX_CSSLength& CFX_CSSComputedStyle::GetTextIndent() const {
  return m_InheritedData.m_TextIndent;
}

CFX_CSSTextAlign CFX_CSSComputedStyle::GetTextAlign() const {
  return m_InheritedData.m_eTextAlign;
}

CFX_CSSVerticalAlign CFX_CSSComputedStyle::GetVerticalAlign() const {
  return m_NonInheritedData.m_eVerticalAlignType;
}

float CFX_CSSComputedStyle::GetNumberVerticalAlign() const {
  return m_NonInheritedData.m_fVerticalAlign;
}

uint32_t CFX_CSSComputedStyle::GetTextDecoration() const {
  return m_NonInheritedData.m_dwTextDecoration;
}

const CFX_CSSLength& CFX_CSSComputedStyle::GetLetterSpacing() const {
  return m_InheritedData.m_LetterSpacing;
}

void CFX_CSSComputedStyle::SetLineHeight(float fLineHeight) {
  m_InheritedData.m_fLineHeight = fLineHeight;
}

void CFX_CSSComputedStyle::SetTextIndent(const CFX_CSSLength& textIndent) {
  m_InheritedData.m_TextIndent = textIndent;
}

void CFX_CSSComputedStyle::SetTextAlign(CFX_CSSTextAlign eTextAlign) {
  m_InheritedData.m_eTextAlign = eTextAlign;
}

void CFX_CSSComputedStyle::SetNumberVerticalAlign(float fAlign) {
  m_NonInheritedData.m_eVerticalAlignType = CFX_CSSVerticalAlign::Number,
  m_NonInheritedData.m_fVerticalAlign = fAlign;
}

void CFX_CSSComputedStyle::SetTextDecoration(uint32_t dwTextDecoration) {
  m_NonInheritedData.m_dwTextDecoration = dwTextDecoration;
}

void CFX_CSSComputedStyle::SetLetterSpacing(
    const CFX_CSSLength& letterSpacing) {
  m_InheritedData.m_LetterSpacing = letterSpacing;
}

void CFX_CSSComputedStyle::AddCustomStyle(const CFX_CSSCustomProperty& prop) {
  // Force the property to be copied so we aren't dependent on the lifetime
  // of whatever currently owns it.
  m_CustomProperties.push_back(prop);
}

CFX_CSSComputedStyle::InheritedData::InheritedData()
    : m_LetterSpacing(CFX_CSSLengthUnit::Normal, 0),
      m_WordSpacing(CFX_CSSLengthUnit::Normal, 0),
      m_TextIndent(CFX_CSSLengthUnit::Point, 0),
      m_pFontFamily(nullptr),
      m_fFontSize(12.0f),
      m_fLineHeight(14.0f),
      m_dwFontColor(0xFF000000),
      m_wFontWeight(400),
      m_eFontVariant(CFX_CSSFontVariant::Normal),
      m_eFontStyle(CFX_CSSFontStyle::Normal),
      m_eTextAlign(CFX_CSSTextAlign::Left) {}

CFX_CSSComputedStyle::InheritedData::~InheritedData() = default;

CFX_CSSComputedStyle::NonInheritedData::NonInheritedData()
    : m_MarginWidth(CFX_CSSLengthUnit::Point, 0),
      m_BorderWidth(CFX_CSSLengthUnit::Point, 0),
      m_PaddingWidth(CFX_CSSLengthUnit::Point, 0),
      m_fVerticalAlign(0.0f),
      m_eDisplay(CFX_CSSDisplay::Inline),
      m_eVerticalAlignType(CFX_CSSVerticalAlign::Baseline),
      m_dwTextDecoration(0),
      m_bHasMargin(false),
      m_bHasBorder(false),
      m_bHasPadding(false) {}
