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

#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
#include "../../include/javascript/IJavaScript.h"
#include "Field.h"
#include "Icon.h"
#include "JS_Context.h"
#include "JS_Define.h"
#include "JS_EventHandler.h"
#include "JS_Object.h"
#include "JS_Runtime.h"
#include "JS_Value.h"
#include "app.h"
#include "resource.h"
#include "third_party/base/numerics/safe_math.h"

static v8::Isolate* GetIsolate(IJS_Context* cc) {
  CJS_Context* pContext = (CJS_Context*)cc;
  ASSERT(pContext != NULL);

  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  ASSERT(pRuntime != NULL);

  return pRuntime->GetIsolate();
}

BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)

PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject)
    : CJS_EmbedObj(pJSObject) {
  bUI = TRUE;
  nStart = 0;
  nEnd = 0;
  bSilent = FALSE;
  bShrinkToFit = FALSE;
  bPrintAsImage = FALSE;
  bReverse = FALSE;
  bAnnotations = TRUE;
}

/* ---------------------- Document ---------------------- */

#define MINWIDTH 5.0f
#define MINHEIGHT 5.0f

BEGIN_JS_STATIC_CONST(CJS_Document)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_Document)
JS_STATIC_PROP_ENTRY(ADBE)
JS_STATIC_PROP_ENTRY(author)
JS_STATIC_PROP_ENTRY(baseURL)
JS_STATIC_PROP_ENTRY(bookmarkRoot)
JS_STATIC_PROP_ENTRY(calculate)
JS_STATIC_PROP_ENTRY(Collab)
JS_STATIC_PROP_ENTRY(creationDate)
JS_STATIC_PROP_ENTRY(creator)
JS_STATIC_PROP_ENTRY(delay)
JS_STATIC_PROP_ENTRY(dirty)
JS_STATIC_PROP_ENTRY(documentFileName)
JS_STATIC_PROP_ENTRY(external)
JS_STATIC_PROP_ENTRY(filesize)
JS_STATIC_PROP_ENTRY(icons)
JS_STATIC_PROP_ENTRY(info)
JS_STATIC_PROP_ENTRY(keywords)
JS_STATIC_PROP_ENTRY(layout)
JS_STATIC_PROP_ENTRY(media)
JS_STATIC_PROP_ENTRY(modDate)
JS_STATIC_PROP_ENTRY(mouseX)
JS_STATIC_PROP_ENTRY(mouseY)
JS_STATIC_PROP_ENTRY(numFields)
JS_STATIC_PROP_ENTRY(numPages)
JS_STATIC_PROP_ENTRY(pageNum)
JS_STATIC_PROP_ENTRY(pageWindowRect)
JS_STATIC_PROP_ENTRY(path)
JS_STATIC_PROP_ENTRY(producer)
JS_STATIC_PROP_ENTRY(subject)
JS_STATIC_PROP_ENTRY(title)
JS_STATIC_PROP_ENTRY(zoom)
JS_STATIC_PROP_ENTRY(zoomType)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_Document)
JS_STATIC_METHOD_ENTRY(addAnnot)
JS_STATIC_METHOD_ENTRY(addField)
JS_STATIC_METHOD_ENTRY(addLink)
JS_STATIC_METHOD_ENTRY(addIcon)
JS_STATIC_METHOD_ENTRY(calculateNow)
JS_STATIC_METHOD_ENTRY(closeDoc)
JS_STATIC_METHOD_ENTRY(createDataObject)
JS_STATIC_METHOD_ENTRY(deletePages)
JS_STATIC_METHOD_ENTRY(exportAsText)
JS_STATIC_METHOD_ENTRY(exportAsFDF)
JS_STATIC_METHOD_ENTRY(exportAsXFDF)
JS_STATIC_METHOD_ENTRY(extractPages)
JS_STATIC_METHOD_ENTRY(getAnnot)
JS_STATIC_METHOD_ENTRY(getAnnots)
JS_STATIC_METHOD_ENTRY(getAnnot3D)
JS_STATIC_METHOD_ENTRY(getAnnots3D)
JS_STATIC_METHOD_ENTRY(getField)
JS_STATIC_METHOD_ENTRY(getIcon)
JS_STATIC_METHOD_ENTRY(getLinks)
JS_STATIC_METHOD_ENTRY(getNthFieldName)
JS_STATIC_METHOD_ENTRY(getOCGs)
JS_STATIC_METHOD_ENTRY(getPageBox)
JS_STATIC_METHOD_ENTRY(getPageNthWord)
JS_STATIC_METHOD_ENTRY(getPageNthWordQuads)
JS_STATIC_METHOD_ENTRY(getPageNumWords)
JS_STATIC_METHOD_ENTRY(getPrintParams)
JS_STATIC_METHOD_ENTRY(getURL)
JS_STATIC_METHOD_ENTRY(importAnFDF)
JS_STATIC_METHOD_ENTRY(importAnXFDF)
JS_STATIC_METHOD_ENTRY(importTextData)
JS_STATIC_METHOD_ENTRY(insertPages)
JS_STATIC_METHOD_ENTRY(mailForm)
JS_STATIC_METHOD_ENTRY(print)
JS_STATIC_METHOD_ENTRY(removeField)
JS_STATIC_METHOD_ENTRY(replacePages)
JS_STATIC_METHOD_ENTRY(resetForm)
JS_STATIC_METHOD_ENTRY(removeIcon)
JS_STATIC_METHOD_ENTRY(saveAs)
JS_STATIC_METHOD_ENTRY(submitForm)
JS_STATIC_METHOD_ENTRY(mailDoc)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_Document, Document)

