// 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/fsdk_define.h"
#include "../include/fsdk_mgr.h"
#include "../include/fsdk_baseannot.h"


//---------------------------------------------------------------------------
//								CPDFSDK_DateTime	
//---------------------------------------------------------------------------
int _gAfxGetTimeZoneInSeconds(FX_CHAR tzhour, FX_BYTE tzminute)
{
	return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
}

FX_BOOL _gAfxIsLeapYear(FX_SHORT year)
{
	return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
}

FX_WORD _gAfxGetYearDays(FX_SHORT year)
{
	return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365);
}

FX_BYTE _gAfxGetMonthDays(FX_SHORT year, FX_BYTE month)
{
	FX_BYTE	mDays;
	switch (month)
	{
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		mDays = 31;
		break;

	case 4:
	case 6:
	case 9:
	case 11:
		mDays = 30;
		break;

	case 2:
		if (_gAfxIsLeapYear(year) == TRUE)
			mDays = 29;
		else
			mDays = 28;
		break;

	default:
		mDays = 0;
		break;
	}

	return mDays;
}

CPDFSDK_DateTime::CPDFSDK_DateTime()
{
	ResetDateTime();
}

CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr)
{
	ResetDateTime();

	FromPDFDateTimeString(dtStr);
}

CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime)
{
	operator = (datetime);
}

CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st)
{
	operator = (st) ;
}


void CPDFSDK_DateTime::ResetDateTime()
{
	tzset();

	time_t	curTime;
	time(&curTime);
	struct tm* newtime;
	//newtime = gmtime(&curTime);
	newtime = localtime(&curTime);

	dt.year = newtime->tm_year + 1900;
	dt.month = newtime->tm_mon + 1;
	dt.day = newtime->tm_mday;
	dt.hour = newtime->tm_hour;
	dt.minute = newtime->tm_min;
	dt.second = newtime->tm_sec;
// 	dt.tzHour = _timezone / 3600 * -1;
// 	dt.tzMinute = (abs(_timezone) % 3600) / 60;
}

CPDFSDK_DateTime& CPDFSDK_DateTime::operator = (const CPDFSDK_DateTime& datetime)
{
	FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
	return *this;
}

CPDFSDK_DateTime& CPDFSDK_DateTime::operator = (const FX_SYSTEMTIME& st)
{
	tzset();

	dt.year = (FX_SHORT)st.wYear;
	dt.month = (FX_BYTE)st.wMonth;
	dt.day = (FX_BYTE)st.wDay;
	dt.hour = (FX_BYTE)st.wHour;
	dt.minute = (FX_BYTE)st.wMinute;
	dt.second = (FX_BYTE)st.wSecond;
// 	dt.tzHour = _timezone / 3600 * -1;
// 	dt.tzMinute = (abs(_timezone) % 3600) / 60;
	return *this;
}

FX_BOOL CPDFSDK_DateTime::operator == (CPDFSDK_DateTime& datetime)
{
	return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
}

FX_BOOL CPDFSDK_DateTime::operator != (CPDFSDK_DateTime& datetime)
{
	return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) != 0);
}

FX_BOOL CPDFSDK_DateTime::operator > (CPDFSDK_DateTime& datetime)
{
	CPDFSDK_DateTime dt1 = ToGMT();
	CPDFSDK_DateTime dt2 = datetime.ToGMT();
	int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
	int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second;
	int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
	int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second;

	if (d1 > d3) return TRUE;
	if (d2 > d4) return TRUE;
	return FALSE;
}

FX_BOOL CPDFSDK_DateTime::operator >= (CPDFSDK_DateTime& datetime)
{
	CPDFSDK_DateTime dt1 = ToGMT();
	CPDFSDK_DateTime dt2 = datetime.ToGMT();
	int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
	int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second;
	int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
	int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second;

	if (d1 >= d3) return TRUE;
	if (d2 >= d4) return TRUE;
	return FALSE;
}

