// 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/fsdk_define.h"
#include "../include/fsdk_mgr.h"
#include "../include/formfiller/FFL_FormFiller.h"
#include "../include/fsdk_annothandler.h"


CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(CPDFDoc_Environment* pApp)
{
	m_pApp = pApp;

	CPDFSDK_BFAnnotHandler* pHandler = new CPDFSDK_BFAnnotHandler(m_pApp);
	pHandler->SetFormFiller(m_pApp->GetIFormFiller());
	RegisterAnnotHandler(pHandler);
}

CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr()
{
	for(int i=0; i<m_Handlers.GetSize(); i++)
	{
		IPDFSDK_AnnotHandler* pHandler = m_Handlers.GetAt(i);
		delete pHandler;
	}
	m_Handlers.RemoveAll();
	m_mapType2Handler.RemoveAll();
}

void	CPDFSDK_AnnotHandlerMgr::RegisterAnnotHandler(IPDFSDK_AnnotHandler* pAnnotHandler)
{
	ASSERT(pAnnotHandler != NULL);
	
	ASSERT(GetAnnotHandler(pAnnotHandler->GetType()) == NULL);
	
	m_Handlers.Add(pAnnotHandler);
	m_mapType2Handler.SetAt(pAnnotHandler->GetType(), (void*)pAnnotHandler);
}

void CPDFSDK_AnnotHandlerMgr::UnRegisterAnnotHandler(IPDFSDK_AnnotHandler* pAnnotHandler)
{
	ASSERT(pAnnotHandler != NULL);
	
	m_mapType2Handler.RemoveKey(pAnnotHandler->GetType());
	
	for (int i=0, sz=m_Handlers.GetSize(); i<sz; i++)
	{
		if (m_Handlers.GetAt(i) == pAnnotHandler)
		{
			m_Handlers.RemoveAt(i);
			break;
		}
	}
}

CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot * pAnnot, CPDFSDK_PageView *pPageView)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pPageView != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot->GetSubType()))
	{
		return pAnnotHandler->NewAnnot(pAnnot, pPageView);
	}
	
	return new CPDFSDK_Annot(pAnnot, pPageView);
}

void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	
	pAnnot->GetPDFPage();
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		pAnnotHandler->OnRelease(pAnnot);
		pAnnotHandler->ReleaseAnnot(pAnnot);
	}
	else
	{
		delete (CPDFSDK_Annot*)pAnnot;
	}
}

void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	
	CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
	ASSERT(pPDFAnnot != NULL);
	ASSERT(pPDFAnnot->m_pAnnotDict != NULL);
	
	CPDFSDK_DateTime curTime;
	pPDFAnnot->m_pAnnotDict->SetAtString("M", curTime.ToPDFDateTimeString());
	pPDFAnnot->m_pAnnotDict->SetAtNumber("F", (int)0);	
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		pAnnotHandler->OnCreate(pAnnot);
	}
}

void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		pAnnotHandler->OnLoad(pAnnot);
	}
}

IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(CPDFSDK_Annot* pAnnot) const
{
	ASSERT(pAnnot != NULL);
	
	CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
	ASSERT(pPDFAnnot != NULL);
	
	return GetAnnotHandler(pPDFAnnot->GetSubType());
}

IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(const CFX_ByteString& sType) const
{
	void* pRet = NULL;
	m_mapType2Handler.Lookup(sType, pRet);	
	return (IPDFSDK_AnnotHandler*)pRet;
}

void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,FX_DWORD dwFlags)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		pAnnotHandler->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
	}
	else
	{
		pAnnot->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
	}
}


FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnLButtonDown(pPageView, pAnnot, nFlags, point);
	}
	return FALSE;
}
FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
 {
	ASSERT(pAnnot != NULL);

	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnLButtonUp(pPageView, pAnnot, nFlags, point);
	}
	return FALSE;
 }
FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
	}
	return FALSE;
}
FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnMouseMove(pPageView, pAnnot, nFlags, point);
	}
	return FALSE;
}
FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, short zDelta, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnMouseWheel(pPageView, pAnnot,nFlags,zDelta, point);
	}
	return FALSE;
}
FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnRButtonDown(pPageView, pAnnot, nFlags, point);
	}
	return FALSE;
}
FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnRButtonUp(pPageView, pAnnot, nFlags, point);
	}
	return FALSE;
}

void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		pAnnotHandler->OnMouseEnter(pPageView, pAnnot, nFlag);
	}
	return ;
}

void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(CPDFSDK_PageView * pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		pAnnotHandler->OnMouseExit(pPageView, pAnnot, nFlag);
	}
	return;
}

FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot, FX_DWORD nChar, FX_DWORD nFlags)
{

	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnChar(pAnnot,nChar, nFlags);
	}
	return FALSE;

}

