// 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 _FSDK_BASEANNOT_H_
#define _FSDK_BASEANNOT_H_

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

class CPDFSDK_PageView;
#define CFX_IntArray				CFX_ArrayTemplate<int>

class  CPDFSDK_DateTime : public CFX_Object
{
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
	{
		FX_SHORT	year;
		FX_BYTE		month;
		FX_BYTE		day;
		FX_BYTE		hour;
		FX_BYTE		minute;
		FX_BYTE		second;
		FX_INT8 	tzHour;
		FX_BYTE		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

