// 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 "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/Document.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_Runtime.h"
#include "../../include/javascript/app.h"
#include "../../include/javascript/Field.h"
#include "../../include/javascript/Icon.h"
#include "../../include/javascript/resource.h"

#include "../../../third_party/base/numerics/safe_math.h"

static v8::Isolate* GetIsolate(IFXJS_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(IFXJS_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(IFXJS_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(IFXJS_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(IFXJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

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

  return TRUE;
}

FX_BOOL Document::pageNum(IFXJS_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(IFXJS_Context* cc,
                           const CJS_Parameters& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
  // Not supported.
  return TRUE;
}

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

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

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

FX_BOOL Document::exportAsXFDF(IFXJS_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(IFXJS_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,
                           FXJS_GetObjDefnID(pRuntime->GetIsolate(), L"Field"));

  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(IFXJS_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(IFXJS_Context* cc,
                              const CJS_Parameters& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

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

FX_BOOL Document::importTextData(IFXJS_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(IFXJS_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(IFXJS_Context* cc,
                        const CJS_Parameters& params,
                        CJS_Value& vRet,
                        CFX_WideString& sError) {
  CJS_Context* pContext = (CJS_Context*)cc;
  ASSERT(pContext != NULL);
  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  ASSERT(pRuntime != NULL);

  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) ==
            FXJS_GetObjDefnID(pRuntime->GetIsolate(), L"PrintParamsObj")) {
          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(IFXJS_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);

      CPDF_Page* pPage = pWidget->GetPDFPage();
      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(IFXJS_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);

  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
  ASSERT(pPDFForm != NULL);

  v8::Isolate* isolate = GetIsolate(cc);
  CJS_Array aName(isolate);

  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(isolate);
      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(IFXJS_Context* cc,
                         const CJS_Parameters& params,
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
  // Unsafe, not supported.
  return TRUE;
}

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

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

  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(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
    pValue = FXJS_GetObjectElement(isolate, pObj, L"bFDF");
    bFDF = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
    pValue = FXJS_GetObjectElement(isolate, pObj, L"bEmpty");
    bEmpty = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
    pValue = FXJS_GetObjectElement(isolate, pObj, L"aFields");
    aFields.Attach(
        CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToV8Array());
  }

  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  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(isolate);
    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(IFXJS_Context* cc,
                               CJS_PropValue& vp,
                               CFX_WideString& sError) {
  return TRUE;
}

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

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

  v8::Isolate* isolate = GetIsolate(cc);

  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(isolate, pValue, GET_VALUE_TYPE(pValue)).ToInt();

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

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

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

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

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

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

  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(IFXJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
  ASSERT(m_pDocument != NULL);

  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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;
}

FX_BOOL Document::creationDate(IFXJS_Context* cc,
                               CJS_PropValue& vp,
                               CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_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(IFXJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_Context* cc,
                          CJS_PropValue& vp,
                          CFX_WideString& sError) {
  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
  if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL)
    return FALSE;

  CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->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(IFXJS_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(IFXJS_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(IFXJS_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(IFXJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  return TRUE;
}

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

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

FX_BOOL Document::calculate(IFXJS_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(IFXJS_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(IFXJS_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(IFXJS_Context* cc,
                                 CJS_PropValue& vp,
                                 CFX_WideString& sError) {
  return TRUE;
}

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

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

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

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

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

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

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

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

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

FX_BOOL Document::getLinks(IFXJS_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(IFXJS_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();

  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  if (FXJS_GetObjDefnID(pJSIcon) !=
      FXJS_GetObjDefnID(pRuntime->GetIsolate(), L"Icon")) {
    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(IFXJS_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_Array Icons(m_isolate);
  IconElement* pIconElement = NULL;
  int iIconTreeLength = m_pIconTree->GetLength();

  CJS_Context* pContext = (CJS_Context*)cc;
  CJS_Runtime* pRuntime = pContext->GetJSRuntime();

  for (int i = 0; i < iIconTreeLength; i++) {
    pIconElement = (*m_pIconTree)[i];

    v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
        pRuntime->GetIsolate(), pContext,
        FXJS_GetObjDefnID(pRuntime->GetIsolate(), L"Icon"));
    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(m_isolate, pJS_Icon));
  }

  vp << Icons;
  return TRUE;
}

FX_BOOL Document::getIcon(IFXJS_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,
          FXJS_GetObjDefnID(pRuntime->GetIsolate(), L"Icon"));
      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(IFXJS_Context* cc,
                             const CJS_Parameters& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
  // Unsafe, no supported.
  return TRUE;
}

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

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

FX_BOOL Document::calculateNow(IFXJS_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(IFXJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
  return TRUE;
}

FX_BOOL Document::getPageNthWord(IFXJS_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();
  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(IFXJS_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(IFXJS_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();
  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(IFXJS_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,
      FXJS_GetObjDefnID(pRuntime->GetIsolate(), L"PrintParamsObj"));

  // 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(IFXJS_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(IFXJS_Context* cc,
                           CJS_PropValue& vp,
                           CFX_WideString& sError) {
  return TRUE;
}

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

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

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

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

FX_BOOL Document::getURL(IFXJS_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);
}
