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

#include <utility>

#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffarc.h"
#include "xfa/fxfa/cxfa_ffbarcode.h"
#include "xfa/fxfa/cxfa_ffcheckbutton.h"
#include "xfa/fxfa/cxfa_ffcombobox.h"
#include "xfa/fxfa/cxfa_ffdatetimeedit.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffexclgroup.h"
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffimage.h"
#include "xfa/fxfa/cxfa_ffimageedit.h"
#include "xfa/fxfa/cxfa_ffline.h"
#include "xfa/fxfa/cxfa_fflistbox.h"
#include "xfa/fxfa/cxfa_ffnumericedit.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffpasswordedit.h"
#include "xfa/fxfa/cxfa_ffpushbutton.h"
#include "xfa/fxfa/cxfa_ffrectangle.h"
#include "xfa/fxfa/cxfa_ffsignature.h"
#include "xfa/fxfa/cxfa_fftext.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_ffwidgethandler.h"
#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
#include "xfa/fxfa/cxfa_textlayout.h"
#include "xfa/fxfa/cxfa_textprovider.h"
#include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_barcode.h"
#include "xfa/fxfa/parser/cxfa_binditems.h"
#include "xfa/fxfa/parser/cxfa_button.h"
#include "xfa/fxfa/parser/cxfa_checkbutton.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_passwordedit.h"

CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}

CXFA_FFNotify::~CXFA_FFNotify() {}

void CXFA_FFNotify::OnPageEvent(CXFA_ViewLayoutItem* pSender,
                                uint32_t dwEvent) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
  if (pDocView)
    pDocView->OnPageEvent(pSender, dwEvent);
}

void CXFA_FFNotify::OnWidgetListItemAdded(CXFA_Node* pSender,
                                          const WideString& wsLabel,
                                          int32_t iIndex) {
  if (pSender->GetFFWidgetType() != XFA_FFWidgetType::kChoiceList)
    return;

  CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
  for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
    if (pWidget->IsLoaded())
      ToDropDown(ToField(pWidget))->InsertItem(wsLabel, iIndex);
  }
}

void CXFA_FFNotify::OnWidgetListItemRemoved(CXFA_Node* pSender,
                                            int32_t iIndex) {
  if (pSender->GetFFWidgetType() != XFA_FFWidgetType::kChoiceList)
    return;

  CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
  for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
    if (pWidget->IsLoaded())
      ToDropDown(ToField(pWidget))->DeleteItem(iIndex);
  }
}

std::unique_ptr<CXFA_FFPageView> CXFA_FFNotify::OnCreateViewLayoutItem(
    CXFA_Node* pNode) {
  if (pNode->GetElementType() != XFA_Element::PageArea)
    return nullptr;

  auto* pLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
  return std::make_unique<CXFA_FFPageView>(m_pDoc->GetDocView(pLayout), pNode);
}

std::unique_ptr<CXFA_FFWidget> CXFA_FFNotify::OnCreateContentLayoutItem(
    CXFA_Node* pNode) {
  ASSERT(pNode->GetElementType() != XFA_Element::ContentArea);
  ASSERT(pNode->GetElementType() != XFA_Element::PageArea);

  // We only need to create the widget for certain types of objects.
  if (!pNode->HasCreatedUIWidget())
    return nullptr;

  std::unique_ptr<CXFA_FFWidget> pWidget;
  switch (pNode->GetFFWidgetType()) {
    case XFA_FFWidgetType::kBarcode: {
      CXFA_Node* child = pNode->GetUIChildNode();
      if (child->GetElementType() != XFA_Element::Barcode)
        return nullptr;

      pWidget = std::make_unique<CXFA_FFBarcode>(
          pNode, static_cast<CXFA_Barcode*>(child));
      break;
    }
    case XFA_FFWidgetType::kButton: {
      CXFA_Node* child = pNode->GetUIChildNode();
      if (child->GetElementType() != XFA_Element::Button)
        return nullptr;

      pWidget = std::make_unique<CXFA_FFPushButton>(
          pNode, static_cast<CXFA_Button*>(child));
      break;
    }
    case XFA_FFWidgetType::kCheckButton: {
      CXFA_Node* child = pNode->GetUIChildNode();
      if (child->GetElementType() != XFA_Element::CheckButton)
        return nullptr;

      pWidget = std::make_unique<CXFA_FFCheckButton>(
          pNode, static_cast<CXFA_CheckButton*>(child));
      break;
    }
    case XFA_FFWidgetType::kChoiceList: {
      if (pNode->IsListBox())
        pWidget = std::make_unique<CXFA_FFListBox>(pNode);
      else
        pWidget = std::make_unique<CXFA_FFComboBox>(pNode);
      break;
    }
    case XFA_FFWidgetType::kDateTimeEdit:
      pWidget = std::make_unique<CXFA_FFDateTimeEdit>(pNode);
      break;
    case XFA_FFWidgetType::kImageEdit:
      pWidget = std::make_unique<CXFA_FFImageEdit>(pNode);
      break;
    case XFA_FFWidgetType::kNumericEdit:
      pWidget = std::make_unique<CXFA_FFNumericEdit>(pNode);
      break;
    case XFA_FFWidgetType::kPasswordEdit: {
      CXFA_Node* child = pNode->GetUIChildNode();
      if (child->GetElementType() != XFA_Element::PasswordEdit)
        return nullptr;

      pWidget = std::make_unique<CXFA_FFPasswordEdit>(
          pNode, static_cast<CXFA_PasswordEdit*>(child));
      break;
    }
    case XFA_FFWidgetType::kSignature:
      pWidget = std::make_unique<CXFA_FFSignature>(pNode);
      break;
    case XFA_FFWidgetType::kTextEdit:
      pWidget = std::make_unique<CXFA_FFTextEdit>(pNode);
      break;
    case XFA_FFWidgetType::kArc:
      pWidget = std::make_unique<CXFA_FFArc>(pNode);
      break;
    case XFA_FFWidgetType::kLine:
      pWidget = std::make_unique<CXFA_FFLine>(pNode);
      break;
    case XFA_FFWidgetType::kRectangle:
      pWidget = std::make_unique<CXFA_FFRectangle>(pNode);
      break;
    case XFA_FFWidgetType::kText:
      pWidget = std::make_unique<CXFA_FFText>(pNode);
      break;
    case XFA_FFWidgetType::kImage:
      pWidget = std::make_unique<CXFA_FFImage>(pNode);
      break;
    case XFA_FFWidgetType::kSubform:
      pWidget = std::make_unique<CXFA_FFWidget>(pNode);
      break;
    case XFA_FFWidgetType::kExclGroup:
      pWidget = std::make_unique<CXFA_FFExclGroup>(pNode);
      break;
    case XFA_FFWidgetType::kNone:
      return nullptr;
  }
  ASSERT(pWidget);
  auto* pLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
  pWidget->SetDocView(m_pDoc->GetDocView(pLayout));
  return pWidget;
}

