// 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 "xfa/fxfa/cxfa_ffwidgethandler.h"

#include <vector>

#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
#include "xfa/fxfa/parser/cxfa_checkbutton.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_ui.h"
#include "xfa/fxfa/parser/cxfa_validate.h"

CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
    : m_pDocView(pDocView) {}

CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}

bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
  m_pDocView->LockUpdate();
  bool bRet = hWidget->OnMouseEnter();
  m_pDocView->UnlockUpdate();
  m_pDocView->UpdateDocView();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
  m_pDocView->LockUpdate();
  bool bRet = hWidget->OnMouseExit();
  m_pDocView->UnlockUpdate();
  m_pDocView->UpdateDocView();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
                                         uint32_t dwFlags,
                                         const CFX_PointF& point) {
  m_pDocView->LockUpdate();
  bool bRet = hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
  if (bRet && m_pDocView->SetFocus(hWidget)) {
    m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
        m_pDocView->GetDoc(), hWidget);
  }
  m_pDocView->UnlockUpdate();
  m_pDocView->UpdateDocView();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
                                       uint32_t dwFlags,
                                       const CFX_PointF& point) {
  m_pDocView->LockUpdate();
  m_pDocView->m_bLayoutEvent = true;
  bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
  m_pDocView->UnlockUpdate();
  m_pDocView->UpdateDocView();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
                                           uint32_t dwFlags,
                                           const CFX_PointF& point) {
  bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
                                       uint32_t dwFlags,
                                       const CFX_PointF& point) {
  bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
                                        uint32_t dwFlags,
                                        int16_t zDelta,
                                        const CFX_PointF& point) {
  bool bRet =
      hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point));
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
                                         uint32_t dwFlags,
                                         const CFX_PointF& point) {
  bool bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
  if (bRet && m_pDocView->SetFocus(hWidget)) {
    m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
        m_pDocView->GetDoc(), hWidget);
  }
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
                                       uint32_t dwFlags,
                                       const CFX_PointF& point) {
  bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
                                           uint32_t dwFlags,
                                           const CFX_PointF& point) {
  bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
                                     uint32_t dwKeyCode,
                                     uint32_t dwFlags) {
  bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
  m_pDocView->RunInvalidate();
  m_pDocView->UpdateDocView();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnKeyUp(CXFA_FFWidget* hWidget,
                                   uint32_t dwKeyCode,
                                   uint32_t dwFlags) {
  bool bRet = hWidget->OnKeyUp(dwKeyCode, dwFlags);
  m_pDocView->RunInvalidate();
  return bRet;
}

bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
                                  uint32_t dwChar,
                                  uint32_t dwFlags) {
  bool bRet = hWidget->OnChar(dwChar, dwFlags);
  m_pDocView->RunInvalidate();
  return bRet;
}

WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
  if (!widget->CanCopy())
    return WideString();

  WideString val;
  widget->Copy(val);
  return val;
}

void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
                                     const WideString& text) {
  if (!widget->CanPaste())
    return;

  widget->Paste(text);
}

FWL_WidgetHit CXFA_FFWidgetHandler::OnHitTest(CXFA_FFWidget* hWidget,
                                              const CFX_PointF& point) {
  if (!(hWidget->GetStatus() & XFA_WidgetStatus_Visible))
    return FWL_WidgetHit::Unknown;
  return hWidget->OnHitTest(hWidget->Rotate2Normal(point));
}

bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
                                       const CFX_PointF& point) {
  return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
}

void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
                                        CXFA_Graphics* pGS,
                                        const CFX_Matrix& matrix,
                                        bool bHighlight) {
  hWidget->RenderWidget(pGS, matrix,
                        bHighlight ? XFA_WidgetStatus_Highlight : 0);
}

bool CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
                                    XFA_EVENTTYPE eEventType) {
  if (eEventType == XFA_EVENT_Unknown)
    return false;

  if (!pWidgetAcc || pWidgetAcc->GetElementType() == XFA_Element::Draw)
    return false;

  switch (eEventType) {
    case XFA_EVENT_Calculate: {
      CXFA_CalculateData calcData = pWidgetAcc->GetCalculateData();
      return calcData.HasValidNode() && calcData.GetScript();
    }
    case XFA_EVENT_Validate: {
      CXFA_Validate* validate = pWidgetAcc->GetValidate(false);
      return validate && validate->GetScript();
    }
    default:
      break;
  }
  return !pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType], false)
              .empty();
}

