// 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/formfiller/FFL_FormFiller.h"
#include "../../include/formfiller/FFL_IFormFiller.h"
#include "../../include/formfiller/FFL_CheckBox.h"
#include "../../include/formfiller/FFL_ComboBox.h"
#include "../../include/formfiller/FFL_ListBox.h"
#include "../../include/formfiller/FFL_PushButton.h"
#include "../../include/formfiller/FFL_RadioButton.h"
#include "../../include/formfiller/FFL_TextField.h"

#define FFL_MAXLISTBOXHEIGHT		140.0f

// HHOOK CFFL_IFormFiller::m_hookSheet = NULL;
// MSG CFFL_IFormFiller::g_Msg;

/* ----------------------------- CFFL_IFormFiller ----------------------------- */

CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp) :
	m_pApp(pApp),
	m_bNotifying(FALSE)
{
}

CFFL_IFormFiller::~CFFL_IFormFiller()
{
	FX_POSITION pos = m_Maps.GetStartPosition();
	while (pos)
	{
		CPDFSDK_Annot * pAnnot = NULL;
		CFFL_FormFiller * pFormFiller = NULL;
		m_Maps.GetNextAssoc(pos,pAnnot,pFormFiller);
		delete pFormFiller;
	}
	m_Maps.RemoveAll();
}

FX_BOOL	CFFL_IFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,CPDFSDK_Annot* pAnnot, CPDF_Point point)
{
	CPDF_Rect rc = pAnnot->GetRect();
	if(rc.Contains(point.x, point.y))
		return TRUE;
	return FALSE;
}

FX_RECT CFFL_IFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
{
	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->GetViewBBox(pPageView, pAnnot);
	}
	else
	{
		ASSERT(pPageView != NULL);
		ASSERT(pAnnot != NULL);

		CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
		ASSERT(pPDFAnnot != NULL);

		CPDF_Rect rcAnnot;
		pPDFAnnot->GetRect(rcAnnot);

// 		CRect rcWin;
// 		pPageView->DocToWindow(rcAnnot, rcWin);
		CPDF_Rect rcWin = CPWL_Utils::InflateRect(rcAnnot,1);
//		rcWin.InflateRect(1, 1);

		return rcWin.GetOutterRect();
	}
}

void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot,
						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
{
	ASSERT(pPageView != NULL);
	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;

	if (IsVisible(pWidget))
	{
		if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
		{
 			if (pFormFiller->IsValid())
 			{
				pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);

				pAnnot->GetPDFPage();


				CPDFSDK_Document* pDocument = m_pApp->GetCurrentDoc();
				ASSERT(pDocument != NULL);

				if (pDocument->GetFocusAnnot() == pAnnot)
				{
					CPDF_Rect rcFocus = pFormFiller->GetFocusBox(pPageView);
					if (!rcFocus.IsEmpty())
					{
						CFX_PathData path;

						path.SetPointCount(5);
						path.SetPoint(0, rcFocus.left,  rcFocus.top, FXPT_MOVETO);
						path.SetPoint(1, rcFocus.left,  rcFocus.bottom, FXPT_LINETO);
						path.SetPoint(2, rcFocus.right,  rcFocus.bottom, FXPT_LINETO);
						path.SetPoint(3, rcFocus.right,  rcFocus.top, FXPT_LINETO);
						path.SetPoint(4, rcFocus.left,  rcFocus.top, FXPT_LINETO);

						CFX_GraphStateData gsd;
						gsd.SetDashCount(1);
						gsd.m_DashArray[0] = 1.0f;
						gsd.m_DashPhase = 0;

						gsd.m_LineWidth = 1.0f;
						pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255,0,0,0), FXFILL_ALTERNATE);

					//	::DrawFocusRect(hDC, &rcFocus);
					}
				}

				return;
			}
		}

		if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
			pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
		else
			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);

		if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
		{
			pWidget->DrawShadow(pDevice, pPageView);
		}

	}
}