void CJS_Document::InitInstance(IJS_Runtime* pIRuntime) {
  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
  Document* pDoc = static_cast<Document*>(GetEmbedObject());
  pDoc->AttachDoc(pRuntime->GetReaderDocument());
  pDoc->SetIsolate(pRuntime->GetIsolate());
}

/* --------------------------------- Document ---------------------------------
 */

Document::Document(CJS_Object* pJSObject)
    : CJS_EmbedObj(pJSObject),
      m_isolate(NULL),
      m_pIconTree(NULL),
      m_pDocument(NULL),
      m_cwBaseURL(L""),
      m_bDelay(FALSE) {}

Document::~Document() {
  if (m_pIconTree) {
    m_pIconTree->DeleteIconTree();
    delete m_pIconTree;
    m_pIconTree = NULL;
  }
  for (int i = 0; i < m_DelayData.GetSize(); i++) {
    if (CJS_DelayData* pData = m_DelayData.GetAt(i)) {
      delete pData;
      pData = NULL;
      m_DelayData.SetAt(i, NULL);
    }
  }

  m_DelayData.RemoveAll();
  m_DelayAnnotData.RemoveAll();
}

// the total number of fileds in document.
FX_BOOL Document::numFields(IJS_Context* cc,
                            CJS_PropValue& vp,
                            CFX_WideString& sError) {
  if (vp.IsSetting()) {
    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
    return FALSE;
  }
  CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
  vp << (int)pPDFForm->CountFields();
  return TRUE;
}

FX_BOOL Document::dirty(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (vp.IsGetting()) {
    if (m_pDocument->GetChangeMark())
      vp << true;
    else
      vp << false;
  } else {
    bool bChanged = false;

    vp >> bChanged;

    if (bChanged)
      m_pDocument->SetChangeMark();
    else
      m_pDocument->ClearChangeMark();
  }

  return TRUE;
}

FX_BOOL Document::ADBE(IJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (vp.IsGetting()) {
    vp.SetNull();
  } else {
  }

  return TRUE;
}

FX_BOOL Document::pageNum(IJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (vp.IsGetting()) {
    if (CPDFSDK_PageView* pPageView = m_pDocument->GetCurrentView()) {
      vp << pPageView->GetPageIndex();
    }
  } else {
    int iPageCount = m_pDocument->GetPageCount();
    int iPageNum = 0;
    vp >> iPageNum;

    CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
    if (iPageNum >= 0 && iPageNum < iPageCount) {
      pEnv->JS_docgotoPage(iPageNum);
    } else if (iPageNum >= iPageCount) {
      pEnv->JS_docgotoPage(iPageCount - 1);
    } else if (iPageNum < 0) {
      pEnv->JS_docgotoPage(0);
    }
  }

  return TRUE;
}

FX_BOOL Document::addAnnot(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  // Not supported.
  return TRUE;
}

FX_BOOL Document::addField(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  // Not supported.
  return TRUE;
}

FX_BOOL Document::exportAsText(IJS_Context* cc,
                               const CJS_Parameters& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::exportAsFDF(IJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::exportAsXFDF(IJS_Context* cc,
                               const CJS_Parameters& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

// Maps a field object in PDF document to a JavaScript variable
// comment:
// note: the paremter cName, this is clue how to treat if the cName is not a
// valiable filed name in this document

FX_BOOL Document::getField(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  if (params.size() < 1) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
    return FALSE;
  }

  CFX_WideString wideName = params[0].ToCFXWideString();

  CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
  if (pPDFForm->CountFields(wideName) <= 0) {
    vRet.SetNull();
    return TRUE;
  }

  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);

  v8::Isolate* isolate = GetIsolate(cc);
  CJS_Field* pJSField = (CJS_Field*)FXJS_GetPrivate(isolate, pFieldObj);
  Field* pField = (Field*)pJSField->GetEmbedObject();
  pField->AttachField(this, wideName);

  vRet = pJSField;
  return TRUE;
}

// Gets the name of the nth field in the document
FX_BOOL Document::getNthFieldName(IJS_Context* cc,
                                  const CJS_Parameters& params,
                                  CJS_Value& vRet,
                                  CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  if (params.size() != 1) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
    return FALSE;
  }

  int nIndex = params[0].ToInt();
  if (nIndex < 0) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
    return FALSE;
  }

  CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
  CPDF_FormField* pField = pPDFForm->GetField(nIndex);
  if (!pField)
    return FALSE;

  vRet = pField->GetFullName().c_str();
  return TRUE;
}

