// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h"

#include <memory>
#include <utility>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fxcrt/retain_ptr.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
#include "fxjs/ijs_runtime.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_ffwidgethandler.h"
#include "xfa/fxfa/cxfa_readynodeiterator.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_submit.h"

#define IDS_XFA_Validate_Input                                          \
  "At least one required field was empty. Please fill in the required " \
  "fields\r\n(highlighted) before continuing."

// submit
#define FXFA_CONFIG 0x00000001
#define FXFA_TEMPLATE 0x00000010
#define FXFA_LOCALESET 0x00000100
#define FXFA_DATASETS 0x00001000
#define FXFA_XMPMETA 0x00010000
#define FXFA_XFDF 0x00100000
#define FXFA_FORM 0x01000000
#define FXFA_PDF 0x10000000
#define FXFA_XFA_ALL 0x01111111

CPDFXFA_DocEnvironment::CPDFXFA_DocEnvironment(CPDFXFA_Context* pContext)
    : m_pContext(pContext) {
  ASSERT(m_pContext);
}

CPDFXFA_DocEnvironment::~CPDFXFA_DocEnvironment() {}

void CPDFXFA_DocEnvironment::SetChangeMark(CXFA_FFDoc* hDoc) {
  if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv())
    m_pContext->GetFormFillEnv()->SetChangeMark();
}

void CPDFXFA_DocEnvironment::InvalidateRect(CXFA_FFPageView* pPageView,
                                            const CFX_RectF& rt) {
  if (!m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return;

  if (m_pContext->GetFormType() != FormType::kXFAFull)
    return;

  RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pPageView);
  if (!pPage)
    return;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  pFormFillEnv->Invalidate(pPage.Get(), rt.ToFloatRect().ToFxRect());
}

void CPDFXFA_DocEnvironment::DisplayCaret(CXFA_FFWidget* hWidget,
                                          bool bVisible,
                                          const CFX_RectF* pRtAnchor) {
  if (!hWidget || !pRtAnchor || !m_pContext->GetXFADoc() ||
      !m_pContext->GetFormFillEnv() || !m_pContext->GetXFADocView())
    return;

  if (m_pContext->GetFormType() != FormType::kXFAFull)
    return;

  CXFA_FFWidgetHandler* pWidgetHandler =
      m_pContext->GetXFADocView()->GetWidgetHandler();
  if (!pWidgetHandler)
    return;

  CXFA_FFPageView* pPageView = hWidget->GetPageView();
  if (!pPageView)
    return;

  RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pPageView);
  if (!pPage)
    return;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  CFX_FloatRect rcCaret = pRtAnchor->ToFloatRect();
  pFormFillEnv->DisplayCaret(pPage.Get(), bVisible, rcCaret.left, rcCaret.top,
                             rcCaret.right, rcCaret.bottom);
}