void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot)
{
	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		pFormFiller->OnCreate(pAnnot);
	}
}

void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot)
{
	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		pFormFiller->OnLoad(pAnnot);
	}
}

void CFFL_IFormFiller::OnDelete(CPDFSDK_Annot* pAnnot)
{
	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		pFormFiller->OnDelete(pAnnot);
	}

	UnRegisterFormFiller(pAnnot);
}

void CFFL_IFormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (!m_bNotifying)
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
		if (pWidget->GetAAction(CPDF_AAction::CursorEnter))
		{
			m_bNotifying = TRUE;

			int nValueAge = pWidget->GetValueAge();

			pWidget->ClearAppModified();

			ASSERT(pPageView != NULL);



			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
			pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView );
			m_bNotifying = FALSE;

			//if ( !IsValidAnnot(pPageView, pAnnot) ) return;

			if (pWidget->IsAppModified())
			{
				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
				{
					pFormFiller->ResetPDFWindow(pPageView, pWidget->GetValueAge() == nValueAge);
				}
			}
		}
	}

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
	{
		pFormFiller->OnMouseEnter(pPageView, pAnnot);
	}
}

void CFFL_IFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (!m_bNotifying)
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
		if (pWidget->GetAAction(CPDF_AAction::CursorExit))
		{
			m_bNotifying = TRUE;
			pWidget->GetAppearanceAge();
			int nValueAge = pWidget->GetValueAge();
			pWidget->ClearAppModified();

			ASSERT(pPageView != NULL);



			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);

			pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
			m_bNotifying = FALSE;

			//if (!IsValidAnnot(pPageView, pAnnot)) return;

			if (pWidget->IsAppModified())
			{
				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
				{
					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
				}
			}
		}
	}

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		pFormFiller->OnMouseExit(pPageView, pAnnot);
	}
}

FX_BOOL	CFFL_IFormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (!m_bNotifying)
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
		if (Annot_HitTest(pPageView, pAnnot, point) && pWidget->GetAAction(CPDF_AAction::ButtonDown))
		{
			m_bNotifying = TRUE;
			pWidget->GetAppearanceAge();
			int nValueAge = pWidget->GetValueAge();
			pWidget->ClearAppModified();

			ASSERT(pPageView != NULL);



			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlags);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlags);
			pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
			m_bNotifying = FALSE;

			if (!IsValidAnnot(pPageView, pAnnot)) return TRUE;

			if (pWidget->IsAppModified())
			{
				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
				{
					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
				}
			}
		}
	}

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
	// 	CReader_Page* pPage = pAnnot->GetPage();
	// 	ASSERT(pPage != NULL);
	CPDFSDK_Document* pDocument = m_pApp->GetCurrentDoc();
	ASSERT(pDocument != NULL);

	switch (pWidget->GetFieldType())
	{
	case FIELDTYPE_PUSHBUTTON:
	case FIELDTYPE_CHECKBOX:
	case FIELDTYPE_RADIOBUTTON:
		if (GetViewBBox(pPageView, pAnnot).Contains((int)point.x, (int)point.y))
		{
			pDocument->SetFocusAnnot(pAnnot);
		}
		break;
	default:
		pDocument->SetFocusAnnot(pAnnot);
		break;
	}

	FX_BOOL bRet = FALSE;

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
	}

	if (pDocument->GetFocusAnnot() == pAnnot)
	{
		FX_BOOL bExit = FALSE;
		FX_BOOL bReset = FALSE;
		OnButtonUp(pWidget, pPageView, bReset, bExit,nFlags);
		if (bExit) return TRUE;
	}
	return bRet;
}