FX_BOOL Document::importAnFDF(IJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::importAnXFDF(IJS_Context* cc,
                               const CJS_Parameters& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::importTextData(IJS_Context* cc,
                                 const CJS_Parameters& params,
                                 CJS_Value& vRet,
                                 CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

// exports the form data and mails the resulting fdf file as an attachment to
// all recipients.
// comment: need reader supports
// note:
// int CPDFSDK_Document::mailForm(FX_BOOL bUI,String cto,string ccc,string
// cbcc,string cSubject,string cms);

FX_BOOL Document::mailForm(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
    return FALSE;

  int iLength = params.size();

  FX_BOOL bUI = iLength > 0 ? params[0].ToBool() : TRUE;
  CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString() : L"";
  CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString() : L"";
  CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString() : L"";
  CFX_WideString cSubject = iLength > 4 ? params[4].ToCFXWideString() : L"";
  CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString() : L"";

  CPDFSDK_InterForm* pInterForm =
      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  CFX_ByteTextBuf textBuf;
  if (!pInterForm->ExportFormToFDFTextBuf(textBuf))
    return FALSE;

  CJS_Context* pContext = (CJS_Context*)cc;
  ASSERT(pContext != NULL);
  CPDFDoc_Environment* pEnv = pContext->GetReaderApp();
  ASSERT(pEnv != NULL);
  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  ASSERT(pRuntime != NULL);

  pRuntime->BeginBlock();
  pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI,
                       cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(),
                       cMsg.c_str());
  pRuntime->EndBlock();
  return TRUE;
}

FX_BOOL Document::print(IJS_Context* cc,
                        const CJS_Parameters& params,
                        CJS_Value& vRet,
                        CFX_WideString& sError) {
  FX_BOOL bUI = TRUE;
  int nStart = 0;
  int nEnd = 0;
  FX_BOOL bSilent = FALSE;
  FX_BOOL bShrinkToFit = FALSE;
  FX_BOOL bPrintAsImage = FALSE;
  FX_BOOL bReverse = FALSE;
  FX_BOOL bAnnotations = FALSE;

  int nlength = params.size();
  if (nlength == 9) {
    if (params[8].GetType() == CJS_Value::VT_fxobject) {
      v8::Local<v8::Object> pObj = params[8].ToV8Object();
      {
        if (FXJS_GetObjDefnID(pObj) == CJS_PrintParamsObj::g_nObjDefnID) {
          if (CJS_Object* pJSObj = params[8].ToCJSObject()) {
            if (PrintParamsObj* pprintparamsObj =
                    (PrintParamsObj*)pJSObj->GetEmbedObject()) {
              bUI = pprintparamsObj->bUI;
              nStart = pprintparamsObj->nStart;
              nEnd = pprintparamsObj->nEnd;
              bSilent = pprintparamsObj->bSilent;
              bShrinkToFit = pprintparamsObj->bShrinkToFit;
              bPrintAsImage = pprintparamsObj->bPrintAsImage;
              bReverse = pprintparamsObj->bReverse;
              bAnnotations = pprintparamsObj->bAnnotations;
            }
          }
        }
      }
    }
  } else {
    if (nlength >= 1)
      bUI = params[0].ToBool();
    if (nlength >= 2)
      nStart = params[1].ToInt();
    if (nlength >= 3)
      nEnd = params[2].ToInt();
    if (nlength >= 4)
      bSilent = params[3].ToBool();
    if (nlength >= 5)
      bShrinkToFit = params[4].ToBool();
    if (nlength >= 6)
      bPrintAsImage = params[5].ToBool();
    if (nlength >= 7)
      bReverse = params[6].ToBool();
    if (nlength >= 8)
      bAnnotations = params[7].ToBool();
  }

  ASSERT(m_pDocument != NULL);

  if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) {
    pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage,
                      bReverse, bAnnotations);
    return TRUE;
  }
  return FALSE;
}

// removes the specified field from the document.
// comment:
// note: if the filed name is not retional, adobe is dumb for it.

FX_BOOL Document::removeField(IJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
        m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM)))
    return FALSE;

  CJS_Context* pContext = (CJS_Context*)cc;
  if (params.size() != 1) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
    return FALSE;
  }

  CFX_WideString sFieldName = params[0].ToCFXWideString();
  CPDFSDK_InterForm* pInterForm =
      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  std::vector<CPDFSDK_Widget*> widgets;
  pInterForm->GetWidgets(sFieldName, &widgets);

  if (widgets.empty())
    return TRUE;

  for (CPDFSDK_Widget* pWidget : widgets) {
    CPDF_Rect rcAnnot = pWidget->GetRect();
    --rcAnnot.left;
    --rcAnnot.bottom;
    ++rcAnnot.right;
    ++rcAnnot.top;

    CFX_RectArray aRefresh;
    aRefresh.Add(rcAnnot);

    CPDFXFA_Page* pPage = pWidget->GetPDFXFAPage();
    ASSERT(pPage);

    CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage);
    pPageView->DeleteAnnot(pWidget);
    pPageView->UpdateRects(aRefresh);
  }
  m_pDocument->SetChangeMark();

  return TRUE;
}

// reset filed values within a document.
// comment:
// note: if the fields names r not rational, aodbe is dumb for it.

FX_BOOL Document::resetForm(IJS_Context* cc,
                            const CJS_Parameters& params,
                            CJS_Value& vRet,
                            CFX_WideString& sError) {
  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
        m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
        m_pDocument->GetPermissions(FPDFPERM_FILL_FORM)))
    return FALSE;

  CPDFSDK_InterForm* pInterForm =
      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
  CJS_Array aName(pRuntime);

  // TODO(thestig) Convert CJS_Parameters to a std::vector and use .empty().
  if (params.size() <= 0) {
    pPDFForm->ResetForm(TRUE);
    m_pDocument->SetChangeMark();
    return TRUE;
  }

  switch (params[0].GetType()) {
    default:
      aName.Attach(params[0].ToV8Array());
      break;
    case CJS_Value::VT_string:
      aName.SetElement(0, params[0]);
      break;
  }

  std::vector<CPDF_FormField*> aFields;
  for (int i = 0, isz = aName.GetLength(); i < isz; ++i) {
    CJS_Value valElement(pRuntime);
    aName.GetElement(i, valElement);
    CFX_WideString swVal = valElement.ToCFXWideString();
    for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j)
      aFields.push_back(pPDFForm->GetField(j, swVal));
  }

  if (!aFields.empty()) {
    pPDFForm->ResetForm(aFields, TRUE, TRUE);
    m_pDocument->SetChangeMark();
  }

  return TRUE;
}

