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

#ifndef _FPDFSDK_MGR_H
#define _FPDFSDK_MGR_H

#include "fsdk_common.h"
#include "fsdk_define.h"
#include "fx_systemhandler.h"
#include "fsdk_baseannot.h"
#include "fsdk_baseform.h"
#include "fpdfformfill.h"
#include "fsdk_annothandler.h"
#include "fsdk_actionhandler.h"

//cross platform keycode and events define.
#include "fpdf_fwlevent.h"


class CPDFSDK_Document;
class CPDFSDK_PageView;
class CPDFSDK_Annot;
class CFFL_IFormFiller;
class CPDFSDK_Widget;
class IFX_SystemHandler;
class CPDFSDK_ActionHandler;
class CJS_RuntimeFactory;

#include "javascript/IJavaScript.h"

class CPDFDoc_Environment FX_FINAL
{
public:
	CPDFDoc_Environment(CPDF_Document * pDoc);
	~CPDFDoc_Environment();

	int RegAppHandle(FPDF_FORMFILLINFO* pFFinfo);//{ m_pInfo  = pFFinfo; return TRUE;}

	void FFI_Invalidate(FPDF_PAGE page, double left, double top, double right, double bottom)
	{
		if (m_pInfo && m_pInfo->FFI_Invalidate) 
		{
			m_pInfo->FFI_Invalidate(m_pInfo, page, left, top, right, bottom);
		}
	}
	void FFI_OutputSelectedRect(FPDF_PAGE page, double left, double top, double right, double bottom)
	{
		if (m_pInfo && m_pInfo->FFI_OutputSelectedRect) 
		{
			m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, left, top, right, bottom);
		}
	}

	void FFI_SetCursor(int nCursorType)
	{
		if (m_pInfo && m_pInfo->FFI_SetCursor) 
		{
			m_pInfo->FFI_SetCursor(m_pInfo, nCursorType);
		}
	}

	int  FFI_SetTimer(int uElapse, TimerCallback lpTimerFunc)
	{
		if (m_pInfo && m_pInfo->FFI_SetTimer) 
		{
			return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
		}
		return -1;
	}
		
	void FFI_KillTimer(int nTimerID)
	{
		if (m_pInfo && m_pInfo->FFI_KillTimer) 
		{
			m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
		}
	}
	FX_SYSTEMTIME FFI_GetLocalTime()
	{
		FX_SYSTEMTIME fxtime;
		if(m_pInfo && m_pInfo->FFI_GetLocalTime)
		{
			FPDF_SYSTEMTIME systime = m_pInfo->FFI_GetLocalTime(m_pInfo);
			fxtime.wDay = systime.wDay;
			fxtime.wDayOfWeek = systime.wDayOfWeek;
			fxtime.wHour = systime.wHour;
			fxtime.wMilliseconds = systime.wMilliseconds;
			fxtime.wMinute = systime.wMinute;
			fxtime.wMonth = systime.wMonth;
			fxtime.wSecond = systime.wSecond;
			fxtime.wYear = systime.wYear;
		}
		return fxtime;
	}

	void FFI_OnChange()
	{
		if(m_pInfo && m_pInfo->FFI_OnChange)
		{
			m_pInfo->FFI_OnChange(m_pInfo);
		}
	}

	FX_BOOL	FFI_IsSHIFTKeyDown(FX_DWORD nFlag)
	{
		
		return (nFlag & FWL_EVENTFLAG_ShiftKey) != 0;
	}
	FX_BOOL	FFI_IsCTRLKeyDown(FX_DWORD nFlag)
	{

		return (nFlag & FWL_EVENTFLAG_ControlKey) != 0;
	}
	FX_BOOL	FFI_IsALTKeyDown(FX_DWORD nFlag)
	{

		return (nFlag & FWL_EVENTFLAG_AltKey) != 0;
	}
	FX_BOOL	FFI_IsINSERTKeyDown(FX_DWORD nFlag)
	{
		return FALSE;
	}

	int JS_appAlert(FX_LPCWSTR Msg, FX_LPCWSTR Title, FX_UINT Type, FX_UINT Icon)
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert)
		{
			CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
			CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
			FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
			FPDF_WIDESTRING pTitle = (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
			int ret = m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, pMsg, pTitle, Type, Icon);
			bsMsg.ReleaseBuffer();
			bsTitle.ReleaseBuffer();
			return ret;
		}
		return -1;
	}

	int JS_appResponse(FX_LPCWSTR Question, FX_LPCWSTR Title, FX_LPCWSTR Default, FX_LPCWSTR cLabel, FPDF_BOOL bPassword, void* response, int length)
	{
		if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_response)
		{
			CFX_ByteString bsQuestion = CFX_WideString(Question).UTF16LE_Encode();
			CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
			CFX_ByteString bsDefault = CFX_WideString(Default).UTF16LE_Encode();
			CFX_ByteString bsLabel = CFX_WideString(cLabel).UTF16LE_Encode();
			FPDF_WIDESTRING pQuestion = (FPDF_WIDESTRING)bsQuestion.GetBuffer(bsQuestion.GetLength());
			FPDF_WIDESTRING pTitle = (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
			FPDF_WIDESTRING pDefault = (FPDF_WIDESTRING)bsDefault.GetBuffer(bsDefault.GetLength());
			FPDF_WIDESTRING pLabel = (FPDF_WIDESTRING)bsLabel.GetBuffer(bsLabel.GetLength());
			int ret = m_pInfo->m_pJsPlatform->app_response(m_pInfo->m_pJsPlatform, pQuestion, pTitle, 
				pDefault, pLabel, bPassword, response, length);
			bsQuestion.ReleaseBuffer();
			bsTitle.ReleaseBuffer();
			bsDefault.ReleaseBuffer();
			bsLabel.ReleaseBuffer();
			return ret;
		}
		return -1;
	}

	void JS_appBeep(int nType)
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_beep)
		{
			m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType);
		}
	}

	CFX_WideString JS_fieldBrowse()
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Field_browse)
		{
			int nLen = m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, NULL, 0);
			if(nLen <= 0)
				return L"";
			char* pbuff = new char[nLen];
			if(pbuff)
				memset(pbuff, 0, nLen);
			else	
				return L"";
			nLen = m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, pbuff, nLen);
			CFX_ByteString bsRet = CFX_ByteString(pbuff, nLen);
			CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
			delete[] pbuff;
			return wsRet;
		}
		return L"";
	}

	CFX_WideString JS_docGetFilePath()
	{		
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_getFilePath)
		{
			int nLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(m_pInfo->m_pJsPlatform, NULL, 0);
			if(nLen <= 0)
				return L"";
			char* pbuff = new char[nLen];
			if(pbuff)
				memset(pbuff, 0, nLen);
			else
				return L"";
			nLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(m_pInfo->m_pJsPlatform, pbuff, nLen);
			CFX_ByteString bsRet = CFX_ByteString(pbuff, nLen);
			CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
			delete[] pbuff;
			return wsRet;
		}
		return L"";
	}

	void JS_docSubmitForm(void* formData, int length, FX_LPCWSTR URL)
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_submitForm)
		{
			CFX_ByteString bsDestination = CFX_WideString(URL).UTF16LE_Encode();
			FPDF_WIDESTRING pDestination = (FPDF_WIDESTRING)bsDestination.GetBuffer(bsDestination.GetLength());
			m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData, length, pDestination);
			bsDestination.ReleaseBuffer();
		}
	}

	void JS_docmailForm(void* mailData, int length, FPDF_BOOL bUI,FX_LPCWSTR To, FX_LPCWSTR Subject, FX_LPCWSTR CC, FX_LPCWSTR BCC, FX_LPCWSTR Msg)
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_mail)
		{
			CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode();
			CFX_ByteString bsCC = CFX_WideString(Subject).UTF16LE_Encode();
			CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
			CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode();
			CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
			FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
			FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
			FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
			FPDF_WIDESTRING pSubject = (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
			FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
			m_pInfo->m_pJsPlatform->Doc_mail(m_pInfo->m_pJsPlatform, mailData, length, bUI, pTo, pSubject,
				pCC, pBcc, pMsg);
			bsTo.ReleaseBuffer();
			bsCC.ReleaseBuffer();
			bsBcc.ReleaseBuffer();
			bsSubject.ReleaseBuffer();
			bsMsg.ReleaseBuffer();
		}
	}
	CFX_WideString JS_appbrowseForDoc(FPDF_BOOL bSave, FX_LPCWSTR cFilenameInit)
	{
		//to do....
		return L"";
// 		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_browseForDoc)
// 		{
// 			CFX_ByteString bsFilenameInit = CFX_WideString(cFilenameInit).UTF16LE_Encode();
// 			FPDF_WIDESTRING pFileNameInit = (FPDF_WIDESTRING)bsFilenameInit.GetBuffer(bsFilenameInit.GetLength());
// 
// 			m_pInfo->m_pJsPlatform->app_browseForDoc(m_pInfo->m_pJsPlatform, pFileNameInit);
// 			bsFilenameInit.ReleaseBuffer();
// 		}
	}

	void JS_docprint(FPDF_BOOL bUI , int nStart, int nEnd, FPDF_BOOL bSilent ,FPDF_BOOL bShrinkToFit,FPDF_BOOL bPrintAsImage ,FPDF_BOOL bReverse ,FPDF_BOOL bAnnotations)
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_print)
		{
			m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations);
		}
	}
	void JS_docgotoPage(int nPageNum)
	{
		if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_gotoPage)
		{
			m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum);
		}
	}

	FPDF_PAGE	FFI_GetPage(FPDF_DOCUMENT document,int nPageIndex)
	{
		if(m_pInfo && m_pInfo->FFI_GetPage)
		{
			return m_pInfo->FFI_GetPage(m_pInfo, document, nPageIndex);
		}
		return NULL;
	}

	FPDF_PAGE FFI_GetCurrentPage(FPDF_DOCUMENT document)
	{
		if(m_pInfo && m_pInfo->FFI_GetCurrentPage)
		{
			return m_pInfo->FFI_GetCurrentPage(m_pInfo, document);
		}
		return NULL;
	}

	int 	FFI_GetRotation(FPDF_PAGE page)
	{
		if(m_pInfo && m_pInfo->FFI_GetRotation)
		{
			return m_pInfo->FFI_GetRotation(m_pInfo, page);
		}
		return 0;
	}
	void	FFI_ExecuteNamedAction(FX_LPCSTR namedAction)
	{
		if(m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
		{
			m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction);
		}
	}
	void	FFI_OnSetFieldInputFocus(void* field,FPDF_WIDESTRING focusText, FPDF_DWORD nTextLen, FX_BOOL bFocus)
	{
		if(m_pInfo && m_pInfo->FFI_SetTextFieldFocus)
		{
			m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus);
		}
	}

	void	FFI_DoURIAction(FX_LPCSTR bsURI)
	{
		if(m_pInfo && m_pInfo->FFI_DoURIAction)
		{
			m_pInfo->FFI_DoURIAction(m_pInfo, bsURI);
		}
	}

	void	FFI_DoGoToAction(int nPageIndex, int zoomMode, float* fPosArray, int sizeOfArray)
	{
		if(m_pInfo && m_pInfo->FFI_DoGoToAction)
		{
			m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray, sizeOfArray);
		}
	}