int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
                                           CXFA_EventParam* pParam) {
  if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
    return XFA_EVENTERROR_NotExist;
  if (!pWidgetAcc || pWidgetAcc->GetElementType() == XFA_Element::Draw)
    return XFA_EVENTERROR_NotExist;

  switch (pParam->m_eType) {
    case XFA_EVENT_Calculate:
      return pWidgetAcc->ProcessCalculate();
    case XFA_EVENT_Validate:
      if (m_pDocView->GetDoc()->GetDocEnvironment()->IsValidationsEnabled(
              m_pDocView->GetDoc())) {
        return pWidgetAcc->ProcessValidate(0);
      }
      return XFA_EVENTERROR_Disabled;
    case XFA_EVENT_InitCalculate: {
      CXFA_CalculateData calcData = pWidgetAcc->GetCalculateData();
      if (!calcData.HasValidNode())
        return XFA_EVENTERROR_NotExist;
      if (pWidgetAcc->GetNode()->IsUserInteractive())
        return XFA_EVENTERROR_Disabled;
      return pWidgetAcc->ExecuteScript(calcData.GetScript(), pParam);
    }
    default:
      break;
  }
  int32_t iRet =
      pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
  return iRet;
}

CXFA_FFWidget* CXFA_FFWidgetHandler::CreateWidget(CXFA_FFWidget* hParent,
                                                  XFA_WIDGETTYPE eType,
                                                  CXFA_FFWidget* hBefore) {
  CXFA_Node* pParentFormItem =
      hParent ? hParent->GetDataAcc()->GetNode() : nullptr;
  CXFA_Node* pBeforeFormItem =
      hBefore ? hBefore->GetDataAcc()->GetNode() : nullptr;
  CXFA_Node* pNewFormItem =
      CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
  if (!pNewFormItem)
    return nullptr;

  pNewFormItem->GetTemplateNode()->SetFlag(XFA_NodeFlag_Initialized, true);
  pNewFormItem->SetFlag(XFA_NodeFlag_Initialized, true);
  m_pDocView->RunLayout();
  CXFA_LayoutItem* pLayout =
      m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
  return static_cast<CXFA_FFWidget*>(pLayout);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
    XFA_WIDGETTYPE eType,
    CXFA_Node* pParent,
    CXFA_Node* pBefore) const {
  switch (eType) {
    case XFA_WIDGETTYPE_Barcode:
      return nullptr;
    case XFA_WIDGETTYPE_PushButton:
      return CreatePushButton(pParent, pBefore);
    case XFA_WIDGETTYPE_CheckButton:
      return CreateCheckButton(pParent, pBefore);
    case XFA_WIDGETTYPE_ExcludeGroup:
      return CreateExclGroup(pParent, pBefore);
    case XFA_WIDGETTYPE_RadioButton:
      return CreateRadioButton(pParent, pBefore);
    case XFA_WIDGETTYPE_Arc:
      return CreateArc(pParent, pBefore);
    case XFA_WIDGETTYPE_Rectangle:
      return CreateRectangle(pParent, pBefore);
    case XFA_WIDGETTYPE_Image:
      return CreateImage(pParent, pBefore);
    case XFA_WIDGETTYPE_Line:
      return CreateLine(pParent, pBefore);
    case XFA_WIDGETTYPE_Text:
      return CreateText(pParent, pBefore);
    case XFA_WIDGETTYPE_DatetimeEdit:
      return CreateDatetimeEdit(pParent, pBefore);
    case XFA_WIDGETTYPE_DecimalField:
      return CreateDecimalField(pParent, pBefore);
    case XFA_WIDGETTYPE_NumericField:
      return CreateNumericField(pParent, pBefore);
    case XFA_WIDGETTYPE_Signature:
      return CreateSignature(pParent, pBefore);
    case XFA_WIDGETTYPE_TextEdit:
      return CreateTextEdit(pParent, pBefore);
    case XFA_WIDGETTYPE_DropdownList:
      return CreateDropdownList(pParent, pBefore);
    case XFA_WIDGETTYPE_ListBox:
      return CreateListBox(pParent, pBefore);
    case XFA_WIDGETTYPE_ImageField:
      return CreateImageField(pParent, pBefore);
    case XFA_WIDGETTYPE_PasswordEdit:
      return CreatePasswordEdit(pParent, pBefore);
    case XFA_WIDGETTYPE_Subform:
      return CreateSubform(pParent, pBefore);
    default:
      return nullptr;
  }
}

CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
                                                  CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateField(XFA_Element::Button, pParent, pBefore);
  CXFA_Node* pCaption = CreateCopyNode(XFA_Element::Caption, pField);
  CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pCaption);
  CXFA_Node* pText = CreateCopyNode(XFA_Element::Text, pValue);
  pText->JSObject()->SetContent(L"Button", L"Button", false, false, true);

  CXFA_Node* pPara = CreateCopyNode(XFA_Element::Para, pCaption);
  pPara->JSObject()->SetEnum(XFA_Attribute::VAlign, XFA_AttributeEnum::Middle,
                             false);
  pPara->JSObject()->SetEnum(XFA_Attribute::HAlign, XFA_AttributeEnum::Center,
                             false);
  CreateFontNode(pCaption);

  CXFA_Node* pBorder = CreateCopyNode(XFA_Element::Border, pField);
  pBorder->JSObject()->SetEnum(XFA_Attribute::Hand, XFA_AttributeEnum::Right,
                               false);

  CXFA_Node* pEdge = CreateCopyNode(XFA_Element::Edge, pBorder);
  pEdge->JSObject()->SetEnum(XFA_Attribute::Stroke, XFA_AttributeEnum::Raised,
                             false);

  CXFA_Node* pFill = CreateCopyNode(XFA_Element::Fill, pBorder);
  CXFA_Node* pColor = CreateCopyNode(XFA_Element::Color, pFill);
  pColor->JSObject()->SetCData(XFA_Attribute::Value, L"212, 208, 200", false,
                               false);

  CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
  pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
                             false);

  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
                                                   CXFA_Node* pBefore) const {
  return CreateField(XFA_Element::CheckButton, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
                                                 CXFA_Node* pBefore) const {
  return CreateFormItem(XFA_Element::ExclGroup, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
                                                   CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateField(XFA_Element::CheckButton, pParent, pBefore);
  CXFA_Ui* pUi = pField->GetFirstChildByClass<CXFA_Ui>(XFA_Element::Ui);
  CXFA_CheckButton* pWidget =
      pUi->GetFirstChildByClass<CXFA_CheckButton>(XFA_Element::CheckButton);
  pWidget->JSObject()->SetEnum(XFA_Attribute::Shape, XFA_AttributeEnum::Round,
                               false);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
                                                    CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateField(XFA_Element::DateTimeEdit, pParent, pBefore);
  CreateValueNode(XFA_Element::Date, pField);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
                                                    CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateNumericField(pParent, pBefore);
  CreateValueNode(XFA_Element::Decimal, pField);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
                                                    CXFA_Node* pBefore) const {
  return CreateField(XFA_Element::NumericEdit, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
                                                 CXFA_Node* pBefore) const {
  return CreateField(XFA_Element::Signature, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
                                                CXFA_Node* pBefore) const {
  return CreateField(XFA_Element::TextEdit, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
                                                    CXFA_Node* pBefore) const {
  return CreateField(XFA_Element::ChoiceList, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
                                               CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
  CXFA_Node* pUi = pField->GetNodeItem(XFA_NODEITEM_FirstChild);
  CXFA_Node* pListBox = pUi->GetNodeItem(XFA_NODEITEM_FirstChild);
  pListBox->JSObject()->SetEnum(XFA_Attribute::Open, XFA_AttributeEnum::Always,
                                false);
  pListBox->JSObject()->SetEnum(XFA_Attribute::CommitOn,
                                XFA_AttributeEnum::Exit, false);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
                                                  CXFA_Node* pBefore) const {
  return CreateField(XFA_Element::ImageEdit, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
                                                    CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateField(XFA_Element::PasswordEdit, pParent, pBefore);
  CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
  pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
                             false);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_Element eElement,
                                             CXFA_Node* pParent,
                                             CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateFormItem(XFA_Element::Field, pParent, pBefore);
  CreateCopyNode(eElement, CreateCopyNode(XFA_Element::Ui, pField));
  CreateFontNode(pField);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
                                           CXFA_Node* pBefore) const {
  return CreateDraw(XFA_Element::Arc, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
                                                 CXFA_Node* pBefore) const {
  return CreateDraw(XFA_Element::Rectangle, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
                                             CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateDraw(XFA_Element::Image, pParent, pBefore);
  CreateCopyNode(XFA_Element::ImageEdit,
                 CreateCopyNode(XFA_Element::Ui, pField));
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
                                            CXFA_Node* pBefore) const {
  return CreateDraw(XFA_Element::Line, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
                                            CXFA_Node* pBefore) const {
  CXFA_Node* pField = CreateDraw(XFA_Element::Text, pParent, pBefore);
  CreateCopyNode(XFA_Element::TextEdit,
                 CreateCopyNode(XFA_Element::Ui, pField));
  CreateFontNode(pField);
  return pField;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_Element eElement,
                                            CXFA_Node* pParent,
                                            CXFA_Node* pBefore) const {
  CXFA_Node* pDraw = CreateFormItem(XFA_Element::Draw, pParent, pBefore);
  CreateValueNode(eElement, pDraw);
  return pDraw;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
                                               CXFA_Node* pBefore) const {
  return CreateFormItem(XFA_Element::Subform, pParent, pBefore);
}

CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_Element eElement,
                                                CXFA_Node* pParent,
                                                CXFA_Node* pBefore) const {
  CXFA_Node* pTemplateParent = pParent ? pParent->GetTemplateNode() : nullptr;
  CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(false);
  if (pParent)
    pParent->InsertChild(pNewFormItem, pBefore);
  return pNewFormItem;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_Element eElement,
                                                CXFA_Node* pParent,
                                                CXFA_Node* pBefore) const {
  CXFA_Node* pTemplateParent = pParent ? pParent->GetTemplateNode() : nullptr;
  CXFA_Node* pNewNode =
      CreateTemplateNode(eElement, pTemplateParent,
                         pBefore ? pBefore->GetTemplateNode() : nullptr)
          ->Clone(false);
  if (pParent)
    pParent->InsertChild(pNewNode, pBefore);
  return pNewNode;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateTemplateNode(XFA_Element eElement,
                                                    CXFA_Node* pParent,
                                                    CXFA_Node* pBefore) const {
  CXFA_Document* pXFADoc = GetXFADoc();
  CXFA_Node* pNewTemplateNode =
      pXFADoc->CreateNode(XFA_PacketType::Template, eElement);
  if (pParent)
    pParent->InsertChild(pNewTemplateNode, pBefore);
  return pNewTemplateNode;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
  CXFA_Node* pFont = CreateCopyNode(XFA_Element::Font, pParent);
  pFont->JSObject()->SetCData(XFA_Attribute::Typeface, L"Myriad Pro", false,
                              false);
  return pFont;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
                                                  uint32_t dwFlags,
                                                  float fInsets[4]) const {
  CXFA_Node* pMargin = CreateCopyNode(XFA_Element::Margin, pParent);
  if (dwFlags & 0x01)
    pMargin->JSObject()->SetMeasure(XFA_Attribute::LeftInset,
                                    CXFA_Measurement(fInsets[0], XFA_Unit::Pt),
                                    false);
  if (dwFlags & 0x02)
    pMargin->JSObject()->SetMeasure(XFA_Attribute::TopInset,
                                    CXFA_Measurement(fInsets[1], XFA_Unit::Pt),
                                    false);
  if (dwFlags & 0x04)
    pMargin->JSObject()->SetMeasure(XFA_Attribute::RightInset,
                                    CXFA_Measurement(fInsets[2], XFA_Unit::Pt),
                                    false);
  if (dwFlags & 0x08)
    pMargin->JSObject()->SetMeasure(XFA_Attribute::BottomInset,
                                    CXFA_Measurement(fInsets[3], XFA_Unit::Pt),
                                    false);
  return pMargin;
}

CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_Element eValue,
                                                 CXFA_Node* pParent) const {
  CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pParent);
  CreateCopyNode(eValue, pValue);
  return pValue;
}

CXFA_Document* CXFA_FFWidgetHandler::GetObjFactory() const {
  return GetXFADoc();
}

CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
  return m_pDocView->GetDoc()->GetXFADoc();
}