FX_BOOL Document::saveAs(IJS_Context* cc,
                         const CJS_Parameters& params,
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::submitForm(IJS_Context* cc,
                             const CJS_Parameters& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  int nSize = params.size();
  if (nSize < 1) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
    return FALSE;
  }

  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
  v8::Isolate* isolate = pRuntime->GetIsolate();
  CJS_Array aFields(pRuntime);
  CFX_WideString strURL;
  FX_BOOL bFDF = TRUE;
  FX_BOOL bEmpty = FALSE;

  CJS_Value v = params[0];
  if (v.GetType() == CJS_Value::VT_string) {
    strURL = params[0].ToCFXWideString();
    if (nSize > 1)
      bFDF = params[1].ToBool();
    if (nSize > 2)
      bEmpty = params[2].ToBool();
    if (nSize > 3)
      aFields.Attach(params[3].ToV8Array());
  } else if (v.GetType() == CJS_Value::VT_object) {
    v8::Local<v8::Object> pObj = params[0].ToV8Object();
    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"cURL");
    if (!pValue.IsEmpty())
      strURL =
          CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"bFDF");
    bFDF = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"bEmpty");
    bEmpty = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"aFields");
    aFields.Attach(
        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToV8Array());
  }

  CPDFSDK_InterForm* pInterForm =
      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
  FX_BOOL bAll = (aFields.GetLength() == 0);
  if (bAll && bEmpty) {
    if (pPDFInterForm->CheckRequiredFields(nullptr, true)) {
      pRuntime->BeginBlock();
      pInterForm->SubmitForm(strURL, FALSE);
      pRuntime->EndBlock();
    }
    return TRUE;
  }

  std::vector<CPDF_FormField*> fieldObjects;
  for (int i = 0, sz = aFields.GetLength(); i < sz; ++i) {
    CJS_Value valName(pRuntime);
    aFields.GetElement(i, valName);

    CFX_WideString sName = valName.ToCFXWideString();
    CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
    for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) {
      CPDF_FormField* pField = pPDFForm->GetField(j, sName);
      if (!bEmpty && pField->GetValue().IsEmpty())
        continue;

      fieldObjects.push_back(pField);
    }
  }

  if (pPDFInterForm->CheckRequiredFields(&fieldObjects, true)) {
    pRuntime->BeginBlock();
    pInterForm->SubmitFields(strURL, fieldObjects, TRUE, !bFDF);
    pRuntime->EndBlock();
  }
  return TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////////

void Document::AttachDoc(CPDFSDK_Document* pDoc) {
  m_pDocument = pDoc;
}

CPDFSDK_Document* Document::GetReaderDoc() {
  return m_pDocument;
}

FX_BOOL Document::ExtractFileName(CPDFSDK_Document* pDoc,
                                  CFX_ByteString& strFileName) {
  return FALSE;
}

FX_BOOL Document::ExtractFolderName(CPDFSDK_Document* pDoc,
                                    CFX_ByteString& strFolderName) {
  return FALSE;
}

FX_BOOL Document::bookmarkRoot(IJS_Context* cc,
                               CJS_PropValue& vp,
                               CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::mailDoc(IJS_Context* cc,
                          const CJS_Parameters& params,
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
  FX_BOOL bUI = TRUE;
  CFX_WideString cTo = L"";
  CFX_WideString cCc = L"";
  CFX_WideString cBcc = L"";
  CFX_WideString cSubject = L"";
  CFX_WideString cMsg = L"";

  if (params.size() >= 1)
    bUI = params[0].ToBool();
  if (params.size() >= 2)
    cTo = params[1].ToCFXWideString();
  if (params.size() >= 3)
    cCc = params[2].ToCFXWideString();
  if (params.size() >= 4)
    cBcc = params[3].ToCFXWideString();
  if (params.size() >= 5)
    cSubject = params[4].ToCFXWideString();
  if (params.size() >= 6)
    cMsg = params[5].ToCFXWideString();

  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
  v8::Isolate* isolate = pRuntime->GetIsolate();

  if (params.size() >= 1 && params[0].GetType() == CJS_Value::VT_object) {
    v8::Local<v8::Object> pObj = params[0].ToV8Object();

    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
    bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToInt();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
    cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
    cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
    cBcc =
        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
    cSubject =
        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

    pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
    cMsg =
        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
  }

  pRuntime->BeginBlock();
  CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
  pEnv->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(),
                       cBcc.c_str(), cMsg.c_str());
  pRuntime->EndBlock();

  return TRUE;
}

FX_BOOL Document::author(IJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("Author");
    return TRUE;
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString csAuthor;
    vp >> csAuthor;
    pDictionary->SetAtString("Author", PDF_EncodeText(csAuthor));
    m_pDocument->SetChangeMark();
    return TRUE;
  }
}

