// 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

#ifndef FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
#define FPDFSDK_INCLUDE_FSDK_BASEFORM_H_

#if _FX_OS_ == _FX_ANDROID_
#include "time.h"
#else
#include <ctime>
#endif

#include "../../core/include/fpdfapi/fpdf_parser.h"
#include "../../core/include/fpdfdoc/fpdf_doc.h"
#include "../../core/include/fxcrt/fx_basic.h"
#include "../../core/include/fxge/fx_dib.h"
#include "fsdk_baseannot.h"

class CFFL_FormFiller;
class CPDFSDK_Annot;
class CPDFSDK_DateTime;
class CPDFSDK_Document;
class CPDFSDK_InterForm;
class CPDFSDK_PageView;
class CPDF_Action;
class CPDF_FormField;
struct CPWL_Color;

typedef struct _PDFSDK_FieldAction
{
	_PDFSDK_FieldAction()
	{
		bModifier = FALSE;
		bShift = FALSE;
		nCommitKey = 0;
		bKeyDown = FALSE;
		nSelEnd = nSelStart = 0;
		bWillCommit = FALSE;
		bFieldFull = FALSE;
		bRC = TRUE;
	}

	FX_BOOL					bModifier;		//in
	FX_BOOL					bShift;			//in
	int						nCommitKey;		//in
	CFX_WideString			sChange;		//in[out]
	CFX_WideString			sChangeEx;		//in
	FX_BOOL					bKeyDown;		//in
	int						nSelEnd;		//in[out]
	int						nSelStart;		//in[out]
	CFX_WideString			sValue;			//in[out]
	FX_BOOL					bWillCommit;	//in
	FX_BOOL					bFieldFull;		//in
	FX_BOOL					bRC;			//in[out]
}PDFSDK_FieldAction;
class CPDFSDK_Widget : public CPDFSDK_Annot
{
public:
	CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm);
	virtual ~CPDFSDK_Widget();

	virtual CFX_ByteString			GetSubType() const;

	virtual CPDF_Action				GetAAction(CPDF_AAction::AActionType eAAT);

	int								GetFieldType() const;
	//define layout order to 2.
	virtual int						GetLayoutOrder() const {return 2;}
	/*
	FIELDFLAG_READONLY
	FIELDFLAG_REQUIRED
	FIELDFLAG_NOEXPORT
	*/

	int								GetFieldFlags() const;
	int								GetRotate() const;

	FX_BOOL							GetFillColor(FX_COLORREF& color) const;
	FX_BOOL							GetBorderColor(FX_COLORREF& color) const;
	FX_BOOL							GetTextColor(FX_COLORREF& color) const;
	FX_FLOAT						GetFontSize() const;

	int								GetSelectedIndex(int nIndex) const;
	CFX_WideString					GetValue() const;
	CFX_WideString					GetDefaultValue() const;
	CFX_WideString					GetOptionLabel(int nIndex) const;
	int								CountOptions() const;
	FX_BOOL							IsOptionSelected(int nIndex) const;
	int								GetTopVisibleIndex() const;
	FX_BOOL							IsChecked() const;
	/*
	BF_ALIGN_LEFT
	BF_ALIGN_MIDDL
	BF_ALIGN_RIGHT
	*/
	int								GetAlignment() const;
	int								GetMaxLen() const;
	CFX_WideString					GetAlternateName() const;

//Set Properties.
	void							SetCheck(FX_BOOL bChecked, FX_BOOL bNotify);
	void							SetValue(const CFX_WideString& sValue, FX_BOOL bNotify);
	void							SetDefaultValue(const CFX_WideString& sValue);
	void							SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify);
	void							ClearSelection(FX_BOOL bNotify);
	void							SetTopVisibleIndex(int index);

	void							ResetAppearance(const FX_WCHAR* sValue, FX_BOOL bValueChanged);
	void							ResetFieldAppearance(FX_BOOL bValueChanged);
	void							UpdateField();
	CFX_WideString					OnFormat(FX_BOOL& bFormated);