FX_BOOL CPDFSDK_DateTime::operator < (CPDFSDK_DateTime& datetime)
{
	CPDFSDK_DateTime dt1 = ToGMT();
	CPDFSDK_DateTime dt2 = datetime.ToGMT();
	int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
	int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second;
	int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
	int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second;

	if (d1 < d3) return TRUE;
	if (d2 < d4) return TRUE;
	return FALSE;
}

FX_BOOL CPDFSDK_DateTime::operator <= (CPDFSDK_DateTime& datetime)
{
	CPDFSDK_DateTime dt1 = ToGMT();
	CPDFSDK_DateTime dt2 = datetime.ToGMT();
	int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
	int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second;
	int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
	int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second;

	if (d1 <= d3) return TRUE;
	if (d2 <= d4) return TRUE;
	return FALSE;
}

CPDFSDK_DateTime::operator time_t()
{
	struct tm newtime;

	newtime.tm_year = dt.year - 1900;
	newtime.tm_mon = dt.month - 1;
	newtime.tm_mday = dt.day;
	newtime.tm_hour = dt.hour;
	newtime.tm_min = dt.minute;
	newtime.tm_sec = dt.second;

	return mktime(&newtime);
}

CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(const CFX_ByteString& dtStr)
{
	int strLength = dtStr.GetLength();
	if (strLength > 0)
	{
		int i = 0;
		int j, k;
		FX_CHAR ch;
		while (i < strLength)
		{
			ch = dtStr[i];
			if (ch >= '0' && ch <= '9') break;
			i ++;
		}
		if (i >= strLength) return *this;

		j = 0;
		k = 0;
		while (i < strLength && j < 4)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.year = (FX_SHORT)k;
		if (i >= strLength || j < 4) return *this;

		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.month = (FX_BYTE)k;
		if (i >= strLength || j < 2) return *this;

		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.day = (FX_BYTE)k;
		if (i >= strLength || j < 2) return *this;

		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.hour = (FX_BYTE)k;
		if (i >= strLength || j < 2) return *this;

		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.minute = (FX_BYTE)k;
		if (i >= strLength || j < 2) return *this;

		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.second = (FX_BYTE)k;
		if (i >= strLength || j < 2) return *this;

		ch = dtStr[i ++];
		if (ch != '-' && ch != '+') return *this;
		if (ch == '-')
			dt.tzHour = -1;
		else
			dt.tzHour = 1;
		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.tzHour *= (FX_CHAR)k;
		if (i >= strLength || j < 2) return *this;

		ch = dtStr[i ++];
		if (ch != '\'') return *this;
		j = 0;
		k = 0;
		while (i < strLength && j < 2)
		{
			ch = dtStr[i];
			k = k * 10 + ch - '0';
			j ++;
			if (ch < '0' || ch > '9') break;
			i ++;
		}
		dt.tzMinute = (FX_BYTE)k;
		if (i >= strLength || j < 2) return *this;
	}

	return  *this;
}

CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString()
{
	CFX_ByteString str1;
	str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
	if (dt.tzHour < 0)
		str1 += "-";
	else
		str1 += "+";
	CFX_ByteString str2;
	str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
	return str1 + str2;
}

CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString()
{
	CFX_ByteString dtStr;
	char tempStr[32];
	sprintf(tempStr, "D:%04d%02d%02d%02d%02d%02d", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
	dtStr = CFX_ByteString(tempStr);
	if (dt.tzHour < 0)
		dtStr += CFX_ByteString("-");
	else
		dtStr += CFX_ByteString("+");
	sprintf(tempStr, "%02d'%02d'", abs(dt.tzHour), dt.tzMinute);
	dtStr += CFX_ByteString(tempStr);
	return dtStr;
}

void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st)
{
	CPDFSDK_DateTime dt = *this;
	time_t t = (time_t)dt;
	struct tm* pTime = localtime(&t);
	if(pTime){ 
		st.wYear = (FX_WORD)pTime->tm_year + 1900;
		st.wMonth = (FX_WORD)pTime->tm_mon + 1;
		st.wDay = (FX_WORD)pTime->tm_mday;
		st.wDayOfWeek = (FX_WORD)pTime->tm_wday;
		st.wHour = (FX_WORD)pTime->tm_hour;
		st.wMinute = (FX_WORD)pTime->tm_min;
		st.wSecond = (FX_WORD)pTime->tm_sec;
		st.wMilliseconds = 0;
	}
}

CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT()
{
	CPDFSDK_DateTime dt = *this;
	dt.AddSeconds(-_gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
	dt.dt.tzHour = 0;
	dt.dt.tzMinute = 0;
	return dt;
}

CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days)
{
	if (days == 0) return *this;

	FX_SHORT	y = dt.year, yy;
	FX_BYTE		m = dt.month;
	FX_BYTE		d = dt.day;
	int			mdays, ydays, ldays;

	ldays = days;
	if (ldays > 0)
	{
		yy = y;
		if (((FX_WORD)m * 100 + d) > 300) yy ++;
		ydays = _gAfxGetYearDays(yy);
		while (ldays >= ydays)
		{
			y ++;
			ldays -= ydays;
			yy ++;
			mdays = _gAfxGetMonthDays(y, m);
			if (d > mdays)
			{
				m ++;
				d -= mdays;
			}
			ydays = _gAfxGetYearDays(yy);
		}
		mdays = _gAfxGetMonthDays(y, m) - d + 1;
		while (ldays >= mdays)
		{
			ldays -= mdays;
			m ++;
			d = 1;
			mdays = _gAfxGetMonthDays(y, m);
		}
		d += ldays;
	}
	else
	{
		ldays *= -1;
		yy = y;
		if (((FX_WORD)m * 100 + d) < 300) yy --;
		ydays = _gAfxGetYearDays(yy);
		while (ldays >= ydays)
		{
			y --;
			ldays -= ydays;
			yy --;
			mdays = _gAfxGetMonthDays(y, m);
			if (d > mdays)
			{
				m ++;
				d -= mdays;
			}
			ydays = _gAfxGetYearDays(yy);
		}
		while (ldays >= d)
		{
			ldays -= d;
			m --;
			mdays = _gAfxGetMonthDays(y, m);
			d = mdays;
		}
		d -= ldays;
	}

	dt.year = y;
	dt.month = m;
	dt.day = d;

	return *this;
}

CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds)
{
	if (seconds == 0) return *this;

	int	n;
	int	days;

	n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
	if (n < 0)
	{
		days = (n - 86399) / 86400;
		n -= days * 86400;
	}
	else
	{
		days = n / 86400;
		n %= 86400;
	}
	dt.hour = (FX_BYTE)(n / 3600);
	dt.hour %= 24;
	n %= 3600;
	dt.minute = (FX_BYTE)(n / 60);
	dt.second = (FX_BYTE)(n % 60);
	if (days != 0) AddDays(days);

	return *this;
}


//---------------------------------------------------------------------------
//								CPDFSDK_Annot	
//---------------------------------------------------------------------------
CPDFSDK_Annot::CPDFSDK_Annot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView) :
m_pAnnot(pAnnot),
m_pPageView(pPageView),
m_bSelected(FALSE),
m_nTabOrder(-1)
{
}

CPDFSDK_Annot::~CPDFSDK_Annot()
{
	m_pAnnot = NULL;
	m_pPageView = NULL;
}

CPDF_Annot*	CPDFSDK_Annot::GetPDFAnnot()
{
	return m_pAnnot;
}

FX_DWORD CPDFSDK_Annot::GetFlags()
{
	ASSERT(m_pAnnot != NULL);
	
	return m_pAnnot->GetFlags();
}

