// 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_bDoActioning(FALSE),
	m_nNotifyFlag(0)
{
	ASSERT(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)

