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

#include "core/fxcrt/include/fx_ext.h"
#include "xfa/fxbarcode/include/BC_Library.h"
#include "xfa/fxfa/app/xfa_ffnotify.h"
#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
#include "xfa/fxfa/parser/xfa_docdata.h"
#include "xfa/fxfa/parser/xfa_doclayout.h"
#include "xfa/fxfa/parser/xfa_document.h"
#include "xfa/fxfa/parser/xfa_localemgr.h"
#include "xfa/fxfa/parser/xfa_localevalue.h"
#include "xfa/fxfa/parser/xfa_object.h"
#include "xfa/fxfa/parser/xfa_parser.h"
#include "xfa/fxfa/parser/xfa_script.h"
#include "xfa/fxfa/parser/xfa_utils.h"

static FX_ARGB XFA_WStringToColor(const CFX_WideStringC& wsValue) {
  uint8_t r = 0, g = 0, b = 0;
  if (wsValue.GetLength() == 0) {
    return 0xff000000;
  }
  int cc = 0;
  const FX_WCHAR* str = wsValue.raw_str();
  int len = wsValue.GetLength();
  while (XFA_IsSpace(str[cc]) && cc < len) {
    cc++;
  }
  if (cc >= len) {
    return 0xff000000;
  }
  while (cc < len) {
    if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
      break;
    }
    r = r * 10 + str[cc] - '0';
    cc++;
  }
  if (cc < len && str[cc] == ',') {
    cc++;
    while (XFA_IsSpace(str[cc]) && cc < len) {
      cc++;
    }
    while (cc < len) {
      if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
        break;
      }
      g = g * 10 + str[cc] - '0';
      cc++;
    }
    if (cc < len && str[cc] == ',') {
      cc++;
      while (XFA_IsSpace(str[cc]) && cc < len) {
        cc++;
      }
      while (cc < len) {
        if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
          break;
        }
        b = b * 10 + str[cc] - '0';
        cc++;
      }
    }
  }
  return (0xff << 24) | (r << 16) | (g << 8) | b;
}
XFA_ELEMENT CXFA_Data::GetClassID() const {
  return m_pNode ? m_pNode->GetClassID() : XFA_ELEMENT_UNKNOWN;
}
FX_BOOL CXFA_Data::TryMeasure(XFA_ATTRIBUTE eAttr,
                              FX_FLOAT& fValue,
                              FX_BOOL bUseDefault) const {
  CXFA_Measurement ms;
  if (m_pNode->TryMeasure(eAttr, ms, bUseDefault)) {
    fValue = ms.ToUnit(XFA_UNIT_Pt);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_Data::SetMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT fValue) {
  CXFA_Measurement ms(fValue, XFA_UNIT_Pt);
  return m_pNode->SetMeasure(eAttr, ms);
}
CXFA_Fill::CXFA_Fill(CXFA_Node* pNode) : CXFA_Data(pNode) {}
CXFA_Fill::~CXFA_Fill() {}
int32_t CXFA_Fill::GetPresence() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
}
void CXFA_Fill::SetColor(FX_ARGB color) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
  CFX_WideString wsColor;
  int a, r, g, b;
  ArgbDecode(color, a, r, g, b);
  wsColor.Format(L"%d,%d,%d", r, g, b);
  pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
}
FX_ARGB CXFA_Fill::GetColor(FX_BOOL bText) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    if (pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE)) {
      return XFA_WStringToColor(wsColor);
    }
  }
  if (bText) {
    return 0xFF000000;
  }
  return 0xFFFFFFFF;
}
int32_t CXFA_Fill::GetFillType() {
  CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pChild) {
    int32_t eType = pChild->GetClassID();
    if (eType != XFA_ELEMENT_Color && eType != XFA_ELEMENT_Extras) {
      return eType;
    }
    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return XFA_ELEMENT_Solid;
}
int32_t CXFA_Fill::GetPattern(FX_ARGB& foreColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Pattern);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    foreColor = XFA_WStringToColor(wsColor);
  } else {
    foreColor = 0xFF000000;
  }
  return pNode->GetEnum(XFA_ATTRIBUTE_Type);
}
int32_t CXFA_Fill::GetStipple(FX_ARGB& stippleColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Stipple);
  int32_t eAttr = 50;
  pNode->TryInteger(XFA_ATTRIBUTE_Rate, eAttr);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    stippleColor = XFA_WStringToColor(wsColor);
  } else {
    stippleColor = 0xFF000000;
  }
  return eAttr;
}
int32_t CXFA_Fill::GetLinear(FX_ARGB& endColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Linear);
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToRight;
  pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    endColor = XFA_WStringToColor(wsColor);
  } else {
    endColor = 0xFF000000;
  }
  return eAttr;
}
int32_t CXFA_Fill::GetRadial(FX_ARGB& endColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Radial);
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToEdge;
  pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    endColor = XFA_WStringToColor(wsColor);
  } else {
    endColor = 0xFF000000;
  }
  return eAttr;
}
CXFA_Margin::CXFA_Margin(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_Margin::GetLeftInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_LeftInset, fInset);
}
FX_BOOL CXFA_Margin::GetTopInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_TopInset, fInset);
}
FX_BOOL CXFA_Margin::GetRightInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_RightInset, fInset);
}
FX_BOOL CXFA_Margin::GetBottomInset(FX_FLOAT& fInset,
                                    FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_BottomInset, fInset);
}
CXFA_Font::CXFA_Font(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_FLOAT CXFA_Font::GetBaselineShift() {
  return m_pNode->GetMeasure(XFA_ATTRIBUTE_BaselineShift).ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Font::GetHorizontalScale() {
  CFX_WideString wsValue;
  m_pNode->TryCData(XFA_ATTRIBUTE_FontHorizontalScale, wsValue);
  int32_t iScale = FXSYS_wtoi((const FX_WCHAR*)wsValue);
  return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
}
FX_FLOAT CXFA_Font::GetVerticalScale() {
  CFX_WideString wsValue;
  m_pNode->TryCData(XFA_ATTRIBUTE_FontVerticalScale, wsValue);
  int32_t iScale = FXSYS_wtoi((const FX_WCHAR*)wsValue);
  return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
}
FX_FLOAT CXFA_Font::GetLetterSpacing() {
  CFX_WideStringC wsValue;
  if (!m_pNode->TryCData(XFA_ATTRIBUTE_LetterSpacing, wsValue)) {
    return 0;
  }
  CXFA_Measurement ms(wsValue);
  if (ms.GetUnit() == XFA_UNIT_Em) {
    return ms.GetValue() * GetFontSize();
  }
  return ms.ToUnit(XFA_UNIT_Pt);
}
int32_t CXFA_Font::GetLineThrough() {
  int32_t iValue = 0;
  m_pNode->TryInteger(XFA_ATTRIBUTE_LineThrough, iValue);
  return iValue;
}
int32_t CXFA_Font::GetUnderline() {
  int32_t iValue = 0;
  m_pNode->TryInteger(XFA_ATTRIBUTE_Underline, iValue);
  return iValue;
}
int32_t CXFA_Font::GetUnderlinePeriod() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
  m_pNode->TryEnum(XFA_ATTRIBUTE_UnderlinePeriod, eAttr);
  return eAttr;
}
FX_FLOAT CXFA_Font::GetFontSize() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_Size, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
void CXFA_Font::GetTypeface(CFX_WideStringC& wsTypeFace) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Typeface, wsTypeFace);
}
FX_BOOL CXFA_Font::IsBold() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Weight, eAttr);
  return eAttr == XFA_ATTRIBUTEENUM_Bold;
}
FX_BOOL CXFA_Font::IsItalic() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Posture, eAttr);
  return eAttr == XFA_ATTRIBUTEENUM_Italic;
}
void CXFA_Font::SetColor(FX_ARGB color) {
  CXFA_Fill fill(m_pNode->GetProperty(0, XFA_ELEMENT_Fill));
  fill.SetColor(color);
}
FX_ARGB CXFA_Font::GetColor() {
  CXFA_Fill fill(m_pNode->GetChild(0, XFA_ELEMENT_Fill));
  return fill ? fill.GetColor(TRUE) : 0xFF000000;
}
CXFA_Caption::CXFA_Caption(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Caption::GetPresence() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Visible;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Presence, eAttr);
  return eAttr;
}
int32_t CXFA_Caption::GetPlacementType() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Placement, eAttr);
  return eAttr;
}
FX_FLOAT CXFA_Caption::GetReserve() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_Reserve, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
CXFA_Margin CXFA_Caption::GetMargin() {
  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin) : NULL);
}
CXFA_Font CXFA_Caption::GetFont() {
  return CXFA_Font(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Font) : NULL);
}
CXFA_Value CXFA_Caption::GetValue() {
  return CXFA_Value(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Value) : NULL);
}
CXFA_Para::CXFA_Para(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Para::GetHorizontalAlign() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
  m_pNode->TryEnum(XFA_ATTRIBUTE_HAlign, eAttr);
  return eAttr;
}
int32_t CXFA_Para::GetVerticalAlign() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Top;
  m_pNode->TryEnum(XFA_ATTRIBUTE_VAlign, eAttr);
  return eAttr;
}
FX_FLOAT CXFA_Para::GetLineHeight() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_LineHeight, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetMarginLeft() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginLeft, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetMarginRight() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginRight, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetSpaceAbove() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceAbove, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetSpaceBelow() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceBelow, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetTextIndent() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_TextIndent, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
CXFA_Event::CXFA_Event(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Event::GetActivity() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Activity);
}
int32_t CXFA_Event::GetEventType() {
  CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pChild) {
    int32_t eType = pChild->GetClassID();
    if (eType != XFA_ELEMENT_Extras) {
      return eType;
    }
    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return XFA_ELEMENT_UNKNOWN;
}
void CXFA_Event::GetRef(CFX_WideStringC& wsRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
}
CXFA_Script CXFA_Event::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
CXFA_Submit CXFA_Event::GetSubmit() {
  return CXFA_Submit(m_pNode->GetChild(0, XFA_ELEMENT_Submit));
}
void CXFA_Event::GetSignDataTarget(CFX_WideString& wsTarget) {
  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData)) {
    CFX_WideStringC wsCData;
    pNode->TryCData(XFA_ATTRIBUTE_Target, wsCData);
    wsTarget = wsCData;
  }
}
CXFA_Script::CXFA_Script(CXFA_Node* pNode) : CXFA_Data(pNode) {}
XFA_SCRIPTTYPE CXFA_Script::GetContentType() {
  CFX_WideStringC cData;
  if (m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, cData, FALSE)) {
    if (cData == FX_WSTRC(L"application/x-javascript")) {
      return XFA_SCRIPTTYPE_Javascript;
    } else if (cData == FX_WSTRC(L"application/x-formcalc")) {
      return XFA_SCRIPTTYPE_Formcalc;
    } else {
      return XFA_SCRIPTTYPE_Unkown;
    }
  }
  return XFA_SCRIPTTYPE_Formcalc;
}
int32_t CXFA_Script::GetRunAt() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_RunAt);
}
void CXFA_Script::GetExpression(CFX_WideString& wsExpression) {
  m_pNode->TryContent(wsExpression);
}
CXFA_Submit::CXFA_Submit(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_Submit::IsSubmitEmbedPDF() {
  return m_pNode->GetBoolean(XFA_ATTRIBUTE_EmbedPDF);
}
int32_t CXFA_Submit::GetSubmitFormat() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Format);
}
void CXFA_Submit::GetSubmitTarget(CFX_WideStringC& wsTarget) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Target, wsTarget);
}
void CXFA_Submit::GetSubmitXDPContent(CFX_WideStringC& wsContent) {
  m_pNode->TryCData(XFA_ATTRIBUTE_XdpContent, wsContent);
}
XFA_ELEMENT CXFA_Value::GetChildValueClassID() {
  if (!m_pNode) {
    return XFA_ELEMENT_UNKNOWN;
  }
  if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
    return pNode->GetClassID();
  }
  return XFA_ELEMENT_UNKNOWN;
}
FX_BOOL CXFA_Value::GetChildValueContent(CFX_WideString& wsContent) {
  if (!m_pNode) {
    return FALSE;
  }
  if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
    return pNode->TryContent(wsContent);
  }
  return FALSE;
}
CXFA_Arc CXFA_Value::GetArc() {
  return CXFA_Arc(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                          : nullptr);
}
CXFA_Line CXFA_Value::GetLine() {
  return CXFA_Line(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                           : nullptr);
}
CXFA_Rectangle CXFA_Value::GetRectangle() {
  return CXFA_Rectangle(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                                : nullptr);
}
CXFA_Text CXFA_Value::GetText() {
  return CXFA_Text(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                           : nullptr);
}
CXFA_ExData CXFA_Value::GetExData() {
  return CXFA_ExData(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                             : nullptr);
}
CXFA_Image CXFA_Value::GetImage() {
  return CXFA_Image(
      m_pNode ? (m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : nullptr,
      TRUE);
}
int32_t CXFA_Line::GetHand() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
}
FX_BOOL CXFA_Line::GetSlop() {
  XFA_ATTRIBUTEENUM eSlop = m_pNode->GetEnum(XFA_ATTRIBUTE_Slope);
  return eSlop == XFA_ATTRIBUTEENUM_Slash;
}
CXFA_Edge CXFA_Line::GetEdge() {
  return CXFA_Edge(m_pNode->GetChild(0, XFA_ELEMENT_Edge));
}
CXFA_Text::CXFA_Text(CXFA_Node* pNode) : CXFA_Data(pNode) {}
void CXFA_Text::GetContent(CFX_WideString& wsText) {
  m_pNode->TryContent(wsText);
}
CXFA_ExData::CXFA_ExData(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_ExData::SetContentType(const CFX_WideString& wsContentType) {
  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
}
CXFA_Image::CXFA_Image(CXFA_Node* pNode, FX_BOOL bDefValue)
    : CXFA_Data(pNode), m_bDefValue(bDefValue) {}
int32_t CXFA_Image::GetAspect() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Aspect);
}
FX_BOOL CXFA_Image::GetContentType(CFX_WideString& wsContentType) {
  return m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, wsContentType);
}
FX_BOOL CXFA_Image::GetHref(CFX_WideString& wsHref) {
  if (m_bDefValue) {
    return m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref);
  }
  return m_pNode->GetAttribute(FX_WSTRC(L"href"), wsHref);
}
int32_t CXFA_Image::GetTransferEncoding() {
  if (m_bDefValue) {
    return m_pNode->GetEnum(XFA_ATTRIBUTE_TransferEncoding);
  }
  return XFA_ATTRIBUTEENUM_Base64;
}
FX_BOOL CXFA_Image::GetContent(CFX_WideString& wsText) {
  return m_pNode->TryContent(wsText);
}
FX_BOOL CXFA_Image::SetContentType(const CFX_WideString& wsContentType) {
  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
}
FX_BOOL CXFA_Image::SetHref(const CFX_WideString& wsHref) {
  if (m_bDefValue) {
    return m_pNode->SetCData(XFA_ATTRIBUTE_Href, wsHref);
  }
  return m_pNode->SetAttribute(XFA_ATTRIBUTE_Href, wsHref.AsWideStringC());
}
FX_BOOL CXFA_Image::SetTransferEncoding(int32_t iTransferEncoding) {
  if (m_bDefValue) {
    return m_pNode->SetEnum(XFA_ATTRIBUTE_TransferEncoding,
                            (XFA_ATTRIBUTEENUM)iTransferEncoding);
  }
  return TRUE;
}
CXFA_Calculate::CXFA_Calculate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Calculate::GetOverride() {
  XFA_ATTRIBUTEENUM eAtt = XFA_ATTRIBUTEENUM_Error;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Override, eAtt, FALSE);
  return eAtt;
}
CXFA_Script CXFA_Calculate::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
void CXFA_Calculate::GetMessageText(CFX_WideString& wsMessage) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Message)) {
    CXFA_Text text(pNode->GetChild(0, XFA_ELEMENT_Text));
    if (text) {
      text.GetContent(wsMessage);
    }
  }
}
CXFA_Validate::CXFA_Validate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Validate::GetFormatTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_FormatTest);
}
FX_BOOL CXFA_Validate::SetTestValue(int32_t iType,
                                    CFX_WideString& wsValue,
                                    XFA_ATTRIBUTEENUM eName) {
  const XFA_ATTRIBUTEENUMINFO* pInfo =
      XFA_GetAttributeEnumByName(wsValue.AsWideStringC());
  if (pInfo) {
    eName = pInfo->eName;
  }
  m_pNode->SetEnum((XFA_ATTRIBUTE)iType, eName, FALSE);
  return TRUE;
}
FX_BOOL CXFA_Validate::SetNullTest(CFX_WideString wsValue) {
  return SetTestValue(XFA_ATTRIBUTE_NullTest, wsValue,
                      XFA_ATTRIBUTEENUM_Disabled);
}
int32_t CXFA_Validate::GetNullTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_NullTest);
}
int32_t CXFA_Validate::GetScriptTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_ScriptTest);
}
void CXFA_Validate::GetMessageText(CFX_WideString& wsMessage,
                                   const CFX_WideStringC& wsMessageType) {
  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, FALSE)) {
    CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pItemNode;
         pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
        continue;
      }
      CFX_WideStringC wsName;
      pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName.IsEmpty() || wsName == wsMessageType) {
        pItemNode->TryContent(wsMessage);
        return;
      }
    }
  }
}
void CXFA_Validate::SetFormatMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
}
void CXFA_Validate::GetFormatMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
}
void CXFA_Validate::SetNullMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
}
void CXFA_Validate::GetNullMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
}
void CXFA_Validate::SetMessageText(CFX_WideString& wsMessage,
                                   const CFX_WideStringC& wsMessageType) {
  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, TRUE)) {
    CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pItemNode;
         pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
        continue;
      }
      CFX_WideStringC wsName;
      pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName.IsEmpty() || wsName == wsMessageType) {
        pItemNode->SetContent(wsMessage, wsMessage, FALSE);
        return;
      }
    }
    CXFA_Node* pTextNode = pNode->CreateSamePacketNode(XFA_ELEMENT_Text);
    pNode->InsertChild(pTextNode);
    pTextNode->SetCData(XFA_ATTRIBUTE_Name, wsMessageType, FALSE);
    pTextNode->SetContent(wsMessage, wsMessage, FALSE);
  }
}
void CXFA_Validate::GetScriptMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
}
void CXFA_Validate::SetScriptMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
}
void CXFA_Validate::GetPicture(CFX_WideString& wsPicture) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
    pNode->TryContent(wsPicture);
  }
}
CXFA_Script CXFA_Validate::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
CXFA_Bind::CXFA_Bind(CXFA_Node* pNode) : CXFA_Data(pNode) {}
void CXFA_Bind::GetPicture(CFX_WideString& wsPicture) {
  if (CXFA_Node* pPicture = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
    pPicture->TryContent(wsPicture);
  }
}
CXFA_Assist::CXFA_Assist(CXFA_Node* pNode) : CXFA_Data(pNode) {}
CXFA_ToolTip CXFA_Assist::GetToolTip() {
  return CXFA_ToolTip(m_pNode->GetChild(0, XFA_ELEMENT_ToolTip));
}
CXFA_ToolTip::CXFA_ToolTip(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_ToolTip::GetTip(CFX_WideString& wsTip) {
  return m_pNode->TryContent(wsTip);
}
CXFA_BindItems::CXFA_BindItems(CXFA_Node* pNode) : CXFA_Data(pNode) {}
void CXFA_BindItems::GetLabelRef(CFX_WideStringC& wsLabelRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_LabelRef, wsLabelRef);
}
void CXFA_BindItems::GetValueRef(CFX_WideStringC& wsValueRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_ValueRef, wsValueRef);
}
void CXFA_BindItems::GetRef(CFX_WideStringC& wsRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
}
FX_BOOL CXFA_BindItems::SetConnection(const CFX_WideString& wsConnection) {
  return m_pNode->SetCData(XFA_ATTRIBUTE_Connection, wsConnection);
}
int32_t CXFA_Box::GetHand() const {
  if (!m_pNode) {
    return XFA_ATTRIBUTEENUM_Even;
  }
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
}
int32_t CXFA_Box::GetPresence() const {
  if (!m_pNode) {
    return XFA_ATTRIBUTEENUM_Hidden;
  }
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
}
int32_t CXFA_Box::CountEdges() const {
  if (!m_pNode) {
    return 0;
  }
  return m_pNode->CountChildren(XFA_ELEMENT_Edge);
}
CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
  return CXFA_Edge(
      m_pNode ? m_pNode->GetProperty(nIndex, XFA_ELEMENT_Edge, nIndex == 0)
              : nullptr);
}
static void XFA_BOX_GetStrokes(CXFA_Node* pNode,
                               CXFA_StrokeArray& strokes,
                               FX_BOOL bNULL) {
  strokes.RemoveAll();
  if (!pNode) {
    return;
  }
  strokes.SetSize(8);
  int32_t i, j;
  for (i = 0, j = 0; i < 4; i++) {
    CXFA_Corner corner =
        CXFA_Corner(pNode->GetProperty(i, XFA_ELEMENT_Corner, i == 0));
    if (corner || i == 0) {
      strokes.SetAt(j, corner);
    } else if (bNULL) {
      strokes.SetAt(j, CXFA_Stroke(nullptr));
    } else if (i == 1) {
      strokes.SetAt(j, strokes[0]);
    } else if (i == 2) {
      strokes.SetAt(j, strokes[0]);
    } else {
      strokes.SetAt(j, strokes[2]);
    }
    j++;
    CXFA_Edge edge = CXFA_Edge(pNode->GetProperty(i, XFA_ELEMENT_Edge, i == 0));
    if (edge || i == 0) {
      strokes.SetAt(j, edge);
    } else if (bNULL) {
      strokes.SetAt(j, CXFA_Stroke(nullptr));
    } else if (i == 1) {
      strokes.SetAt(j, strokes[1]);
    } else if (i == 2) {
      strokes.SetAt(j, strokes[1]);
    } else {
      strokes.SetAt(j, strokes[3]);
    }
    j++;
  }
}
void CXFA_Box::GetStrokes(CXFA_StrokeArray& strokes) const {
  XFA_BOX_GetStrokes(m_pNode, strokes, FALSE);
}
FX_BOOL CXFA_Box::IsCircular() const {
  if (!m_pNode) {
    return FALSE;
  }
  return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
}
FX_BOOL CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
  fStartAngle = 0;
  if (!m_pNode) {
    return FALSE;
  }
  CXFA_Measurement ms;
  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, FALSE);
  if (bRet) {
    fStartAngle = ms.GetValue();
  }
  return bRet;
}
FX_BOOL CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
  fSweepAngle = 360;
  if (!m_pNode) {
    return FALSE;
  }
  CXFA_Measurement ms;
  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, FALSE);
  if (bRet) {
    fSweepAngle = ms.GetValue();
  }
  return bRet;
}
CXFA_Fill CXFA_Box::GetFill(FX_BOOL bModified) const {
  if (!m_pNode) {
    return CXFA_Fill(nullptr);
  }
  CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_ELEMENT_Fill, bModified);
  return CXFA_Fill(pFillNode);
}
CXFA_Margin CXFA_Box::GetMargin() const {
  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin)
                             : nullptr);
}
static int32_t XFA_BOX_3DStyle(const CXFA_StrokeArray& strokes,
                               CXFA_Stroke& stroke) {
  int32_t iCount = strokes.GetSize();
  if (iCount < 1) {
    return 0;
  }
  stroke = strokes[0];
  for (int32_t i = 1; i < iCount; i++) {
    CXFA_Stroke find = strokes[i];
    if (!find) {
      continue;
    }
    if (!stroke) {
      stroke = find;
    } else if (stroke.GetStrokeType() != find.GetStrokeType()) {
      stroke = find;
      break;
    }
  }
  int32_t iType = stroke.GetStrokeType();
  if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
      iType == XFA_ATTRIBUTEENUM_Etched ||
      iType == XFA_ATTRIBUTEENUM_Embossed) {
    return iType;
  }
  return 0;
}
int32_t CXFA_Box::Get3DStyle(FX_BOOL& bVisible, FX_FLOAT& fThickness) const {
  if (IsArc()) {
    return 0;
  }
  CXFA_StrokeArray strokes;
  XFA_BOX_GetStrokes(m_pNode, strokes, TRUE);
  CXFA_Stroke stroke(NULL);
  int32_t iType = XFA_BOX_3DStyle(strokes, stroke);
  if (iType) {
    bVisible = stroke.IsVisible();
    fThickness = stroke.GetThickness();
  }
  return iType;
}
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;
}
FX_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;
  }
  CFX_WideStringC wsColor;
  pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor);
  return XFA_WStringToColor(wsColor);
}
void CXFA_Stroke::SetColor(FX_ARGB argb) {
  if (!m_pNode) {
    return;
  }
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
  CFX_WideString wsColor;
  int a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  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;
}
FX_BOOL CXFA_Stroke::IsInverted() const {
  return m_pNode ? m_pNode->GetBoolean(XFA_ATTRIBUTE_Inverted) : FALSE;
}
FX_FLOAT CXFA_Stroke::GetRadius() const {
  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Radius).ToUnit(XFA_UNIT_Pt)
                 : 0;
}
FX_BOOL CXFA_Stroke::SameStyles(CXFA_Stroke stroke, uint32_t dwFlags) const {
  if (m_pNode == stroke.GetNode()) {
    return TRUE;
  }
  if (FXSYS_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 &&
      FXSYS_fabs(GetRadius() - stroke.GetRadius()) >= 0.01f) {
    return FALSE;
  }
  return TRUE;
}
FX_FLOAT XFA_GetEdgeThickness(const CXFA_StrokeArray& strokes,
                              FX_BOOL b3DStyle,
                              int32_t nIndex) {
  FX_FLOAT fThickness = 0;
  {
    if (strokes[nIndex * 2 + 1].GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
      if (nIndex == 0) {
        fThickness += 2.5f;
      }
      fThickness += strokes[nIndex * 2 + 1].GetThickness() * (b3DStyle ? 4 : 2);
    }
  }
  return fThickness;
}
CXFA_WidgetData::CXFA_WidgetData(CXFA_Node* pNode)
    : CXFA_Data(pNode),
      m_bIsNull(TRUE),
      m_bPreNull(TRUE),
      m_pUiChildNode(NULL),
      m_eUIType(XFA_ELEMENT_UNKNOWN) {}
