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

#include "../../../third_party/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,0)
	JS_STATIC_METHOD_ENTRY(addField, 4)
	JS_STATIC_METHOD_ENTRY(addLink, 0)
	JS_STATIC_METHOD_ENTRY(addIcon, 0)
	JS_STATIC_METHOD_ENTRY(calculateNow, 0)
	JS_STATIC_METHOD_ENTRY(closeDoc, 0)
	JS_STATIC_METHOD_ENTRY(createDataObject, 0)
	JS_STATIC_METHOD_ENTRY(deletePages, 2)
	JS_STATIC_METHOD_ENTRY(exportAsText, 3)
	JS_STATIC_METHOD_ENTRY(exportAsFDF, 6)
	JS_STATIC_METHOD_ENTRY(exportAsXFDF, 5)
	JS_STATIC_METHOD_ENTRY(extractPages, 3)
	JS_STATIC_METHOD_ENTRY(getAnnot, 0)
	JS_STATIC_METHOD_ENTRY(getAnnots, 2)
	JS_STATIC_METHOD_ENTRY(getAnnot3D, 2)
	JS_STATIC_METHOD_ENTRY(getAnnots3D, 1)
	JS_STATIC_METHOD_ENTRY(getField, 1)
	JS_STATIC_METHOD_ENTRY(getIcon, 0)
	JS_STATIC_METHOD_ENTRY(getLinks, 0)
	JS_STATIC_METHOD_ENTRY(getNthFieldName, 1)
	JS_STATIC_METHOD_ENTRY(getOCGs, 0)
	JS_STATIC_METHOD_ENTRY(getPageBox, 0)
	JS_STATIC_METHOD_ENTRY(getPageNthWord, 3)
	JS_STATIC_METHOD_ENTRY(getPageNthWordQuads, 2)
	JS_STATIC_METHOD_ENTRY(getPageNumWords, 1)
	JS_STATIC_METHOD_ENTRY(getPrintParams, 0)
	JS_STATIC_METHOD_ENTRY(getURL, 2)
	JS_STATIC_METHOD_ENTRY(importAnFDF, 1)
	JS_STATIC_METHOD_ENTRY(importAnXFDF, 1)
	JS_STATIC_METHOD_ENTRY(importTextData, 2)
	JS_STATIC_METHOD_ENTRY(insertPages, 4)
	JS_STATIC_METHOD_ENTRY(mailForm, 6)
	JS_STATIC_METHOD_ENTRY(print, 9)
	JS_STATIC_METHOD_ENTRY(removeField, 1)
	JS_STATIC_METHOD_ENTRY(replacePages, 4)
	JS_STATIC_METHOD_ENTRY(resetForm, 1)
	JS_STATIC_METHOD_ENTRY(removeIcon, 0)
	JS_STATIC_METHOD_ENTRY(saveAs, 5)
	JS_STATIC_METHOD_ENTRY(submitForm, 23)
	JS_STATIC_METHOD_ENTRY(mailDoc, 0)		
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_cwBaseURL(L""),
	m_pIconTree(NULL),
	m_pDocument(NULL),
	m_bDelay(FALSE),
	m_isolate(NULL)
{
}

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(OBJ_PROP_PARAMS)
{
	if (!vp.IsGetting()) return FALSE;

	ASSERT(m_pDocument != NULL);

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

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

	vp << (int)pPDFForm->CountFields();

	return TRUE;
}