void CFFL_IFormFiller::OnButtonUp(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit,FX_UINT nFlag)
{
	ASSERT(pWidget != NULL);

	if (!m_bNotifying)
	{
		if (pWidget->GetAAction(CPDF_AAction::ButtonUp))
		{
			m_bNotifying = TRUE;
			int nAge = pWidget->GetAppearanceAge();
			int nValueAge = pWidget->GetValueAge();

			ASSERT(pPageView != NULL);
// 			CReader_DocView* pDocView = pPageView->GetDocView();
// 			ASSERT(pDocView != NULL);



			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);

			pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
			m_bNotifying = FALSE;

			if (!IsValidAnnot(pPageView, pWidget))
			{
				bExit = TRUE;
				return;
			}

			if (nAge != pWidget->GetAppearanceAge())
			{
				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
				{
					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
				}

				bReset = TRUE;
			}
		}
	}
}

FX_BOOL	CFFL_IFormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	//change cursor
	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
	{
		return pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, short zDelta, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnRButtonDblClk(pPageView, pAnnot, nFlags, point);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);
	}

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (nChar == FWL_VKEY_Tab) return TRUE;

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		return pFormFiller->OnChar(pAnnot, nChar, nFlags);
	}

	return FALSE;
}

void CFFL_IFormFiller::OnDeSelected(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		pFormFiller->OnDeSelected(pAnnot);
	}
}

void CFFL_IFormFiller::OnSelected(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		pFormFiller->OnSelected(pAnnot);
	}
}

FX_BOOL CFFL_IFormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
{
	if(!pAnnot) return FALSE;
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (!m_bNotifying)
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
 		if (pWidget->GetAAction(CPDF_AAction::GetFocus))
 		{
  			m_bNotifying = TRUE;
			pWidget->GetAppearanceAge();
			int nValueAge = pWidget->GetValueAge();
 			pWidget->ClearAppModified();


 			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
 			ASSERT(pPageView != NULL);

 			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);


 			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, TRUE);
 			if(!pFormFiller) return FALSE;
 			pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);

 			pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
 			m_bNotifying = FALSE;

 //			if (!IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pAnnot)) return FALSE;

 			if (pWidget->IsAppModified())
 			{
 				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
 				{
 					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
 				}
 			}
		}
	}

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
	{
		if (pFormFiller->OnSetFocus(pAnnot, nFlag))
		{
			return TRUE;
		}
		else
			return FALSE;
	}

	return TRUE;
}

FX_BOOL	CFFL_IFormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
{
	if(!pAnnot) return FALSE;
	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
	{
		if (pFormFiller->OnKillFocus(pAnnot, nFlag))
		{
 			if (!m_bNotifying)
 			{
 				CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
 				if (pWidget->GetAAction(CPDF_AAction::LoseFocus))
 				{
 					m_bNotifying = TRUE;
 					pWidget->ClearAppModified();

 					CPDFSDK_PageView* pPageView = pWidget->GetPageView();
 					ASSERT(pPageView != NULL);

 					PDFSDK_FieldAction fa;
					fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 					fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);

 					pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);

 					pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
 					m_bNotifying = FALSE;

 				}
 			}
		}
		else
			return FALSE;
	}

	return TRUE;
}

FX_BOOL	CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget)
{
	return pWidget->IsVisible();
}

FX_BOOL	CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget)
{
	ASSERT(pWidget != NULL);

	int nFieldFlags = pWidget->GetFieldFlags();

	return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
}

FX_BOOL	CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget)
{
	ASSERT(pWidget != NULL);

	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_MODIFY);
 	}
	return TRUE;
}

CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot, FX_BOOL bRegister)
{
// 	ASSERT(pAnnot != NULL);
// 	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");

	CFFL_FormFiller * pFormFiller = NULL;
	m_Maps.Lookup(pAnnot, pFormFiller);

	if (pFormFiller)
		return pFormFiller;

	if (bRegister)
	{
		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;

		int nFieldType = pWidget->GetFieldType();
		switch(nFieldType)
		{
 		case FIELDTYPE_PUSHBUTTON:
 			pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
 			break;
		case FIELDTYPE_CHECKBOX:
			pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
			break;
 		case FIELDTYPE_RADIOBUTTON:
 			pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
 			break;
 		case FIELDTYPE_TEXTFIELD:
			pFormFiller = new CFFL_TextField(m_pApp, pWidget);
			break;
		case FIELDTYPE_LISTBOX:
			pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
			break;
		case FIELDTYPE_COMBOBOX:
			pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
			break;
		case FIELDTYPE_UNKNOWN:
		default:
			pFormFiller = NULL;
			break;
		}

		if (pFormFiller)
		{
			m_Maps.SetAt(pAnnot, pFormFiller);
		}
	}

	return pFormFiller;
}

