// 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/app/xfa_fftextedit.h"

#include <vector>

#include "xfa/fwl/core/cfwl_datetimepicker.h"
#include "xfa/fwl/core/cfwl_edit.h"
#include "xfa/fwl/core/cfwl_msgkillfocus.h"
#include "xfa/fwl/core/cfwl_msgmouse.h"
#include "xfa/fwl/core/cfwl_msgsetfocus.h"
#include "xfa/fwl/core/fwl_noteimp.h"
#include "xfa/fwl/core/ifwl_edit.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/parser/xfa_localevalue.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdoc.h"
#include "xfa/fxfa/xfa_ffdocview.h"
#include "xfa/fxfa/xfa_ffpageview.h"
#include "xfa/fxfa/xfa_ffwidget.h"

CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_FFPageView* pPageView,
                                 CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) {}

CXFA_FFTextEdit::~CXFA_FFTextEdit() {
  if (m_pNormalWidget) {
    IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
    CFWL_NoteDriver* pNoteDriver = pWidget->GetOwnerApp()->GetNoteDriver();
    pNoteDriver->UnregisterEventTarget(pWidget);
  }
}

bool CXFA_FFTextEdit::LoadWidget() {
  CFWL_Edit* pFWLEdit = new CFWL_Edit(GetFWLApp());
  pFWLEdit->Initialize();
  m_pNormalWidget = pFWLEdit;
  m_pNormalWidget->SetLayoutItem(this);

  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
  CFWL_NoteDriver* pNoteDriver = pWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pWidget, pWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  UpdateWidgetProperty();
  CFX_WideString wsText;
  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
  pFWLEdit->SetText(wsText);
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}
void CXFA_FFTextEdit::UpdateWidgetProperty() {
  CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
  if (!pWidget) {
    return;
  }
  uint32_t dwStyle = 0;
  uint32_t dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus |
                             FWL_STYLEEXT_EDT_OuterScrollbar |
                             FWL_STYLEEXT_EDT_LastLineHeight;
  dwExtendedStyle |= UpdateUIProperty();
  if (m_pDataAcc->IsMultiLine()) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine | FWL_STYLEEXT_EDT_WantReturn;
    if (m_pDataAcc->GetVerticalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
      dwStyle |= FWL_WGTSTYLE_VScroll;
      dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoVScroll;
    }
  } else if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
  }
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
    dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine;
  }
  XFA_Element eType = XFA_Element::Unknown;
  int32_t iMaxChars = m_pDataAcc->GetMaxChars(eType);
  if (eType == XFA_Element::ExData) {
    iMaxChars = 0;
  }
  int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
  if (iNumCells == 0) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
    pWidget->SetLimit(iMaxChars > 0 ? iMaxChars : 1);
  } else if (iNumCells > 0) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
    pWidget->SetLimit(iNumCells);
  } else {
    pWidget->SetLimit(iMaxChars);
  }
  dwExtendedStyle |= GetAlignment();
  m_pNormalWidget->ModifyStyles(dwStyle, 0xFFFFFFFF);
  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
}
bool CXFA_FFTextEdit::OnLButtonDown(uint32_t dwFlags,
                                    FX_FLOAT fx,
                                    FX_FLOAT fy) {
  if (!PtInActiveRect(fx, fy)) {
    return false;
  }
  if (!IsFocused()) {
    m_dwStatus |= XFA_WidgetStatus_Focused;
    UpdateFWLData();
    AddInvalidateRect();
  }
  SetButtonDown(true);
  CFWL_MsgMouse ms;
  ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown;
  ms.m_dwFlags = dwFlags;
  ms.m_fx = fx;
  ms.m_fy = fy;
  ms.m_pDstTarget = m_pNormalWidget->GetWidget();
  FWLToClient(ms.m_fx, ms.m_fy);
  TranslateFWLMessage(&ms);
  return true;
}
bool CXFA_FFTextEdit::OnRButtonDown(uint32_t dwFlags,
                                    FX_FLOAT fx,
                                    FX_FLOAT fy) {
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
    return false;
  }
  if (!PtInActiveRect(fx, fy)) {
    return false;
  }
  if (!IsFocused()) {
    m_dwStatus |= XFA_WidgetStatus_Focused;
    UpdateFWLData();
    AddInvalidateRect();
  }
  SetButtonDown(true);
  CFWL_MsgMouse ms;
  ms.m_dwCmd = FWL_MouseCommand::RightButtonDown;
  ms.m_dwFlags = dwFlags;
  ms.m_fx = fx;
  ms.m_fy = fy;
  FWLToClient(ms.m_fx, ms.m_fy);
  TranslateFWLMessage(&ms);
  return true;
}
bool CXFA_FFTextEdit::OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
  if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy))
    return false;

  GetDoc()->GetDocEnvironment()->PopupMenu(this, CFX_PointF(fx, fy));
  return true;
}
bool CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget) {
  m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged;
  if (!IsFocused()) {
    m_dwStatus |= XFA_WidgetStatus_Focused;
    UpdateFWLData();
    AddInvalidateRect();
  }
  CXFA_FFWidget::OnSetFocus(pOldWidget);
  CFWL_MsgSetFocus ms;
  ms.m_pDstTarget = m_pNormalWidget->GetWidget();
  ms.m_pSrcTarget = nullptr;
  TranslateFWLMessage(&ms);
  return true;
}
bool CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget) {
  CFWL_MsgKillFocus ms;
  ms.m_pDstTarget = m_pNormalWidget->GetWidget();
  ms.m_pSrcTarget = nullptr;
  TranslateFWLMessage(&ms);
  m_dwStatus &= ~XFA_WidgetStatus_Focused;
  SetEditScrollOffset();
  ProcessCommittedData();
  UpdateFWLData();
  AddInvalidateRect();
  CXFA_FFWidget::OnKillFocus(pNewWidget);
  m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged;
  return true;
}
bool CXFA_FFTextEdit::CommitData() {
  CFX_WideString wsText;
  ((CFWL_Edit*)m_pNormalWidget)->GetText(wsText);
  if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
    m_pDataAcc->UpdateUIDisplay(this);
    return true;
  }
  ValidateNumberField(wsText);
  return false;
}
void CXFA_FFTextEdit::ValidateNumberField(const CFX_WideString& wsText) {
  CXFA_WidgetAcc* pAcc = GetDataAcc();
  if (pAcc && pAcc->GetUIType() == XFA_Element::NumericEdit) {
    IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
    if (pAppProvider) {
      CFX_WideString wsTitle;
      pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
      CFX_WideString wsError;
      pAppProvider->LoadString(XFA_IDS_ValidateNumberError, wsError);
      CFX_WideString wsSomField;
      pAcc->GetNode()->GetSOMExpression(wsSomField);
      CFX_WideString wsMessage;
      wsMessage.Format(wsError.c_str(), wsText.c_str(), wsSomField.c_str());
      pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
    }
  }
}
bool CXFA_FFTextEdit::IsDataChanged() {
  return (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) != 0;
}
uint32_t CXFA_FFTextEdit::GetAlignment() {
  uint32_t dwExtendedStyle = 0;
  if (CXFA_Para para = m_pDataAcc->GetPara()) {
    int32_t iHorz = para.GetHorizontalAlign();
    switch (iHorz) {
      case XFA_ATTRIBUTEENUM_Center:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_HCenter;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_Justified;
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        break;
      case XFA_ATTRIBUTEENUM_Radix:
        break;
      case XFA_ATTRIBUTEENUM_Right:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_HFar;
        break;
      default:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_HNear;
        break;
    }
    int32_t iVert = para.GetVerticalAlign();
    switch (iVert) {
      case XFA_ATTRIBUTEENUM_Middle:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_VCenter;
        break;
      case XFA_ATTRIBUTEENUM_Bottom:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_VFar;
        break;
      default:
        dwExtendedStyle |= FWL_STYLEEXT_EDT_VNear;
        break;
    }
  }
  return dwExtendedStyle;
}
bool CXFA_FFTextEdit::UpdateFWLData() {
  if (!m_pNormalWidget) {
    return false;
  }
  XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
  if (IsFocused()) {
    eType = XFA_VALUEPICTURE_Edit;
  }
  bool bUpdate = false;
  if (m_pDataAcc->GetUIType() == XFA_Element::TextEdit &&
      m_pDataAcc->GetNumberOfCells() < 0) {
    XFA_Element elementType = XFA_Element::Unknown;
    int32_t iMaxChars = m_pDataAcc->GetMaxChars(elementType);
    if (elementType == XFA_Element::ExData) {
      iMaxChars = eType == XFA_VALUEPICTURE_Edit ? iMaxChars : 0;
    }
    if (((CFWL_Edit*)m_pNormalWidget)->GetLimit() != iMaxChars) {
      ((CFWL_Edit*)m_pNormalWidget)->SetLimit(iMaxChars);
      bUpdate = true;
    }
  }
  if (m_pDataAcc->GetUIType() == XFA_Element::Barcode) {
    int32_t nDataLen = 0;
    if (eType == XFA_VALUEPICTURE_Edit)
      m_pDataAcc->GetBarcodeAttribute_DataLength(nDataLen);
    static_cast<CFWL_Edit*>(m_pNormalWidget)->SetLimit(nDataLen);
    bUpdate = true;
  }
  CFX_WideString wsText;
  m_pDataAcc->GetValue(wsText, eType);
  CFX_WideString wsOldText;
  ((CFWL_Edit*)m_pNormalWidget)->GetText(wsOldText);
  if (wsText != wsOldText || (eType == XFA_VALUEPICTURE_Edit && bUpdate)) {
    ((CFWL_Edit*)m_pNormalWidget)->SetText(wsText);
    bUpdate = true;
  }
  if (bUpdate) {
    m_pNormalWidget->Update();
  }
  return true;
}
void CXFA_FFTextEdit::OnTextChanged(IFWL_Widget* pWidget,
                                    const CFX_WideString& wsChanged,
                                    const CFX_WideString& wsPrevText) {
  m_dwStatus |= XFA_WidgetStatus_TextEditValueChanged;
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_Change;
  eParam.m_wsChange = wsChanged;
  eParam.m_pTarget = m_pDataAcc;
  eParam.m_wsPrevText = wsPrevText;
  CFWL_Edit* pEdit = ((CFWL_Edit*)m_pNormalWidget);
  if (m_pDataAcc->GetUIType() == XFA_Element::DateTimeEdit) {
    CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)pEdit;
    pDateTime->GetEditText(eParam.m_wsNewText);
    int32_t iSels = pDateTime->CountSelRanges();
    if (iSels) {
      eParam.m_iSelEnd = pDateTime->GetSelRange(0, eParam.m_iSelStart);
    }
  } else {
    pEdit->GetText(eParam.m_wsNewText);
    int32_t iSels = pEdit->CountSelRanges();
    if (iSels) {
      eParam.m_iSelEnd = pEdit->GetSelRange(0, eParam.m_iSelStart);
    }
  }
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
}
void CXFA_FFTextEdit::OnTextFull(IFWL_Widget* pWidget) {
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_Full;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Full, &eParam);
}