FX_BOOL Document::dirty(OBJ_PROP_PARAMS)
{
	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(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	return TRUE;
}

FX_BOOL Document::pageNum(OBJ_PROP_PARAMS)
{
	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(!pEnv)
			return FALSE;

		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::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj)
{
	return TRUE;
}

FX_BOOL Document::addAnnot(OBJ_METHOD_PARAMS)
{
 	return TRUE;
}

FX_BOOL Document::addField(OBJ_METHOD_PARAMS)
{
	//Doesn't support.
	return TRUE;
}

//exports form fields as a tab-delimited text file to a local hard disk.
//comment: need reader support
//note : watch the third parameter:cPath, for what case it can be safely saved?
//int CPDFSDK_InterForm::ExportAsText(FX_BOOL bNoPassword,StringArray aFields,String cPath);
//return value, int the index of the parameters illegal, the index is based on 1.

FX_BOOL Document::exportAsText(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;
	return TRUE;
}

//exports form fields as a fdf file to the local hard drive
//comment: need reader supports
//note:the last parameter hasn't been confirmed.because the previous one blocks the way.
//int CPDFSDK_Document::ExportAsFDF(FX_BOOL bAllFields,BOOL bNoPassword,StringArray aFields,FX_BOOL bFlags,String cPath,FX_BOOL bAnnotations);

FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS)
{
	v8::Isolate* isolate = GetIsolate(cc);
	if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

	FX_BOOL bAllFields = params.size() > 0 ? (FX_BOOL)params[0] : FALSE;
	FX_BOOL bNoPassWord = params.size() > 1 ? (FX_BOOL)params[1] : TRUE;
	FX_BOOL bWhole = params.size() > 2 ? (params[2].GetType() == VT_null) : TRUE;
	CJS_Array arrayFileds(isolate);
	if (!bWhole)
		arrayFileds.Attach(params[2]);
	//FX_BOOL bFlags = params.size() > 3 ? (FX_BOOL)params[3] : FALSE;
    CFX_WideString swFilePath = params.size() > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : (FX_LPCWSTR)L"";

	if (swFilePath.IsEmpty())
	{
		CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
		swFilePath = pEnv->JS_fieldBrowse();
		if(swFilePath.IsEmpty())
			return TRUE;
	}
	else
	{
		swFilePath = app::PDFPathToSysPath(swFilePath);
	}
    
	m_pDocument->SetFocusAnnot(NULL);
   
    CPDFSDK_InterForm* pInterForm= (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
	ASSERT(pInterForm != NULL);

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

	CFX_PtrArray aFields;

	if (bWhole)
	{
		for (int j=0,jsz=pPDFForm->CountFields(); j<jsz; j++)
		{
			aFields.Add(pPDFForm->GetField(j));
		}
	}
	else
	{
		for (int i=0,isz=arrayFileds.GetLength(); i<isz; i++)
		{
			CJS_Value valName(isolate);
			arrayFileds.GetElement(i,valName);
			CFX_WideString swName = valName.operator CFX_WideString();

			for (int j=0, jsz=pPDFForm->CountFields(swName); j<jsz; j++)
			{
				aFields.Add(pPDFForm->GetField(j, swName));
			}
		}
	}

	CFX_PtrArray fields;

	for (int i=0,sz=aFields.GetSize(); i<sz; i++)
	{
	    CPDF_FormField* pField = (CPDF_FormField*)aFields[i];
		
		if (!bAllFields)
			if (pField->GetValue() == L"")
				continue;

		if (bNoPassWord)
			if (pField->GetFieldFlags() & 0x2000)
				continue;

        fields.Add((void*)pField);
	}    

    return pInterForm->ExportFieldsToFDFFile(swFilePath, fields, TRUE);
}

//exports form fields an XFDF file to the local hard drive
//comment: need reder supports
//note:the last parameter can't be test
//int CPDFSDK_Document::ExportAsXFDF(FX_BOOL bAllFields,FX_BOOL  bNoPassWord,StringArray aFields,String cPath,FX_BOOL bAnnoatations);

FX_BOOL Document::exportAsXFDF(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;
	ASSERT(m_pDocument != NULL);

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

	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(OBJ_METHOD_PARAMS)
{
	v8::Isolate* isolate = GetIsolate(cc);
	ASSERT(m_pDocument != NULL);

	if (params.size() < 1) return FALSE;

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

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

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

	if (pPDFForm->CountFields(wideName) <= 0) 
	{
		vRet.SetNull();
		return TRUE;
	}

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

	JSFXObject  pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field"));

	CJS_Field * pJSField = (CJS_Field*)JS_GetPrivate(isolate,pFieldObj);
	ASSERT(pJSField != NULL);

	Field * pField = (Field *)pJSField->GetEmbedObject(); 
	ASSERT(pField != NULL);

	pField->AttachField(this, wideName);
	vRet = pJSField;

	return TRUE;
}

//Gets the name of the nth field in the document 
//comment:
//note: the parameter nIndex, if it is not available

FX_BOOL Document::getNthFieldName(OBJ_METHOD_PARAMS)
{
	ASSERT(m_pDocument != NULL);

	int nIndex = params.size() > 0 ? (int)params[0] : -1;
	if (nIndex == -1) return FALSE;

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

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

	CPDF_FormField* pField = pPDFForm->GetField(nIndex);
	if (!pField)
		return FALSE;

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

//imports the specified fdf file.
//comments: need reader suppport
//note:once the cpath is illigl  then a file dialog box pops up in order to ask user to chooose the file
//int CPDFSDK_Document::importAnFDF(String cPath);

FX_BOOL Document::importAnFDF(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;
	ASSERT(m_pDocument != NULL);

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


	CFX_WideString swPath;
	
	if (params.size() > 0)
		swPath = params[0];
    
	if (swPath.IsEmpty())
	{
		CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
		swPath = pEnv->JS_fieldBrowse();
		if(swPath.IsEmpty())
			return TRUE;
	}
	else
	{
		swPath = app::PDFPathToSysPath(swPath);
	}

	m_pDocument->SetFocusAnnot(NULL);

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

	if (!pInterForm->ImportFormFromFDFFile(swPath, TRUE))
		return FALSE;

 	m_pDocument->SetChangeMark();
// 	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
// 	ASSERT(pEnv != NULL);
// 	IUndo* pUndo = IUndo::GetUndo(pEnv);
// 	ASSERT(pUndo != NULL);
// 	pUndo->Reset(m_pDocument);

	return TRUE;
}

//imports and specified XFDF file containing XML form data
//comment: need reader supports
//note: same as up
//int CPDFSDK_Document::importAnFDF(String cPath)

FX_BOOL Document::importAnXFDF(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;
	ASSERT(m_pDocument != NULL);

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

	return TRUE;
}

//imports and specified text file 
//commnet: need reader supports
//note: same as up,when nRow is not rational,adobe is dumb for it.
//int CPDFSDK_Document::importTextData(String cPath,int nRow);

FX_BOOL Document::importTextData(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;
	ASSERT(m_pDocument != NULL);

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

	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(OBJ_METHOD_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	int iLength = params.size();

	FX_BOOL bUI = iLength > 0 ? (FX_BOOL)params[0] : TRUE;
	CFX_WideString cTo = iLength > 1 ? (FX_LPCWSTR)params[1].operator CFX_WideString() : (FX_LPCWSTR)L"";
	CFX_WideString cCc = iLength > 2 ? (FX_LPCWSTR)params[2].operator CFX_WideString() : (FX_LPCWSTR)L"";
	CFX_WideString cBcc = iLength > 3 ? (FX_LPCWSTR)params[3].operator CFX_WideString() : (FX_LPCWSTR)L"";
	CFX_WideString cSubject = iLength > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : (FX_LPCWSTR)L"";
	CFX_WideString cMsg = iLength > 5 ? (FX_LPCWSTR)params[5].operator CFX_WideString() : (FX_LPCWSTR)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, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
	pRuntime->EndBlock();
 	return TRUE;
}

FX_BOOL Document::print(OBJ_METHOD_PARAMS)
{
	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() == VT_fxobject)
		{
			JSFXObject pObj = (JSFXObject)params[8];
			{
				if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"))
				{
					if (CJS_Object* pJSObj = (CJS_Object*)params[8])
					{
							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];
		if(nlength >= 2)
			 nStart = (int)params[1];
		if(nlength >= 3)
		    nEnd = (int)params[2];
		if(nlength >= 4)
			bSilent = params[3];
		if(nlength >= 5)
		    bShrinkToFit = params[4];
		if(nlength >= 6)
			bPrintAsImage = params[5];
		if(nlength >= 7)
			bReverse = params[6];
		if(nlength >= 8)
			bAnnotations = params[7];
	}

 	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(OBJ_METHOD_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (params.size() < 1)
		return TRUE;

	CFX_WideString sFieldName = params[0].operator CFX_WideString();

	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(OBJ_METHOD_PARAMS)
{
	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]);
			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.operator CFX_WideString();	
			
			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(OBJ_METHOD_PARAMS)
{

	if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

//	m_pDocument->DoSaveAs();

	return TRUE;
}


FX_BOOL Document::submitForm(OBJ_METHOD_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	int nSize = params.size();
	if (nSize < 1) 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() == VT_string)
	{
		strURL = params[0].operator CFX_WideString();
		if (nSize > 1)
			bFDF = params[1];
		if (nSize > 2)
			bEmpty = params[2];
		if (nSize > 3)
			aFields.Attach(params[3]);
	}
	else if (v.GetType() == VT_object)
	{
		JSObject pObj = (JSObject)params[0];
		v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"cURL");
		if (!pValue.IsEmpty())
			strURL = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
		pValue = JS_GetObjectElement(isolate,pObj, L"bFDF");
			bFDF = CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue));
		pValue = JS_GetObjectElement(isolate,pObj, L"bEmpty");
			bEmpty = CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue));
		pValue = JS_GetObjectElement(isolate,pObj,L"aFields");
			aFields.Attach(CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue)));
	}		

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

	FX_BOOL bAll = (aFields.GetLength() == 0);

	if (bAll && bEmpty)
	{
		CJS_Context* pContext = (CJS_Context*)cc;
		ASSERT(pContext != NULL);
		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
		ASSERT(pRuntime != NULL);

		
		if (pPDFInterForm->CheckRequiredFields())
		{
			pRuntime->BeginBlock();
			pInterForm->SubmitForm(strURL, FALSE);
			pRuntime->EndBlock();
		}

		return TRUE;
	}
	else
	{	
		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.operator CFX_WideString();

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

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

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

		
		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(OBJ_PROP_PARAMS)
{	
	return TRUE;
}

FX_BOOL Document::mailDoc(OBJ_METHOD_PARAMS)
{
	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"";
	

	bUI = params.size()>=1?static_cast<FX_BOOL>(params[0]):TRUE;
	cTo = params.size()>=2?(const wchar_t*)params[1].operator CFX_WideString():L"";
	cCc = params.size()>=3?(const wchar_t*)params[2].operator CFX_WideString():L"";
	cBcc = params.size()>=4?(const wchar_t*)params[3].operator CFX_WideString():L"";
	cSubject = params.size()>=5?(const wchar_t*)params[4].operator CFX_WideString():L"";
	cMsg = params.size()>=6?(const wchar_t*)params[5].operator CFX_WideString():L"";
	
	v8::Isolate* isolate = GetIsolate(cc);

	if(params.size()>=1 && params[0].GetType() == VT_object)
	{
		JSObject  pObj = (JSObject )params[0];

		v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
			bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));

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

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

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

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

		pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
			cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
	
	}

	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, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
	pRuntime->EndBlock();

	return TRUE;
}