FX_BOOL Document::info(IJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  CFX_WideString cwAuthor = pDictionary->GetUnicodeText("Author");
  CFX_WideString cwTitle = pDictionary->GetUnicodeText("Title");
  CFX_WideString cwSubject = pDictionary->GetUnicodeText("Subject");
  CFX_WideString cwKeywords = pDictionary->GetUnicodeText("Keywords");
  CFX_WideString cwCreator = pDictionary->GetUnicodeText("Creator");
  CFX_WideString cwProducer = pDictionary->GetUnicodeText("Producer");
  CFX_WideString cwCreationDate = pDictionary->GetUnicodeText("CreationDate");
  CFX_WideString cwModDate = pDictionary->GetUnicodeText("ModDate");
  CFX_WideString cwTrapped = pDictionary->GetUnicodeText("Trapped");

  v8::Isolate* isolate = GetIsolate(cc);
  if (vp.IsGetting()) {
    CJS_Context* pContext = (CJS_Context*)cc;
    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
    v8::Local<v8::Object> pObj =
        FXJS_NewFxDynamicObj(pRuntime->GetIsolate(), pRuntime, -1);
    FXJS_PutObjectString(isolate, pObj, L"Author", cwAuthor.c_str());
    FXJS_PutObjectString(isolate, pObj, L"Title", cwTitle.c_str());
    FXJS_PutObjectString(isolate, pObj, L"Subject", cwSubject.c_str());
    FXJS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords.c_str());
    FXJS_PutObjectString(isolate, pObj, L"Creator", cwCreator.c_str());
    FXJS_PutObjectString(isolate, pObj, L"Producer", cwProducer.c_str());
    FXJS_PutObjectString(isolate, pObj, L"CreationDate",
                         cwCreationDate.c_str());
    FXJS_PutObjectString(isolate, pObj, L"ModDate", cwModDate.c_str());
    FXJS_PutObjectString(isolate, pObj, L"Trapped", cwTrapped.c_str());

    // It's to be compatible to non-standard info dictionary.
    FX_POSITION pos = pDictionary->GetStartPos();
    while (pos) {
      CFX_ByteString bsKey;
      CPDF_Object* pValueObj = pDictionary->GetNextElement(pos, bsKey);
      CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey, bsKey.GetLength());

      if (pValueObj->IsString() || pValueObj->IsName()) {
        FXJS_PutObjectString(isolate, pObj, wsKey.c_str(),
                             pValueObj->GetUnicodeText().c_str());
      } else if (pValueObj->IsNumber()) {
        FXJS_PutObjectNumber(isolate, pObj, wsKey.c_str(),
                             (float)pValueObj->GetNumber());
      } else if (pValueObj->IsBoolean()) {
        FXJS_PutObjectBoolean(isolate, pObj, wsKey.c_str(),
                              (bool)pValueObj->GetInteger());
      }
    }
    vp << pObj;
  }
  return TRUE;
}

FX_BOOL Document::creationDate(IJS_Context* cc,
                               CJS_PropValue& vp,
                               CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("CreationDate");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString csCreationDate;
    vp >> csCreationDate;
    pDictionary->SetAtString("CreationDate", PDF_EncodeText(csCreationDate));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::creator(IJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("Creator");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString csCreator;
    vp >> csCreator;
    pDictionary->SetAtString("Creator", PDF_EncodeText(csCreator));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::delay(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
  if (vp.IsGetting()) {
    vp << m_bDelay;
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    vp >> m_bDelay;
    if (m_bDelay) {
      for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++)
        delete m_DelayData.GetAt(i);

      m_DelayData.RemoveAll();
    } else {
      CFX_ArrayTemplate<CJS_DelayData*> DelayDataToProcess;
      for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) {
        if (CJS_DelayData* pData = m_DelayData.GetAt(i)) {
          DelayDataToProcess.Add(pData);
          m_DelayData.SetAt(i, NULL);
        }
      }
      m_DelayData.RemoveAll();
      for (int i = 0, sz = DelayDataToProcess.GetSize(); i < sz; i++) {
        CJS_DelayData* pData = DelayDataToProcess.GetAt(i);
        Field::DoDelay(m_pDocument, pData);
        DelayDataToProcess.SetAt(i, NULL);
        delete pData;
      }
    }
  }
  return TRUE;
}

