// 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_BASEANNOT_H_
#define FPDFSDK_INCLUDE_FSDK_BASEANNOT_H_

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

#include "../../core/include/fpdfdoc/fpdf_doc.h"
#include "../../core/include/fxcrt/fx_basic.h"
#include "fx_systemhandler.h"

class CPDFSDK_PageView;
class CPDF_Annot;
class CPDF_Page;
class CPDF_Rect;
class CPDF_Matrix;
class CPDF_RenderOptions;
class CFX_RenderDevice;

#define CFX_IntArray				CFX_ArrayTemplate<int>

class  CPDFSDK_DateTime
{
public:
	CPDFSDK_DateTime();
	CPDFSDK_DateTime(const CFX_ByteString& dtStr);
	CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime);
	CPDFSDK_DateTime(const FX_SYSTEMTIME& st);


	CPDFSDK_DateTime&	operator = (const CPDFSDK_DateTime& datetime);
	CPDFSDK_DateTime&	operator = (const FX_SYSTEMTIME& st);
	FX_BOOL				operator == (CPDFSDK_DateTime& datetime);
	FX_BOOL				operator != (CPDFSDK_DateTime& datetime);
	FX_BOOL				operator > (CPDFSDK_DateTime& datetime);
	FX_BOOL				operator >= (CPDFSDK_DateTime& datetime);
	FX_BOOL				operator < (CPDFSDK_DateTime& datetime);
	FX_BOOL				operator <= (CPDFSDK_DateTime& datetime);
						operator time_t();

	CPDFSDK_DateTime&	FromPDFDateTimeString(const CFX_ByteString& dtStr);
	CFX_ByteString		ToCommonDateTimeString();
	CFX_ByteString		ToPDFDateTimeString();
	void				ToSystemTime(FX_SYSTEMTIME& st);
	CPDFSDK_DateTime	ToGMT();
	CPDFSDK_DateTime&	AddDays(short days);
	CPDFSDK_DateTime&	AddSeconds(int seconds);

	void				ResetDateTime();

	struct FX_DATETIME
	{
		int16_t	year;
		uint8_t		month;
		uint8_t		day;
		uint8_t		hour;
		uint8_t		minute;
		uint8_t		second;
		int8_t 	tzHour;
		uint8_t		tzMinute;
	}dt;
};

class CPDFSDK_Annot
{
public:
	CPDFSDK_Annot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
	virtual ~CPDFSDK_Annot();
public:
	virtual FX_FLOAT			GetMinWidth() const;
	virtual FX_FLOAT			GetMinHeight() const;
	//define layout order to 5.
	virtual int					GetLayoutOrder() const { return 5; }

public:
	CPDF_Annot*					GetPDFAnnot();

	void						SetPage(CPDFSDK_PageView* pPageView);
	CPDFSDK_PageView*			GetPageView();
	FX_DWORD					GetFlags();

	// Tab Order
	int							GetTabOrder();
	void						SetTabOrder(int iTabOrder);

	// Selection
	FX_BOOL						IsSelected();
	void						SetSelected(FX_BOOL bSelected);

	CFX_ByteString				GetType() const;
	virtual CFX_ByteString		GetSubType() const;

	CPDF_Page*					GetPDFPage();

public:
	CPDF_Dictionary*			GetAnnotDict() const;

	void						SetRect(const CPDF_Rect& rect);
	CPDF_Rect					GetRect() const;

	void						SetContents(const CFX_WideString& sContents);
	CFX_WideString				GetContents() const;

	void						SetAnnotName(const CFX_WideString& sName);
	CFX_WideString				GetAnnotName() const;

	void						SetModifiedDate(const FX_SYSTEMTIME& st);
	FX_SYSTEMTIME				GetModifiedDate() const;

	void						SetFlags(int nFlags);
	int							GetFlags() const;

	void						SetAppState(const CFX_ByteString& str);
	CFX_ByteString				GetAppState() const;

	void						SetStructParent(int key);
	int							GetStructParent() const;

	//border
	void						SetBorderWidth(int nWidth);
	int							GetBorderWidth() const;

	//BBS_SOLID
	//BBS_DASH
	//BBS_BEVELED
	//BBS_INSET
	//BBS_UNDERLINE

	void						SetBorderStyle(int nStyle);
	int							GetBorderStyle() const;

	void						SetBorderDash(const CFX_IntArray& array);
	void						GetBorderDash(CFX_IntArray& array) const;

	//The background of the annotation's icon when closed
	//The title bar of the annotation's pop-up window
	//The border of a link annotation

	void						SetColor(FX_COLORREF color);
	void						RemoveColor();
	FX_BOOL						GetColor(FX_COLORREF& color) const;

	FX_BOOL						IsVisible() const;
	//action

	CPDF_Action					GetAction() const;
	void						SetAction(const CPDF_Action& a);
	void						RemoveAction();

	CPDF_AAction				GetAAction() const;
	void						SetAAction(const CPDF_AAction& aa);
	void						RemoveAAction();

	virtual CPDF_Action			GetAAction(CPDF_AAction::AActionType eAAT);

public:
	FX_BOOL						IsAppearanceValid();
	FX_BOOL						IsAppearanceValid(CPDF_Annot::AppearanceMode mode);
	void						DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
		CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions);
	void						DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
		const CPDF_RenderOptions* pOptions);

	void						ClearCachedAP();

	void						WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox,
		const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
		const CFX_ByteString& sAPState = "");

public:
	virtual void			Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions);
public:


private:
	FX_BOOL CreateFormFiller();
protected:
	CPDF_Annot*			m_pAnnot;
	CPDFSDK_PageView*	m_pPageView;
	FX_BOOL				m_bSelected;
	int					m_nTabOrder;

};

#endif  // FPDFSDK_INCLUDE_FSDK_BASEANNOT_H_