FX_BOOL Document::author(OBJ_PROP_PARAMS)
{
	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(OBJ_PROP_PARAMS)
{
	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.IsSetting())
	{
		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);
		JS_PutObjectString(isolate,pObj, L"Title", cwTitle);
		JS_PutObjectString(isolate,pObj, L"Subject", cwSubject);
		JS_PutObjectString(isolate,pObj, L"Keywords", cwKeywords);
		JS_PutObjectString(isolate,pObj, L"Creator", cwCreator);
		JS_PutObjectString(isolate,pObj, L"Producer", cwProducer);
		JS_PutObjectString(isolate,pObj, L"CreationDate", cwCreationDate);
		JS_PutObjectString(isolate,pObj, L"ModDate", cwModDate);
		JS_PutObjectString(isolate,pObj, L"Trapped", cwTrapped);

// 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);
			if((pValueObj->GetType()==PDFOBJ_STRING) || (pValueObj->GetType()==PDFOBJ_NAME) )
					JS_PutObjectString(isolate,pObj, wsKey, pValueObj->GetUnicodeText());
			if(pValueObj->GetType()==PDFOBJ_NUMBER)
				JS_PutObjectNumber(isolate,pObj, wsKey, (float)pValueObj->GetNumber());
			if(pValueObj->GetType()==PDFOBJ_BOOLEAN)
				JS_PutObjectBoolean(isolate,pObj, wsKey, (bool)pValueObj->GetInteger());
		}

		vp << pObj;
		return TRUE;
	}
	else
	{
		return TRUE;
	}
}