CXFA_Node* CXFA_WidgetData::GetUIChild() {
  if (m_eUIType == XFA_ELEMENT_UNKNOWN) {
    m_pUiChildNode = XFA_CreateUIChild(m_pNode, m_eUIType);
  }
  return m_pUiChildNode;
}
XFA_ELEMENT CXFA_WidgetData::GetUIType() {
  GetUIChild();
  return m_eUIType;
}
CFX_WideString CXFA_WidgetData::GetRawValue() {
  return m_pNode->GetContent();
}
int32_t CXFA_WidgetData::GetAccess(FX_BOOL bTemplate) {
  if (bTemplate) {
    CXFA_Node* pNode = m_pNode->GetTemplateNode();
    if (pNode) {
      return pNode->GetEnum(XFA_ATTRIBUTE_Access);
    }
    return XFA_ATTRIBUTEENUM_Open;
  }
  CXFA_Node* pNode = m_pNode;
  while (pNode) {
    int32_t iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Access);
    if (iAcc != XFA_ATTRIBUTEENUM_Open) {
      return iAcc;
    }
    pNode =
        pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
  }
  return XFA_ATTRIBUTEENUM_Open;
}
int32_t CXFA_WidgetData::GetRotate() {
  CXFA_Measurement ms;
  if (!m_pNode->TryMeasure(XFA_ATTRIBUTE_Rotate, ms, FALSE)) {
    return 0;
  }
  int32_t iRotate = FXSYS_round(ms.GetValue());
  iRotate = XFA_MapRotation(iRotate);
  return iRotate / 90 * 90;
}
CXFA_Border CXFA_WidgetData::GetBorder(FX_BOOL bModified) {
  return CXFA_Border(m_pNode->GetProperty(0, XFA_ELEMENT_Border, bModified));
}
CXFA_Caption CXFA_WidgetData::GetCaption(FX_BOOL bModified) {
  return CXFA_Caption(m_pNode->GetProperty(0, XFA_ELEMENT_Caption, bModified));
}
CXFA_Font CXFA_WidgetData::GetFont(FX_BOOL bModified) {
  return CXFA_Font(m_pNode->GetProperty(0, XFA_ELEMENT_Font, bModified));
}
CXFA_Margin CXFA_WidgetData::GetMargin(FX_BOOL bModified) {
  return CXFA_Margin(m_pNode->GetProperty(0, XFA_ELEMENT_Margin, bModified));
}
CXFA_Para CXFA_WidgetData::GetPara(FX_BOOL bModified) {
  return CXFA_Para(m_pNode->GetProperty(0, XFA_ELEMENT_Para, bModified));
}
void CXFA_WidgetData::GetEventList(CXFA_NodeArray& events) {
  m_pNode->GetNodeList(events, 0, XFA_ELEMENT_Event);
}
int32_t CXFA_WidgetData::GetEventByActivity(int32_t iActivity,
                                            CXFA_NodeArray& events,
                                            FX_BOOL bIsFormReady) {
  CXFA_NodeArray allEvents;
  GetEventList(allEvents);
  int32_t iCount = allEvents.GetSize();
  for (int32_t i = 0; i < iCount; i++) {
    CXFA_Event event(allEvents[i]);
    if (event.GetActivity() == iActivity) {
      if (iActivity == XFA_ATTRIBUTEENUM_Ready) {
        CFX_WideStringC wsRef;
        event.GetRef(wsRef);
        if (bIsFormReady) {
          if (wsRef == CFX_WideStringC(L"$form")) {
            events.Add(allEvents[i]);
          }
        } else {
          if (wsRef == CFX_WideStringC(L"$layout")) {
            events.Add(allEvents[i]);
          }
        }
      } else {
        events.Add(allEvents[i]);
      }
    }
  }
  return events.GetSize();
}
CXFA_Value CXFA_WidgetData::GetDefaultValue(FX_BOOL bModified) {
  CXFA_Node* pTemNode = m_pNode->GetTemplateNode();
  return CXFA_Value(pTemNode
                        ? pTemNode->GetProperty(0, XFA_ELEMENT_Value, bModified)
                        : nullptr);
}
CXFA_Value CXFA_WidgetData::GetFormValue(FX_BOOL bModified) {
  return CXFA_Value(m_pNode->GetProperty(0, XFA_ELEMENT_Value, bModified));
}
CXFA_Calculate CXFA_WidgetData::GetCalculate(FX_BOOL bModified) {
  return CXFA_Calculate(
      m_pNode->GetProperty(0, XFA_ELEMENT_Calculate, bModified));
}
CXFA_Validate CXFA_WidgetData::GetValidate(FX_BOOL bModified) {
  return CXFA_Validate(
      m_pNode->GetProperty(0, XFA_ELEMENT_Validate, bModified));
}
CXFA_Bind CXFA_WidgetData::GetBind(FX_BOOL bModified) {
  return CXFA_Bind(m_pNode->GetProperty(0, XFA_ELEMENT_Bind, bModified));
}
CXFA_Assist CXFA_WidgetData::GetAssist(FX_BOOL bModified) {
  return CXFA_Assist(m_pNode->GetProperty(0, XFA_ELEMENT_Assist, bModified));
}
FX_BOOL CXFA_WidgetData::GetWidth(FX_FLOAT& fWidth) {
  return TryMeasure(XFA_ATTRIBUTE_W, fWidth);
}
FX_BOOL CXFA_WidgetData::GetHeight(FX_FLOAT& fHeight) {
  return TryMeasure(XFA_ATTRIBUTE_H, fHeight);
}
FX_BOOL CXFA_WidgetData::GetMinWidth(FX_FLOAT& fMinWidth) {
  return TryMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
}
FX_BOOL CXFA_WidgetData::GetMinHeight(FX_FLOAT& fMinHeight) {
  return TryMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
}
FX_BOOL CXFA_WidgetData::GetMaxWidth(FX_FLOAT& fMaxWidth) {
  return TryMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
}
FX_BOOL CXFA_WidgetData::GetMaxHeight(FX_FLOAT& fMaxHeight) {
  return TryMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
}
CXFA_Border CXFA_WidgetData::GetUIBorder(FX_BOOL bModified) {
  CXFA_Node* pUIChild = GetUIChild();
  return CXFA_Border(
      pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Border, bModified)
               : nullptr);
}
CXFA_Margin CXFA_WidgetData::GetUIMargin(FX_BOOL bModified) {
  CXFA_Node* pUIChild = GetUIChild();
  return CXFA_Margin(
      pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Margin, bModified)
               : nullptr);
}
void CXFA_WidgetData::GetUIMargin(CFX_RectF& rtUIMargin) {
  rtUIMargin.Reset();
  CXFA_Margin mgUI = GetUIMargin();
  if (!mgUI) {
    return;
  }
  CXFA_Border border = GetUIBorder();
  if (border && border.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    return;
  }
  FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
  FX_BOOL bLeft = mgUI.GetLeftInset(fLeftInset);
  FX_BOOL bTop = mgUI.GetTopInset(fTopInset);
  FX_BOOL bRight = mgUI.GetRightInset(fRightInset);
  FX_BOOL bBottom = mgUI.GetBottomInset(fBottomInset);
  if (border) {
    FX_BOOL bVisible = FALSE;
    FX_FLOAT fThickness = 0;
    border.Get3DStyle(bVisible, fThickness);
    if (!bLeft || !bTop || !bRight || !bBottom) {
      CXFA_StrokeArray strokes;
      border.GetStrokes(strokes);
      if (!bTop) {
        fTopInset = XFA_GetEdgeThickness(strokes, bVisible, 0);
      }
      if (!bRight) {
        fRightInset = XFA_GetEdgeThickness(strokes, bVisible, 1);
      }
      if (!bBottom) {
        fBottomInset = XFA_GetEdgeThickness(strokes, bVisible, 2);
      }
      if (!bLeft) {
        fLeftInset = XFA_GetEdgeThickness(strokes, bVisible, 3);
      }
    }
  }
  rtUIMargin.Set(fLeftInset, fTopInset, fRightInset, fBottomInset);
}
int32_t CXFA_WidgetData::GetButtonHighlight() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Highlight);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_Button, XFA_ATTRIBUTE_Highlight, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::GetButtonRollover(CFX_WideString& wsRollover,
                                           FX_BOOL& bRichText) {
  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    while (pText) {
      CFX_WideStringC wsName;
      pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName == FX_WSTRC(L"rollover")) {
        pText->TryContent(wsRollover);
        bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
        return !wsRollover.IsEmpty();
      }
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetButtonDown(CFX_WideString& wsDown,
                                       FX_BOOL& bRichText) {
  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    while (pText) {
      CFX_WideStringC wsName;
      pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName == FX_WSTRC(L"down")) {
        pText->TryContent(wsDown);
        bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
        return !wsDown.IsEmpty();
      }
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
  }
  return FALSE;
}
int32_t CXFA_WidgetData::GetCheckButtonShape() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Shape);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetCheckButtonMark() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Mark);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::IsRadioButton() {
  if (CXFA_Node* pParent = m_pNode->GetNodeItem(XFA_NODEITEM_Parent)) {
    return pParent->GetClassID() == XFA_ELEMENT_ExclGroup;
  }
  return FALSE;
}
FX_FLOAT CXFA_WidgetData::GetCheckButtonSize() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetMeasure(XFA_ATTRIBUTE_Size).ToUnit(XFA_UNIT_Pt);
  }
  return XFA_GetAttributeDefaultValue_Measure(
             XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Size, XFA_XDPPACKET_Form)
      .ToUnit(XFA_UNIT_Pt);
}
FX_BOOL CXFA_WidgetData::IsAllowNeutral() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetBoolean(XFA_ATTRIBUTE_AllowNeutral);
  }
  return XFA_GetAttributeDefaultValue_Boolean(
      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_AllowNeutral, XFA_XDPPACKET_Form);
}
XFA_CHECKSTATE CXFA_WidgetData::GetCheckState() {
  CFX_WideString wsValue = GetRawValue();
  if (wsValue.IsEmpty()) {
    return XFA_CHECKSTATE_Off;
  }
  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    int32_t i = 0;
    while (pText) {
      CFX_WideString wsContent;
      if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
        return (XFA_CHECKSTATE)i;
      }
      i++;
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
  }
  return XFA_CHECKSTATE_Off;
}
void CXFA_WidgetData::SetCheckState(XFA_CHECKSTATE eCheckState,
                                    FX_BOOL bNotify) {
  CXFA_WidgetData exclGroup(GetExclGroupNode());
  if (exclGroup) {
    CFX_WideString wsValue;
    if (eCheckState != XFA_CHECKSTATE_Off) {
      if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
        CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
        if (pText) {
          pText->TryContent(wsValue);
        }
      }
    }
    CXFA_Node* pChild =
        exclGroup.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pChild->GetClassID() != XFA_ELEMENT_Field) {
        continue;
      }
      CXFA_Node* pItem = pChild->GetChild(0, XFA_ELEMENT_Items);
      if (!pItem) {
        continue;
      }
      CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
      if (!pItemchild) {
        continue;
      }
      CFX_WideString text = pItemchild->GetContent();
      CFX_WideString wsChildValue = text;
      if (wsValue != text) {
        pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
        if (pItemchild) {
          wsChildValue = pItemchild->GetContent();
        } else {
          wsChildValue.Empty();
        }
      }
      CXFA_WidgetData ch(pChild);
      ch.SyncValue(wsChildValue, bNotify);
    }
    exclGroup.SyncValue(wsValue, bNotify);
  } else {
    CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items);
    if (!pItems) {
      return;
    }
    int32_t i = -1;
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    CFX_WideString wsContent;
    while (pText) {
      i++;
      if (i == eCheckState) {
        pText->TryContent(wsContent);
        break;
      }
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    SyncValue(wsContent, bNotify);
  }
}
CXFA_Node* CXFA_WidgetData::GetExclGroupNode() {
  CXFA_Node* pExcl = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_Parent));
  if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
    return NULL;
  }
  return pExcl;
}
CXFA_Node* CXFA_WidgetData::GetSelectedMember() {
  CXFA_Node* pSelectedMember = NULL;
  CFX_WideString wsState = GetRawValue();
  if (wsState.IsEmpty()) {
    return pSelectedMember;
  }
  for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    CXFA_WidgetData widgetData(pNode);
    if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
      pSelectedMember = pNode;
      break;
    }
  }
  return pSelectedMember;
}
CXFA_Node* CXFA_WidgetData::SetSelectedMember(const CFX_WideStringC& wsName,
                                              FX_BOOL bNotify) {
  CXFA_Node* pSelectedMember = NULL;
  uint32_t nameHash =
      FX_HashCode_String_GetW(wsName.raw_str(), wsName.GetLength());
  for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetNameHash() == nameHash) {
      CXFA_WidgetData widgetData(pNode);
      widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
      pSelectedMember = pNode;
      break;
    }
  }
  return pSelectedMember;
}
void CXFA_WidgetData::SetSelectedMemberByValue(const CFX_WideStringC& wsValue,
                                               FX_BOOL bNotify,
                                               FX_BOOL bScriptModify,
                                               FX_BOOL bSyncData) {
  CFX_WideString wsExclGroup;
  for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Field) {
      continue;
    }
    CXFA_Node* pItem = pNode->GetChild(0, XFA_ELEMENT_Items);
    if (!pItem) {
      continue;
    }
    CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
    if (!pItemchild) {
      continue;
    }
    CFX_WideString wsChildValue = pItemchild->GetContent();
    if (wsValue != wsChildValue) {
      pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
      if (pItemchild) {
        wsChildValue = pItemchild->GetContent();
      } else {
        wsChildValue.Empty();
      }
    } else {
      wsExclGroup = wsValue;
    }
    pNode->SetContent(wsChildValue, wsChildValue, bNotify, bScriptModify,
                      FALSE);
  }
  if (m_pNode) {
    m_pNode->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
                        bSyncData);
  }
}
CXFA_Node* CXFA_WidgetData::GetExclGroupFirstMember() {
  CXFA_Node* pExcl = GetNode();
  if (!pExcl) {
    return NULL;
  }
  CXFA_Node* pNode = pExcl->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pNode) {
    if (pNode->GetClassID() == XFA_ELEMENT_Field) {
      return pNode;
    }
    pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return NULL;
}
CXFA_Node* CXFA_WidgetData::GetExclGroupNextMember(CXFA_Node* pNode) {
  if (!pNode) {
    return NULL;
  }
  CXFA_Node* pNodeField = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
  while (pNodeField) {
    if (pNodeField->GetClassID() == XFA_ELEMENT_Field) {
      return pNodeField;
    }
    pNodeField = pNodeField->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return NULL;
}
int32_t CXFA_WidgetData::GetChoiceListCommitOn() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_CommitOn);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_CommitOn, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::IsChoiceListAllowTextEntry() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetBoolean(XFA_ATTRIBUTE_TextEntry);
  }
  return XFA_GetAttributeDefaultValue_Boolean(
      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_TextEntry, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetChoiceListOpen() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Open);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::IsListBox() {
  int32_t iOpenMode = GetChoiceListOpen();
  return (iOpenMode == XFA_ATTRIBUTEENUM_Always ||
          iOpenMode == XFA_ATTRIBUTEENUM_MultiSelect);
}
int32_t CXFA_WidgetData::CountChoiceListItems(FX_BOOL bSaveValue) {
  CXFA_NodeArray pItems;
  CXFA_Node* pItem = NULL;
  int32_t iCount = 0;
  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    pItems.Add(pNode);
    if (iCount == 2) {
      break;
    }
  }
  if (iCount == 0) {
    return 0;
  }
  pItem = pItems[0];
  if (iCount > 1) {
    FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
    FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
      pItem = pItems[1];
    }
  }
  pItems.RemoveAll();
  return pItem->CountChildren(XFA_ELEMENT_UNKNOWN);
}
FX_BOOL CXFA_WidgetData::GetChoiceListItem(CFX_WideString& wsText,
                                           int32_t nIndex,
                                           FX_BOOL bSaveValue) {
  wsText.Empty();
  CXFA_NodeArray pItemsArray;
  CXFA_Node* pItems = NULL;
  int32_t iCount = 0;
  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    pItemsArray.Add(pNode);
    if (iCount == 2) {
      break;
    }
  }
  if (iCount == 0) {
    return FALSE;
  }
  pItems = pItemsArray[0];
  if (iCount > 1) {
    FX_BOOL bItemOneHasSave = pItemsArray[0]->GetBoolean(XFA_ATTRIBUTE_Save);
    FX_BOOL bItemTwoHasSave = pItemsArray[1]->GetBoolean(XFA_ATTRIBUTE_Save);
    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
      pItems = pItemsArray[1];
    }
  }
  if (pItems) {
    CXFA_Node* pItem = pItems->GetChild(nIndex, XFA_ELEMENT_UNKNOWN);
    if (pItem) {
      pItem->TryContent(wsText);
      return TRUE;
    }
  }
  return FALSE;
}
void CXFA_WidgetData::GetChoiceListItems(CFX_WideStringArray& wsTextArray,
                                         FX_BOOL bSaveValue) {
  CXFA_NodeArray pItems;
  CXFA_Node* pItem = NULL;
  int32_t iCount = 0;
  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    pItems.Add(pNode);
    if (iCount == 2) {
      break;
    }
  }
  if (iCount == 0) {
    return;
  }
  pItem = pItems[0];
  if (iCount > 1) {
    FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
    FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
      pItem = pItems[1];
    }
  }
  pItems.RemoveAll();
  pNode = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    pNode->TryContent(wsTextArray.Add());
  }
}
int32_t CXFA_WidgetData::CountSelectedItems() {
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  if (IsListBox() || !IsChoiceListAllowTextEntry()) {
    return wsValueArray.GetSize();
  }
  int32_t iSelected = 0;
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  int32_t iValues = wsValueArray.GetSize();
  for (int32_t i = 0; i < iValues; i++) {
    int32_t iSaves = wsSaveTextArray.GetSize();
    for (int32_t j = 0; j < iSaves; j++) {
      if (wsValueArray[i] == wsSaveTextArray[j]) {
        iSelected++;
        break;
      }
    }
  }
  return iSelected;
}
int32_t CXFA_WidgetData::GetSelectedItem(int32_t nIndex) {
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  int32_t iSaves = wsSaveTextArray.GetSize();
  for (int32_t j = 0; j < iSaves; j++) {
    if (wsValueArray[nIndex] == wsSaveTextArray[j]) {
      return j;
    }
  }
  return -1;
}
void CXFA_WidgetData::GetSelectedItems(CFX_Int32Array& iSelArray) {
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  int32_t iValues = wsValueArray.GetSize();
  if (iValues < 1) {
    return;
  }
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  int32_t iSaves = wsSaveTextArray.GetSize();
  for (int32_t i = 0; i < iValues; i++) {
    for (int32_t j = 0; j < iSaves; j++) {
      if (wsValueArray[i] == wsSaveTextArray[j]) {
        iSelArray.Add(j);
        break;
      }
    }
  }
}
void CXFA_WidgetData::GetSelectedItemsValue(
    CFX_WideStringArray& wsSelTextArray) {
  CFX_WideString wsValue = GetRawValue();
  if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
    if (!wsValue.IsEmpty()) {
      int32_t iStart = 0;
      int32_t iLength = wsValue.GetLength();
      int32_t iEnd = wsValue.Find(L'\n', iStart);
      iEnd = (iEnd == -1) ? iLength : iEnd;
      while (iEnd >= iStart) {
        wsSelTextArray.Add(wsValue.Mid(iStart, iEnd - iStart));
        iStart = iEnd + 1;
        if (iStart >= iLength) {
          break;
        }
        iEnd = wsValue.Find(L'\n', iStart);
        if (iEnd < 0) {
          wsSelTextArray.Add(wsValue.Mid(iStart, iLength - iStart));
        }
      }
    }
  } else {
    wsSelTextArray.Add(wsValue);
  }
}
FX_BOOL CXFA_WidgetData::GetItemState(int32_t nIndex) {
  if (nIndex < 0) {
    return FALSE;
  }
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  if (wsSaveTextArray.GetSize() <= nIndex) {
    return FALSE;
  }
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  int32_t iValues = wsValueArray.GetSize();
  for (int32_t j = 0; j < iValues; j++) {
    if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
      return TRUE;
    }
  }
  return FALSE;
}
void CXFA_WidgetData::SetItemState(int32_t nIndex,
                                   FX_BOOL bSelected,
                                   FX_BOOL bNotify,
                                   FX_BOOL bScriptModify,
                                   FX_BOOL bSyncData) {
  if (nIndex < 0) {
    return;
  }
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  if (wsSaveTextArray.GetSize() <= nIndex) {
    return;
  }
  int32_t iSel = -1;
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  int32_t iValues = wsValueArray.GetSize();
  for (int32_t j = 0; j < iValues; j++) {
    if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
      iSel = j;
      break;
    }
  }
  if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
    if (bSelected) {
      if (iSel < 0) {
        CFX_WideString wsValue = GetRawValue();
        if (!wsValue.IsEmpty()) {
          wsValue += L"\n";
        }
        wsValue += wsSaveTextArray[nIndex];
        m_pNode->SetContent(wsValue, wsValue, bNotify, bScriptModify,
                            bSyncData);
      }
    } else if (iSel >= 0) {
      CFX_Int32Array iSelArray;
      GetSelectedItems(iSelArray);
      for (int32_t i = 0; i < iSelArray.GetSize(); i++) {
        if (iSelArray[i] == nIndex) {
          iSelArray.RemoveAt(i);
          break;
        }
      }
      SetSelectdItems(iSelArray, bNotify, bScriptModify, bSyncData);
    }
  } else {
    if (bSelected) {
      if (iSel < 0) {
        CFX_WideString wsSaveText = wsSaveTextArray[nIndex];
        CFX_WideString wsFormatText(wsSaveText);
        GetFormatDataValue(wsSaveText.AsWideStringC(), wsFormatText);
        m_pNode->SetContent(wsSaveText, wsFormatText, bNotify, bScriptModify,
                            bSyncData);
      }
    } else if (iSel >= 0) {
      m_pNode->SetContent(CFX_WideString(), CFX_WideString(), bNotify,
                          bScriptModify, bSyncData);
    }
  }
}
void CXFA_WidgetData::SetSelectdItems(CFX_Int32Array& iSelArray,
                                      FX_BOOL bNotify,
                                      FX_BOOL bScriptModify,
                                      FX_BOOL bSyncData) {
  CFX_WideString wsValue;
  int32_t iSize = iSelArray.GetSize();
  if (iSize >= 1) {
    CFX_WideStringArray wsSaveTextArray;
    GetChoiceListItems(wsSaveTextArray, TRUE);
    CFX_WideString wsItemValue;
    for (int32_t i = 0; i < iSize; i++) {
      wsItemValue = (iSize == 1)
                        ? wsSaveTextArray[iSelArray[i]]
                        : wsSaveTextArray[iSelArray[i]] + FX_WSTRC(L"\n");
      wsValue += wsItemValue;
    }
  }
  CFX_WideString wsFormat(wsValue);
  if (GetChoiceListOpen() != XFA_ATTRIBUTEENUM_MultiSelect) {
    GetFormatDataValue(wsValue.AsWideStringC(), wsFormat);
  }
  m_pNode->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
}
void CXFA_WidgetData::ClearAllSelections() {
  CXFA_Node* pBind = m_pNode->GetBindData();
  if (pBind && GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
    while (CXFA_Node* pChildNode =
               pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
      pBind->RemoveChild(pChildNode);
    }
  } else {
    SyncValue(CFX_WideString(), FALSE);
  }
}
void CXFA_WidgetData::InsertItem(const CFX_WideString& wsLabel,
                                 const CFX_WideString& wsValue,
                                 int32_t nIndex,
                                 FX_BOOL bNotify) {
  CFX_WideString wsNewValue(wsValue);
  if (wsNewValue.IsEmpty()) {
    wsNewValue = wsLabel;
  }
  CXFA_NodeArray listitems;
  int32_t iCount = 0;
  CXFA_Node* pItemNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItemNode;
       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItemNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    listitems.Add(pItemNode);
    iCount++;
  }
  if (iCount < 1) {
    CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
    m_pNode->InsertChild(-1, pItems);
    InsertListTextItem(pItems, wsLabel.AsWideStringC(), nIndex);
    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
    m_pNode->InsertChild(-1, pSaveItems);
    pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
    InsertListTextItem(pSaveItems, wsNewValue.AsWideStringC(), nIndex);
  } else if (iCount > 1) {
    for (int32_t i = 0; i < 2; i++) {
      CXFA_Node* pNode = listitems[i];
      FX_BOOL bHasSave = pNode->GetBoolean(XFA_ATTRIBUTE_Save);
      if (bHasSave) {
        InsertListTextItem(pNode, wsNewValue.AsWideStringC(), nIndex);
      } else {
        InsertListTextItem(pNode, wsLabel.AsWideStringC(), nIndex);
      }
    }
  } else {
    CXFA_Node* pNode = listitems[0];
    pNode->SetBoolean(XFA_ATTRIBUTE_Save, FALSE);
    pNode->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Visible);
    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
    m_pNode->InsertChild(-1, pSaveItems);
    pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
    pSaveItems->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Hidden);
    listitems.RemoveAll();
    CXFA_Node* pListNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    int32_t i = 0;
    while (pListNode) {
      CFX_WideString wsOldValue;
      pListNode->TryContent(wsOldValue);
      InsertListTextItem(pSaveItems, wsOldValue.AsWideStringC(), i);
      i++;
      pListNode = pListNode->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    InsertListTextItem(pNode, wsLabel.AsWideStringC(), nIndex);
    InsertListTextItem(pSaveItems, wsNewValue.AsWideStringC(), nIndex);
  }
  if (!bNotify) {
    return;
  }
  m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(
      this, XFA_WIDGETEVENT_ListItemAdded, (void*)(const FX_WCHAR*)wsLabel,
      (void*)(const FX_WCHAR*)wsValue, (void*)(uintptr_t)nIndex);
}
void CXFA_WidgetData::GetItemLabel(const CFX_WideStringC& wsValue,
                                   CFX_WideString& wsLabel) {
  int32_t iCount = 0;
  CXFA_NodeArray listitems;
  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    listitems.Add(pItems);
  }
  if (iCount <= 1) {
    wsLabel = wsValue;
  } else {
    CXFA_Node* pLabelItems = listitems[0];
    FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
    CXFA_Node* pSaveItems = NULL;
    if (bSave) {
      pSaveItems = pLabelItems;
      pLabelItems = listitems[1];
    } else {
      pSaveItems = listitems[1];
    }
    iCount = 0;
    int32_t iSearch = -1;
    CFX_WideString wsContent;
    CXFA_Node* pChildItem = pSaveItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pChildItem;
         pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      pChildItem->TryContent(wsContent);
      if (wsContent == wsValue) {
        iSearch = iCount;
        break;
      }
      iCount++;
    }
    if (iSearch < 0) {
      return;
    }
    if (CXFA_Node* pText =
            pLabelItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
      pText->TryContent(wsLabel);
    }
  }
}
void CXFA_WidgetData::GetItemValue(const CFX_WideStringC& wsLabel,
                                   CFX_WideString& wsValue) {
  int32_t iCount = 0;
  CXFA_NodeArray listitems;
  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    listitems.Add(pItems);
  }
  if (iCount <= 1) {
    wsValue = wsLabel;
  } else {
    CXFA_Node* pLabelItems = listitems[0];
    FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
    CXFA_Node* pSaveItems = NULL;
    if (bSave) {
      pSaveItems = pLabelItems;
      pLabelItems = listitems[1];
    } else {
      pSaveItems = listitems[1];
    }
    iCount = 0;
    int32_t iSearch = -1;
    CFX_WideString wsContent;
    CXFA_Node* pChildItem = pLabelItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pChildItem;
         pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      pChildItem->TryContent(wsContent);
      if (wsContent == wsLabel) {
        iSearch = iCount;
        break;
      }
      iCount++;
    }
    if (iSearch < 0) {
      return;
    }
    if (CXFA_Node* pText = pSaveItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
      pText->TryContent(wsValue);
    }
  }
}
FX_BOOL CXFA_WidgetData::DeleteItem(int32_t nIndex,
                                    FX_BOOL bNotify,
                                    FX_BOOL bScriptModify,
                                    FX_BOOL bSyncData) {
  FX_BOOL bSetValue = FALSE;
  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    if (nIndex < 0) {
      while (CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild)) {
        pItems->RemoveChild(pNode);
      }
    } else {
      if (!bSetValue && pItems->GetBoolean(XFA_ATTRIBUTE_Save)) {
        SetItemState(nIndex, FALSE, TRUE, bScriptModify, bSyncData);
        bSetValue = TRUE;
      }
      int32_t i = 0;
      CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
      while (pNode) {
        if (i == nIndex) {
          pItems->RemoveChild(pNode);
          break;
        }
        i++;
        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
      }
    }
  }
  if (!bNotify) {
    return TRUE;
  }
  m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(
      this, XFA_WIDGETEVENT_ListItemRemoved, (void*)(uintptr_t)nIndex);
  return TRUE;
}
int32_t CXFA_WidgetData::GetHorizontalScrollPolicy() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_HScrollPolicy);
  }
  return XFA_ATTRIBUTEENUM_Auto;
}
int32_t CXFA_WidgetData::GetNumberOfCells() {
  CXFA_Node* pUIChild = GetUIChild();
  if (!pUIChild) {
    return -1;
  }
  if (CXFA_Node* pNode = pUIChild->GetChild(0, XFA_ELEMENT_Comb)) {
    return pNode->GetInteger(XFA_ATTRIBUTE_NumberOfCells);
  }
  return -1;
}
CFX_WideString CXFA_WidgetData::GetBarcodeType() {
  CXFA_Node* pUIChild = GetUIChild();
  return pUIChild ? pUIChild->GetCData(XFA_ATTRIBUTE_Type) : NULL;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_CharEncoding(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsCharEncoding;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_CharEncoding, wsCharEncoding)) {
    if (wsCharEncoding.CompareNoCase(L"UTF-16")) {
      val = CHAR_ENCODING_UNICODE;
      return TRUE;
    } else if (wsCharEncoding.CompareNoCase(L"UTF-8")) {
      val = CHAR_ENCODING_UTF8;
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Checksum(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  XFA_ATTRIBUTEENUM eChecksum;
  if (pUIChild->TryEnum(XFA_ATTRIBUTE_Checksum, eChecksum)) {
    switch (eChecksum) {
      case XFA_ATTRIBUTEENUM_None:
        val = 0;
        return TRUE;
      case XFA_ATTRIBUTEENUM_Auto:
        val = 1;
        return TRUE;
      case XFA_ATTRIBUTEENUM_1mod10:
        break;
      case XFA_ATTRIBUTEENUM_1mod10_1mod11:
        break;
      case XFA_ATTRIBUTEENUM_2mod10:
        break;
      default:
        break;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_DataLength(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsDataLength;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_DataLength, wsDataLength)) {
    val = FXSYS_wtoi(wsDataLength);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_StartChar(FX_CHAR& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideStringC wsStartEndChar;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_StartChar, wsStartEndChar)) {
    if (wsStartEndChar.GetLength()) {
      val = (FX_CHAR)wsStartEndChar.GetAt(0);
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_EndChar(FX_CHAR& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideStringC wsStartEndChar;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_EndChar, wsStartEndChar)) {
    if (wsStartEndChar.GetLength()) {
      val = (FX_CHAR)wsStartEndChar.GetAt(0);
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ECLevel(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsECLevel;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_ErrorCorrectionLevel, wsECLevel)) {
    val = FXSYS_wtoi(wsECLevel);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleWidth(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CXFA_Measurement mModuleWidthHeight;
  if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleWidth, mModuleWidthHeight)) {
    val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleHeight(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CXFA_Measurement mModuleWidthHeight;
  if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleHeight, mModuleWidthHeight)) {
    val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_PrintChecksum(FX_BOOL& val) {
  CXFA_Node* pUIChild = GetUIChild();
  FX_BOOL bPrintCheckDigit;
  if (pUIChild->TryBoolean(XFA_ATTRIBUTE_PrintCheckDigit, bPrintCheckDigit)) {
    val = bPrintCheckDigit;
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_TextLocation(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  XFA_ATTRIBUTEENUM eTextLocation;
  if (pUIChild->TryEnum(XFA_ATTRIBUTE_TextLocation, eTextLocation)) {
    switch (eTextLocation) {
      case XFA_ATTRIBUTEENUM_None:
        val = BC_TEXT_LOC_NONE;
        return TRUE;
      case XFA_ATTRIBUTEENUM_Above:
        val = BC_TEXT_LOC_ABOVE;
        return TRUE;
      case XFA_ATTRIBUTEENUM_Below:
        val = BC_TEXT_LOC_BELOW;
        return TRUE;
      case XFA_ATTRIBUTEENUM_AboveEmbedded:
        val = BC_TEXT_LOC_ABOVEEMBED;
        return TRUE;
      case XFA_ATTRIBUTEENUM_BelowEmbedded:
        val = BC_TEXT_LOC_BELOWEMBED;
        return TRUE;
      default:
        break;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Truncate(FX_BOOL& val) {
  CXFA_Node* pUIChild = GetUIChild();
  FX_BOOL bTruncate;
  if (pUIChild->TryBoolean(XFA_ATTRIBUTE_Truncate, bTruncate)) {
    val = bTruncate;
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsWideNarrowRatio;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_WideNarrowRatio, wsWideNarrowRatio)) {
    FX_STRSIZE ptPos = wsWideNarrowRatio.Find(':');
    FX_FLOAT fRatio = 0;
    if (ptPos >= 0) {
      fRatio = (FX_FLOAT)FXSYS_wtoi(wsWideNarrowRatio);
    } else {
      int32_t fA, fB;
      fA = FXSYS_wtoi(wsWideNarrowRatio.Left(ptPos));
      fB = FXSYS_wtoi(wsWideNarrowRatio.Mid(ptPos + 1));
      if (fB) {
        fRatio = (FX_FLOAT)fA / fB;
      }
    }
    val = fRatio;
    return TRUE;
  }
  return FALSE;
}
void CXFA_WidgetData::GetPasswordChar(CFX_WideString& wsPassWord) {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    pUIChild->TryCData(XFA_ATTRIBUTE_PasswordChar, wsPassWord);
  } else {
    wsPassWord = XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT_PasswordEdit,
                                                    XFA_ATTRIBUTE_PasswordChar,
                                                    XFA_XDPPACKET_Form);
  }
}
FX_BOOL CXFA_WidgetData::IsMultiLine() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetBoolean(XFA_ATTRIBUTE_MultiLine);
  }
  return XFA_GetAttributeDefaultValue_Boolean(
      XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_MultiLine, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetVerticalScrollPolicy() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_VScrollPolicy);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_VScrollPolicy, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetMaxChars(XFA_ELEMENT& eType) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
    if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
      switch (pChild->GetClassID()) {
        case XFA_ELEMENT_Text:
          eType = XFA_ELEMENT_Text;
          return pChild->GetInteger(XFA_ATTRIBUTE_MaxChars);
        case XFA_ELEMENT_ExData: {
          eType = XFA_ELEMENT_ExData;
          int32_t iMax = pChild->GetInteger(XFA_ATTRIBUTE_MaxLength);
          return iMax < 0 ? 0 : iMax;
        }
        default:
          break;
      }
    }
  }
  return 0;
}
FX_BOOL CXFA_WidgetData::GetFracDigits(int32_t& iFracDigits) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
    if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
      return pChild->TryInteger(XFA_ATTRIBUTE_FracDigits, iFracDigits);
    }
  }
  iFracDigits = -1;
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetLeadDigits(int32_t& iLeadDigits) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
    if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
      return pChild->TryInteger(XFA_ATTRIBUTE_LeadDigits, iLeadDigits);
    }
  }
  iLeadDigits = -1;
  return FALSE;
}
CFX_WideString XFA_NumericLimit(const CFX_WideString& wsValue,
                                int32_t iLead,
                                int32_t iTread) {
  if ((iLead == -1) && (iTread == -1)) {
    return wsValue;
  }
  CFX_WideString wsRet;
  int32_t iLead_ = 0, iTread_ = -1;
  int32_t iCount = wsValue.GetLength();
  if (iCount == 0) {
    return wsValue;
  }
  int32_t i = 0;
  if (wsValue[i] == L'-') {
    wsRet += L'-';
    i++;
  }
  for (; i < iCount; i++) {
    FX_WCHAR wc = wsValue[i];
    if (XFA_IsDigit(wc)) {
      if (iLead >= 0) {
        iLead_++;
        if (iLead_ > iLead) {
          return L"0";
        }
      } else if (iTread_ >= 0) {
        iTread_++;
        if (iTread_ > iTread) {
          if (iTread != -1) {
            CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsWideStringC());
            wsDeci.SetScale(iTread);
            wsRet = wsDeci;
          }
          return wsRet;
        }
      }
    } else if (wc == L'.') {
      iTread_ = 0;
      iLead = -1;
    }
    wsRet += wc;
  }
  return wsRet;
}
FX_BOOL CXFA_WidgetData::SetValue(const CFX_WideString& wsValue,
                                  XFA_VALUEPICTURE eValueType) {
  if (wsValue.IsEmpty()) {
    SyncValue(wsValue, TRUE);
    return TRUE;
  }
  m_bPreNull = m_bIsNull;
  m_bIsNull = FALSE;
  CFX_WideString wsNewText(wsValue);
  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, eValueType);
  FX_BOOL bValidate = TRUE;
  FX_BOOL bSyncData = FALSE;
  CXFA_Node* pNode = GetUIChild();
  if (!pNode) {
    return TRUE;
  }
  XFA_ELEMENT uiType = pNode->GetClassID();
  if (!wsPicture.IsEmpty()) {
    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
    IFX_Locale* pLocale = GetLocal();
    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
    bValidate =
        widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
    if (bValidate) {
      widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
                                     wsPicture, pLocale, pLocalMgr);
      wsNewText = widgetValue.GetValue();
      if (uiType == XFA_ELEMENT_NumericEdit) {
        int32_t iLeadDigits = 0;
        int32_t iFracDigits = 0;
        GetLeadDigits(iLeadDigits);
        GetFracDigits(iFracDigits);
        wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
      }
      bSyncData = TRUE;
    }
  } else {
    if (uiType == XFA_ELEMENT_NumericEdit) {
      if (wsNewText != FX_WSTRC(L"0")) {
        int32_t iLeadDigits = 0;
        int32_t iFracDigits = 0;
        GetLeadDigits(iLeadDigits);
        GetFracDigits(iFracDigits);
        wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
      }
      bSyncData = TRUE;
    }
  }
  if (uiType != XFA_ELEMENT_NumericEdit || bSyncData) {
    SyncValue(wsNewText, TRUE);
  }
  return bValidate;
}
FX_BOOL CXFA_WidgetData::GetPictureContent(CFX_WideString& wsPicture,
                                           XFA_VALUEPICTURE ePicture) {
  if (ePicture == XFA_VALUEPICTURE_Raw) {
    return FALSE;
  }
  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
  switch (ePicture) {
    case XFA_VALUEPICTURE_Display: {
      if (CXFA_Node* pFormat = m_pNode->GetChild(0, XFA_ELEMENT_Format)) {
        if (CXFA_Node* pPicture = pFormat->GetChild(0, XFA_ELEMENT_Picture)) {
          if (pPicture->TryContent(wsPicture)) {
            return TRUE;
          }
        }
      }
      CFX_WideString wsDataPicture, wsTimePicture;
      IFX_Locale* pLocale = GetLocal();
      if (!pLocale) {
        return FALSE;
      }
      uint32_t dwType = widgetValue.GetType();
      switch (dwType) {
        case XFA_VT_DATE:
          pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsPicture);
          break;
        case XFA_VT_TIME:
          pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsPicture);
          break;
        case XFA_VT_DATETIME:
          pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsDataPicture);
          pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsTimePicture);
          wsPicture = wsDataPicture + FX_WSTRC(L"T") + wsTimePicture;
          break;
        case XFA_VT_DECIMAL:
        case XFA_VT_FLOAT:
          break;
        default:
          break;
      }
    }
      return TRUE;
    case XFA_VALUEPICTURE_Edit: {
      CXFA_Node* pUI = m_pNode->GetChild(0, XFA_ELEMENT_Ui);
      if (pUI) {
        if (CXFA_Node* pPicture = pUI->GetChild(0, XFA_ELEMENT_Picture)) {
          if (pPicture->TryContent(wsPicture)) {
            return TRUE;
          }
        }
      }
      {
        CFX_WideString wsDataPicture, wsTimePicture;
        IFX_Locale* pLocale = GetLocal();
        if (!pLocale) {
          return FALSE;
        }
        uint32_t dwType = widgetValue.GetType();
        switch (dwType) {
          case XFA_VT_DATE:
            pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsPicture);
            break;
          case XFA_VT_TIME:
            pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsPicture);
            break;
          case XFA_VT_DATETIME:
            pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsDataPicture);
            pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsTimePicture);
            wsPicture = wsDataPicture + L"T" + wsTimePicture;
            break;
          default:
            break;
        }
      }
    }
      return TRUE;
    case XFA_VALUEPICTURE_DataBind: {
      if (CXFA_Bind bind = GetBind()) {
        bind.GetPicture(wsPicture);
        return TRUE;
      }
    } break;
    default:
      break;
  }
  return FALSE;
}
IFX_Locale* CXFA_WidgetData::GetLocal() {
  IFX_Locale* pLocale = NULL;
  if (!m_pNode) {
    return pLocale;
  }
  FX_BOOL bLocale = FALSE;
  CFX_WideString wsLocaleName;
  bLocale = m_pNode->GetLocaleName(wsLocaleName);
  if (bLocale) {
    if (wsLocaleName == FX_WSTRC(L"ambient")) {
      pLocale = m_pNode->GetDocument()->GetLocalMgr()->GetDefLocale();
    } else {
      pLocale = m_pNode->GetDocument()->GetLocalMgr()->GetLocaleByName(
          wsLocaleName.AsWideStringC());
    }
  }
  return pLocale;
}
static FX_BOOL XFA_SplitDateTime(const CFX_WideString& wsDateTime,
                                 CFX_WideString& wsDate,
                                 CFX_WideString& wsTime) {
  wsDate = L"";
  wsTime = L"";
  if (wsDateTime.IsEmpty()) {
    return FALSE;
  }
  int nSplitIndex = -1;
  nSplitIndex = wsDateTime.Find('T');
  if (nSplitIndex < 0) {
    nSplitIndex = wsDateTime.Find(' ');
  }
  if (nSplitIndex < 0) {
    return FALSE;
  }
  wsDate = wsDateTime.Left(nSplitIndex);
  if (!wsDate.IsEmpty()) {
    int32_t iCount = wsDate.GetLength();
    int32_t i = 0;
    for (i = 0; i < iCount; i++) {
      if (wsDate[i] >= '0' && wsDate[i] <= '9') {
        break;
      }
    }
    if (i == iCount) {
      return FALSE;
    }
  }
  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
  if (!wsTime.IsEmpty()) {
    int32_t iCount = wsTime.GetLength();
    int32_t i = 0;
    for (i = 0; i < iCount; i++) {
      if (wsTime[i] >= '0' && wsTime[i] <= '9') {
        break;
      }
    }
    if (i == iCount) {
      return FALSE;
    }
  }
  return TRUE;
}

