// 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/JavaScript.h"
#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)

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

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

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

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

    return true;
}

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

bool Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj)
{
    // Not supported.
    return true;
}

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

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

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

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

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

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();
    JSFXObject pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field"));

    v8::Isolate* isolate = GetIsolate(cc);
    CJS_Field* pJSField = (CJS_Field*)JS_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
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;
}

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

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

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(bool bUI,String cto,string ccc,string cbcc,string cSubject,string cms);

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

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

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

    bool bUI = true;
    int nStart = 0;
    int nEnd = 0;
    bool bSilent = false;
    bool bShrinkToFit = false;
    bool bPrintAsImage = false;
    bool bReverse = false;
    bool bAnnotations = false;

    int nlength = params.size();
    if(nlength ==9)
    {
        if (params[8].GetType() == VT_fxobject)
        {
            JSFXObject pObj = params[8].ToV8Object();
            {
                if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, 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.

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.

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


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


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;
    bool bFDF = true;
    bool bEmpty = false;
    v8::Isolate* isolate = GetIsolate(cc);
    CJS_Array aFields(isolate);

    CJS_Value v = params[0];
    if (v.GetType() == 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() == VT_object)
    {
        JSObject pObj = params[0].ToV8Object();
        v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cURL");
        if (!pValue.IsEmpty())
            strURL = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
        pValue = JS_GetObjectElement(isolate, pObj, L"bFDF");
        bFDF = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
        pValue = JS_GetObjectElement(isolate, pObj, L"bEmpty");
        bEmpty = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
        pValue = JS_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();
    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;
}

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

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

bool Document::bookmarkRoot(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
    return true;
}

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

    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() == VT_object)
    {
        JSObject pObj = params[0].ToV8Object();

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

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

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

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

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

        pValue = JS_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;
}

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

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();
        JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1);
        JS_PutObjectString(isolate, pObj, L"Author", cwAuthor.c_str());
        JS_PutObjectString(isolate, pObj, L"Title", cwTitle.c_str());
        JS_PutObjectString(isolate, pObj, L"Subject", cwSubject.c_str());
        JS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords.c_str());
        JS_PutObjectString(isolate, pObj, L"Creator", cwCreator.c_str());
        JS_PutObjectString(isolate, pObj, L"Producer", cwProducer.c_str());
        JS_PutObjectString(isolate, pObj, L"CreationDate", cwCreationDate.c_str());
        JS_PutObjectString(isolate, pObj, L"ModDate", cwModDate.c_str());
        JS_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) )
                JS_PutObjectString(isolate, pObj, wsKey.c_str(), pValueObj->GetUnicodeText().c_str());
            if(pValueObj->GetType()==PDFOBJ_NUMBER)
                JS_PutObjectNumber(isolate,pObj, wsKey.c_str(), (float)pValueObj->GetNumber());
            if(pValueObj->GetType()==PDFOBJ_BOOLEAN)
                JS_PutObjectBoolean(isolate,pObj, wsKey.c_str(), (bool)pValueObj->GetInteger());
        }
        vp << pObj;
    }
    return true;
}

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

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

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;

        bool b;
        vp >> b;
        m_bDelay = b;
        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;
}

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

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

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

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

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

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

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

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

bool Document::mouseX(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
    return true;
}

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

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

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

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 (int 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;
}

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

bool Document::pageWindowRect(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
    return true;
}

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

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

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

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

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

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

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

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

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

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

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();
    JSFXObject pJSIcon = params[1].ToV8Object();

    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
    if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, 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;
}

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

        JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
        if (pObj.IsEmpty()) return false;

        CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(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;
}

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;

            JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
            if (pObj.IsEmpty()) return false;

            CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(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;
}

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

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

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

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

bool Document::Collab(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
    return true;
}

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

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

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

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();
    JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, 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;

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

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)
*/

bool Document::zoomType(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
    return true;
}

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

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

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

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

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