bool CXFA_FFTextEdit::CheckWord(const CFX_ByteStringC& sWord) {
  if (sWord.IsEmpty() || m_pDataAcc->GetUIType() != XFA_Element::TextEdit)
    return true;
  return false;
}

void CXFA_FFTextEdit::OnProcessMessage(CFWL_Message* pMessage) {
  m_pOldDelegate->OnProcessMessage(pMessage);
}

void CXFA_FFTextEdit::OnProcessEvent(CFWL_Event* pEvent) {
  CXFA_FFField::OnProcessEvent(pEvent);
  switch (pEvent->GetClassID()) {
    case CFWL_EventType::TextChanged: {
      CFWL_EvtEdtTextChanged* event = (CFWL_EvtEdtTextChanged*)pEvent;
      CFX_WideString wsChange;
      OnTextChanged(m_pNormalWidget->GetWidget(), wsChange, event->wsPrevText);
      break;
    }
    case CFWL_EventType::TextFull: {
      OnTextFull(m_pNormalWidget->GetWidget());
      break;
    }
    case CFWL_EventType::CheckWord: {
      CFX_WideString wstr(L"FWL_EVENT_DTP_SelectChanged");
      CFWL_EvtEdtCheckWord* event = (CFWL_EvtEdtCheckWord*)pEvent;
      event->bCheckWord = CheckWord(event->bsWord.AsStringC());
      break;
    }
    default:
      break;
  }
  m_pOldDelegate->OnProcessEvent(pEvent);
}