FX_BOOL Document::keywords(IJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("Keywords");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString csKeywords;
    vp >> csKeywords;
    pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::modDate(IJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("ModDate");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString csmodDate;
    vp >> csmodDate;
    pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::producer(IJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("Producer");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString csproducer;
    vp >> csproducer;
    pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::subject(IJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("Subject");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString cssubject;
    vp >> cssubject;
    pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::title(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
  if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL)
    return FALSE;

  CPDF_Dictionary* pDictionary =
      m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
  if (!pDictionary)
    return FALSE;

  if (vp.IsGetting()) {
    vp << pDictionary->GetUnicodeText("Title");
  } else {
    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
      return FALSE;

    CFX_WideString cstitle;
    vp >> cstitle;
    pDictionary->SetAtString("Title", PDF_EncodeText(cstitle));
    m_pDocument->SetChangeMark();
  }
  return TRUE;
}

FX_BOOL Document::numPages(IJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  if (vp.IsSetting()) {
    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
    return FALSE;
  }
  vp << m_pDocument->GetPageCount();
  return TRUE;
}

FX_BOOL Document::external(IJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  // In Chrome case,should always return true.
  if (vp.IsGetting()) {
    vp << true;
  }
  return TRUE;
}

FX_BOOL Document::filesize(IJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  if (vp.IsSetting()) {
    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
    return FALSE;
  }
  vp << 0;
  return TRUE;
}

FX_BOOL Document::mouseX(IJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::mouseY(IJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::baseURL(IJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  if (vp.IsGetting()) {
    vp << m_cwBaseURL;
  } else {
    vp >> m_cwBaseURL;
  }
  return TRUE;
}

FX_BOOL Document::calculate(IJS_Context* cc,
                            CJS_PropValue& vp,
                            CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  CPDFSDK_InterForm* pInterForm =
      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  if (vp.IsGetting()) {
    if (pInterForm->IsCalculateEnabled())
      vp << true;
    else
      vp << false;
  } else {
    bool bCalculate;
    vp >> bCalculate;

    pInterForm->EnableCalculate(bCalculate);
  }

  return TRUE;
}

FX_BOOL Document::documentFileName(IJS_Context* cc,
                                   CJS_PropValue& vp,
                                   CFX_WideString& sError) {
  if (vp.IsSetting()) {
    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
    return FALSE;
  }
  CFX_WideString wsFilePath = m_pDocument->GetPath();
  int32_t i = wsFilePath.GetLength() - 1;
  for (; i >= 0; i--) {
    if (wsFilePath.GetAt(i) == L'\\' || wsFilePath.GetAt(i) == L'/')
      break;
  }
  if (i >= 0 && i < wsFilePath.GetLength() - 1) {
    vp << (wsFilePath.GetBuffer(wsFilePath.GetLength()) + i + 1);
  } else {
    vp << L"";
  }
  return TRUE;
}

CFX_WideString Document::ReversalStr(CFX_WideString cbFrom) {
  size_t iLength = cbFrom.GetLength();
  pdfium::base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
  iSize *= (iLength + 1);
  wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
  wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);

  for (size_t i = 0; i < iLength; i++) {
    pResult[i] = *(pFrom + iLength - i - 1);
  }
  pResult[iLength] = L'\0';

  cbFrom.ReleaseBuffer();
  CFX_WideString cbRet = CFX_WideString(pResult);
  free(pResult);
  pResult = NULL;
  return cbRet;
}

CFX_WideString Document::CutString(CFX_WideString cbFrom) {
  size_t iLength = cbFrom.GetLength();
  pdfium::base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
  iSize *= (iLength + 1);
  wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
  wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);

  for (size_t i = 0; i < iLength; i++) {
    if (pFrom[i] == L'\\' || pFrom[i] == L'/') {
      pResult[i] = L'\0';
      break;
    }
    pResult[i] = pFrom[i];
  }
  pResult[iLength] = L'\0';

  cbFrom.ReleaseBuffer();
  CFX_WideString cbRet = CFX_WideString(pResult);
  free(pResult);
  pResult = NULL;
  return cbRet;
}

FX_BOOL Document::path(IJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
  if (vp.IsSetting()) {
    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
    return FALSE;
  }
  vp << app::SysPathToPDFPath(m_pDocument->GetPath());
  return TRUE;
}

FX_BOOL Document::pageWindowRect(IJS_Context* cc,
                                 CJS_PropValue& vp,
                                 CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::layout(IJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::addLink(IJS_Context* cc,
                          const CJS_Parameters& params,
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::closeDoc(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);
  return TRUE;
}

FX_BOOL Document::getPageBox(IJS_Context* cc,
                             const CJS_Parameters& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::getAnnot(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::getAnnots(IJS_Context* cc,
                            const CJS_Parameters& params,
                            CJS_Value& vRet,
                            CFX_WideString& sError) {
  vRet.SetNull();
  return TRUE;
}

FX_BOOL Document::getAnnot3D(IJS_Context* cc,
                             const CJS_Parameters& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
  vRet.SetNull();
  return TRUE;
}

FX_BOOL Document::getAnnots3D(IJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  vRet = CJS_Value::VT_undefined;
  return TRUE;
}

FX_BOOL Document::getOCGs(IJS_Context* cc,
                          const CJS_Parameters& params,
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::getLinks(IJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  return TRUE;
}

bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect) {
  return (rect.left <= LinkRect.left && rect.top <= LinkRect.top &&
          rect.right >= LinkRect.right && rect.bottom >= LinkRect.bottom);
}

void IconTree::InsertIconElement(IconElement* pNewIcon) {
  if (!pNewIcon)
    return;

  if (m_pHead == NULL && m_pEnd == NULL) {
    m_pHead = m_pEnd = pNewIcon;
    m_iLength++;
  } else {
    m_pEnd->NextIcon = pNewIcon;
    m_pEnd = pNewIcon;
    m_iLength++;
  }
}

void IconTree::DeleteIconTree() {
  if (!m_pHead || !m_pEnd)
    return;

  IconElement* pTemp = NULL;
  while (m_pEnd != m_pHead) {
    pTemp = m_pHead;
    m_pHead = m_pHead->NextIcon;
    delete pTemp;
  }

  delete m_pEnd;
  m_pHead = NULL;
  m_pEnd = NULL;
}

int IconTree::GetLength() {
  return m_iLength;
}

IconElement* IconTree::operator[](int iIndex) {
  if (iIndex >= 0 && iIndex <= m_iLength) {
    IconElement* pTemp = m_pHead;
    for (int i = 0; i < iIndex; i++) {
      pTemp = pTemp->NextIcon;
    }
    return pTemp;
  }
  return NULL;
}

FX_BOOL Document::addIcon(IJS_Context* cc,
                          const CJS_Parameters& params,
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  if (params.size() != 2) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
    return FALSE;
  }
  CFX_WideString swIconName = params[0].ToCFXWideString();

  if (params[1].GetType() != CJS_Value::VT_object) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
    return FALSE;
  }

  v8::Local<v8::Object> pJSIcon = params[1].ToV8Object();
  if (FXJS_GetObjDefnID(pJSIcon) != CJS_Icon::g_nObjDefnID) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
    return FALSE;
  }

  CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject();
  if (!pEmbedObj) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
    return FALSE;
  }

  Icon* pIcon = (Icon*)pEmbedObj;
  if (!m_pIconTree)
    m_pIconTree = new IconTree();

  IconElement* pNewIcon = new IconElement();
  pNewIcon->IconName = swIconName;
  pNewIcon->NextIcon = NULL;
  pNewIcon->IconStream = pIcon;
  m_pIconTree->InsertIconElement(pNewIcon);
  return TRUE;
}

FX_BOOL Document::icons(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
  if (vp.IsSetting()) {
    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
    return FALSE;
  }

  if (!m_pIconTree) {
    vp.SetNull();
    return TRUE;
  }

  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
  CJS_Array Icons(pRuntime);
  IconElement* pIconElement = NULL;
  int iIconTreeLength = m_pIconTree->GetLength();
  for (int i = 0; i < iIconTreeLength; i++) {
    pIconElement = (*m_pIconTree)[i];

    v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
        pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID);
    if (pObj.IsEmpty())
      return FALSE;

    CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(m_isolate, pObj);
    if (!pJS_Icon)
      return FALSE;

    Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
    if (!pIcon)
      return FALSE;

    pIcon->SetStream(pIconElement->IconStream->GetStream());
    pIcon->SetIconName(pIconElement->IconName);
    Icons.SetElement(i, CJS_Value(pRuntime, pJS_Icon));
  }

  vp << Icons;
  return TRUE;
}

FX_BOOL Document::getIcon(IJS_Context* cc,
                          const CJS_Parameters& params,
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  if (params.size() != 1) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
    return FALSE;
  }

  if (!m_pIconTree)
    return FALSE;
  CFX_WideString swIconName = params[0].ToCFXWideString();
  int iIconCounts = m_pIconTree->GetLength();

  CJS_Runtime* pRuntime = pContext->GetJSRuntime();

  for (int i = 0; i < iIconCounts; i++) {
    if ((*m_pIconTree)[i]->IconName == swIconName) {
      Icon* pRetIcon = (*m_pIconTree)[i]->IconStream;

      v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
          pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID);
      if (pObj.IsEmpty())
        return FALSE;

      CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(m_isolate, pObj);
      if (!pJS_Icon)
        return FALSE;

      Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
      if (!pIcon)
        return FALSE;

      pIcon->SetIconName(swIconName);
      pIcon->SetStream(pRetIcon->GetStream());
      vRet = pJS_Icon;
      return TRUE;
    }
  }

  return FALSE;
}