public:
	FX_BOOL				IsJSInitiated();

public:	
	void				SetCurrentDoc(CPDFSDK_Document* pFXDoc) {m_pSDKDoc = pFXDoc;}
	CPDFSDK_Document*	GetCurrentDoc();
	CPDF_Document*		GetPDFDocument() {return m_pPDFDoc;}
// 	CPDFSDK_Document*   GetDocument(int nIndex);
// 	int					CountDocuments() {return m_docMap.GetCount();}

	CPDFSDK_Document*		OpenDocument(CFX_WideString &fileName);
	CPDFSDK_Document*		OpenMemPDFDoc(CPDF_Document* pNewDoc, CFX_WideString &fileName);
	FX_BOOL					OpenURL(CFX_WideString &filePath);
	

	CFX_ByteString		GetAppName() {return "";}

	CFFL_IFormFiller*	GetIFormFiller();
	IFX_SystemHandler*	GetSysHandler() {return m_pSysHandler;}

public:
	CPDFSDK_AnnotHandlerMgr* GetAnnotHandlerMgr();
	IFXJS_Runtime*	GetJSRuntime();
	CPDFSDK_ActionHandler* GetActionHander();
private:
	CPDFSDK_AnnotHandlerMgr* m_pAnnotHandlerMgr;
	CPDFSDK_ActionHandler*	m_pActionHandler;
	IFXJS_Runtime*	m_pJSRuntime;
