// 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::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*)sContents.c_str(), 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;
}