FX_BOOL			CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag)
{

	if (!m_pApp->FFI_IsCTRLKeyDown(nFlag) && !m_pApp->FFI_IsALTKeyDown(nFlag))
	{
		CPDFSDK_PageView* pPage = pAnnot->GetPageView();
		CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
		if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab))
		{
			CPDFSDK_Annot* pNext = GetNextAnnot(pFocusAnnot, !m_pApp->FFI_IsSHIFTKeyDown(nFlag));

			if(pNext && pNext != pFocusAnnot)
			{
				CPDFSDK_Document* pDocument = pPage->GetSDKDocument();
				pDocument->SetFocusAnnot(pNext);
				return TRUE;
			}
		}
	}

	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->OnKeyDown(pAnnot,nKeyCode, nFlag);
	}
	return FALSE;
}
FX_BOOL			CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag)
{
	return FALSE;
}

FX_BOOL			CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
{
	ASSERT(pAnnot != NULL);

	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		if (pAnnotHandler->OnSetFocus(pAnnot, nFlag))
		{
			CPDFSDK_PageView* pPage = pAnnot->GetPageView();
			ASSERT(pPage != NULL);

			pPage->GetSDKDocument();
	//		pDocument->SetTopmostAnnot(pAnnot);

			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	
	return FALSE;
}

FX_BOOL			CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
{
	ASSERT(pAnnot != NULL);
	
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		if (pAnnotHandler->OnKillFocus(pAnnot, nFlag))
		{	
			return TRUE;
		}
		else
			return FALSE;
	}
	
	return FALSE;
}

CPDF_Rect	CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot);
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		return pAnnotHandler->GetViewBBox(pPageView, pAnnot);
	}
	return pAnnot->GetRect();
}

FX_BOOL	CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, const CPDF_Point& point)
{
	ASSERT(pAnnot);
	if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
	{
		if(pAnnotHandler->CanAnswer(pAnnot))
			return pAnnotHandler->HitTest(pPageView, pAnnot, point);
	}
	return FALSE;
}

CPDFSDK_Annot*	CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,FX_BOOL bNext)
{
	 CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), "Widget", "");

	 CPDFSDK_Annot* pNext = bNext ? 
		 ai.GetNextAnnot(pSDKAnnot) : 
		ai.GetPrevAnnot(pSDKAnnot);
	
		return pNext;
}

FX_BOOL CPDFSDK_BFAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot);
	ASSERT(pAnnot->GetType() == "Widget");
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
		if (!pWidget->IsVisible()) return FALSE;

		int nFieldFlags = pWidget->GetFieldFlags();
		if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) return FALSE;
		if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
			return TRUE;
		else
		{
			CPDF_Page* pPage = pWidget->GetPDFPage();
			ASSERT(pPage != NULL);
			
			CPDF_Document* pDocument = pPage->m_pDocument;
			ASSERT(pDocument != NULL);
			
			FX_DWORD dwPermissions = pDocument->GetUserPermissions();
			return (dwPermissions&FPDFPERM_FILL_FORM) || 
				(dwPermissions&FPDFPERM_ANNOT_FORM) || 
 			(dwPermissions&FPDFPERM_ANNOT_FORM);
		}
	}

	return FALSE;
}

CPDFSDK_Annot*		CPDFSDK_BFAnnotHandler::NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage)
{
	ASSERT(pPage != NULL);
	pPage->GetPDFDocument();
	
	CPDFSDK_Document* pSDKDoc  = m_pApp->GetCurrentDoc();
	ASSERT(pSDKDoc);
	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pSDKDoc->GetInterForm();
	ASSERT(pInterForm != NULL);
	
	CPDFSDK_Widget* pWidget = NULL;
	if (CPDF_FormControl* pCtrl = CPDFSDK_Widget::GetFormControl(pInterForm->GetInterForm(), pAnnot->m_pAnnotDict))
	{
		pWidget = new CPDFSDK_Widget(pAnnot, pPage, pInterForm);
		pInterForm->AddMap(pCtrl, pWidget);
		CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
		if(pPDFInterForm && pPDFInterForm->NeedConstructAP())
			pWidget->ResetAppearance(NULL,FALSE);
	}
	
	return pWidget;
}

void CPDFSDK_BFAnnotHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);

	if (m_pFormFiller)
		m_pFormFiller->OnDelete(pAnnot);
	
	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
	CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
	ASSERT(pInterForm != NULL);
	
	CPDF_FormControl* pCtrol = pWidget->GetFormControl();
	pInterForm->RemoveMap(pCtrol);
	

	delete pWidget;
}


void CPDFSDK_BFAnnotHandler::OnDraw(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,  FX_DWORD dwFlags)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
		pAnnot->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
	}
	else
	{
		if (m_pFormFiller)
		{
			m_pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
		}
	}
}