public:
	FPDF_FORMFILLINFO* GetFormFillInfo() {return m_pInfo;}
private:
	FPDF_FORMFILLINFO*	m_pInfo;
//	CFX_MapPtrTemplate<CPDF_Document*, CPDFSDK_Document*> m_docMap;
	CPDFSDK_Document* m_pSDKDoc;
	CPDF_Document* m_pPDFDoc;

	CFFL_IFormFiller* m_pIFormFiller;
	IFX_SystemHandler* m_pSysHandler;

public:
	CJS_RuntimeFactory*  m_pJSRuntimeFactory;
};



// class CFX_App
// {
// public:
// 	CFX_App():m_pCurDoc(NULL) {}
// 	void SetAt(CPDF_Document* pPDFDoc, CPDFSDK_Document* pFXDoc);
// 	CPDFSDK_Document* GetAt(CPDF_Document* pPDFDoc);
// public:
// 	void SetCurrentDocument(CPDFSDK_Document* pFXDoc) {m_pCurDoc = pFXDoc;}
// 	CPDFSDK_Document* GetCurrentDocument() {return m_pCurDoc;}
// private:
// 	CFX_MapPtrTemplate<CPDF_Document*, CPDFSDK_Document*> m_docArray;
// 	CPDFSDK_Document* m_pCurDoc;
// };
class CPDFSDK_InterForm;
class CPDFSDK_Document
{
public:
	CPDFSDK_Document(CPDF_Document* pDoc, CPDFDoc_Environment* pEnv);
	~CPDFSDK_Document();
public:
	CPDFSDK_InterForm*		GetInterForm() ;
	CPDF_Document*			GetDocument() {return m_pDoc;}

public:
	void					InitPageView();
	void					AddPageView(CPDF_Page* pPDFPage, CPDFSDK_PageView* pPageView);
	CPDFSDK_PageView*		GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReNew = TRUE);
	CPDFSDK_PageView*		GetPageView(int nIndex);
	CPDFSDK_PageView*		GetCurrentView();
	void					ReMovePageView(CPDF_Page* pPDFPage);
	void					UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot);

	CPDFSDK_Annot*			GetFocusAnnot();//{return NULL;}

	IFXJS_Runtime *			GetJsRuntime();
	
	FX_BOOL					SetFocusAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag = 0);//{return FALSE;}
	FX_BOOL					KillFocusAnnot(FX_UINT nFlag = 0);

	FX_BOOL					ExtractPages(const CFX_WordArray &arrExtraPages, CPDF_Document* pDstDoc);
	FX_BOOL					InsertPages(int nInsertAt, const CPDF_Document* pSrcDoc, const CFX_WordArray &arrSrcPages);
	FX_BOOL					DeletePages(int nStart, int nCount);
	FX_BOOL					ReplacePages(int nPage, const CPDF_Document* pSrcDoc, const CFX_WordArray &arrSrcPages);

	void					OnCloseDocument();

	int						GetPageCount() {return m_pDoc->GetPageCount();}
	FX_BOOL					GetPermissions(int nFlag);
	FX_BOOL					GetChangeMark() {return m_bChangeMask;}
	void					SetChangeMark() {m_bChangeMask = TRUE;}
	void					ClearChangeMark() {m_bChangeMask= FALSE;}