FX_BOOL CXFA_WidgetData::GetValue(CFX_WideString& wsValue,
                                  XFA_VALUEPICTURE eValueType) {
  wsValue = m_pNode->GetContent();

  if (eValueType == XFA_VALUEPICTURE_Display)
    GetItemLabel(wsValue.AsWideStringC(), wsValue);

  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, eValueType);
  CXFA_Node* pNode = GetUIChild();
  if (!pNode)
    return TRUE;

  XFA_ELEMENT uiType = GetUIChild()->GetClassID();
  switch (uiType) {
    case XFA_ELEMENT_ChoiceList: {
      if (eValueType == XFA_VALUEPICTURE_Display) {
        int32_t iSelItemIndex = GetSelectedItem(0);
        if (iSelItemIndex >= 0) {
          GetChoiceListItem(wsValue, iSelItemIndex);
          wsPicture.Empty();
        }
      }
    } break;
    case XFA_ELEMENT_NumericEdit:
      if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
        IFX_Locale* pLocale = GetLocal();
        if (eValueType == XFA_VALUEPICTURE_Display && pLocale) {
          CFX_WideString wsOutput;
          NormalizeNumStr(wsValue, wsOutput);
          FormatNumStr(wsOutput, pLocale, wsOutput);
          wsValue = wsOutput;
        }
      }
      break;
    default:
      break;
  }
  if (wsPicture.IsEmpty())
    return TRUE;

  if (IFX_Locale* pLocale = GetLocal()) {
    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
    switch (widgetValue.GetType()) {
      case XFA_VT_DATE: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
          if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
            return TRUE;
        }
        break;
      }
      case XFA_VT_TIME: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
          if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
            return TRUE;
        }
        break;
      }
      default:
        break;
    }
    widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
  }
  return TRUE;
}

