// Copyright 2016 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 "xfa/fxfa/parser/cxfa_stroke.h"

#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/xfa_utils.h"

int32_t CXFA_Stroke::GetPresence() const {
  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Presence)
                 : XFA_ATTRIBUTEENUM_Invisible;
}

int32_t CXFA_Stroke::GetCapType() const {
  if (!m_pNode)
    return XFA_ATTRIBUTEENUM_Square;
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Cap);
}

int32_t CXFA_Stroke::GetStrokeType() const {
  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Stroke)
                 : XFA_ATTRIBUTEENUM_Solid;
}

float CXFA_Stroke::GetThickness() const {
  return GetMSThickness().ToUnit(XFA_UNIT_Pt);
}

CXFA_Measurement CXFA_Stroke::GetMSThickness() const {
  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Thickness)
                 : XFA_GetAttributeDefaultValue_Measure(XFA_Element::Edge,
                                                        XFA_ATTRIBUTE_Thickness,
                                                        XFA_XDPPACKET_Form);
}

void CXFA_Stroke::SetMSThickness(CXFA_Measurement msThinkness) {
  if (!m_pNode)
    return;

  m_pNode->SetMeasure(XFA_ATTRIBUTE_Thickness, msThinkness);
}

FX_ARGB CXFA_Stroke::GetColor() const {
  if (!m_pNode)
    return 0xFF000000;

  CXFA_Node* pNode = m_pNode->GetChild(0, XFA_Element::Color);
  if (!pNode)
    return 0xFF000000;

  WideStringView wsColor;
  pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor);
  return CXFA_Data::ToColor(wsColor);
}

void CXFA_Stroke::SetColor(FX_ARGB argb) {
  if (!m_pNode)
    return;

  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_Element::Color);
  WideString wsColor;
  int a;
  int r;
  int g;
  int b;
  std::tie(a, r, g, b) = ArgbDecode(argb);
  wsColor.Format(L"%d,%d,%d", r, g, b);
  pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
}

int32_t CXFA_Stroke::GetJoinType() const {
  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Join)
                 : XFA_ATTRIBUTEENUM_Square;
}

bool CXFA_Stroke::IsInverted() const {
  return m_pNode ? m_pNode->GetBoolean(XFA_ATTRIBUTE_Inverted) : false;
}

float CXFA_Stroke::GetRadius() const {
  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Radius).ToUnit(XFA_UNIT_Pt)
                 : 0;
}

bool CXFA_Stroke::SameStyles(CXFA_Stroke stroke, uint32_t dwFlags) const {
  if (m_pNode == stroke.GetNode())
    return true;
  if (fabs(GetThickness() - stroke.GetThickness()) >= 0.01f)
    return false;
  if ((dwFlags & XFA_STROKE_SAMESTYLE_NoPresence) == 0 &&
      IsVisible() != stroke.IsVisible()) {
    return false;
  }
  if (GetStrokeType() != stroke.GetStrokeType())
    return false;
  if (GetColor() != stroke.GetColor())
    return false;
  if ((dwFlags & XFA_STROKE_SAMESTYLE_Corner) != 0 &&
      fabs(GetRadius() - stroke.GetRadius()) >= 0.01f) {
    return false;
  }
  return true;
}