void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot)
{
	if ( pAnnot != NULL )
	{
		UnRegisterFormFiller( pAnnot );
	}
}

void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot)
{
    CFFL_FormFiller* pFormFiller = nullptr;
    if (m_Maps.Lookup(pAnnot,pFormFiller)) {
        delete pFormFiller;
        m_Maps.RemoveKey(pAnnot);
    }
}

void CFFL_IFormFiller::SetFocusAnnotTab(CPDFSDK_Annot* pWidget, FX_BOOL bSameField, FX_BOOL bNext)
{

}

void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData, FX_FLOAT fPopupMin,FX_FLOAT fPopupMax, int32_t & nRet, FX_FLOAT & fPopupRet)
{
	ASSERT(pPrivateData != NULL);

	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;




	CPDF_Rect rcPageView(0,0,0,0);
	rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
	rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
	rcPageView.Normalize();


	ASSERT(pData->pWidget != NULL);
	CPDF_Rect rcAnnot = pData->pWidget->GetRect();

	FX_FLOAT fTop = 0.0f;
	FX_FLOAT fBottom = 0.0f;

	CPDFSDK_Widget * pWidget = (CPDFSDK_Widget*)pData->pWidget;
	switch (pWidget->GetRotate() / 90)
	{
	default:
	case 0:
		fTop = rcPageView.top - rcAnnot.top;
		fBottom = rcAnnot.bottom - rcPageView.bottom;
		break;
	case 1:
		fTop = rcAnnot.left - rcPageView.left;
		fBottom = rcPageView.right - rcAnnot.right;
		break;
	case 2:
		fTop = rcAnnot.bottom - rcPageView.bottom;
		fBottom = rcPageView.top - rcAnnot.top;
		break;
	case 3:
		fTop = rcPageView.right - rcAnnot.right;
		fBottom = rcAnnot.left - rcPageView.left;
		break;
	}

	FX_FLOAT fFactHeight = 0;
	FX_BOOL bBottom = TRUE;
	FX_FLOAT fMaxListBoxHeight = 0;
	if (fPopupMax > FFL_MAXLISTBOXHEIGHT)
	{
		if (fPopupMin > FFL_MAXLISTBOXHEIGHT)
		{
			fMaxListBoxHeight = fPopupMin;
		}
		else
		{
			fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
		}
	}
	else
		fMaxListBoxHeight = fPopupMax;

	if (fBottom > fMaxListBoxHeight)
	{
		fFactHeight = fMaxListBoxHeight;
		bBottom = TRUE;
	}
	else
	{
		if (fTop > fMaxListBoxHeight)
		{
			fFactHeight = fMaxListBoxHeight;
			bBottom = FALSE;
		}
		else
		{
			if (fTop > fBottom)
			{
				fFactHeight = fTop;
				bBottom = FALSE;
			}
			else
			{
				fFactHeight = fBottom;
				bBottom = TRUE;
			}
		}
	}

	nRet = bBottom ? 0 : 1;
	fPopupRet = fFactHeight;
}