//	FX_BOOL					GetChangeMark(){return FALSE;}//IsAnnotModified()||IsFormModified() || IsWidgetModified()|| m_nChangeMark>0 ;}	
//	void                    ClearChangeMark(){}
	CFX_WideString			GetPath() ;
	CPDF_Page*				GetPage(int nIndex);
	CPDFDoc_Environment *	GetEnv() {return m_pEnv; }
	void				    ProcJavascriptFun();
	FX_BOOL					ProcOpenAction();
	CPDF_OCContext*			GetOCContext();
private:
	//CFX_ArrayTemplate<CPDFSDK_PageView*> m_pageArray;
	CFX_MapPtrTemplate<CPDF_Page*, CPDFSDK_PageView*> m_pageMap;
	CPDF_Document*			m_pDoc;

	CPDFSDK_InterForm*		m_pInterForm;
	CPDFSDK_Annot*			m_pFocusAnnot;
	CPDFDoc_Environment *	m_pEnv;
	CPDF_OCContext *		m_pOccontent;
	FX_BOOL					m_bChangeMask;
};

class CPDFSDK_PageView FX_FINAL
{
public:
	CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page);
	~CPDFSDK_PageView();
public:
	void PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions) ;
public:
	CPDF_Annot*						GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
	CPDFSDK_Annot*					GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
	CPDF_Annot*						GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
	CPDFSDK_Annot*					GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
	CPDFSDK_Annot*					GetFocusAnnot() ;
	void							SetFocusAnnot(CPDFSDK_Annot* pSDKAnnot,FX_UINT nFlag = 0) {m_pSDKDoc->SetFocusAnnot(pSDKAnnot, nFlag);}
	FX_BOOL							KillFocusAnnot(FX_UINT nFlag = 0) {return m_pSDKDoc->KillFocusAnnot(nFlag);}
	FX_BOOL							Annot_HasAppearance(CPDF_Annot* pAnnot);

	CPDFSDK_Annot*					AddAnnot(CPDF_Dictionary * pDict);
	CPDFSDK_Annot*					AddAnnot(FX_LPCSTR lpSubType,CPDF_Dictionary * pDict);
	CPDFSDK_Annot*					AddAnnot(CPDF_Annot * pPDFAnnot);
	FX_BOOL							DeleteAnnot(CPDFSDK_Annot* pAnnot);							
	
	int								CountAnnots();
	CPDFSDK_Annot*					GetAnnot(int nIndex);
	CPDFSDK_Annot*				    GetAnnotByDict(CPDF_Dictionary * pDict);
	CPDF_Page*						GetPDFPage(){return m_page;}
	CPDF_Document*					GetPDFDocument();
	CPDFSDK_Document*				GetSDKDocument() {return m_pSDKDoc;}	