bool CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget,
                                         float fMinPopup,
                                         float fMaxPopup,
                                         const CFX_RectF& rtAnchor,
                                         CFX_RectF* pPopupRect) {
  if (!hWidget)
    return false;

  CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
  if (!pXFAPageView)
    return false;

  RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pXFAPageView);
  if (!pPage)
    return false;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  FS_RECTF page_view_rect = {0.0f, 0.0f, 0.0f, 0.0f};
  pFormFillEnv->GetPageViewRect(pPage.Get(), page_view_rect);

  int nRotate = hWidget->GetNode()->GetRotate();

  int space_available_below_anchor;
  int space_available_above_anchor;
  switch (nRotate) {
    case 0:
    default: {
      space_available_below_anchor =
          static_cast<int>(page_view_rect.bottom - rtAnchor.bottom());
      space_available_above_anchor =
          static_cast<int>(rtAnchor.top - page_view_rect.top);

      if (rtAnchor.left < page_view_rect.left)
        pPopupRect->left += page_view_rect.left - rtAnchor.left;
      if (rtAnchor.right() > page_view_rect.right)
        pPopupRect->left -= rtAnchor.right() - page_view_rect.right;
      break;
    }
    case 90: {
      space_available_below_anchor =
          static_cast<int>(page_view_rect.right - rtAnchor.right());
      space_available_above_anchor =
          static_cast<int>(rtAnchor.left - page_view_rect.left);

      if (rtAnchor.bottom() > page_view_rect.bottom)
        pPopupRect->left += rtAnchor.bottom() - page_view_rect.bottom;
      if (rtAnchor.top < page_view_rect.top)
        pPopupRect->left -= page_view_rect.top - rtAnchor.top;
      break;
    }
    case 180: {
      space_available_below_anchor =
          static_cast<int>(rtAnchor.top - page_view_rect.top);
      space_available_above_anchor =
          static_cast<int>(page_view_rect.bottom - rtAnchor.bottom());

      if (rtAnchor.right() > page_view_rect.right)
        pPopupRect->left += rtAnchor.right() - page_view_rect.right;
      if (rtAnchor.left < page_view_rect.left)
        pPopupRect->left -= page_view_rect.left - rtAnchor.left;
      break;
    }
    case 270: {
      space_available_below_anchor =
          static_cast<int>(rtAnchor.left - page_view_rect.left);
      space_available_above_anchor =
          static_cast<int>(page_view_rect.right - rtAnchor.right());

      if (rtAnchor.top < page_view_rect.top)
        pPopupRect->left += page_view_rect.top - rtAnchor.top;
      if (rtAnchor.bottom() > page_view_rect.bottom)
        pPopupRect->left -= rtAnchor.bottom() - page_view_rect.bottom;
      break;
    }
  }

  // If there is no space on either side, the popup can't be rendered.
  if (space_available_below_anchor <= 0 && space_available_above_anchor <= 0)
    return false;

  // Determine whether to draw above or below the anchor.
  bool draw_below_anchor;
  if (space_available_below_anchor <= 0)
    draw_below_anchor = false;
  else if (space_available_above_anchor <= 0)
    draw_below_anchor = true;
  else if (space_available_below_anchor > space_available_above_anchor)
    draw_below_anchor = true;
  else
    draw_below_anchor = false;

  int space_available = (draw_below_anchor ? space_available_below_anchor
                                           : space_available_above_anchor);

  // Set the popup height and y position according to what was decided above.
  float popup_height;
  if (space_available < fMinPopup)
    popup_height = fMinPopup;
  else if (space_available > fMaxPopup)
    popup_height = fMaxPopup;
  else
    popup_height = static_cast<float>(space_available);

  switch (nRotate) {
    case 0:
    case 180: {
      if (draw_below_anchor)
        pPopupRect->top = rtAnchor.height;
      else
        pPopupRect->top = -popup_height;
      break;
    }
    case 90:
    case 270: {
      if (draw_below_anchor)
        pPopupRect->top = rtAnchor.width;
      else
        pPopupRect->top = -popup_height;
      break;
    }
    default:
      break;
  }

  pPopupRect->height = popup_height;

  return true;
}

bool CPDFXFA_DocEnvironment::PopupMenu(CXFA_FFWidget* hWidget,
                                       CFX_PointF ptPopup) {
  if (!hWidget)
    return false;

  CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
  if (!pXFAPageView)
    return false;

  RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pXFAPageView);
  if (!pPage)
    return false;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  int menuFlag = 0;
  if (hWidget->CanUndo())
    menuFlag |= FXFA_MENU_UNDO;
  if (hWidget->CanRedo())
    menuFlag |= FXFA_MENU_REDO;
  if (hWidget->CanPaste())
    menuFlag |= FXFA_MENU_PASTE;
  if (hWidget->CanCopy())
    menuFlag |= FXFA_MENU_COPY;
  if (hWidget->CanCut())
    menuFlag |= FXFA_MENU_CUT;
  if (hWidget->CanSelectAll())
    menuFlag |= FXFA_MENU_SELECTALL;

  return pFormFillEnv->PopupMenu(
      pPage.Get(), FPDFWidgetFromCXFAFFWidget(hWidget), menuFlag, ptPopup);
}