void CPDFSDK_BFAnnotHandler::OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) 
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			 m_pFormFiller->OnMouseEnter(pPageView, pAnnot, nFlag);
	}
	

}
void CPDFSDK_BFAnnotHandler::OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) 
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			 m_pFormFiller->OnMouseExit(pPageView, pAnnot, nFlag);
	}
	
}
FX_BOOL CPDFSDK_BFAnnotHandler::OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnLButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{	
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();

	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;

}


FX_BOOL CPDFSDK_BFAnnotHandler::OnMouseWheel(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, short zDelta, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta,point);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnRButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
	}
	
	return FALSE;
}
FX_BOOL CPDFSDK_BFAnnotHandler::OnRButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnChar(CPDFSDK_Annot* pAnnot, FX_DWORD nChar, FX_DWORD nFlags)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnChar(pAnnot,nChar, nFlags);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnKeyDown(pAnnot,nKeyCode, nFlag);
	}
	
	return FALSE;
}

FX_BOOL CPDFSDK_BFAnnotHandler::OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag)
{

	return FALSE;
}
void	CPDFSDK_BFAnnotHandler::OnCreate(CPDFSDK_Annot* pAnnot) 
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			m_pFormFiller->OnCreate(pAnnot);
	}
}

void CPDFSDK_BFAnnotHandler::OnLoad(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
		
	if (!pWidget->IsAppearanceValid())
			pWidget->ResetAppearance(NULL, FALSE);
		
		int nFieldType = pWidget->GetFieldType();
		
		if (nFieldType == FIELDTYPE_TEXTFIELD || nFieldType == FIELDTYPE_COMBOBOX)
		{
			FX_BOOL bFormated = FALSE;
			CFX_WideString sValue = pWidget->OnFormat(0, bFormated);
			
			if (bFormated && nFieldType == FIELDTYPE_COMBOBOX)
			{
				pWidget->ResetAppearance(sValue, FALSE);
			}
		}
		

		if (m_pFormFiller)
			m_pFormFiller->OnLoad(pAnnot);

	}
}

FX_BOOL	CPDFSDK_BFAnnotHandler::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnSetFocus(pAnnot,nFlag);
	}
	
	return TRUE;
}
FX_BOOL	CPDFSDK_BFAnnotHandler::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->OnKillFocus(pAnnot,nFlag);
	}
	
	return TRUE;
}

CPDF_Rect CPDFSDK_BFAnnotHandler::GetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	CFX_ByteString sSubType = pAnnot->GetSubType();
	
	if (sSubType == BFFT_SIGNATURE)
	{
	}
	else
	{
		if (m_pFormFiller)
			return m_pFormFiller->GetViewBBox(pPageView, pAnnot);

	}
	
	return CPDF_Rect(0,0,0,0);
}

FX_BOOL	CPDFSDK_BFAnnotHandler::HitTest(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, const CPDF_Point& point)
{
	ASSERT(pPageView);
	ASSERT(pAnnot);

	CPDF_Rect rect = GetViewBBox(pPageView, pAnnot);
	return rect.Contains(point.x, point.y);
}

//CReader_AnnotIteratorEx

CPDFSDK_AnnotIterator::CPDFSDK_AnnotIterator(CPDFSDK_PageView * pPageView,FX_BOOL bReverse,
												 FX_BOOL bIgnoreTopmost/*=FALSE*/,
												 FX_BOOL bCircle/*=FALSE*/,
												 CFX_PtrArray *pList/*=NULL*/)
{
	ASSERT(pPageView);
	m_bReverse=bReverse;
	m_bIgnoreTopmost= bIgnoreTopmost;
	m_bCircle=bCircle;
	m_pIteratorAnnotList.RemoveAll();
	InitIteratorAnnotList(pPageView,pList);
}

CPDFSDK_Annot*	CPDFSDK_AnnotIterator::NextAnnot (const CPDFSDK_Annot* pCurrent) 
{
	
	int index=-1;
	int nCount=this->m_pIteratorAnnotList.GetSize();
	if(pCurrent){
		for(int i=0;i<nCount;i++){
			CPDFSDK_Annot * pReaderAnnot= (CPDFSDK_Annot *)m_pIteratorAnnotList.GetAt(i);
			if(pReaderAnnot ==pCurrent){			
				index=i;
				break;
			}			
		}
	}	
	return NextAnnot(index);
}
CPDFSDK_Annot*	CPDFSDK_AnnotIterator::PrevAnnot (const CPDFSDK_Annot*pCurrent)
{
	
	int index=-1;
	int nCount=this->m_pIteratorAnnotList.GetSize();
	if(pCurrent){
		for(int i=0;i<nCount;i++){
			CPDFSDK_Annot * pReaderAnnot= (CPDFSDK_Annot*)m_pIteratorAnnotList.GetAt(i);
			if(pReaderAnnot ==pCurrent){			
				index=i;
				break;
			}			
		}	
	}
	return PrevAnnot(index);	
}
CPDFSDK_Annot*	CPDFSDK_AnnotIterator::NextAnnot (int& index) 
{	
	
	int nCount=m_pIteratorAnnotList.GetSize();
    if(nCount<=0) index=-1;
    else{
		if(index<0){
			index=0;		
		}
		else{		
			if(m_bCircle){			
				index=( index <nCount-1) ? (index+1) :0;		
			}
			else{
				index=( index <nCount-1) ? (index+1) :-1;		
			}
			
		}	
	}
	return (index <0) ? NULL : (CPDFSDK_Annot*)m_pIteratorAnnotList.GetAt(index);		
}