public:
	FX_BOOL					OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag);
	FX_BOOL					OnLButtonUp(const CPDF_Point & point, FX_UINT nFlag);
	FX_BOOL					OnChar(int nChar, FX_UINT nFlag);
	FX_BOOL					OnKeyDown(int nKeyCode, int nFlag);
	FX_BOOL					OnKeyUp(int nKeyCode, int nFlag);

	FX_BOOL					OnMouseMove(const CPDF_Point & point, int nFlag);
	FX_BOOL					OnMouseWheel(double deltaX, double deltaY,const CPDF_Point& point, int nFlag);
	FX_BOOL					IsValidAnnot(FX_LPVOID p);
public:
	void					GetCurrentMatrix(CPDF_Matrix& matrix) {matrix = m_curMatrix;}
	void					UpdateRects(CFX_RectArray& rects);
	void							UpdateView(CPDFSDK_Annot* pAnnot);
	CFX_PtrArray*					GetAnnotList(){ return &m_fxAnnotArray; }

public:
	int						GetPageIndex();
	void							LoadFXAnnots();
private:
	CPDF_Matrix m_curMatrix;

private:
	void PageView_OnHighlightFormFields(CFX_RenderDevice* pDevice, CPDFSDK_Widget* pWidget);

private:
	CPDF_Page* m_page;
	CPDF_AnnotList* m_pAnnotList;

	//CPDFSDK_Annot* m_pFocusAnnot;
	CFX_PtrArray  m_fxAnnotArray;

	CPDFSDK_Document* m_pSDKDoc;