void CPDFXFA_DocEnvironment::PageViewEvent(CXFA_FFPageView* pPageView,
                                           uint32_t dwFlags) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  if (m_pContext->GetLoadStatus() == FXFA_LOADSTATUS_LOADING ||
      m_pContext->GetLoadStatus() == FXFA_LOADSTATUS_CLOSING ||
      XFA_PAGEVIEWEVENT_StopLayout != dwFlags)
    return;

  int nNewCount = m_pContext->GetPageCount();
  if (nNewCount == m_pContext->GetOriginalPageCount())
    return;

  CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
  if (!pXFADocView)
    return;

  for (int iPageIter = 0; iPageIter < m_pContext->GetOriginalPageCount();
       iPageIter++) {
    RetainPtr<CPDFXFA_Page> pPage = (*m_pContext->GetXFAPageList())[iPageIter];
    if (!pPage)
      continue;

    m_pContext->GetFormFillEnv()->RemovePageView(pPage.Get());
    pPage->SetXFAPageView(pXFADocView->GetPageView(iPageIter));
  }

  int flag = (nNewCount < m_pContext->GetOriginalPageCount())
                 ? FXFA_PAGEVIEWEVENT_POSTREMOVED
                 : FXFA_PAGEVIEWEVENT_POSTADDED;
  int count = abs(nNewCount - m_pContext->GetOriginalPageCount());
  m_pContext->SetOriginalPageCount(nNewCount);
  pFormFillEnv->PageEvent(count, flag);
}

void CPDFXFA_DocEnvironment::WidgetPostAdd(CXFA_FFWidget* hWidget) {
  if (m_pContext->GetFormType() != FormType::kXFAFull || !hWidget)
    return;

  CXFA_FFPageView* pPageView = hWidget->GetPageView();
  if (!pPageView)
    return;

  RetainPtr<CPDFXFA_Page> pXFAPage = m_pContext->GetXFAPage(pPageView);
  if (!pXFAPage)
    return;

  m_pContext->GetFormFillEnv()
      ->GetPageView(pXFAPage.Get(), true)
      ->AddAnnot(hWidget);
}

void CPDFXFA_DocEnvironment::WidgetPreRemove(CXFA_FFWidget* hWidget) {
  if (m_pContext->GetFormType() != FormType::kXFAFull || !hWidget)
    return;

  CXFA_FFPageView* pPageView = hWidget->GetPageView();
  if (!pPageView)
    return;

  RetainPtr<CPDFXFA_Page> pXFAPage = m_pContext->GetXFAPage(pPageView);
  if (!pXFAPage)
    return;

  CPDFSDK_PageView* pSdkPageView =
      m_pContext->GetFormFillEnv()->GetPageView(pXFAPage.Get(), true);
  CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget);
  if (pAnnot)
    pSdkPageView->DeleteAnnot(pAnnot);
}

int32_t CPDFXFA_DocEnvironment::CountPages(CXFA_FFDoc* hDoc) {
  if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv())
    return m_pContext->GetPageCount();
  return 0;
}

int32_t CPDFXFA_DocEnvironment::GetCurrentPage(CXFA_FFDoc* hDoc) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return -1;

  if (m_pContext->GetFormType() != FormType::kXFAFull)
    return -1;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  return pFormFillEnv ? pFormFillEnv->GetCurrentPageIndex() : -1;
}

void CPDFXFA_DocEnvironment::SetCurrentPage(CXFA_FFDoc* hDoc,
                                            int32_t iCurPage) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv() ||
      !m_pContext->ContainsXFAForm() || iCurPage < 0 ||
      iCurPage >= m_pContext->GetFormFillEnv()->GetPageCount()) {
    return;
  }

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  pFormFillEnv->SetCurrentPage(iCurPage);
}

