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

	CPDFSDK_DateTime curTime;
	pPDFAnnot->GetAnnotDict()->SetAtString("M", curTime.ToPDFDateTimeString());
	pPDFAnnot->GetAnnotDict()->SetAtNumber("F", 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", "");
    return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
}

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->GetAnnotDict()))
	{
		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(bFormated);
			if (bFormated && nFieldType == FIELDTYPE_COMBOBOX)
			{
				pWidget->ResetAppearance(sValue.c_str(), 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 = 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 = 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();
	}

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