FX_BOOL Document::removeIcon(IJS_Context* cc,
                             const CJS_Parameters& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
  // Unsafe, no supported.
  return TRUE;
}

FX_BOOL Document::createDataObject(IJS_Context* cc,
                                   const CJS_Parameters& params,
                                   CJS_Value& vRet,
                                   CFX_WideString& sError) {
  // Unsafe, not implemented.
  return TRUE;
}

FX_BOOL Document::media(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::calculateNow(IJS_Context* cc,
                               const CJS_Parameters& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
        m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
        m_pDocument->GetPermissions(FPDFPERM_FILL_FORM)))
    return FALSE;

  CPDFSDK_InterForm* pInterForm =
      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);
  pInterForm->OnCalculate();
  return TRUE;
}

FX_BOOL Document::Collab(IJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::getPageNthWord(IJS_Context* cc,
                                 const CJS_Parameters& params,
                                 CJS_Value& vRet,
                                 CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
    return FALSE;

  int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;
  int nWordNo = params.GetSize() > 1 ? params[1].ToInt() : 0;
  bool bStrip = params.GetSize() > 2 ? params[2].ToBool() : true;

  CPDF_Document* pDocument = m_pDocument->GetDocument()->GetPDFDoc();
  if (!pDocument)
    return FALSE;

  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
  if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
    return FALSE;
  }

  CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
  if (!pPageDict)
    return FALSE;

  CPDF_Page page;
  page.Load(pDocument, pPageDict);
  page.StartParse();
  page.ParseContent();

  FX_POSITION pos = page.GetFirstObjectPosition();

  int nWords = 0;

  CFX_WideString swRet;

  while (pos) {
    if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) {
      if (pPageObj->m_Type == PDFPAGE_TEXT) {
        int nObjWords = CountWords((CPDF_TextObject*)pPageObj);

        if (nWords + nObjWords >= nWordNo) {
          swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
          break;
        }

        nWords += nObjWords;
      }
    }
  }

  if (bStrip) {
    swRet.TrimLeft();
    swRet.TrimRight();
  }

  vRet = swRet.c_str();
  return TRUE;
}

FX_BOOL Document::getPageNthWordQuads(IJS_Context* cc,
                                      const CJS_Parameters& params,
                                      CJS_Value& vRet,
                                      CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
    return FALSE;

  return FALSE;
}