bool CPDFXFA_DocEnvironment::IsCalculationsEnabled(CXFA_FFDoc* hDoc) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return false;
  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
    return m_pContext->GetFormFillEnv()
        ->GetInterForm()
        ->IsXfaCalculateEnabled();
  }
  return false;
}

void CPDFXFA_DocEnvironment::SetCalculationsEnabled(CXFA_FFDoc* hDoc,
                                                    bool bEnabled) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return;
  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
    m_pContext->GetFormFillEnv()->GetInterForm()->XfaEnableCalculate(bEnabled);
  }
}

void CPDFXFA_DocEnvironment::GetTitle(CXFA_FFDoc* hDoc, WideString& wsTitle) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc())
    return;

  const CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo();
  if (!pInfoDict)
    return;

  ByteString csTitle = pInfoDict->GetStringFor("Title");
  wsTitle = WideString::FromLocal(csTitle.c_str());
}

void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc,
                                      const WideString& wsTitle) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc())
    return;

  CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo();
  if (pInfoDict)
    pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle);
}

void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc,
                                        const WideString& wsFilePath,
                                        bool bXDP) {
  if (hDoc != m_pContext->GetXFADoc())
    return;

  if (!m_pContext->ContainsXFAForm())
    return;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;
  ByteString bs = wsFilePath.UTF16LE_Encode();
  if (wsFilePath.IsEmpty()) {
    if (!pFormFillEnv->GetFormFillInfo() ||
        !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform) {
      return;
    }

    WideString filepath = pFormFillEnv->JS_fieldBrowse();
    bs = filepath.UTF16LE_Encode();
  }
  FPDF_FILEHANDLER* pFileHandler = pFormFillEnv->OpenFile(
      bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML, AsFPDFWideString(&bs), "wb");
  if (!pFileHandler)
    return;

  RetainPtr<IFX_SeekableStream> fileWrite = MakeSeekableStream(pFileHandler);
  if (fileType == FXFA_SAVEAS_XML) {
    ByteString content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
    fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
                          content.GetLength());
    CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
    ffdoc->SavePackage(
        ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Data)), fileWrite);
  } else if (fileType == FXFA_SAVEAS_XDP) {
    if (!m_pContext->GetPDFDoc())
      return;

    const CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
    if (!pRoot)
      return;

    const CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
    if (!pAcroForm)
      return;

    const CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
    if (!pArray)
      return;

    int size = pArray->GetCount();
    for (int i = 1; i < size; i += 2) {
      const CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
      const CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
      if (!pPrePDFObj->IsString())
        continue;
      if (!pPDFObj->IsReference())
        continue;

      const CPDF_Stream* pStream = ToStream(pPDFObj->GetDirect());
      if (!pStream)
        continue;
      if (pPrePDFObj->GetString() == "form") {
        CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
        ffdoc->SavePackage(
            ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)),
            fileWrite);
        continue;
      }
      if (pPrePDFObj->GetString() == "datasets") {
        CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
        ffdoc->SavePackage(
            ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Datasets)),
            fileWrite);
        continue;
      }
      if (i == size - 1) {
        WideString wPath = WideString::FromUTF16LE(
            reinterpret_cast<const unsigned short*>(bs.c_str()),
            bs.GetLength() / sizeof(unsigned short));
        ByteString bPath = wPath.UTF8Encode();
        const char* szFormat =
            "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
        ByteString content = ByteString::Format(szFormat, bPath.c_str());
        fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
                              content.GetLength());
      }
      auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
      pAcc->LoadAllDataFiltered();
      fileWrite->WriteBlock(pAcc->GetData(), fileWrite->GetSize(),
                            pAcc->GetSize());
    }
  }
  fileWrite->Flush();
}

void CPDFXFA_DocEnvironment::GotoURL(CXFA_FFDoc* hDoc,
                                     const WideString& wsURL) {
  if (hDoc != m_pContext->GetXFADoc())
    return;

  if (m_pContext->GetFormType() != FormType::kXFAFull)
    return;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  pFormFillEnv->GotoURL(wsURL);
}