void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem,
                                         float* pCalcWidth,
                                         float* pCalcHeight) {
  pItem->StartWidgetLayout(m_pDoc.Get(), pCalcWidth, pCalcHeight);
}

bool CXFA_FFNotify::RunScript(CXFA_Script* script, CXFA_Node* item) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return false;

  CXFA_EventParam EventParam;
  EventParam.m_eType = XFA_EVENT_Unknown;

  XFA_EventError iRet;
  bool bRet;
  std::tie(iRet, bRet) = item->ExecuteBoolScript(pDocView, script, &EventParam);
  return iRet == XFA_EventError::kSuccess && bRet;
}

XFA_EventError CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode,
                                                   XFA_EVENTTYPE eEventType,
                                                   bool bIsFormReady,
                                                   bool bRecursive) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return XFA_EventError::kNotExist;
  return pDocView->ExecEventActivityByDeepFirst(pFormNode, eEventType,
                                                bIsFormReady, bRecursive);
}

void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  pDocView->AddCalculateNode(pNode);
  pDocView->AddValidateNode(pNode);
}

IXFA_AppProvider* CXFA_FFNotify::GetAppProvider() {
  return m_pDoc->GetApp()->GetAppProvider();
}

CXFA_FFWidgetHandler* CXFA_FFNotify::GetWidgetHandler() {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  return pDocView ? pDocView->GetWidgetHandler() : nullptr;
}

void CXFA_FFNotify::OpenDropDownList(CXFA_Node* pNode) {
  auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
  if (!pLayoutItem)
    return;

  CXFA_FFWidget* hWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem);
  if (!hWidget)
    return;

  // SetFocusWidget() may destroy |hWidget| object by JS callback.
  ObservedPtr<CXFA_FFWidget> pObservedWidget(hWidget);
  CXFA_FFDoc* hDoc = GetHDOC();
  hDoc->GetDocEnvironment()->SetFocusWidget(hDoc, hWidget);
  if (!pObservedWidget)
    return;

  if (hWidget->GetNode()->GetFFWidgetType() != XFA_FFWidgetType::kChoiceList)
    return;

  if (!hWidget->IsLoaded())
    return;

  CXFA_FFDropDown* pDropDown = ToDropDown(ToField(hWidget));
  CXFA_FFComboBox* pComboBox = ToComboBox(pDropDown);
  if (!pComboBox)
    return;

  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  pDocView->LockUpdate();
  pComboBox->OpenDropDownList();
  pDocView->UnlockUpdate();
  pDocView->UpdateDocView();
}

void CXFA_FFNotify::ResetData(CXFA_Node* pNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  pDocView->ResetNode(pNode);
}

int32_t CXFA_FFNotify::GetLayoutStatus() {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  return pDocView ? pDocView->GetLayoutStatus() : 0;
}

void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  pDocView->AddNewFormNode(pNode);
}

void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  pDocView->AddIndexChangedSubform(pSubformNode);
}

CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode() {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  return pDocView ? pDocView->GetFocusNode() : nullptr;
}

void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;
  pDocView->SetFocusNode(pNode);
}