void CFFL_IFormFiller::OnSetWindowRect(void* pPrivateData, const CPDF_Rect & rcWindow)
{
	ASSERT(pPrivateData != NULL);

	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;

	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, TRUE))
	{

		CPDF_Rect rcOld = pFormFiller->PWLtoFFL(pFormFiller->GetWindowRect(pData->pPageView));
		CPDF_Rect rcNew = pFormFiller->PWLtoFFL(rcWindow);
		pFormFiller->SetWindowRect(pData->pPageView, rcWindow);

		CPDF_Rect unRect = rcOld;
		unRect.Union(rcNew);
		//FX_RECT rcRect = unRect.GetOutterRect();
		unRect.left = (FX_FLOAT)(unRect.left - 0.5);
		unRect.right = (FX_FLOAT)(unRect.right + 0.5);
		unRect.top = (FX_FLOAT)(unRect.top + 0.5);
		unRect.bottom = (FX_FLOAT)(unRect.bottom -0.5);
		m_pApp->FFI_Invalidate(pData->pWidget->GetPDFPage(), unRect.left, unRect.top, unRect.right, unRect.bottom);
	}
}

void CFFL_IFormFiller::OnKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, int32_t nKeyCode, CFX_WideString& strChange,
								   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown,
								   FX_BOOL & bRC, FX_BOOL & bExit)
{
	ASSERT(pPrivateData != NULL);
	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
	ASSERT(pData->pWidget != NULL);

	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
	ASSERT(pFormFiller != NULL);

	pFormFiller->OnKeyStroke(bKeyDown);
}

void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bRC, FX_BOOL& bExit, FX_DWORD nFlag)
{
	if (!m_bNotifying)
	{
		ASSERT(pWidget != NULL);
		if (pWidget->GetAAction(CPDF_AAction::KeyStroke))
		{
			m_bNotifying = TRUE;
			pWidget->ClearAppModified();

			ASSERT(pPageView != NULL);
// 			CReader_DocView* pDocView = pPageView->GetDocView();
// 			ASSERT(pDocView != NULL);



			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
			fa.bWillCommit = TRUE;
			fa.bKeyDown = TRUE;
			fa.bRC = TRUE;

			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
			ASSERT(pFormFiller != NULL);

			pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
			pFormFiller->SaveState(pPageView);

			PDFSDK_FieldAction faOld = fa;
			pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);

			bRC = fa.bRC;
//			bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);

			m_bNotifying = FALSE;
		}
	}
}

void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bRC, FX_BOOL& bExit, FX_DWORD nFlag)
{
	if (!m_bNotifying)
	{
		ASSERT(pWidget != NULL);
		if (pWidget->GetAAction(CPDF_AAction::Validate))
		{
			m_bNotifying = TRUE;
			pWidget->ClearAppModified();

			ASSERT(pPageView != NULL);
// 			CReader_DocView* pDocView = pPageView->GetDocView();
// 			ASSERT(pDocView != NULL);



			PDFSDK_FieldAction fa;
			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
			fa.bKeyDown = TRUE;
			fa.bRC = TRUE;

			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
			ASSERT(pFormFiller != NULL);

			pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
			pFormFiller->SaveState(pPageView);

			PDFSDK_FieldAction faOld = fa;
			pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);

			bRC = fa.bRC;
//			bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);

			m_bNotifying = FALSE;
		}
	}
}

void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bExit, FX_DWORD nFlag)
{
	if (!m_bNotifying)
	{
		ASSERT(pWidget != NULL);
		ASSERT(pPageView != NULL);
// 		CReader_DocView* pDocView = pPageView->GetDocView();
// 		ASSERT(pDocView != NULL);
		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
		ASSERT(pDocument != NULL);

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

		pInterForm->OnCalculate(pWidget->GetFormField());

//		bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);

		m_bNotifying = FALSE;
	}
}

void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bExit, FX_DWORD nFlag)
{
	if (!m_bNotifying)
	{
		ASSERT(pWidget != NULL);
		ASSERT(pPageView != NULL);
// 		CReader_DocView* pDocView = pPageView->GetDocView();
// 		ASSERT(pDocView != NULL);
		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
		ASSERT(pDocument != NULL);

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

		FX_BOOL bFormated = FALSE;
		CFX_WideString sValue = pInterForm->OnFormat(pWidget->GetFormField(), bFormated);

//		bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);

		if (bExit) return;

		if (bFormated)
		{
			pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue.c_str(), TRUE);
			pInterForm->UpdateField(pWidget->GetFormField());
		}

		m_bNotifying = FALSE;
	}
}