bool CPDFXFA_DocEnvironment::IsValidationsEnabled(CXFA_FFDoc* hDoc) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return false;
  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
    return m_pContext->GetFormFillEnv()
        ->GetInterForm()
        ->IsXfaValidationsEnabled();
  }
  return true;
}

void CPDFXFA_DocEnvironment::SetValidationsEnabled(CXFA_FFDoc* hDoc,
                                                   bool bEnabled) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return;
  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
    m_pContext->GetFormFillEnv()->GetInterForm()->XfaSetValidationsEnabled(
        bEnabled);
  }
}

void CPDFXFA_DocEnvironment::SetFocusWidget(CXFA_FFDoc* hDoc,
                                            CXFA_FFWidget* hWidget) {
  if (hDoc != m_pContext->GetXFADoc())
    return;

  if (!hWidget) {
    CPDFSDK_Annot::ObservedPtr pNull;
    m_pContext->GetFormFillEnv()->SetFocusAnnot(&pNull);
    return;
  }

  int pageViewCount = m_pContext->GetFormFillEnv()->GetPageViewCount();
  for (int i = 0; i < pageViewCount; i++) {
    CPDFSDK_PageView* pPageView = m_pContext->GetFormFillEnv()->GetPageView(i);
    if (!pPageView)
      continue;

    CPDFSDK_Annot::ObservedPtr pAnnot(pPageView->GetAnnotByXFAWidget(hWidget));
    if (pAnnot) {
      m_pContext->GetFormFillEnv()->SetFocusAnnot(&pAnnot);
      break;
    }
  }
}

void CPDFXFA_DocEnvironment::Print(CXFA_FFDoc* hDoc,
                                   int32_t nStartPage,
                                   int32_t nEndPage,
                                   uint32_t dwOptions) {
  if (hDoc != m_pContext->GetXFADoc())
    return;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv || !pFormFillEnv->GetFormFillInfo() ||
      !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform ||
      !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print) {
    return;
  }

  pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(
      pFormFillEnv->GetFormFillInfo()->m_pJsPlatform,
      dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,
      dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,
      dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,
      dwOptions & XFA_PRINTOPT_PrintAnnot);
}

FX_ARGB CPDFXFA_DocEnvironment::GetHighlightColor(CXFA_FFDoc* hDoc) {
  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
    return 0;

  CPDFSDK_InterForm* pInterForm = m_pContext->GetFormFillEnv()->GetInterForm();
  if (!pInterForm)
    return 0;

  return AlphaAndColorRefToArgb(
      pInterForm->GetHighlightAlpha(),
      pInterForm->GetHighlightColor(FormFieldType::kXFA));
}

bool CPDFXFA_DocEnvironment::NotifySubmit(bool bPrevOrPost) {
  if (bPrevOrPost)
    return OnBeforeNotifySubmit();

  OnAfterNotifySubmit();
  return true;
}

bool CPDFXFA_DocEnvironment::OnBeforeNotifySubmit() {
  if (!m_pContext->ContainsXFAForm())
    return true;

  CXFA_FFDocView* docView = m_pContext->GetXFADocView();
  if (!docView)
    return true;

  CXFA_FFWidgetHandler* pWidgetHandler = docView->GetWidgetHandler();
  if (!pWidgetHandler)
    return true;

  auto it = docView->CreateReadyNodeIterator();
  if (it) {
    CXFA_EventParam Param;
    Param.m_eType = XFA_EVENT_PreSubmit;
    while (CXFA_Node* pNode = it->MoveToNext())
      pWidgetHandler->ProcessEvent(pNode, &Param);
  }

  it = docView->CreateReadyNodeIterator();
  if (!it)
    return true;

  (void)it->MoveToNext();
  CXFA_Node* pNode = it->MoveToNext();

  while (pNode) {
    int fRet = pNode->ProcessValidate(docView, -1);
    if (fRet == XFA_EVENTERROR_Error) {
      CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
      if (!pFormFillEnv)
        return false;

      WideString ws = WideString::FromLocal(IDS_XFA_Validate_Input);
      ByteString bs = ws.UTF16LE_Encode();
      pFormFillEnv->Alert(AsFPDFWideString(&bs),
                          reinterpret_cast<FPDF_WIDESTRING>(L""), 0, 1);
      return false;
    }
    pNode = it->MoveToNext();
  }

  docView->UpdateDocView();
  return true;
}