CPDFSDK_Annot*	CPDFSDK_AnnotIterator::PrevAnnot (int& index)
{
	
	int nCount=m_pIteratorAnnotList.GetSize();
    if(nCount<=0) index=-1;
	else{	
		if(index<0){
			index=nCount-1;		 
		}
		else{	
			if(m_bCircle){			
				index = ( index >0) ? (index-1) :nCount-1;		
			}
			else{
				index = ( index >0) ? (index-1) :-1;	
			}				
		}
	}
	return (index <0) ? NULL : (CPDFSDK_Annot*)m_pIteratorAnnotList.GetAt(index);		
}


CPDFSDK_Annot*CPDFSDK_AnnotIterator::Next(const CPDFSDK_Annot* pCurrent) 
{

	return (m_bReverse) ? PrevAnnot(pCurrent):NextAnnot(pCurrent);		 

}

CPDFSDK_Annot*	CPDFSDK_AnnotIterator::Prev(const CPDFSDK_Annot* pCurrent) 
{

	return (m_bReverse) ? NextAnnot(pCurrent):PrevAnnot(pCurrent);		 
}

CPDFSDK_Annot*CPDFSDK_AnnotIterator::Next(int& index )
{
	
	return (m_bReverse) ? PrevAnnot(index):NextAnnot(index);		 
	
}

CPDFSDK_Annot*	CPDFSDK_AnnotIterator::Prev(int& index )
{
	
	return (m_bReverse) ? NextAnnot(index):PrevAnnot(index);		 
}


void CPDFSDK_AnnotIterator::InsertSort(CFX_PtrArray &arrayList, AI_COMPARE pCompare)
{
	for (int i = 1; i < arrayList.GetSize(); i++)
	{
		if (pCompare((CPDFSDK_Annot*)(arrayList[i]) , (CPDFSDK_Annot*)(arrayList[i-1])) < 0)
		{
			int j = i-1;
			CPDFSDK_Annot* pTemp = (CPDFSDK_Annot*)arrayList[i];
			
			do
			{
				arrayList[j + 1] = arrayList[j];
			} while (--j >= 0 && pCompare(pTemp, (CPDFSDK_Annot*)arrayList[j]) < 0);

			arrayList[j+1] = pTemp;
		}
	}
}

int LyOrderCompare(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
{
	if(p1->GetLayoutOrder() < p2->GetLayoutOrder())
		return -1;
	else if (p1->GetLayoutOrder() == p2->GetLayoutOrder())
		return 0;
	else
		return 1;
}

FX_BOOL CPDFSDK_AnnotIterator::InitIteratorAnnotList(CPDFSDK_PageView* pPageView,CFX_PtrArray * pAnnotList)
{
	ASSERT(pPageView);
	
	

	if(pAnnotList==NULL){	
		pAnnotList=pPageView->GetAnnotList();
	}

	this->m_pIteratorAnnotList.RemoveAll();
	if(!pAnnotList) return FALSE;

	CPDFSDK_Annot * pTopMostAnnot= (m_bIgnoreTopmost) ? NULL : pPageView->GetFocusAnnot();


	int nCount =pAnnotList->GetSize();

	for(int i = nCount- 1 ;i >= 0;i--)
	{
		CPDFSDK_Annot * pReaderAnnot= (CPDFSDK_Annot*)pAnnotList->GetAt(i);
		m_pIteratorAnnotList.Add(pReaderAnnot);	
	}

	InsertSort(m_pIteratorAnnotList,&LyOrderCompare);

	if(pTopMostAnnot)
	{
		for(int i=0 ;i<nCount;i++)
		{
			CPDFSDK_Annot * pReaderAnnot = (CPDFSDK_Annot*)m_pIteratorAnnotList.GetAt(i);
			if(pReaderAnnot == pTopMostAnnot)
			{
				m_pIteratorAnnotList.RemoveAt(i);
				m_pIteratorAnnotList.InsertAt(0, pReaderAnnot);
				break;
			}	
		}
	}

	return TRUE;
}