FX_BOOL	CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
{

	ASSERT(pPageView != NULL);
	ASSERT(pAnnot != NULL);

	if(pPageView)
		return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
	else
		return FALSE;
}

void CFFL_IFormFiller::BeforeUndo(CPDFSDK_Document* pDocument)
{

}

void CFFL_IFormFiller::BeforeRedo(CPDFSDK_Document* pDocument)
{
	BeforeUndo(pDocument);
}

void CFFL_IFormFiller::AfterUndo(CPDFSDK_Document* pDocument)
{
}

void CFFL_IFormFiller::AfterRedo(CPDFSDK_Document* pDocument)
{
}

FX_BOOL	CFFL_IFormFiller::CanCopy(CPDFSDK_Document* pDocument)
{

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::CanCut(CPDFSDK_Document* pDocument)
{

	return FALSE;
}

FX_BOOL	CFFL_IFormFiller::CanPaste(CPDFSDK_Document* pDocument)
{

	return FALSE;
}

void CFFL_IFormFiller::DoCopy(CPDFSDK_Document* pDocument)
{
}

void CFFL_IFormFiller::DoCut(CPDFSDK_Document* pDocument)
{
}

void CFFL_IFormFiller::DoPaste(CPDFSDK_Document* pDocument)
{

}
void CFFL_IFormFiller::OnBeforeKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, int32_t nKeyCode,
											  CFX_WideString & strChange, const CFX_WideString& strChangeEx,
											  int nSelStart, int nSelEnd,
										FX_BOOL bKeyDown, FX_BOOL & bRC, FX_BOOL & bExit, FX_DWORD nFlag)
{
	ASSERT(pPrivateData != NULL);
	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
	ASSERT(pData->pWidget != NULL);

	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
	ASSERT(pFormFiller != NULL);

	if (!m_bNotifying)
	{
		if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke))
		{
			m_bNotifying = TRUE;
			int nAge = pData->pWidget->GetAppearanceAge();
			int nValueAge = pData->pWidget->GetValueAge();

			ASSERT(pData->pPageView != NULL);
			CPDFSDK_Document* pDocument  = pData->pPageView->GetSDKDocument();

			PDFSDK_FieldAction fa;
 			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
			fa.sChange = strChange;
			fa.sChangeEx = strChangeEx;
			fa.bKeyDown = bKeyDown;
			fa.bWillCommit = FALSE;
			fa.bRC = TRUE;
			fa.nSelStart = nSelStart;
			fa.nSelEnd = nSelEnd;


			pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
			pFormFiller->SaveState(pData->pPageView);

			if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pData->pPageView))
			{
				if (!IsValidAnnot(pData->pPageView, pData->pWidget))
				{
					bExit = TRUE;
					m_bNotifying = FALSE;
					return;
				}

				if (nAge != pData->pWidget->GetAppearanceAge())
				{
					CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
					pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
					bExit = TRUE;
				}

				if (fa.bRC)
				{
					pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
					bRC = FALSE;
				}
				else
				{
					pFormFiller->RestoreState(pData->pPageView);
					bRC = FALSE;
				}

				if (pDocument->GetFocusAnnot() != pData->pWidget)
				{
					pFormFiller->CommitData(pData->pPageView,nFlag);
					bExit = TRUE;
				}
			}
			else
			{
				if (!IsValidAnnot(pData->pPageView, pData->pWidget))
				{
					bExit = TRUE;
					m_bNotifying = FALSE;
					return;
				}
			}

			m_bNotifying = FALSE;
		}
	}
}

void	CFFL_IFormFiller::OnAfterKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_BOOL & bExit,FX_DWORD nFlag)
{
	ASSERT(pPrivateData != NULL);
	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
	ASSERT(pData->pWidget != NULL);

	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
	ASSERT(pFormFiller != NULL);

	if (!bEditOrList)
		pFormFiller->OnKeyStroke(bExit);
}