void CPDFXFA_DocEnvironment::OnAfterNotifySubmit() {
  if (!m_pContext->ContainsXFAForm())
    return;

  if (!m_pContext->GetXFADocView())
    return;

  CXFA_FFWidgetHandler* pWidgetHandler =
      m_pContext->GetXFADocView()->GetWidgetHandler();
  if (!pWidgetHandler)
    return;

  auto it = m_pContext->GetXFADocView()->CreateReadyNodeIterator();
  if (!it)
    return;

  CXFA_EventParam Param;
  Param.m_eType = XFA_EVENT_PostSubmit;
  CXFA_Node* pNode = it->MoveToNext();
  while (pNode) {
    pWidgetHandler->ProcessEvent(pNode, &Param);
    pNode = it->MoveToNext();
  }
  m_pContext->GetXFADocView()->UpdateDocView();
}

bool CPDFXFA_DocEnvironment::Submit(CXFA_FFDoc* hDoc, CXFA_Submit* submit) {
  if (!NotifySubmit(true) || !m_pContext->GetXFADocView())
    return false;

  m_pContext->GetXFADocView()->UpdateDocView();
  bool ret = SubmitInternal(hDoc, submit);
  NotifySubmit(false);
  return ret;
}

RetainPtr<IFX_SeekableReadStream> CPDFXFA_DocEnvironment::OpenLinkedFile(
    CXFA_FFDoc* hDoc,
    const WideString& wsLink) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return nullptr;

  ByteString bs = wsLink.UTF16LE_Encode();
  FPDF_FILEHANDLER* pFileHandler =
      pFormFillEnv->OpenFile(0, AsFPDFWideString(&bs), "rb");
  if (!pFileHandler)
    return nullptr;

  return MakeSeekableStream(pFileHandler);
}

bool CPDFXFA_DocEnvironment::ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,
                                              int fileType,
                                              FPDF_DWORD encodeType,
                                              FPDF_DWORD flag) {
  if (!m_pContext->GetXFADocView())
    return false;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
  RetainPtr<IFX_SeekableStream> fileStream = MakeSeekableStream(pFileHandler);
  if (fileType == FXFA_SAVEAS_XML) {
    static constexpr char kContent[] =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
    fileStream->WriteBlock(kContent, 0, strlen(kContent));

    ffdoc->SavePackage(
        ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Data)),
        fileStream);
    return true;
  }

  if (fileType != FXFA_SAVEAS_XDP)
    return true;

  if (!flag) {
    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
  }
  if (!m_pContext->GetPDFDoc()) {
    fileStream->Flush();
    return false;
  }

  const CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
  if (!pRoot) {
    fileStream->Flush();
    return false;
  }

  const CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
  if (!pAcroForm) {
    fileStream->Flush();
    return false;
  }

  const CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
  if (!pArray) {
    fileStream->Flush();
    return false;
  }

  int size = pArray->GetCount();
  for (int i = 1; i < size; i += 2) {
    const CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
    const CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
    if (!pPrePDFObj->IsString())
      continue;
    if (!pPDFObj->IsReference())
      continue;

    const CPDF_Object* pDirectObj = pPDFObj->GetDirect();
    if (!pDirectObj->IsStream())
      continue;
    ByteString bsType = pPrePDFObj->GetString();
    if (bsType == "config" && !(flag & FXFA_CONFIG))
      continue;
    if (bsType == "template" && !(flag & FXFA_TEMPLATE))
      continue;
    if (bsType == "localeSet" && !(flag & FXFA_LOCALESET))
      continue;
    if (bsType == "datasets" && !(flag & FXFA_DATASETS))
      continue;
    if (bsType == "xmpmeta" && !(flag & FXFA_XMPMETA))
      continue;
    if (bsType == "xfdf" && !(flag & FXFA_XFDF))
      continue;
    if (bsType == "form" && !(flag & FXFA_FORM))
      continue;

    if (bsType == "form") {
      ffdoc->SavePackage(
          ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)),
          fileStream);
    } else if (pPrePDFObj->GetString() == "datasets") {
      ffdoc->SavePackage(
          ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Datasets)),
          fileStream);
    }
  }
  return true;
}