FX_BOOL Document::creationDate(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (vp.IsGetting())
	{
		vp << pDictionary->GetUnicodeText("CreationDate");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (vp.IsGetting())
	{
		vp << pDictionary->GetUnicodeText("Creator");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	if (vp.IsGetting())
	{
		vp << m_bDelay;
		return TRUE;
	}
	else
	{
		ASSERT(m_pDocument != NULL);

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

		return TRUE;
	}
}

FX_BOOL Document::keywords(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (vp.IsGetting())
	{
		vp << pDictionary->GetUnicodeText("Keywords");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (vp.IsGetting())
	{
		vp << pDictionary->GetUnicodeText("ModDate");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (vp.IsGetting())
	{
		vp << pDictionary->GetUnicodeText("Producer");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

	if (vp.IsGetting())
	{
		vp << pDictionary->GetUnicodeText("Subject");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	ASSERT(m_pDocument != NULL);

	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");
		return TRUE;
	}
	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(OBJ_PROP_PARAMS)
{
	if (vp.IsGetting())
	{
		ASSERT(m_pDocument != NULL);
		vp << m_pDocument->GetPageCount();
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

FX_BOOL Document::external(OBJ_PROP_PARAMS)
{
	//In Chrome case,should always return true.
	vp << TRUE;
	return TRUE;
}

FX_BOOL Document::filesize(OBJ_PROP_PARAMS)
{
	if (!vp.IsGetting())return FALSE;

	ASSERT(m_pDocument != NULL);

// 	CFile file(m_pDocument->GetPath(), CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone);
// 	vp << (double)file.GetLength();
// 	file.Close();

	if ( m_pDocument->GetPath().IsEmpty() == FALSE)
	{
		CFX_ByteString bsStr = CFX_ByteString::FromUnicode( m_pDocument->GetPath() );
		FILE * pFile = NULL;
		pFile = fopen( bsStr.GetBuffer( bsStr.GetLength() ), "rb" );
		if ( pFile )
		{
			fseek( pFile, 0, SEEK_END );
			long lSize = ftell( pFile );
			fclose( pFile );
			pFile = NULL;

			vp << (FX_INT32)(lSize);
			return TRUE;
		}
	}

	vp << 0;
	return TRUE;
}

FX_BOOL Document::mouseX(OBJ_PROP_PARAMS)
{
 	return TRUE;	
}

FX_BOOL Document::mouseY(OBJ_PROP_PARAMS)
{
 	return TRUE;
}

FX_BOOL Document::baseURL(OBJ_PROP_PARAMS)
{
	if (vp.IsGetting())
	{
		vp << m_cwBaseURL;
		return TRUE;
	}
	else
	{
		vp >> m_cwBaseURL;
		return TRUE;
	}
}

FX_BOOL Document::calculate(OBJ_PROP_PARAMS)
{
	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(OBJ_PROP_PARAMS)
{
	if (!vp.IsGetting())
		return FALSE;

	CFX_WideString wsFilePath = m_pDocument->GetPath();

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

FX_BOOL Document::path(OBJ_PROP_PARAMS)
{
	if (!vp.IsGetting()) return FALSE;

	vp << app::SysPathToPDFPath(m_pDocument->GetPath());

	return TRUE;
}

FX_BOOL Document::pageWindowRect(OBJ_PROP_PARAMS)
{
	return TRUE;
}

FX_BOOL Document::layout(OBJ_PROP_PARAMS)
{	
	return TRUE;
}

FX_BOOL Document::addLink(OBJ_METHOD_PARAMS)
{
 	return TRUE;
}

FX_BOOL Document::closeDoc(OBJ_METHOD_PARAMS)
{
	ASSERT(m_pDocument != NULL);


	
	

	return TRUE;
}

FX_BOOL Document::getPageBox(OBJ_METHOD_PARAMS)
{
 	return TRUE;
}


FX_BOOL Document::getAnnot(OBJ_METHOD_PARAMS)
{
 	return TRUE;
}

FX_BOOL Document::getAnnots(OBJ_METHOD_PARAMS)
{
	vRet.SetNull();
	return TRUE;
}

FX_BOOL Document::getAnnot3D(OBJ_METHOD_PARAMS)
{
	vRet.SetNull();
	return TRUE;
}

FX_BOOL Document::getAnnots3D(OBJ_METHOD_PARAMS)
{
	vRet = VT_undefined;
	return TRUE;
}

FX_BOOL Document::getOCGs(OBJ_METHOD_PARAMS)
{	
	return TRUE;
}

FX_BOOL Document::getLinks(OBJ_METHOD_PARAMS)
{
	return TRUE;
}

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

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;
	}
	else
		return NULL;
}

void IconTree::DeleteIconElement(CFX_WideString swIconName)
{
	IconElement* pTemp = m_pHead;
	int iLoopCount = m_iLength; 
	for (int i = 0; i < iLoopCount - 1; i++)
	{
		if (pTemp == m_pEnd)
			break;
	
		if (m_pHead->IconName == swIconName)
		{
			m_pHead = m_pHead->NextIcon;
			delete pTemp;
			m_iLength--;
			pTemp = m_pHead;
		}
		if (pTemp->NextIcon->IconName == swIconName)
		{
			if (pTemp->NextIcon == m_pEnd)
			{
				m_pEnd = pTemp;
				delete pTemp->NextIcon;
				m_iLength--;
				pTemp->NextIcon = NULL;
			}
			else
			{
				IconElement* pElement = pTemp->NextIcon;
				pTemp->NextIcon = pTemp->NextIcon->NextIcon;
				delete pElement;
				m_iLength--;
				pElement = NULL;
			}

			continue;
		}

		pTemp = pTemp->NextIcon;
	}
}

FX_BOOL Document::addIcon(OBJ_METHOD_PARAMS)
{
	if (params.size() != 2)return FALSE;

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

	CFX_WideString swIconName = params[0].operator CFX_WideString();
	
	JSFXObject pJSIcon = (JSFXObject)params[1];
	if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) return FALSE;

	CJS_EmbedObj* pEmbedObj = ((CJS_Object*)params[1])->GetEmbedObject();
	if (!pEmbedObj)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(OBJ_PROP_PARAMS)
{
	if (vp.IsSetting())
		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;
}

FX_BOOL Document::getIcon(OBJ_METHOD_PARAMS)
{
	if (params.size() != 1)return FALSE;
	if(!m_pIconTree)
		return FALSE;
	CFX_WideString swIconName = params[0].operator CFX_WideString();
	int iIconCounts = m_pIconTree->GetLength();

	CJS_Context* pContext = (CJS_Context *)cc;
	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;
}

FX_BOOL Document::removeIcon(OBJ_METHOD_PARAMS)
{
	if (params.size() != 1)return FALSE;
	if(!m_pIconTree)
		return FALSE;
	CFX_WideString swIconName = params[0].operator CFX_WideString();
#ifndef FOXIT_CHROME_BUILD
	m_pIconTree->DeleteIconElement(swIconName);
#endif
	return TRUE;
}

FX_BOOL Document::createDataObject(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;
	ASSERT(m_pDocument != NULL);

	CFX_WideString swName = L"";
	CFX_ByteString sbName = "";
	CFX_WideString swValue = L"";
	CFX_WideString swMIMEType = L"";
	CFX_WideString swCryptFilter = L"";
	CFX_ByteString sbFileValue = "";
	
	int iParamSize = params.size();
	for (int i = 0; i < iParamSize; i++)
	{
		if (i == 0)
			swName = params[0];
		if (i == 1)
			swValue = params[1];
		if (i == 2)
			swMIMEType = params[2];
		if (i == 3)
			swCryptFilter = params[4];
	}

	FILE* pFile = NULL;

	//CFileStatus fileStatus;
	const int BUFSIZE = 17;
	FX_BYTE buf[BUFSIZE];
	FX_BYTE *pBuffer = NULL;
	char* pBuf = NULL;
	int nFileSize = 0;
	sbFileValue = CFX_ByteString::FromUnicode(swValue);
	sbName = CFX_ByteString::FromUnicode(swName);
	int iBufLength = sbFileValue.GetLength();
	pBuf = (char*)malloc(sizeof(char) * iBufLength);
	pBuf = sbFileValue.GetBuffer(iBufLength);

	if ( NULL == (pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "wb+" )) )
	{
		return FALSE;
	}

	fwrite( pBuf, sizeof(char), iBufLength, pFile );
	fclose( pFile );
	pFile = NULL;

	pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "rb+" );
	fseek( pFile, 0, SEEK_END );
	nFileSize = ftell( pFile );

	pBuffer = new FX_BYTE[nFileSize];
	fseek( pFile, 0, SEEK_SET );
	size_t s = fread( pBuffer, sizeof(char), nFileSize, pFile );
	if(s == 0)
	{
		delete[] pBuffer;
		return FALSE;
	}

	CRYPT_MD5Generate(pBuffer, nFileSize, buf);
	buf[BUFSIZE - 1] = 0;
	CFX_WideString csCheckSum((FX_LPCWSTR)buf, 16);
	delete[] pBuffer;

	return TRUE;
}

FX_BOOL Document::media(OBJ_PROP_PARAMS)
{
	return TRUE;
}

FX_BOOL Document::calculateNow(OBJ_METHOD_PARAMS)
{
	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(OBJ_PROP_PARAMS)
{
	return TRUE;
}

FX_BOOL Document::getPageNthWord(OBJ_METHOD_PARAMS)
{
	//if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

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

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

	if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
	{
		//sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
		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;
	return TRUE;
}

FX_BOOL Document::getPageNthWordQuads(OBJ_METHOD_PARAMS)
{
	//if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

	return FALSE;
}

FX_BOOL Document::getPageNumWords(OBJ_METHOD_PARAMS)
{
	ASSERT(m_pDocument != NULL);

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

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

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

	if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
	{
		//sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
		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(OBJ_METHOD_PARAMS)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);
	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);
	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;

	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(OBJ_PROP_PARAMS)
{

	return TRUE;
}

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

FX_BOOL Document::zoomType(OBJ_PROP_PARAMS)
{
	return TRUE;
}

FX_BOOL Document::deletePages(OBJ_METHOD_PARAMS)
{
	

	
	


	v8::Isolate* isolate = GetIsolate(cc);
// 	if (pEnv->GetAppName().Compare(PHANTOM) != 0)
// 		return TRUE;

	//if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

	int iSize = params.size();
	
	int nStart = 0;
	int nEnd = 0;
	
	if (iSize < 1)
	{
	}
	else if (iSize == 1)
	{
		if (params[0].GetType() == VT_object)
		{
			JSObject  pObj = (JSObject )params[0];
			v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
				nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
				nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
		}
		else
		{
			nStart = (int)params[0];
		}
	}
	else
	{
		nStart = (int)params[0];
		nEnd = (int)params[1];
	}

	int nTotal = m_pDocument->GetPageCount();

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

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

	if (nEnd < nStart) nEnd = nStart;

	

#ifndef FOXIT_CHROME_BUILD
	return m_pDocument->DeletePages(nStart, nEnd - nStart + 1);
#else
	return TRUE;
#endif
}

FX_BOOL Document::extractPages(OBJ_METHOD_PARAMS)
{
	

	
	
	

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

	if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

	int iSize = params.size();
	
	int nTotal = m_pDocument->GetPageCount();
	int nStart = 0;
	int nEnd = nTotal - 1;

	CFX_WideString swFilePath;
	
	if (iSize < 1)
	{
	}
	else if (iSize == 1)
	{
		if (params[0].GetType() == VT_object)
		{
			JSObject  pObj = (JSObject )params[0];
			v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
				nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
				nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"cPath");
				swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
		}
		else
		{
			nStart = (int)params[0];
		}
	}
	else if (iSize == 2)
	{
		nStart = (int)params[0];
		nEnd = (int)params[1];
	}
	else
	{
		nStart = (int)params[0];
		nEnd = (int)params[1];
		swFilePath = params[2].operator CFX_WideString();
	}

	if (nEnd < nStart)
		nEnd = nStart;

	CPDF_Document *pNewDoc = new CPDF_Document;
	pNewDoc->CreateNewDoc();	

	CFX_WordArray array;
	for (int i=nStart; i<=nEnd; i++)
		array.Add(i);

//	m_pDocument->ExtractPages(array, pNewDoc);

	if (swFilePath.IsEmpty())
	{

	}
	else
	{
		swFilePath = app::PDFPathToSysPath(swFilePath);
		CPDF_Creator PDFCreater(pNewDoc);
		PDFCreater.Create(swFilePath);
		delete pNewDoc;
//		pEnv->OpenDocument(swFilePath);
		vRet.SetNull();
	}

	return TRUE;
}

FX_BOOL Document::insertPages(OBJ_METHOD_PARAMS)
{


	



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

	if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

	int iSize = params.size();
	
	int nStart = 0;
	int nEnd = 0;
	int nPage = 0;

	CFX_WideString swFilePath;
	
	if (iSize < 1)
	{
	}
	else if (iSize == 1)
	{
		if (params[0].GetType() == VT_object)
		{
			JSObject  pObj = (JSObject )params[0];

			v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nPage");
				nPage = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"cPath");
				swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();

			pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
				nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
				nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
		}
		else
		{
			nPage = (int)params[0];
		}
	}
	else 
	{
		nPage = (int)params[0];

		if (iSize >= 2)
			swFilePath = params[1].operator CFX_WideString();

		if (iSize >= 3)
			nStart = (int)params[2];

		if (iSize >= 4)
			nEnd = (int)params[3];
	}

	nPage++;

	if (nPage < 0)
		nPage = 0;

	if (nPage > m_pDocument->GetPageCount())
		nPage = m_pDocument->GetPageCount();

	if (swFilePath.IsEmpty()) return FALSE;

	swFilePath = app::PDFPathToSysPath(swFilePath);

	CPDF_Parser pdfParser;
	pdfParser.StartParse(swFilePath, FALSE);
	CPDF_Document* pSrcDoc = pdfParser.GetDocument();

	if (!pSrcDoc) 
	{
		pdfParser.CloseParser();
		return FALSE;
	}

	int nTotal = pSrcDoc->GetPageCount();

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

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

	if (nEnd < nStart) nEnd = nStart;

	CFX_WordArray array;
	for (int i=nStart; i<=nEnd; i++)
		array.Add(i);

//	m_pDocument->InsertPages(nPage, pSrcDoc, array);

	pdfParser.CloseParser();

	return TRUE;
}

FX_BOOL Document::replacePages(OBJ_METHOD_PARAMS)
{


	



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

	if (IsSafeMode(cc)) return TRUE;

	ASSERT(m_pDocument != NULL);

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

	int iSize = params.size();
	
	int nStart = -1;
	int nEnd = -1;
	int nPage = 0;

	CFX_WideString swFilePath;
	
	if (iSize < 1)
	{
	}
	else if (iSize == 1)
	{
		if (params[0].GetType() == VT_object)
		{
			JSObject  pObj = (JSObject )params[0];

			v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nPage");
				nPage = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"cPath");
				swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();

			pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
				nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));

			pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
				nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
		}
		else
		{
			nPage = (int)params[0];
		}
	}
	else 
	{
		nPage = (int)params[0];

		if (iSize >= 2)
			swFilePath = params[1].operator CFX_WideString();

		if (iSize >= 3)
			nStart = (int)params[2];

		if (iSize >= 4)
			nEnd = (int)params[3];
	}

	if (nPage < 0)
		nPage = 0;

	if (nPage >= m_pDocument->GetPageCount())
		nPage = m_pDocument->GetPageCount() - 1;

	if (swFilePath.IsEmpty()) return FALSE;

	swFilePath = app::PDFPathToSysPath(swFilePath);

	CPDF_Parser pdfParser;
	pdfParser.StartParse(swFilePath, FALSE);
	CPDF_Document* pSrcDoc = pdfParser.GetDocument();

	if (!pSrcDoc) 
	{
		pdfParser.CloseParser();
		return FALSE;
	}

	int nTotal = pSrcDoc->GetPageCount();

	if (nStart < 0)
	{
		if (nEnd < 0)
		{
			nStart = 0;
			nEnd = nTotal - 1;
		}
		else
		{
			nStart = 0;
		}
	}
	else
	{
		if (nEnd < 0)
		{
			nEnd = nStart;
		}
		else
		{
			if (nStart >= nTotal) nStart = nTotal - 1;
			if (nEnd >= nTotal) nEnd = nTotal - 1;

			if (nEnd < nStart) nEnd = nStart;
		}
	}

	CFX_WordArray array;
	for (int i=nStart; i<=nEnd; i++)
		array.Add(i);

//	m_pDocument->ReplacePages(nPage, pSrcDoc, array);

	pdfParser.CloseParser();

	return TRUE;
}

FX_BOOL Document::getURL(OBJ_METHOD_PARAMS)
{
	if (IsSafeMode(cc)) return TRUE;

	return TRUE;
}

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

void Document::DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex)
{
	CFX_DWordArray DelArray;

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

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

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

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