private:
	CPDFSDK_Widget* m_CaptureWidget;
	FX_BOOL m_bEnterWidget;
	FX_BOOL m_bExitWidget;
	FX_BOOL m_bOnWidget;
public:
	void SetValid(FX_BOOL bValid) {m_bValid = bValid;}
	FX_BOOL IsValid() {return m_bValid;}
private:
	FX_BOOL m_bValid;
};


template<class TYPE>
class CGW_ArrayTemplate : public CFX_ArrayTemplate<TYPE>
{
public: 
	CGW_ArrayTemplate(){}
	virtual ~CGW_ArrayTemplate(){}
	
	typedef int (*LP_COMPARE)(TYPE p1, TYPE p2);
	
	void Sort(LP_COMPARE pCompare, FX_BOOL bAscent = TRUE)
	{
		int nSize = this->GetSize();
		QuickSort(0, nSize -1, bAscent, pCompare);
	}
	
private:
	void QuickSort(FX_UINT nStartPos, FX_UINT nStopPos, FX_BOOL bAscend, LP_COMPARE pCompare)
	{
		if (nStartPos >= nStopPos) return;
		
		if ((nStopPos - nStartPos) == 1)
		{
			TYPE Value1 = this->GetAt(nStartPos);
			TYPE Value2 = this->GetAt(nStopPos);
			
			int iGreate = (*pCompare)(Value1, Value2);
			if ((bAscend && iGreate > 0) || (!bAscend && iGreate < 0))
			{
				this->SetAt(nStartPos, Value2);
				this->SetAt(nStopPos, Value1);
			}
			return;
		}
		
		FX_UINT m = nStartPos + (nStopPos - nStartPos) / 2;
		FX_UINT i = nStartPos;
		
		TYPE Value = this->GetAt(m);
		
		while (i < m)
		{
			TYPE temp = this->GetAt(i);
			
			int iGreate = (*pCompare)(temp, Value);
			if ((bAscend && iGreate > 0) || (!bAscend && iGreate < 0))
			{
				this->InsertAt(m+1, temp);
				this->RemoveAt(i);
				m--;
			}
			else
			{
				i++;
			}
		}
		
		FX_UINT j = nStopPos;
		
		while (j > m)
		{
			TYPE temp = this->GetAt(j);
			
			int iGreate = (*pCompare)(temp, Value);
			if ((bAscend && iGreate < 0) || (!bAscend && iGreate > 0))
			{
				this->RemoveAt(j);
				this->InsertAt(m, temp);
				m++;
			}
			else
			{
				j--;
			}
		}
		
		if (nStartPos < m) QuickSort(nStartPos, m, bAscend, pCompare);
		if (nStopPos > m) QuickSort(m, nStopPos, bAscend, pCompare);
	}
};


#endif //_FPDFSDK_MGR_H