void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  if (pNode->HasCreatedUIWidget()) {
    pNode->SetWidgetReady();
    return;
  }

  switch (pNode->GetElementType()) {
    case XFA_Element::BindItems:
      pDocView->AddBindItem(static_cast<CXFA_BindItems*>(pNode));
      break;
    case XFA_Element::Validate:
      pNode->SetFlag(XFA_NodeFlag_NeedsInitApp);
      break;
    default:
      break;
  }
}

void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender, XFA_Attribute eAttr) {
  if (eAttr != XFA_Attribute::Presence)
    return;
  if (pSender->GetPacketType() == XFA_PacketType::Datasets)
    return;
  if (!pSender->IsFormContainer())
    return;

  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;
  if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End)
    return;

  CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
  for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
    if (pWidget->IsLoaded())
      pWidget->InvalidateRect();
  }
}

void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender,
                                   XFA_Attribute eAttr,
                                   CXFA_Node* pParentNode,
                                   CXFA_Node* pWidgetNode) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  if (pSender->GetPacketType() != XFA_PacketType::Form) {
    if (eAttr == XFA_Attribute::Value)
      pDocView->AddCalculateNodeNotify(pSender);
    return;
  }

  XFA_Element eType = pParentNode->GetElementType();
  bool bIsContainerNode = pParentNode->IsContainerNode();
  bool bUpdateProperty = false;
  pDocView->SetChangeMark();
  switch (eType) {
    case XFA_Element::Caption: {
      CXFA_TextLayout* pCapOut = pWidgetNode->GetCaptionTextLayout();
      if (!pCapOut)
        return;

      pCapOut->Unload();
      break;
    }
    case XFA_Element::Ui:
    case XFA_Element::Para:
      bUpdateProperty = true;
      break;
    default:
      break;
  }
  if (bIsContainerNode && eAttr == XFA_Attribute::Access)
    bUpdateProperty = true;

  if (eAttr == XFA_Attribute::Value) {
    pDocView->AddCalculateNodeNotify(pSender);
    if (eType == XFA_Element::Value || bIsContainerNode) {
      if (bIsContainerNode) {
        m_pDoc->GetDocView()->UpdateUIDisplay(pWidgetNode, nullptr);
        pDocView->AddCalculateNode(pWidgetNode);
        pDocView->AddValidateNode(pWidgetNode);
      } else if (pWidgetNode->GetParent()->GetElementType() ==
                 XFA_Element::ExclGroup) {
        m_pDoc->GetDocView()->UpdateUIDisplay(pWidgetNode, nullptr);
      }
      return;
    }
  }

  CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pWidgetNode);
  for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
    if (!pWidget->IsLoaded())
      continue;

    if (bUpdateProperty)
      pWidget->UpdateWidgetProperty();
    pWidget->PerformLayout();
    pWidget->InvalidateRect();
  }
}

void CXFA_FFNotify::OnContainerChanged(CXFA_Node* pNode) {
  m_pDoc->GetXFADoc()->GetLayoutProcessor()->AddChangedContainer(pNode);
}

void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender) {
  if (!pSender->IsFormContainer())
    return;

  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  bool bLayoutReady =
      !(pDocView->m_bInLayoutStatus) &&
      (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
  if (bLayoutReady)
    m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc.Get());
}

void CXFA_FFNotify::OnChildRemoved() {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
  if (!pDocView)
    return;

  bool bLayoutReady =
      !(pDocView->m_bInLayoutStatus) &&
      (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
  if (bLayoutReady)
    m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc.Get());
}

void CXFA_FFNotify::OnLayoutItemAdded(CXFA_LayoutProcessor* pLayout,
                                      CXFA_LayoutItem* pSender,
                                      int32_t iPageIdx,
                                      uint32_t dwStatus) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
  if (!pDocView)
    return;

  CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pSender);
  if (!pWidget)
    return;

  CXFA_FFPageView* pNewPageView = pDocView->GetPageView(iPageIdx);
  uint32_t dwFilter = XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable |
                      XFA_WidgetStatus_Printable;
  pWidget->ModifyStatus(dwStatus, dwFilter);
  CXFA_FFPageView* pPrePageView = pWidget->GetPageView();
  if (pPrePageView != pNewPageView ||
      (dwStatus & (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)) ==
          (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)) {
    pWidget->SetPageView(pNewPageView);
    m_pDoc->GetDocEnvironment()->WidgetPostAdd(pWidget);
  }
  if (pDocView->GetLayoutStatus() != XFA_DOCVIEW_LAYOUTSTATUS_End ||
      !(dwStatus & XFA_WidgetStatus_Visible)) {
    return;
  }
  if (pWidget->IsLoaded()) {
    if (pWidget->GetWidgetRect() != pWidget->RecacheWidgetRect())
      pWidget->PerformLayout();
  } else {
    pWidget->LoadWidget();
  }
  pWidget->InvalidateRect();
}

void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_LayoutProcessor* pLayout,
                                         CXFA_LayoutItem* pSender) {
  CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
  if (!pDocView)
    return;

  CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pSender);
  if (!pWidget)
    return;

  pDocView->DeleteLayoutItem(pWidget);
  m_pDoc->GetDocEnvironment()->WidgetPreRemove(pWidget);
  pWidget->InvalidateRect();
}