void CPDFSDK_Annot::SetPage(CPDFSDK_PageView* pPageView)
{
	m_pPageView = pPageView;
}

CPDFSDK_PageView* CPDFSDK_Annot::GetPageView()
{
	return m_pPageView;
}

FX_BOOL CPDFSDK_Annot::IsSelected()
{
	return m_bSelected;
}

void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected)
{
	m_bSelected = bSelected;
}

// Tab Order	
int CPDFSDK_Annot::GetTabOrder()
{
	return m_nTabOrder;
}

void CPDFSDK_Annot::SetTabOrder(int iTabOrder)
{
	m_nTabOrder = iTabOrder;
}

CPDF_Dictionary* CPDFSDK_Annot::GetAnnotDict() const
{
	ASSERT(m_pAnnot != NULL);
	
	return m_pAnnot->m_pAnnotDict;
}

void CPDFSDK_Annot::SetRect(const CPDF_Rect& rect)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	ASSERT(rect.right - rect.left >= GetMinWidth());
	ASSERT(rect.top - rect.bottom >= GetMinHeight());
	
	m_pAnnot->m_pAnnotDict->SetAtRect("Rect", rect);
}

CPDF_Rect CPDFSDK_Annot::GetRect() const
{
	ASSERT(m_pAnnot != NULL);
	
	CPDF_Rect rect;
	m_pAnnot->GetRect(rect);
	
	return rect;
}

CFX_ByteString CPDFSDK_Annot::GetType() const
{
	ASSERT(m_pAnnot != NULL);
	
	return m_pAnnot->GetSubType();
}

CFX_ByteString CPDFSDK_Annot::GetSubType() const
{
	return "";
}

void CPDFSDK_Annot::ResetAppearance()
{
	ASSERT(FALSE);
}

void CPDFSDK_Annot::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
								   CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions)	
{
	ASSERT(m_pPageView != NULL);
	ASSERT(m_pAnnot != NULL);
	
	m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, mode, pOptions);
}

FX_BOOL	CPDFSDK_Annot::IsAppearanceValid()
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetDict("AP") != NULL;
}

FX_BOOL	CPDFSDK_Annot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	CPDF_Dictionary* pAP = m_pAnnot->m_pAnnotDict->GetDict("AP");
	if (pAP == NULL) return FALSE;
	
	// Choose the right sub-ap
	const FX_CHAR* ap_entry = "N";
	if (mode == CPDF_Annot::Down)
		ap_entry = "D";
	else if (mode == CPDF_Annot::Rollover)
		ap_entry = "R";
	if (!pAP->KeyExist(ap_entry))
		ap_entry = "N";
	
	// Get the AP stream or subdirectory
	CPDF_Object* psub = pAP->GetElementValue(ap_entry);
	if (psub == NULL) return FALSE;
	
	return TRUE;
}

void CPDFSDK_Annot::DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
						   const CPDF_RenderOptions* pOptions)
{
	ASSERT(m_pAnnot != NULL);
	m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions); 
}

void CPDFSDK_Annot::ClearCachedAP()
{
	ASSERT(m_pAnnot != NULL);
	m_pAnnot->ClearCachedAP();
}    

void CPDFSDK_Annot::SetContents(const CFX_WideString& sContents)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	if (sContents.IsEmpty())
		m_pAnnot->m_pAnnotDict->RemoveAt("Contents");
	else
		m_pAnnot->m_pAnnotDict->SetAtString("Contents", PDF_EncodeText(sContents));
}

CFX_WideString CPDFSDK_Annot::GetContents() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetUnicodeText("Contents");
}

void CPDFSDK_Annot::SetAnnotName(const CFX_WideString& sName)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	if (sName.IsEmpty())
		m_pAnnot->m_pAnnotDict->RemoveAt("NM");
	else
		m_pAnnot->m_pAnnotDict->SetAtString("NM", PDF_EncodeText(sName));
}

