// 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 "../../../third_party/base/numerics/safe_math.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"

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)

FX_BOOL CJS_Document::InitInstance(IJS_Context* cc) {
  CJS_Context* pContext = (CJS_Context*)cc;
  ASSERT(pContext != NULL);

  Document* pDoc = (Document*)GetEmbedObject();
  ASSERT(pDoc != NULL);

  pDoc->AttachDoc(pContext->GetReaderDocument());
  pDoc->SetIsolate(pContext->GetJSRuntime()->GetIsolate());
  return TRUE;
};

/* --------------------------------- 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(), pContext, 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);

  CFX_PtrArray widgets;
  pInterForm->GetWidgets(sFieldName, widgets);

  int nSize = widgets.GetSize();

  if (nSize > 0) {
    for (int i = 0; i < nSize; i++) {
      CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)widgets[i];
      ASSERT(pWidget != NULL);

      CPDF_Rect rcAnnot = pWidget->GetRect();
      rcAnnot.left -= 1;
      rcAnnot.bottom -= 1;
      rcAnnot.right += 1;
      rcAnnot.top += 1;

      CFX_RectArray aRefresh;
      aRefresh.Add(rcAnnot);

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

      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);

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

    CFX_PtrArray 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.Add((void*)pPDFForm->GetField(j, swVal));
      }
    }

    if (aFields.GetSize() > 0) {
      pPDFForm->ResetForm(aFields, TRUE, TRUE);
      m_pDocument->SetChangeMark();
    }
  } else {
    pPDFForm->ResetForm(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()) {
      pRuntime->BeginBlock();
      pInterForm->SubmitForm(strURL, FALSE);
      pRuntime->EndBlock();
    }
    return TRUE;
  }

  CFX_PtrArray 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.Add(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(), pContext, -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->GetType() == PDFOBJ_STRING) ||
          (pValueObj->GetType() == PDFOBJ_NAME))
        FXJS_PutObjectString(isolate, pObj, wsKey.c_str(),
                             pValueObj->GetUnicodeText().c_str());
      if (pValueObj->GetType() == PDFOBJ_NUMBER)
        FXJS_PutObjectNumber(isolate, pObj, wsKey.c_str(),
                             (float)pValueObj->GetNumber());
      if (pValueObj->GetType() == PDFOBJ_BOOLEAN)
        FXJS_PutObjectBoolean(isolate, pObj, wsKey.c_str(),
                              (bool)pValueObj->GetInteger());
    }

    vp << pObj;
    return TRUE;
  } else {
    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 {
      for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) {
        if (CJS_DelayData* pData = m_DelayData.GetAt(i)) {
          Field::DoDelay(m_pDocument, pData);
          delete m_DelayData.GetAt(i);
        }
      }
      m_DelayData.RemoveAll();
    }
  }
  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;
}

void IconTree::DeleteIconElement(CFX_WideString swIconName) {
  IconElement* pTemp = m_pHead;
  int iLoopCount = m_iLength;
  for (int i = 0; i < iLoopCount - 1; i++) {
    if (pTemp == m_pEnd)
      break;

    if (m_pHead->IconName == swIconName) {
      m_pHead = m_pHead->NextIcon;
      delete pTemp;
      m_iLength--;
      pTemp = m_pHead;
    }
    if (pTemp->NextIcon->IconName == swIconName) {
      if (pTemp->NextIcon == m_pEnd) {
        m_pEnd = pTemp;
        delete pTemp->NextIcon;
        m_iLength--;
        pTemp->NextIcon = NULL;
      } else {
        IconElement* pElement = pTemp->NextIcon;
        pTemp->NextIcon = pTemp->NextIcon->NextIcon;
        delete pElement;
        m_iLength--;
        pElement = NULL;
      }

      continue;
    }

    pTemp = pTemp->NextIcon;
  }
}

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_Context* pContext = static_cast<CJS_Context*>(cc);
  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(), pContext, 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(), pContext, 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) {
  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();
  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();
  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(), pContext, 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) {
  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
        m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE)))
    return FALSE;

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

  int iSize = params.size();
  int nStart = 0;
  int nEnd = 0;
  if (iSize < 1) {
  } else if (iSize == 1) {
    if (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"nStart");
      nStart = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToInt();
      pValue = FXJS_GetObjectElement(isolate, pObj, L"nEnd");
      nEnd = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToInt();
    } else {
      nStart = params[0].ToInt();
    }
  } else {
    nStart = params[0].ToInt();
    nEnd = params[1].ToInt();
  }

  int nTotal = m_pDocument->GetPageCount();
  if (nStart < 0)
    nStart = 0;
  if (nStart >= nTotal)
    nStart = nTotal - 1;

  if (nEnd < 0)
    nEnd = 0;
  if (nEnd >= nTotal)
    nEnd = nTotal - 1;

  if (nEnd < nStart)
    nEnd = nStart;

  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;

  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) {
        Field::DoDelay(m_pDocument, pData);
        delete pData;
        m_DelayData.SetAt(i, NULL);
        DelArray.Add(i);
      }
    }
  }

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

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);
}