void CXFA_FFTextEdit::OnDrawWidget(CFX_Graphics* pGraphics,
                                   const CFX_Matrix* pMatrix) {
  m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
}

CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_FFPageView* pPageView,
                                       CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFTextEdit(pPageView, pDataAcc) {}
CXFA_FFNumericEdit::~CXFA_FFNumericEdit() {}
bool CXFA_FFNumericEdit::LoadWidget() {
  CFWL_Edit* pWidget = new CFWL_Edit(GetFWLApp());
  pWidget->Initialize();
  m_pNormalWidget = pWidget;

  IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
  m_pNormalWidget->SetLayoutItem(this);
  CFWL_NoteDriver* pNoteDriver = pIWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  CFX_WideString wsText;
  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
  pWidget->SetText(wsText);
  UpdateWidgetProperty();
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}
void CXFA_FFNumericEdit::UpdateWidgetProperty() {
  CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
  if (!pWidget) {
    return;
  }
  uint32_t dwExtendedStyle =
      FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
      FWL_STYLEEXT_EDT_Validate | FWL_STYLEEXT_EDT_Number |
      FWL_STYLEEXT_EDT_LastLineHeight;
  dwExtendedStyle |= UpdateUIProperty();
  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
  }
  int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
  if (iNumCells > 0) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
    pWidget->SetLimit(iNumCells);
  }
  dwExtendedStyle |= GetAlignment();
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
  }
  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
}

void CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event* pEvent) {
  if (pEvent->GetClassID() == CFWL_EventType::Validate) {
    CFWL_EvtEdtValidate* event = (CFWL_EvtEdtValidate*)pEvent;
    CFX_WideString wsChange = event->wsInsert;
    event->bValidate = OnValidate(m_pNormalWidget->GetWidget(), wsChange);
    return;
  }
  CXFA_FFTextEdit::OnProcessEvent(pEvent);
}

bool CXFA_FFNumericEdit::OnValidate(IFWL_Widget* pWidget,
                                    CFX_WideString& wsText) {
  CFX_WideString wsPattern;
  m_pDataAcc->GetPictureContent(wsPattern, XFA_VALUEPICTURE_Edit);
  if (!wsPattern.IsEmpty()) {
    return true;
  }
  int32_t iLeads = 0;
  m_pDataAcc->GetLeadDigits(iLeads);
  int32_t iFracs = 0;
  m_pDataAcc->GetFracDigits(iFracs);
  CFX_WideString wsFormat;
  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(m_pDataAcc);
  widgetValue.GetNumbericFormat(wsFormat, iLeads, iFracs);
  return widgetValue.ValidateNumericTemp(wsText, wsFormat,
                                         m_pDataAcc->GetLocal());
}
CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView,
                                         CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFTextEdit(pPageView, pDataAcc) {}

CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit() {}

bool CXFA_FFPasswordEdit::LoadWidget() {
  CFWL_Edit* pWidget = new CFWL_Edit(GetFWLApp());
  pWidget->Initialize();
  m_pNormalWidget = pWidget;
  m_pNormalWidget->SetLayoutItem(this);

  IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
  CFWL_NoteDriver* pNoteDriver = pIWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  CFX_WideString wsText;
  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
  pWidget->SetText(wsText);
  UpdateWidgetProperty();
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}
void CXFA_FFPasswordEdit::UpdateWidgetProperty() {
  CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
  if (!pWidget) {
    return;
  }
  uint32_t dwExtendedStyle =
      FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
      FWL_STYLEEXT_EDT_Password | FWL_STYLEEXT_EDT_LastLineHeight;
  dwExtendedStyle |= UpdateUIProperty();
  CFX_WideString wsPassWord;
  m_pDataAcc->GetPasswordChar(wsPassWord);
  if (!wsPassWord.IsEmpty()) {
    pWidget->SetAliasChar(wsPassWord.GetAt(0));
  }
  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
  }
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
    dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
  }
  dwExtendedStyle |= GetAlignment();
  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
}
CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView,
                                         CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFTextEdit(pPageView, pDataAcc) {}

CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {}

bool CXFA_FFDateTimeEdit::GetBBox(CFX_RectF& rtBox,
                                  uint32_t dwStatus,
                                  bool bDrawFocus) {
  if (bDrawFocus)
    return false;
  return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
}