CFX_WideString CPDFSDK_Annot::GetAnnotName() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetUnicodeText("NM");
}

void CPDFSDK_Annot::SetModifiedDate(const FX_SYSTEMTIME& st)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	CPDFSDK_DateTime dt(st);
	CFX_ByteString str = dt.ToPDFDateTimeString();
	
	if (str.IsEmpty())
		m_pAnnot->m_pAnnotDict->RemoveAt("M");
	else
		m_pAnnot->m_pAnnotDict->SetAtString("M", str);
}

FX_SYSTEMTIME CPDFSDK_Annot::GetModifiedDate() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	FX_SYSTEMTIME systime;	
	CFX_ByteString str = m_pAnnot->m_pAnnotDict->GetString("M");
	
 	CPDFSDK_DateTime dt(str);
 	dt.ToSystemTime(systime);
	
	return systime;
}

void CPDFSDK_Annot::SetFlags(int nFlags)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	m_pAnnot->m_pAnnotDict->SetAtInteger("F", nFlags);
}

int CPDFSDK_Annot::GetFlags() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetInteger("F");
}

void CPDFSDK_Annot::SetAppState(const CFX_ByteString& str)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	if (str.IsEmpty())
		m_pAnnot->m_pAnnotDict->RemoveAt("AS");
	else
		m_pAnnot->m_pAnnotDict->SetAtString("AS", str);
}

CFX_ByteString CPDFSDK_Annot::GetAppState() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	return m_pAnnot->m_pAnnotDict->GetString("AS");
}

void CPDFSDK_Annot::SetStructParent(int key)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	m_pAnnot->m_pAnnotDict->SetAtInteger("StructParent", key);
}

int	CPDFSDK_Annot::GetStructParent() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetInteger("StructParent");
}

//border
void CPDFSDK_Annot::SetBorderWidth(int nWidth)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");

	if (pBorder)
	{
		pBorder->SetAt(2, FX_NEW CPDF_Number(nWidth));
	}
	else
	{
		CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");

		if (!pBSDict)
		{
			pBSDict = FX_NEW CPDF_Dictionary;
			m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict);
		}

		pBSDict->SetAtInteger("W", nWidth);
	}
}

int	CPDFSDK_Annot::GetBorderWidth() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");

	if (pBorder)
	{
		return pBorder->GetInteger(2);
	}
	else
	{
		CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");

		if (pBSDict)
		{
			return pBSDict->GetInteger("W", 1);
		}
	}
	return 1;
}

void CPDFSDK_Annot::SetBorderStyle(int nStyle)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
	if (!pBSDict)
	{
		pBSDict = FX_NEW CPDF_Dictionary;
		m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict);
	}

	switch (nStyle)
	{
	case BBS_SOLID:
		pBSDict->SetAtName("S", "S");
		break;
	case BBS_DASH:
		pBSDict->SetAtName("S", "D");
		break;
	case BBS_BEVELED:
		pBSDict->SetAtName("S", "B");
		break;
	case BBS_INSET:
		pBSDict->SetAtName("S", "I");
		break;
	case BBS_UNDERLINE:
		pBSDict->SetAtName("S", "U");
		break;
	}
}

int	CPDFSDK_Annot::GetBorderStyle() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
	if (pBSDict)
	{
		CFX_ByteString sBorderStyle = pBSDict->GetString("S", "S");
		if (sBorderStyle == "S") return BBS_SOLID;
		if (sBorderStyle == "D") return BBS_DASH;
		if (sBorderStyle == "B") return BBS_BEVELED;
		if (sBorderStyle == "I") return BBS_INSET;
		if (sBorderStyle == "U") return BBS_UNDERLINE;
	}

	CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");
	if (pBorder)
	{
		if (pBorder->GetCount() >= 4) 
		{ 
			CPDF_Array *pDP = pBorder->GetArray(3);
			if (pDP && pDP->GetCount() > 0)
				return BBS_DASH;
		}
	}

	return BBS_SOLID;
}