FX_BOOL CXFA_WidgetData::GetNormalizeDataValue(
    const CFX_WideStringC& wsValue,
    CFX_WideString& wsNormalizeValue) {
  wsNormalizeValue = wsValue;
  if (wsValue.IsEmpty()) {
    return TRUE;
  }
  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
  if (wsPicture.IsEmpty()) {
    return TRUE;
  }
  FXSYS_assert(GetNode());
  CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
  IFX_Locale* pLocale = GetLocal();
  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
  if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
    widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNormalizeValue,
                                   wsPicture, pLocale, pLocalMgr);
    wsNormalizeValue = widgetValue.GetValue();
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetFormatDataValue(const CFX_WideStringC& wsValue,
                                            CFX_WideString& wsFormatedValue) {
  wsFormatedValue = wsValue;
  if (wsValue.IsEmpty()) {
    return TRUE;
  }
  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
  if (wsPicture.IsEmpty()) {
    return TRUE;
  }
  if (IFX_Locale* pLocale = GetLocal()) {
    FXSYS_assert(GetNode());
    CXFA_Node* pNodeValue = GetNode()->GetChild(0, XFA_ELEMENT_Value);
    if (!pNodeValue) {
      return FALSE;
    }
    CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
    if (!pValueChild) {
      return FALSE;
    }
    int32_t iVTType = XFA_VT_NULL;
    XFA_ELEMENT eType = pValueChild->GetClassID();
    switch (eType) {
      case XFA_ELEMENT_Decimal:
        iVTType = XFA_VT_DECIMAL;
        break;
      case XFA_ELEMENT_Float:
        iVTType = XFA_VT_FLOAT;
        break;
      case XFA_ELEMENT_Date:
        iVTType = XFA_VT_DATE;
        break;
      case XFA_ELEMENT_Time:
        iVTType = XFA_VT_TIME;
        break;
      case XFA_ELEMENT_DateTime:
        iVTType = XFA_VT_DATETIME;
        break;
      case XFA_ELEMENT_Boolean:
        iVTType = XFA_VT_BOOLEAN;
        break;
      case XFA_ELEMENT_Integer:
        iVTType = XFA_VT_INTEGER;
        break;
      case XFA_ELEMENT_Text:
        iVTType = XFA_VT_TEXT;
        break;
      default:
        iVTType = XFA_VT_NULL;
        break;
    }
    CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
    CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
    switch (widgetValue.GetType()) {
      case XFA_VT_DATE: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
          if (date.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
                                  XFA_VALUEPICTURE_DataBind)) {
            return TRUE;
          }
        }
        break;
      }
      case XFA_VT_TIME: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
          if (time.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
                                  XFA_VALUEPICTURE_DataBind)) {
            return TRUE;
          }
        }
        break;
      }
      default:
        break;
    }
    widgetValue.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
                               XFA_VALUEPICTURE_DataBind);
  }
  return FALSE;
}
void CXFA_WidgetData::NormalizeNumStr(const CFX_WideString& wsValue,
                                      CFX_WideString& wsOutput) {
  if (wsValue.IsEmpty()) {
    return;
  }
  wsOutput = wsValue;
  wsOutput.TrimLeft('0');
  int32_t dot_index = wsOutput.Find('.');
  int32_t iFracDigits = 0;
  if (!wsOutput.IsEmpty() && dot_index >= 0 &&
      (!GetFracDigits(iFracDigits) || iFracDigits != -1)) {
    wsOutput.TrimRight(L"0");
    wsOutput.TrimRight(L".");
  }
  if (wsOutput.IsEmpty() || wsOutput[0] == '.') {
    wsOutput.Insert(0, '0');
  }
}
void CXFA_WidgetData::FormatNumStr(const CFX_WideString& wsValue,
                                   IFX_Locale* pLocale,
                                   CFX_WideString& wsOutput) {
  if (wsValue.IsEmpty()) {
    return;
  }
  CFX_WideString wsSrcNum = wsValue;
  CFX_WideString wsGroupSymbol;
  pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
  FX_BOOL bNeg = FALSE;
  if (wsSrcNum[0] == '-') {
    bNeg = TRUE;
    wsSrcNum.Delete(0, 1);
  }
  int32_t len = wsSrcNum.GetLength();
  int32_t dot_index = wsSrcNum.Find('.');
  if (dot_index == -1) {
    dot_index = len;
  }
  int32_t cc = dot_index - 1;
  if (cc >= 0) {
    int nPos = dot_index % 3;
    wsOutput.Empty();
    for (int32_t i = 0; i < dot_index; i++) {
      if (i % 3 == nPos && i != 0) {
        wsOutput += wsGroupSymbol;
      }
      wsOutput += wsSrcNum[i];
    }
    if (dot_index < len) {
      CFX_WideString wsSymbol;
      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
      wsOutput += wsSymbol;
      wsOutput += wsSrcNum.Right(len - dot_index - 1);
    }
    if (bNeg) {
      CFX_WideString wsMinusymbol;
      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
      wsOutput = wsMinusymbol + wsOutput;
    }
  }
}
void CXFA_WidgetData::SyncValue(const CFX_WideString& wsValue,
                                FX_BOOL bNotify) {
  if (!m_pNode) {
    return;
  }
  CFX_WideString wsFormatValue(wsValue);
  CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
  if (pContainerWidgetData) {
    pContainerWidgetData->GetFormatDataValue(wsValue.AsWideStringC(),
                                             wsFormatValue);
  }
  m_pNode->SetContent(wsValue, wsFormatValue, bNotify);
}
void CXFA_WidgetData::InsertListTextItem(CXFA_Node* pItems,
                                         const CFX_WideStringC& wsText,
                                         int32_t nIndex) {
  CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_ELEMENT_Text);
  pItems->InsertChild(nIndex, pText);
  pText->SetContent(wsText, wsText, FALSE, FALSE, FALSE);
}
CXFA_Occur::CXFA_Occur(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Occur::GetMax() {
  int32_t iMax = 1;
  if (m_pNode) {
    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, TRUE)) {
      iMax = GetMin();
    }
  }
  return iMax;
}
int32_t CXFA_Occur::GetMin() {
  int32_t iMin = 1;
  if (m_pNode) {
    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, TRUE) || iMin < 0) {
      iMin = 1;
    }
  }
  return iMin;
}
FX_BOOL CXFA_Occur::GetOccurInfo(int32_t& iMin, int32_t& iMax, int32_t& iInit) {
  if (!m_pNode) {
    return FALSE;
  }
  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE) || iMin < 0) {
    iMin = 1;
  }
  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) {
    if (iMin == 0) {
      iMax = 1;
    } else {
      iMax = iMin;
    }
  }
  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Initial, iInit, FALSE) ||
      iInit < iMin) {
    iInit = iMin;
  }
  return TRUE;
}
void CXFA_Occur::SetMax(int32_t iMax) {
  iMax = (iMax != -1 && iMax < 1) ? 1 : iMax;
  m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
  int32_t iMin = GetMin();
  if (iMax != -1 && iMax < iMin) {
    iMin = iMax;
    m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
  }
}
void CXFA_Occur::SetMin(int32_t iMin) {
  iMin = (iMin < 0) ? 1 : iMin;
  m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
  int32_t iMax = GetMax();
  if (iMax > 0 && iMax < iMin) {
    iMax = iMin;
    m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
  }
}
XFA_ATTRIBUTEENUM XFA_GetEnumTypeAttribute(
    CXFA_Node* pNode,
    XFA_ATTRIBUTE attributeValue = XFA_ATTRIBUTE_Type,
    XFA_ATTRIBUTEENUM eDefaultValue = XFA_ATTRIBUTEENUM_Optional) {
  XFA_ATTRIBUTEENUM eType = eDefaultValue;
  if (pNode) {
    if (!pNode->TryEnum(attributeValue, eType, TRUE)) {
      eType = eDefaultValue;
    }
  }
  return eType;
}