bool CXFA_FFDateTimeEdit::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
  if (!m_pNormalWidget) {
    return false;
  }
  CFX_RectF rtWidget;
  ((CFWL_DateTimePicker*)m_pNormalWidget)->GetBBox(rtWidget);
  if (rtWidget.Contains(fx, fy)) {
    return true;
  }
  return false;
}
bool CXFA_FFDateTimeEdit::LoadWidget() {
  CFWL_DateTimePicker* pWidget = new CFWL_DateTimePicker(GetFWLApp());
  pWidget->Initialize();
  m_pNormalWidget = pWidget;
  m_pNormalWidget->SetLayoutItem(this);
  IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
  CFWL_NoteDriver* pNoteDriver = pIWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  CFX_WideString wsText;
  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
  pWidget->SetEditText(wsText);
  if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
    switch (value.GetChildValueClassID()) {
      case XFA_Element::Date: {
        if (!wsText.IsEmpty()) {
          CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
          CFX_Unitime date = lcValue.GetDate();
          if ((FX_UNITIME)date != 0) {
            pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
          }
        }
      } break;
      default:
        break;
    }
  }
  UpdateWidgetProperty();
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}
void CXFA_FFDateTimeEdit::UpdateWidgetProperty() {
  CFWL_DateTimePicker* pWidget = (CFWL_DateTimePicker*)m_pNormalWidget;
  if (!pWidget) {
    return;
  }
  uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
  dwExtendedStyle |= UpdateUIProperty();
  dwExtendedStyle |= GetAlignment();
  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
  uint32_t dwEditStyles = FWL_STYLEEXT_EDT_LastLineHeight;
  int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
  if (iNumCells > 0) {
    dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
    pWidget->SetEditLimit(iNumCells);
  }
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
    dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
  }
  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
    dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
  }
  pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF);
}
uint32_t CXFA_FFDateTimeEdit::GetAlignment() {
  uint32_t dwExtendedStyle = 0;
  if (CXFA_Para para = m_pDataAcc->GetPara()) {
    int32_t iHorz = para.GetHorizontalAlign();
    switch (iHorz) {
      case XFA_ATTRIBUTEENUM_Center:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        break;
      case XFA_ATTRIBUTEENUM_Radix:
        break;
      case XFA_ATTRIBUTEENUM_Right:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
        break;
      default:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
        break;
    }
    int32_t iVert = para.GetVerticalAlign();
    switch (iVert) {
      case XFA_ATTRIBUTEENUM_Middle:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
        break;
      case XFA_ATTRIBUTEENUM_Bottom:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
        break;
      default:
        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
        break;
    }
  }
  return dwExtendedStyle;
}
bool CXFA_FFDateTimeEdit::CommitData() {
  CFX_WideString wsText;
  ((CFWL_DateTimePicker*)m_pNormalWidget)->GetEditText(wsText);
  if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
    m_pDataAcc->UpdateUIDisplay(this);
    return true;
  }
  return false;
}
bool CXFA_FFDateTimeEdit::UpdateFWLData() {
  if (!m_pNormalWidget) {
    return false;
  }
  XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
  if (IsFocused()) {
    eType = XFA_VALUEPICTURE_Edit;
  }
  CFX_WideString wsText;
  m_pDataAcc->GetValue(wsText, eType);
  ((CFWL_DateTimePicker*)m_pNormalWidget)->SetEditText(wsText);
  if (IsFocused() && !wsText.IsEmpty()) {
    CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
    CFX_Unitime date = lcValue.GetDate();
    if (lcValue.IsValid()) {
      if ((FX_UNITIME)date != 0) {
        ((CFWL_DateTimePicker*)m_pNormalWidget)
            ->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
      }
    }
  }
  m_pNormalWidget->Update();
  return true;
}
bool CXFA_FFDateTimeEdit::IsDataChanged() {
  if (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) {
    return true;
  }
  CFX_WideString wsText;
  ((CFWL_DateTimePicker*)m_pNormalWidget)->GetEditText(wsText);
  CFX_WideString wsOldValue;
  m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Edit);
  return wsOldValue != wsText;
}

void CXFA_FFDateTimeEdit::OnSelectChanged(IFWL_Widget* pWidget,
                                          int32_t iYear,
                                          int32_t iMonth,
                                          int32_t iDay) {
  CFX_WideString wsPicture;
  m_pDataAcc->GetPictureContent(wsPicture, XFA_VALUEPICTURE_Edit);
  CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocalMgr());
  CFX_Unitime dt;
  dt.Set(iYear, iMonth, iDay);
  date.SetDate(dt);
  CFX_WideString wsDate;
  date.FormatPatterns(wsDate, wsPicture, m_pDataAcc->GetLocal(),
                      XFA_VALUEPICTURE_Edit);
  CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)m_pNormalWidget;
  pDateTime->SetEditText(wsDate);
  pDateTime->Update();
  GetDoc()->GetDocEnvironment()->SetFocusWidget(GetDoc(), nullptr);
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_Change;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
}

void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
  if (pEvent->GetClassID() == CFWL_EventType::SelectChanged) {
    CFWL_Event_DtpSelectChanged* event = (CFWL_Event_DtpSelectChanged*)pEvent;
    OnSelectChanged(m_pNormalWidget->GetWidget(), event->iYear, event->iMonth,
                    event->iDay);
    return;
  }
  CXFA_FFTextEdit::OnProcessEvent(pEvent);
}