//Message.
 	FX_BOOL							OnAAction(CPDF_AAction::AActionType type, PDFSDK_FieldAction& data,
												CPDFSDK_PageView* pPageView);

	CPDFSDK_InterForm*				GetInterForm() const {return m_pInterForm;}
	CPDF_FormField*					GetFormField() const;
	CPDF_FormControl*				GetFormControl() const;
	static CPDF_FormControl*		GetFormControl(CPDF_InterForm* pInterForm, CPDF_Dictionary* pAnnotDict);

	void							DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView);

	void							SetAppModified();
	void							ClearAppModified();
	FX_BOOL							IsAppModified() const;

	int32_t						GetAppearanceAge() const;
	int32_t						GetValueAge() const;

private:
	void							ResetAppearance_PushButton();
	void							ResetAppearance_CheckBox();
	void							ResetAppearance_RadioButton();
	void							ResetAppearance_ComboBox(const FX_WCHAR* sValue);
	void							ResetAppearance_ListBox();
	void							ResetAppearance_TextField(const FX_WCHAR* sValue);

	CPDF_Rect						GetClientRect() const;
	CPDF_Rect						GetRotatedRect() const;

	CFX_ByteString					GetBackgroundAppStream() const;
	CFX_ByteString					GetBorderAppStream() const;
	CPDF_Matrix						GetMatrix() const;

	CPWL_Color						GetTextPWLColor() const;
	CPWL_Color						GetBorderPWLColor() const;
	CPWL_Color						GetFillPWLColor() const;

	void							AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
	void							RemoveAppearance(const CFX_ByteString& sAPType);
public:
	FX_BOOL							IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode);
	void							DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
		CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions);
public:
	FX_BOOL							HitTest(FX_FLOAT pageX, FX_FLOAT pageY);
private:
	CPDFSDK_InterForm*				m_pInterForm;
	FX_BOOL							m_bAppModified;
	int32_t						m_nAppAge;
	int32_t						m_nValueAge;
};

#define CPDFSDK_WidgetMap				CFX_MapPtrTemplate<CPDF_FormControl*, CPDFSDK_Widget*>

class CPDFSDK_InterForm : public CPDF_FormNotify
{
public:
	explicit CPDFSDK_InterForm(CPDFSDK_Document* pDocument);
	~CPDFSDK_InterForm() override;

	CPDF_InterForm* GetInterForm() const { return m_pInterForm; }
	CPDFSDK_Document* GetDocument() const { return m_pDocument; }

	FX_BOOL							HighlightWidgets();

	CPDFSDK_Widget*					GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const;
	CPDFSDK_Widget*					GetWidget(CPDF_FormControl* pControl) const;
	void							GetWidgets(const CFX_WideString& sFieldName, CFX_PtrArray& widgets);
	void							GetWidgets(CPDF_FormField* pField, CFX_PtrArray& widgets);

	void							AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget);
	void							RemoveMap(CPDF_FormControl* pControl);

	void							EnableCalculate(FX_BOOL bEnabled);
	FX_BOOL							IsCalculateEnabled() const;

#ifdef _WIN32
	CPDF_Stream*					LoadImageFromFile(const CFX_WideString& sFile);
#endif

	void							OnKeyStrokeCommit(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC);
	void							OnValidate(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC);
	void							OnCalculate(CPDF_FormField* pFormField = NULL);
	CFX_WideString					OnFormat(CPDF_FormField* pFormField, FX_BOOL& bFormated);

	void							ResetFieldAppearance(CPDF_FormField* pFormField, const FX_WCHAR* sValue, FX_BOOL bValueChanged);
	void							UpdateField(CPDF_FormField* pFormField);