void CPDFXFA_DocEnvironment::ToXFAContentFlags(WideString csSrcContent,
                                               FPDF_DWORD& flag) {
  if (csSrcContent.Contains(L" config "))
    flag |= FXFA_CONFIG;
  if (csSrcContent.Contains(L" template "))
    flag |= FXFA_TEMPLATE;
  if (csSrcContent.Contains(L" localeSet "))
    flag |= FXFA_LOCALESET;
  if (csSrcContent.Contains(L" datasets "))
    flag |= FXFA_DATASETS;
  if (csSrcContent.Contains(L" xmpmeta "))
    flag |= FXFA_XMPMETA;
  if (csSrcContent.Contains(L" xfdf "))
    flag |= FXFA_XFDF;
  if (csSrcContent.Contains(L" form "))
    flag |= FXFA_FORM;
  if (flag == 0) {
    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
  }
}

bool CPDFXFA_DocEnvironment::MailToInfo(WideString& csURL,
                                        WideString& csToAddress,
                                        WideString& csCCAddress,
                                        WideString& csBCCAddress,
                                        WideString& csSubject,
                                        WideString& csMsg) {
  WideString srcURL = csURL;
  srcURL.TrimLeft();
  if (srcURL.Left(7).CompareNoCase(L"mailto:") != 0)
    return false;

  auto pos = srcURL.Find(L'?');

  {
    WideString tmp;
    if (!pos.has_value()) {
      pos = srcURL.Find(L'@');
      if (!pos.has_value())
        return false;

      tmp = srcURL.Right(csURL.GetLength() - 7);
    } else {
      tmp = srcURL.Left(pos.value());
      tmp = tmp.Right(tmp.GetLength() - 7);
    }
    tmp.Trim();
    csToAddress = std::move(tmp);
  }

  srcURL = srcURL.Right(srcURL.GetLength() - (pos.value() + 1));
  while (!srcURL.IsEmpty()) {
    srcURL.Trim();
    pos = srcURL.Find(L'&');
    WideString tmp = (!pos.has_value()) ? srcURL : srcURL.Left(pos.value());
    tmp.Trim();
    if (tmp.GetLength() >= 3 && tmp.Left(3).CompareNoCase(L"cc=") == 0) {
      tmp = tmp.Right(tmp.GetLength() - 3);
      if (!csCCAddress.IsEmpty())
        csCCAddress += L';';
      csCCAddress += tmp;
    } else if (tmp.GetLength() >= 4 &&
               tmp.Left(4).CompareNoCase(L"bcc=") == 0) {
      tmp = tmp.Right(tmp.GetLength() - 4);
      if (!csBCCAddress.IsEmpty())
        csBCCAddress += L';';
      csBCCAddress += tmp;
    } else if (tmp.GetLength() >= 8 &&
               tmp.Left(8).CompareNoCase(L"subject=") == 0) {
      tmp = tmp.Right(tmp.GetLength() - 8);
      csSubject += tmp;
    } else if (tmp.GetLength() >= 5 &&
               tmp.Left(5).CompareNoCase(L"body=") == 0) {
      tmp = tmp.Right(tmp.GetLength() - 5);
      csMsg += tmp;
    }
    srcURL = !pos.has_value()
                 ? L""
                 : srcURL.Right(csURL.GetLength() - (pos.value() + 1));
  }
  csToAddress.Replace(L",", L";");
  csCCAddress.Replace(L",", L";");
  csBCCAddress.Replace(L",", L";");
  return true;
}

