// 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/FormFiller.h"
#include "../../include/formfiller/FFL_FormFiller.h"
#include "../../include/formfiller/FFL_Notify.h"
// #include "../../include/formfiller/FFL_ComboBox.h"
// #include "../../include/formfiller/FFL_Module.h"

/* -------------------------------- CFFL_Notify ------------------------------ */

//#pragma warning(disable: 4800)

CFFL_Notify::CFFL_Notify(CFFL_FormFiller * pFormFiller) : 
	m_pFormFiller(pFormFiller),
	m_bDoActioning(FALSE),
	m_nNotifyFlag(0)
{
	ASSERT(m_pFormFiller != NULL);
}

CFFL_Notify::~CFFL_Notify()
{
}

void CFFL_Notify::BeforeNotify()
{
	m_nNotifyFlag ++;
}


void CFFL_Notify::AfterNotify()
{
	m_nNotifyFlag --;
}

FX_BOOL CFFL_Notify::OnMouseUp(FX_BOOL & bExit)
{
	BeforeNotify();
	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::ButtonUp, bExit);
	AfterNotify();
	return bRet;
}

FX_BOOL CFFL_Notify::OnMouseDown(FX_BOOL & bExit)
{
	BeforeNotify();
	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::ButtonDown, bExit);
	AfterNotify();
	return bRet;
}

FX_BOOL CFFL_Notify::OnMouseEnter(FX_BOOL & bExit)
{
	BeforeNotify();
	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::CursorEnter, bExit);
	AfterNotify();
	return bRet;
}

FX_BOOL CFFL_Notify::OnMouseExit(FX_BOOL & bExit)
{
	BeforeNotify();
	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::CursorExit, bExit);
	AfterNotify();
	return bRet;
}

FX_BOOL CFFL_Notify::OnSetFocus(FX_BOOL & bExit)
{
	BeforeNotify();
	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::GetFocus, bExit);
	AfterNotify();
	return bRet;
}

FX_BOOL CFFL_Notify::OnKillFocus(FX_BOOL & bExit)
{
	BeforeNotify();
	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::LoseFocus, bExit);
	AfterNotify();
	return bRet;
}

FX_BOOL CFFL_Notify::OnCalculate()
{
	return TRUE;
}

FX_BOOL CFFL_Notify::OnFormat(int iCommitKey)
{
	return TRUE;
}

FX_BOOL CFFL_Notify::OnKeyStroke(CPDF_FormField* pFormField, int nCommitKey, CFX_WideString& strValue, CFX_WideString& strChange, 
							   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL bModifier,
							   FX_BOOL bShift, FX_BOOL bWillCommit, FX_BOOL bFieldFull, 
							   int& nSelStart, int& nSelEnd, FX_BOOL& bRC)
{
	return TRUE;
}

FX_BOOL CFFL_Notify::OnValidate(CPDF_FormField* pFormField, CFX_WideString& strValue, CFX_WideString & strChange, 
									   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL bModifier,
									   FX_BOOL bShift, FX_BOOL & bRC)
{
	return TRUE;
}

FX_BOOL	CFFL_Notify::DoAAction(CPDF_AAction::AActionType eAAT, FX_BOOL & bExit)
{
	if (this->m_bDoActioning) return FALSE;
	
	CPDF_Action action;
	if (!FindAAction(eAAT,action)) return FALSE;

	this->m_bDoActioning = TRUE;	
	ExecuteActionTree(eAAT,action,bExit);	
	this->m_bDoActioning = FALSE;
	return TRUE;
}

FX_BOOL	CFFL_Notify::ExecuteActionTree(CPDF_AAction::AActionType eAAT,CPDF_Action & action, FX_BOOL& bExit)
{
	if (!ExecuteAction(eAAT,action,bExit)) return FALSE;
	if (bExit) return TRUE;

	for (FX_INT32 i=0,sz=action.GetSubActionsCount(); i<sz; i++)
	{
		CPDF_Action subaction = action.GetSubAction(i);
		if (!ExecuteActionTree(eAAT,subaction,bExit)) return FALSE;
		if (bExit) break;
	}

	return TRUE;
}


FX_BOOL	CFFL_Notify::FindAAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action)
{
	return FALSE;
}

FX_BOOL CFFL_Notify::FindAAction(CPDF_AAction aaction,CPDF_AAction::AActionType eAAT,CPDF_Action & action)
{
	CPDF_Action MyAction;

	if (aaction.ActionExist(eAAT))
	{
		MyAction = aaction.GetAction(eAAT);
	}
	else
		return FALSE;


	if (MyAction.GetType() == CPDF_Action::Unknown)
		return FALSE;

	action = MyAction;

	return TRUE;
}

FX_BOOL	CFFL_Notify::ExecuteAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action,FX_BOOL& bExit)
{
	return FALSE;
}
//#pragma warning(default: 4800)