public:
	FX_BOOL							DoAction_Hide(const CPDF_Action& action);
	FX_BOOL							DoAction_SubmitForm(const CPDF_Action& action);
	FX_BOOL							DoAction_ResetForm(const CPDF_Action& action);
	FX_BOOL							DoAction_ImportData(const CPDF_Action& action);

	void							GetFieldFromObjects(const CFX_PtrArray& objects, CFX_PtrArray& fields);
	FX_BOOL							IsValidField(CPDF_Dictionary* pFieldDict);
	FX_BOOL							SubmitFields(const CFX_WideString& csDestination, const CFX_PtrArray& fields,
		FX_BOOL bIncludeOrExclude, FX_BOOL bUrlEncoded);
	FX_BOOL							SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded);
	FX_BOOL							ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf);
	FX_BOOL							ExportFieldsToFDFTextBuf(const CFX_PtrArray& fields,FX_BOOL bIncludeOrExclude, CFX_ByteTextBuf& textBuf);
	CFX_WideString					GetTemporaryFileName(const CFX_WideString& sFileExt);

private:
	virtual int						BeforeValueChange(const CPDF_FormField* pField, CFX_WideString& csValue);
	virtual int						AfterValueChange(const CPDF_FormField* pField);
	virtual int						BeforeSelectionChange(const CPDF_FormField* pField, CFX_WideString& csValue);
	virtual int						AfterSelectionChange(const CPDF_FormField* pField);
	virtual int						AfterCheckedStatusChange(const CPDF_FormField* pField, const CFX_ByteArray& statusArray);
	virtual int						BeforeFormReset(const CPDF_InterForm* pForm);
	virtual int						AfterFormReset(const CPDF_InterForm* pForm);
	virtual int						BeforeFormImportData(const CPDF_InterForm* pForm);
	virtual int						AfterFormImportData(const CPDF_InterForm* pForm);

private:
	FX_BOOL							FDFToURLEncodedData(CFX_WideString csFDFFile, CFX_WideString csTxtFile);
	FX_BOOL							FDFToURLEncodedData(uint8_t*& pBuf, FX_STRSIZE& nBufSize);
	int								GetPageIndexByAnnotDict(CPDF_Document* pDocument, CPDF_Dictionary* pAnnotDict) const;
	void							DoFDFBuffer(CFX_ByteString sBuffer);

private:
	CPDFSDK_Document*				m_pDocument;
	CPDF_InterForm*					m_pInterForm;
	CPDFSDK_WidgetMap				m_Map;
	FX_BOOL							m_bCalculate;
	FX_BOOL							m_bBusy;

public:
	FX_BOOL IsNeedHighLight(int nFieldType);
	void    RemoveAllHighLight();
	void    SetHighlightAlpha(uint8_t alpha) {m_iHighlightAlpha = alpha;}
	uint8_t GetHighlightAlpha() {return m_iHighlightAlpha;}
	void    SetHighlightColor(FX_COLORREF clr, int nFieldType);
	FX_COLORREF GetHighlightColor(int nFieldType);
private:
	FX_COLORREF m_aHighlightColor[6];
	uint8_t m_iHighlightAlpha;
	FX_BOOL	m_bNeedHightlight[6];
};

#define BAI_STRUCTURE		0
#define BAI_ROW				1
#define BAI_COLUMN			2

#define CPDFSDK_Annots				CFX_ArrayTemplate<CPDFSDK_Annot*>
#define CPDFSDK_SortAnnots			CGW_ArrayTemplate<CPDFSDK_Annot*>
class CBA_AnnotIterator
{
public:
	CBA_AnnotIterator(CPDFSDK_PageView* pPageView, const CFX_ByteString& sType, const CFX_ByteString& sSubType);
	~CBA_AnnotIterator();

	CPDFSDK_Annot*				GetFirstAnnot();
	CPDFSDK_Annot*				GetLastAnnot();
	CPDFSDK_Annot*				GetNextAnnot(CPDFSDK_Annot* pAnnot);
	CPDFSDK_Annot*				GetPrevAnnot(CPDFSDK_Annot* pAnnot);

private:
	void								GenerateResults();
	static int							CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2);
	static int							CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2);
	static CPDF_Rect					GetAnnotRect(CPDFSDK_Annot* pAnnot);

	CPDFSDK_PageView*					m_pPageView;
	CFX_ByteString						m_sType;
	CFX_ByteString						m_sSubType;
	int									m_nTabs;
	CPDFSDK_Annots						m_Annots;
};

#endif  // FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