bool CPDFXFA_DocEnvironment::SubmitInternal(CXFA_FFDoc* hDoc,
                                            CXFA_Submit* submit) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  WideString csURL = submit->GetSubmitTarget();
  if (csURL.IsEmpty()) {
    WideString ws = WideString::FromLocal("Submit cancelled.");
    ByteString bs = ws.UTF16LE_Encode();
    pFormFillEnv->Alert(AsFPDFWideString(&bs),
                        reinterpret_cast<FPDF_WIDESTRING>(L""), 0, 4);
    return false;
  }

  FPDF_FILEHANDLER* pFileHandler = nullptr;
  int fileFlag = -1;
  switch (submit->GetSubmitFormat()) {
    case XFA_AttributeEnum::Xdp: {
      WideString csContent = submit->GetSubmitXDPContent();
      csContent.Trim();

      WideString space = WideString::FromLocal(" ");
      csContent = space + csContent + space;
      FPDF_DWORD flag = 0;
      if (submit->IsSubmitEmbedPDF())
        flag |= FXFA_PDF;

      ToXFAContentFlags(csContent, flag);
      pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XDP, nullptr, "wb");
      fileFlag = FXFA_SAVEAS_XDP;
      ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);
      break;
    }
    case XFA_AttributeEnum::Xml:
      pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
      fileFlag = FXFA_SAVEAS_XML;
      ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
      break;
    case XFA_AttributeEnum::Pdf:
      break;
    case XFA_AttributeEnum::Urlencoded:
      pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
      fileFlag = FXFA_SAVEAS_XML;
      ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
      break;
    default:
      return false;
  }
  if (!pFileHandler)
    return false;

  if (csURL.Left(7).CompareNoCase(L"mailto:") == 0) {
    WideString csToAddress;
    WideString csCCAddress;
    WideString csBCCAddress;
    WideString csSubject;
    WideString csMsg;
    if (!MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,
                    csMsg)) {
      return false;
    }
    ByteString bsTo = WideString(csToAddress).UTF16LE_Encode();
    ByteString bsCC = WideString(csCCAddress).UTF16LE_Encode();
    ByteString bsBcc = WideString(csBCCAddress).UTF16LE_Encode();
    ByteString bsSubject = WideString(csSubject).UTF16LE_Encode();
    ByteString bsMsg = WideString(csMsg).UTF16LE_Encode();
    pFormFillEnv->EmailTo(pFileHandler, AsFPDFWideString(&bsTo),
                          AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC),
                          AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg));
    return true;
  }

  // HTTP or FTP
  ByteString bs = csURL.UTF16LE_Encode();
  pFormFillEnv->UploadTo(pFileHandler, fileFlag, AsFPDFWideString(&bs));
  return true;
}

bool CPDFXFA_DocEnvironment::SetPropertyInNonXFAGlobalObject(
    CXFA_FFDoc* hDoc,
    const ByteStringView& szPropName,
    CFXJSE_Value* pValue) {
  if (hDoc != m_pContext->GetXFADoc())
    return false;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  IJS_Runtime* pIJSRuntime = pFormFillEnv->GetIJSRuntime();
  if (!pIJSRuntime)
    return false;

  IJS_Runtime::ScopedEventContext pContext(pIJSRuntime);
  return pIJSRuntime->SetValueByNameInGlobalObject(szPropName, pValue);
}

bool CPDFXFA_DocEnvironment::GetPropertyFromNonXFAGlobalObject(
    CXFA_FFDoc* hDoc,
    const ByteStringView& szPropName,
    CFXJSE_Value* pValue) {
  if (hDoc != m_pContext->GetXFADoc())
    return false;

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  IJS_Runtime* pIJSRuntime = pFormFillEnv->GetIJSRuntime();
  if (!pIJSRuntime)
    return false;

  IJS_Runtime::ScopedEventContext pContext(pIJSRuntime);
  return pIJSRuntime->GetValueByNameFromGlobalObject(szPropName, pValue);
}