FX_BOOL Document::getPageNumWords(IJS_Context* cc,
                                  const CJS_Parameters& params,
                                  CJS_Value& vRet,
                                  CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
    return FALSE;

  int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;

  CPDF_Document* pDocument = m_pDocument->GetDocument()->GetPDFDoc();
  ASSERT(pDocument != NULL);

  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
  if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
    sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
    return FALSE;
  }

  CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
  if (!pPageDict)
    return FALSE;

  CPDF_Page page;
  page.Load(pDocument, pPageDict);
  page.StartParse();
  page.ParseContent();

  FX_POSITION pos = page.GetFirstObjectPosition();

  int nWords = 0;

  while (pos) {
    if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) {
      if (pPageObj->m_Type == PDFPAGE_TEXT) {
        CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
        nWords += CountWords(pTextObj);
      }
    }
  }

  vRet = nWords;

  return TRUE;
}

FX_BOOL Document::getPrintParams(IJS_Context* cc,
                                 const CJS_Parameters& params,
                                 CJS_Value& vRet,
                                 CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
      pRuntime->GetIsolate(), pRuntime, CJS_PrintParamsObj::g_nObjDefnID);

  // Not implemented yet.

  vRet = pRetObj;
  return TRUE;
}

#define ISLATINWORD(u) (u != 0x20 && u <= 0x28FF)

int Document::CountWords(CPDF_TextObject* pTextObj) {
  if (!pTextObj)
    return 0;

  int nWords = 0;

  CPDF_Font* pFont = pTextObj->GetFont();
  if (!pFont)
    return 0;

  FX_BOOL bIsLatin = FALSE;

  for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) {
    FX_DWORD charcode = -1;
    FX_FLOAT kerning;

    pTextObj->GetCharInfo(i, charcode, kerning);
    CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);

    FX_WORD unicode = 0;
    if (swUnicode.GetLength() > 0)
      unicode = swUnicode[0];

    if (ISLATINWORD(unicode) && bIsLatin)
      continue;

    bIsLatin = ISLATINWORD(unicode);
    if (unicode != 0x20)
      nWords++;
  }

  return nWords;
}

CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj,
                                       int nWordIndex) {
  ASSERT(pTextObj != NULL);

  CFX_WideString swRet;

  CPDF_Font* pFont = pTextObj->GetFont();
  if (!pFont)
    return L"";

  int nWords = 0;
  FX_BOOL bIsLatin = FALSE;

  for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) {
    FX_DWORD charcode = -1;
    FX_FLOAT kerning;

    pTextObj->GetCharInfo(i, charcode, kerning);
    CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);

    FX_WORD unicode = 0;
    if (swUnicode.GetLength() > 0)
      unicode = swUnicode[0];

    if (ISLATINWORD(unicode) && bIsLatin) {
    } else {
      bIsLatin = ISLATINWORD(unicode);
      if (unicode != 0x20)
        nWords++;
    }

    if (nWords - 1 == nWordIndex)
      swRet += unicode;
  }

  return swRet;
}

FX_BOOL Document::zoom(IJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
  return TRUE;
}

/**
(none,  NoVary)
(fitP,  FitPage)
(fitW,  FitWidth)
(fitH,  FitHeight)
(fitV,  FitVisibleWidth)
(pref,  Preferred)
(refW,  ReflowWidth)
*/

FX_BOOL Document::zoomType(IJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::deletePages(IJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  // Unsafe, no supported.
  return TRUE;
}

FX_BOOL Document::extractPages(IJS_Context* cc,
                               const CJS_Parameters& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::insertPages(IJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::replacePages(IJS_Context* cc,
                               const CJS_Parameters& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

FX_BOOL Document::getURL(IJS_Context* cc,
                         const CJS_Parameters& params,
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

void Document::AddDelayData(CJS_DelayData* pData) {
  m_DelayData.Add(pData);
}

void Document::DoFieldDelay(const CFX_WideString& sFieldName,
                            int nControlIndex) {
  CFX_DWordArray DelArray;
  CFX_ArrayTemplate<CJS_DelayData*> DelayDataForFieldAndControlIndex;

  for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) {
    if (CJS_DelayData* pData = m_DelayData.GetAt(i)) {
      if (pData->sFieldName == sFieldName &&
          pData->nControlIndex == nControlIndex) {
        DelayDataForFieldAndControlIndex.Add(pData);
        m_DelayData.SetAt(i, NULL);
        DelArray.Add(i);
      }
    }
  }

  for (int j = DelArray.GetSize() - 1; j >= 0; j--) {
    m_DelayData.RemoveAt(DelArray[j]);
  }

  for (int i = 0, sz = DelayDataForFieldAndControlIndex.GetSize(); i < sz;
       i++) {
    CJS_DelayData* pData = DelayDataForFieldAndControlIndex.GetAt(i);
    Field::DoDelay(m_pDocument, pData);
    DelayDataForFieldAndControlIndex.SetAt(i, NULL);
    delete pData;
  }
}

void Document::AddDelayAnnotData(CJS_AnnotObj* pData) {
  m_DelayAnnotData.Add(pData);
}

void Document::DoAnnotDelay() {
  CFX_DWordArray DelArray;

  for (int j = DelArray.GetSize() - 1; j >= 0; j--) {
    m_DelayData.RemoveAt(DelArray[j]);
  }
}

CJS_Document* Document::GetCJSDoc() const {
  return static_cast<CJS_Document*>(m_pJSObject);
}
