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