void CPDFSDK_Annot::SetBorderDash(const CFX_IntArray& array)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
	if (!pBSDict)
	{
		pBSDict = FX_NEW CPDF_Dictionary;
		m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict);
	}

	CPDF_Array* pArray = FX_NEW CPDF_Array;
	for (int i=0,sz=array.GetSize(); i<sz; i++)
	{
		pArray->AddInteger(array[i]);
	}

	pBSDict->SetAt("D", pArray);
}

void CPDFSDK_Annot::GetBorderDash(CFX_IntArray& array) const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Array* pDash = NULL;

	CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");
	if (pBorder)
	{
		pDash = pBorder->GetArray(3);
	}
	else
	{
		CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
		if (pBSDict)
		{
			pDash = pBSDict->GetArray("D");
		}
	}

	if (pDash)
	{
		for (int i=0,sz=pDash->GetCount(); i<sz; i++)
		{
			array.Add(pDash->GetInteger(i));
		}
	}
}

void CPDFSDK_Annot::SetColor(FX_COLORREF color)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	CPDF_Array* pArray = FX_NEW CPDF_Array;
	pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
	pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
	pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
	m_pAnnot->m_pAnnotDict->SetAt("C", pArray);
}

void CPDFSDK_Annot::RemoveColor()
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	m_pAnnot->m_pAnnotDict->RemoveAt("C") ; 
}

FX_BOOL CPDFSDK_Annot::GetColor(FX_COLORREF& color) const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);

	if (CPDF_Array* pEntry = m_pAnnot->m_pAnnotDict->GetArray("C"))		
	{
		int nCount = pEntry->GetCount();
		if (nCount == 1)
		{
			FX_FLOAT g = pEntry->GetNumber(0) * 255;

			color = FXSYS_RGB((int)g, (int)g, (int)g);

			return TRUE;
		}
		else if (nCount == 3)
		{
			FX_FLOAT r = pEntry->GetNumber(0) * 255;
			FX_FLOAT g = pEntry->GetNumber(1) * 255;
			FX_FLOAT b = pEntry->GetNumber(2) * 255;

			color = FXSYS_RGB((int)r, (int)g, (int)b);

			return TRUE;
		}
		else if (nCount == 4)
		{
			FX_FLOAT c = pEntry->GetNumber(0);
			FX_FLOAT m = pEntry->GetNumber(1);
			FX_FLOAT y = pEntry->GetNumber(2);
			FX_FLOAT k = pEntry->GetNumber(3);

			FX_FLOAT r = 1.0f - FX_MIN(1.0f, c + k);
			FX_FLOAT g = 1.0f - FX_MIN(1.0f, m + k);
			FX_FLOAT b = 1.0f - FX_MIN(1.0f, y + k);

			color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));

			return TRUE;
		}
	}

	return FALSE;
}


void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, 
								const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
								const CFX_ByteString& sAPState)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP");
	
	if (!pAPDict) 
	{
		pAPDict = FX_NEW CPDF_Dictionary;
		m_pAnnot->m_pAnnotDict->SetAt("AP", pAPDict);
	}
	
	CPDF_Stream* pStream = NULL;
	CPDF_Dictionary* pParentDict = NULL;
	
	if (sAPState.IsEmpty())
	{
		pParentDict = pAPDict;
		pStream = pAPDict->GetStream(sAPType);
	}
	else
	{
		CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType);
		if (!pAPTypeDict)
		{
			pAPTypeDict = FX_NEW CPDF_Dictionary;
			pAPDict->SetAt(sAPType, pAPTypeDict);
		}
		
		pParentDict = pAPTypeDict;
		pStream = pAPTypeDict->GetStream(sAPState);
	}
	
	if (!pStream) 
	{
		ASSERT(m_pPageView != NULL);
		CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
		ASSERT(pDoc != NULL);
		
		pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
		FX_INT32 objnum = pDoc->AddIndirectObject(pStream);
		//pAPDict->SetAtReference(sAPType, pDoc, objnum);
		ASSERT(pParentDict != NULL);
		pParentDict->SetAtReference(sAPType, pDoc, objnum);
	}
	
	CPDF_Dictionary * pStreamDict = pStream->GetDict();
	
	if (!pStreamDict)
	{
		pStreamDict = FX_NEW CPDF_Dictionary;
		pStreamDict->SetAtName("Type", "XObject");
		pStreamDict->SetAtName("Subtype", "Form");
		pStreamDict->SetAtInteger("FormType", 1);
		pStream->InitStream(NULL,0,pStreamDict);
	}
	
	if (pStreamDict)
	{
		pStreamDict->SetAtMatrix("Matrix",matrix);	
		pStreamDict->SetAtRect("BBox", rcBBox);		
	}
	
	pStream->SetData((FX_BYTE*)(FX_LPCSTR)sContents, sContents.GetLength(), FALSE, FALSE);
}

#define BA_ANNOT_MINWIDTH			1
#define BA_ANNOT_MINHEIGHT			1

FX_FLOAT CPDFSDK_Annot::GetMinWidth() const
{
	return BA_ANNOT_MINWIDTH;
}

FX_FLOAT CPDFSDK_Annot::GetMinHeight() const
{
	return BA_ANNOT_MINHEIGHT;
}

FX_BOOL CPDFSDK_Annot::CreateFormFiller()
{
	return TRUE;
}
FX_BOOL	CPDFSDK_Annot::IsVisible() const
{
	int nFlags = GetFlags();
	return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) || (nFlags & ANNOTFLAG_NOVIEW));
}

CPDF_Action CPDFSDK_Annot::GetAction() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetDict("A");
}

void CPDFSDK_Annot::SetAction(const CPDF_Action& action)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	ASSERT(action != NULL);
	
	if ((CPDF_Action&)action != m_pAnnot->m_pAnnotDict->GetDict("A"))
	{
		CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
		ASSERT(pDoc != NULL);
		
		if (action.m_pDict && (action.m_pDict->GetObjNum() == 0))
			pDoc->AddIndirectObject(action.m_pDict); 
		m_pAnnot->m_pAnnotDict->SetAtReference("A", pDoc, action.m_pDict->GetObjNum());
	}
}

void CPDFSDK_Annot::RemoveAction()
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	m_pAnnot->m_pAnnotDict->RemoveAt("A");
}

CPDF_AAction CPDFSDK_Annot::GetAAction() const
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	return m_pAnnot->m_pAnnotDict->GetDict("AA");
}

void CPDFSDK_Annot::SetAAction(const CPDF_AAction& aa)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	ASSERT(aa != NULL);
	
	if ((CPDF_AAction&)aa != m_pAnnot->m_pAnnotDict->GetDict("AA"))
		m_pAnnot->m_pAnnotDict->SetAt("AA", (CPDF_AAction&)aa);
}

void CPDFSDK_Annot::RemoveAAction()
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	m_pAnnot->m_pAnnotDict->RemoveAt("AA");
}

CPDF_Action	CPDFSDK_Annot::GetAAction(CPDF_AAction::AActionType eAAT)
{
	CPDF_AAction AAction = GetAAction();
	
	if (AAction.ActionExist(eAAT))
	{
		return AAction.GetAction(eAAT);
	}
	else if (eAAT == CPDF_AAction::ButtonUp)
	{
		return GetAction();
	}
	
	return NULL;
}

void  CPDFSDK_Annot::Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, CPDF_RenderOptions* pOptions)
{
	
	m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
	m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, CPDF_Annot::Normal, NULL);

	return ;
}

CPDF_Page* CPDFSDK_Annot::GetPDFPage()
{
	if(m_pPageView)
		return m_pPageView->GetPDFPage();
	return NULL;
}

