// 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 "../../third_party/base/nonstd_unique_ptr.h"
#include "../include/fsdk_define.h"
#include "../include/fsdk_mgr.h"
#include "../include/fsdk_baseannot.h"
#include "../include/fsdk_baseform.h"
#include "../include/formfiller/FFL_FormFiller.h"
#include "../include/fsdk_actionhandler.h"

#include "../include/javascript/IJavaScript.h"

//------------------------------------------------------------------------------------
//*										CPDFSDK_Widget 
//------------------------------------------------------------------------------------

#define IsFloatZero(f)						((f) < 0.01 && (f) > -0.01)
#define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatEqual(fa,fb)					IsFloatZero((fa)-(fb))

CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) :
					CPDFSDK_Annot(pAnnot, pPageView),
					m_pInterForm(pInterForm),
					m_nAppAge(0),
					m_nValueAge(0)
{
	ASSERT(m_pInterForm != NULL);
}

CPDFSDK_Widget::~CPDFSDK_Widget()
{

}

FX_BOOL		CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode)
{
	CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->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;
	
	int nFieldType = GetFieldType();
	switch (nFieldType)
	{
	case FIELDTYPE_PUSHBUTTON:
	case FIELDTYPE_COMBOBOX:
	case FIELDTYPE_LISTBOX:
	case FIELDTYPE_TEXTFIELD:
	case FIELDTYPE_SIGNATURE:
		return psub->GetType() == PDFOBJ_STREAM;
	case FIELDTYPE_CHECKBOX:
	case FIELDTYPE_RADIOBUTTON:
		if (psub->GetType() == PDFOBJ_DICTIONARY) 
		{
			CPDF_Dictionary* pSubDict = (CPDF_Dictionary*)psub;
			
			return pSubDict->GetStream(GetAppState()) != NULL;
		}
		else
			return FALSE;
		break;
	}
	
	return TRUE;
}

int	CPDFSDK_Widget::GetFieldType() const
{
	CPDF_FormField* pField = GetFormField();
	ASSERT(pField != NULL);
	
	return pField->GetFieldType();
}

int CPDFSDK_Widget::GetFieldFlags() const
{
	CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
	ASSERT(pPDFInterForm != NULL);

	CPDF_FormControl* pFormControl = pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
	CPDF_FormField* pFormField = pFormControl->GetField();
	return pFormField->GetFieldFlags();
}

CFX_ByteString CPDFSDK_Widget::GetSubType() const
{
	int nType = GetFieldType();
	
	if (nType == FIELDTYPE_SIGNATURE)
		return BFFT_SIGNATURE;
	return CPDFSDK_Annot::GetSubType();
}

CPDF_FormField*	CPDFSDK_Widget::GetFormField() const
{
	ASSERT(m_pInterForm != NULL);
	
	CPDF_FormControl* pCtrl = GetFormControl();	
	ASSERT(pCtrl != NULL);
	
	return pCtrl->GetField();
}

CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const
{
	ASSERT(m_pInterForm != NULL);
	
	CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
	ASSERT(pPDFInterForm != NULL);
	
	return pPDFInterForm->GetControlByDict(GetAnnotDict());
}
static CPDF_Dictionary* BF_GetField(CPDF_Dictionary* pFieldDict, const FX_CHAR* name)
{
	if (pFieldDict == NULL) return NULL;
	// First check the dictionary itself
	CPDF_Object* pAttr = pFieldDict->GetElementValue(name);
	if (pAttr) return pFieldDict;
	
	// Now we need to search from parents
	CPDF_Dictionary* pParent = pFieldDict->GetDict("Parent");
	if (pParent == NULL) return NULL;
	
	return BF_GetField(pParent, name);
}

CPDF_FormControl* CPDFSDK_Widget::GetFormControl(CPDF_InterForm* pInterForm, CPDF_Dictionary* pAnnotDict)
{
	ASSERT(pInterForm != NULL);
	ASSERT(pAnnotDict != NULL);
	
	CPDF_FormControl* pControl = pInterForm->GetControlByDict(pAnnotDict);
	
	return pControl;
}

int CPDFSDK_Widget::GetRotate() const
{
	CPDF_FormControl* pCtrl = GetFormControl();
	ASSERT(pCtrl != NULL);
	
	return pCtrl->GetRotation() % 360;
}

FX_BOOL	CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	int iColorType = 0;	
	color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
	
	return iColorType != COLORTYPE_TRANSPARENT;
}

FX_BOOL	CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	int iColorType = 0;	
	color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
	
	return iColorType != COLORTYPE_TRANSPARENT;
}

FX_BOOL	CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
	if (da.HasColor())
	{
		FX_ARGB argb;
		int iColorType = COLORTYPE_TRANSPARENT;	
		da.GetColor(argb, iColorType);
		color = FX_ARGBTOCOLORREF(argb);
		
		return iColorType != COLORTYPE_TRANSPARENT;
	}
	
	return FALSE;
}

FX_FLOAT CPDFSDK_Widget::GetFontSize() const
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
	CFX_ByteString csFont = "";
	FX_FLOAT fFontSize = 0.0f;
	pDa.GetFont(csFont, fFontSize);
	
	return fFontSize;
}

int	CPDFSDK_Widget::GetSelectedIndex(int nIndex) const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->GetSelectedIndex(nIndex);
}

CFX_WideString CPDFSDK_Widget::GetValue() const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->GetValue();
}

CFX_WideString CPDFSDK_Widget::GetDefaultValue() const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->GetDefaultValue();
}

CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->GetOptionLabel(nIndex);
}

int	CPDFSDK_Widget::CountOptions() const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->CountOptions();
}

FX_BOOL	CPDFSDK_Widget::IsOptionSelected(int nIndex) const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->IsItemSelected(nIndex);
}

int	CPDFSDK_Widget::GetTopVisibleIndex() const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->GetTopVisibleIndex();
}

FX_BOOL	CPDFSDK_Widget::IsChecked() const
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	return pFormCtrl->IsChecked();
}

int	CPDFSDK_Widget::GetAlignment() const
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	return pFormCtrl->GetControlAlignment();
}

int	CPDFSDK_Widget::GetMaxLen() const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	return pFormField->GetMaxLen();
}

void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify)
{
	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);
	
	CPDF_FormField*	pFormField = pFormCtrl->GetField();
	ASSERT(pFormField != NULL);
	
	pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked, bNotify);
}

void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify)
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	pFormField->SetValue(sValue, bNotify);
}

void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue)
{
}
void CPDFSDK_Widget::SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify)
{
	CPDF_FormField* pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	pFormField->SetItemSelection(index, bSelected, bNotify);
}

void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify)
{
	CPDF_FormField* pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	pFormField->ClearSelection(bNotify);
}

void CPDFSDK_Widget::SetTopVisibleIndex(int index)
{
}

void CPDFSDK_Widget::SetAppModified()
{
	m_bAppModified = TRUE;
}

void CPDFSDK_Widget::ClearAppModified()
{
	m_bAppModified = FALSE;
}

FX_BOOL CPDFSDK_Widget::IsAppModified() const
{
	return m_bAppModified;
}

void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue, FX_BOOL bValueChanged)
{
	SetAppModified();

	m_nAppAge++;
	if (m_nAppAge > 999999)
		m_nAppAge = 0;
	if (bValueChanged)
		m_nValueAge++;

	int nFieldType = GetFieldType();
	
	switch (nFieldType)
	{
	case FIELDTYPE_PUSHBUTTON:
		ResetAppearance_PushButton();
		break;
	case FIELDTYPE_CHECKBOX:
		ResetAppearance_CheckBox();
		break;
	case FIELDTYPE_RADIOBUTTON:
		ResetAppearance_RadioButton();
		break;
	case FIELDTYPE_COMBOBOX:
		ResetAppearance_ComboBox(sValue);
		break;
	case FIELDTYPE_LISTBOX:
		ResetAppearance_ListBox();
		break;
	case FIELDTYPE_TEXTFIELD:
		ResetAppearance_TextField(sValue);
		break;
	}
	
	ASSERT(m_pAnnot != NULL);
	m_pAnnot->ClearCachedAP();
}

CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated)
{
    CPDF_FormField* pFormField = GetFormField();
    ASSERT(pFormField != NULL);
    return m_pInterForm->OnFormat(pFormField, bFormated);
}

void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged)
{
	CPDF_FormField* pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	ASSERT(m_pInterForm != NULL);

	m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
}

void	CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
		CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions)
{
	int nFieldType = GetFieldType();
	
	if ((nFieldType == FIELDTYPE_CHECKBOX || nFieldType == FIELDTYPE_RADIOBUTTON) &&
		mode == CPDF_Annot::Normal && 
		!IsWidgetAppearanceValid(CPDF_Annot::Normal))
	{
		CFX_PathData pathData;
		
		CPDF_Rect rcAnnot = GetRect();
		
		pathData.AppendRect(rcAnnot.left, rcAnnot.bottom,
			rcAnnot.right, rcAnnot.top);
		
		CFX_GraphStateData gsd;
		gsd.m_LineWidth = 0.0f;
		
		pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA, FXFILL_ALTERNATE);
	}
	else
	{
		CPDFSDK_Annot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
	}
}

void CPDFSDK_Widget::UpdateField()
{
	CPDF_FormField* pFormField = GetFormField();
	ASSERT(pFormField != NULL);
	
	ASSERT(m_pInterForm != NULL);
	m_pInterForm->UpdateField(pFormField);
}

void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView)
{
 	ASSERT(m_pInterForm != NULL);
 
	int nFieldType = GetFieldType();
 	if (m_pInterForm->IsNeedHighLight(nFieldType))
 	{
 
//  		if (nFieldType != FIELDTYPE_PUSHBUTTON)
//  		{
			CPDF_Rect rc  = GetRect();
			FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
			uint8_t alpha = m_pInterForm->GetHighlightAlpha();

			CFX_FloatRect rcDevice;
			ASSERT(m_pInterForm->GetDocument());
			CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
			if(!pEnv)
				return;
			CFX_AffineMatrix page2device;
			pPageView->GetCurrentMatrix(page2device);
			page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), rcDevice.left, rcDevice.bottom);
// 			pEnv->FFI_PageToDevice(m_pPageView->GetPDFPage(), rc.left, rc.bottom, &rcDevice.left, &rcDevice.bottom);
// 			pEnv->FFI_PageToDevice(m_pPageView->GetPDFPage(), rc.right, rc.top, &rcDevice.right, &rcDevice.top);
			page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), rcDevice.right, rcDevice.top);

			rcDevice.Normalize();

			FX_ARGB argb = ArgbEncode((int)alpha, color);
			FX_RECT rcDev((int)rcDevice.left,(int)rcDevice.top,(int)rcDevice.right,(int)rcDevice.bottom);
			pDevice->FillRect(&rcDev, argb);	
			/* 		}*/
	}
}

void CPDFSDK_Widget::ResetAppearance_PushButton()
{
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);


	
	CPDF_Rect rcWindow = GetRotatedRect();	

	int32_t nLayout = 0;

	switch (pControl->GetTextPosition())
	{
	case TEXTPOS_ICON:
		nLayout = PPBL_ICON;
		break;
	case TEXTPOS_BELOW:
		nLayout = PPBL_ICONTOPLABELBOTTOM;
		break;
	case TEXTPOS_ABOVE:
		nLayout = PPBL_LABELTOPICONBOTTOM;
		break;
	case TEXTPOS_RIGHT:
		nLayout = PPBL_ICONLEFTLABELRIGHT;
		break;
	case TEXTPOS_LEFT:
		nLayout = PPBL_LABELLEFTICONRIGHT;
		break;
	case TEXTPOS_OVERLAID:
		nLayout = PPBL_LABELOVERICON;
		break;
	default:
		nLayout = PPBL_LABEL;
		break;
	}

	CPWL_Color crBackground, crBorder;

	int iColorType;
	FX_FLOAT fc[4];

	pControl->GetOriginalBackgroundColor(iColorType, fc);
	if (iColorType > 0)
		crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	pControl->GetOriginalBorderColor(iColorType, fc);
	if (iColorType > 0)
		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
	int32_t nBorderStyle = 0;
	CPWL_Dash dsBorder(3,0,0);
	CPWL_Color crLeftTop,crRightBottom;

	switch (GetBorderStyle())
	{
	case BBS_DASH:
		nBorderStyle = PBS_DASH;
		dsBorder = CPWL_Dash(3, 3, 0);
		break;
	case BBS_BEVELED:
		nBorderStyle = PBS_BEVELED;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
		crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
		break;
	case BBS_INSET:
		nBorderStyle = PBS_INSET;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
		crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
		break;
	case BBS_UNDERLINE:
		nBorderStyle = PBS_UNDERLINED;
		break;
	default: 
		nBorderStyle = PBS_SOLID;
		break;
	}

	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,fBorderWidth);	

	CPWL_Color crText(COLORTYPE_GRAY,0);

	FX_FLOAT fFontSize = 12.0f;
	CFX_ByteString csNameTag;

	CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
	if (da.HasColor())
	{
		da.GetColor(iColorType, fc);
		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
	}

	if (da.HasFont()) 
		da.GetFont(csNameTag, fFontSize);

	CFX_WideString csWCaption;
	CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;

	if (pControl->HasMKEntry("CA"))
	{
		csNormalCaption = pControl->GetNormalCaption();
	}
	if (pControl->HasMKEntry("RC"))
	{
		csRolloverCaption = pControl->GetRolloverCaption();
	}
	if (pControl->HasMKEntry("AC"))
	{
		csDownCaption = pControl->GetDownCaption();
	}

	CPDF_Stream* pNormalIcon = NULL;
	CPDF_Stream* pRolloverIcon = NULL;
	CPDF_Stream* pDownIcon = NULL;

	if (pControl->HasMKEntry("I"))
	{
		pNormalIcon = pControl->GetNormalIcon();
	}
	if (pControl->HasMKEntry("RI"))
	{
		pRolloverIcon = pControl->GetRolloverIcon();
	}
	if (pControl->HasMKEntry("IX"))
	{
		pDownIcon = pControl->GetDownIcon();
	}

	if (pNormalIcon)
	{
		if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict())
		{
			if (pImageDict->GetString("Name").IsEmpty())
				pImageDict->SetAtString("Name", "ImgA");
		}
	}

	if (pRolloverIcon)
	{
		if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict())
		{
			if (pImageDict->GetString("Name").IsEmpty())
				pImageDict->SetAtString("Name", "ImgB");
		}
	}

	if (pDownIcon)
	{
		if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict())
		{
			if (pImageDict->GetString("Name").IsEmpty())
				pImageDict->SetAtString("Name", "ImgC");
		}
	}

	CPDF_IconFit iconFit = pControl->GetIconFit();

	CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
	ASSERT(pDoc != NULL);
	CPDFDoc_Environment* pEnv = pDoc->GetEnv();

 	CBA_FontMap FontMap(this,pEnv->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pBaseForm->GetEnv()));
	FontMap.Initial();

	FontMap.SetAPType("N");

	CFX_ByteString csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 
		CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
		CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);

	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
	if (pNormalIcon)
		AddImageToAppearance("N", pNormalIcon);

	CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
	if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle)
	{
		if (csRolloverCaption.IsEmpty() && !pRolloverIcon)			
		{
			csRolloverCaption = csNormalCaption;
			pRolloverIcon = pNormalIcon;
		}

		FontMap.SetAPType("R");

		csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 
				CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
				CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize, nLayout);

		WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
		if (pRolloverIcon)
			AddImageToAppearance("R", pRolloverIcon);

		if (csDownCaption.IsEmpty() && !pDownIcon)
		{
			csDownCaption = csNormalCaption;
			pDownIcon = pNormalIcon;
		}

		switch (nBorderStyle)
		{
		case PBS_BEVELED:
			{
				CPWL_Color crTemp = crLeftTop;
				crLeftTop = crRightBottom;
				crRightBottom = crTemp;
			}
			break;
		case PBS_INSET:
			crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
			crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
			break;
		}
		
		FontMap.SetAPType("D");

		csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, CPWL_Utils::SubstractColor(crBackground,0.25f)) + 
			CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) + 
			CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);

		WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
		if (pDownIcon)
			AddImageToAppearance("D", pDownIcon);
	}
	else
	{
		RemoveAppearance("D");
		RemoveAppearance("R");
	}
}

void CPDFSDK_Widget::ResetAppearance_CheckBox()
{
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);



	CPWL_Color crBackground, crBorder, crText;
	
	int iColorType;
	FX_FLOAT fc[4];

	pControl->GetOriginalBackgroundColor(iColorType, fc);
	if (iColorType > 0)
		crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	pControl->GetOriginalBorderColor(iColorType, fc);
	if (iColorType > 0)
		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
	int32_t nBorderStyle = 0;
	CPWL_Dash dsBorder(3,0,0);
	CPWL_Color crLeftTop,crRightBottom;

	switch (GetBorderStyle())
	{
	case BBS_DASH:
		nBorderStyle = PBS_DASH;
		dsBorder = CPWL_Dash(3, 3, 0);
		break;
	case BBS_BEVELED:
		nBorderStyle = PBS_BEVELED;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
		crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
		break;
	case BBS_INSET:
		nBorderStyle = PBS_INSET;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
		crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
		break;
	case BBS_UNDERLINE:
		nBorderStyle = PBS_UNDERLINED;
		break;
	default: 
		nBorderStyle = PBS_SOLID;
		break;
	}

	CPDF_Rect rcWindow = GetRotatedRect();
	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,fBorderWidth);

	CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
	if (da.HasColor())
	{
		da.GetColor(iColorType, fc);
		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
	}

	int32_t nStyle = 0;

	CFX_WideString csWCaption = pControl->GetNormalCaption();
	if (csWCaption.GetLength() > 0)
	{
		switch (csWCaption[0])
		{
		case L'l':
			nStyle = PCS_CIRCLE;			
			break;
		case L'8':
			nStyle = PCS_CROSS;
			break;
		case L'u':
			nStyle = PCS_DIAMOND;
			break;
		case L'n':
			nStyle = PCS_SQUARE;
			break;
		case L'H':
			nStyle = PCS_STAR;
			break;
		default: //L'4'
			nStyle = PCS_CHECK;
			break;
		}
	}
	else
	{
		nStyle = PCS_CHECK;
	}

	CFX_ByteString csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,crBackground) +
		CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);

	CFX_ByteString csAP_N_OFF = csAP_N_ON;

	switch (nBorderStyle)
	{
	case PBS_BEVELED:
		{
			CPWL_Color crTemp = crLeftTop;
			crLeftTop = crRightBottom;
			crRightBottom = crTemp;
		}
		break;
	case PBS_INSET:
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
		crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
		break;
	}

	CFX_ByteString csAP_D_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,CPWL_Utils::SubstractColor(crBackground,0.25f)) + 
		CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);

	CFX_ByteString csAP_D_OFF = csAP_D_ON;

	csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient,nStyle,crText);
	csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient,nStyle,crText);

	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, pControl->GetCheckedAPState());
	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");

	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, pControl->GetCheckedAPState());
	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");

	CFX_ByteString csAS = GetAppState();
	if (csAS.IsEmpty())
		SetAppState("Off");
}

void CPDFSDK_Widget::ResetAppearance_RadioButton()
{
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);
	


	CPWL_Color crBackground, crBorder, crText;
	
	int iColorType;
	FX_FLOAT fc[4];

	pControl->GetOriginalBackgroundColor(iColorType, fc);
	if (iColorType > 0)
		crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	pControl->GetOriginalBorderColor(iColorType, fc);
	if (iColorType > 0)
		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
	int32_t nBorderStyle = 0;
	CPWL_Dash dsBorder(3,0,0);
	CPWL_Color crLeftTop,crRightBottom;

	switch (GetBorderStyle())
	{
	case BBS_DASH:
		nBorderStyle = PBS_DASH;
		dsBorder = CPWL_Dash(3, 3, 0);
		break;
	case BBS_BEVELED:
		nBorderStyle = PBS_BEVELED;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
		crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
		break;
	case BBS_INSET:
		nBorderStyle = PBS_INSET;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
		crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
		break;
	case BBS_UNDERLINE:
		nBorderStyle = PBS_UNDERLINED;
		break;
	default: 
		nBorderStyle = PBS_SOLID;
		break;
	}

	CPDF_Rect rcWindow = GetRotatedRect();
	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);

	CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
	if (da.HasColor())
	{
		da.GetColor(iColorType, fc);
		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
	}

	int32_t nStyle = 0;

	CFX_WideString csWCaption = pControl->GetNormalCaption();
	if (csWCaption.GetLength() > 0)
	{
		switch (csWCaption[0])
		{
		default: //L'l':
			nStyle = PCS_CIRCLE;			
			break;
		case L'8':
			nStyle = PCS_CROSS;
			break;
		case L'u':
			nStyle = PCS_DIAMOND;
			break;
		case L'n':
			nStyle = PCS_SQUARE;
			break;
		case L'H':
			nStyle = PCS_STAR;
			break;
		case L'4':
			nStyle = PCS_CHECK;
			break;
		}
	}
	else
	{
		nStyle = PCS_CIRCLE;
	}

	CFX_ByteString csAP_N_ON;

	CPDF_Rect rcCenter = CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
	
	if (nStyle == PCS_CIRCLE)
	{
		if (nBorderStyle == PBS_BEVELED)
		{
			crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
			crRightBottom = CPWL_Utils::SubstractColor(crBackground,0.25f);
		}
		else if (nBorderStyle == PBS_INSET)
		{
			crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5f);
			crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75f);
		}

		csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter,crBackground) + 
			CPWL_Utils::GetCircleBorderAppStream(rcCenter,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
	}
	else
	{
		csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,crBackground) + 
			CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
	}

	CFX_ByteString csAP_N_OFF = csAP_N_ON;

	switch (nBorderStyle)
	{
	case PBS_BEVELED:
		{
			CPWL_Color crTemp = crLeftTop;
			crLeftTop = crRightBottom;
			crRightBottom = crTemp;
		}
		break;
	case PBS_INSET:
		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
		crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
		break;
	}

	CFX_ByteString csAP_D_ON;

	if (nStyle == PCS_CIRCLE)
	{
		CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground,0.25f);
		if (nBorderStyle == PBS_BEVELED)
		{
			crLeftTop = CPWL_Utils::SubstractColor(crBackground,0.25f);
			crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
			crBK = crBackground;
		}
		else if (nBorderStyle == PBS_INSET)
		{
			crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
			crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
		}

		csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter,crBK)
			+ CPWL_Utils::GetCircleBorderAppStream(rcCenter,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
	}
	else
	{
		csAP_D_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,CPWL_Utils::SubstractColor(crBackground,0.25f)) + 
			CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);		
	}

	CFX_ByteString csAP_D_OFF = csAP_D_ON;

	csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient,nStyle,crText);
	csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient,nStyle,crText);

	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, pControl->GetCheckedAPState());
	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");

	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, pControl->GetCheckedAPState());
	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");

	CFX_ByteString csAS = GetAppState();
	if (csAS.IsEmpty())
		SetAppState("Off");
}

void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue)
{
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);
	CPDF_FormField* pField = pControl->GetField();
	ASSERT(pField != NULL);

	CFX_ByteTextBuf sBody, sLines;

	CPDF_Rect rcClient = GetClientRect();
	CPDF_Rect rcButton = rcClient;
	rcButton.left = rcButton.right - 13;
	rcButton.Normalize();

	if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
	{
		pEdit->EnableRefresh(FALSE);

		CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
		ASSERT(pDoc != NULL);
		CPDFDoc_Environment* pEnv = pDoc->GetEnv();
		CBA_FontMap FontMap(this,pEnv->GetSysHandler());
		FontMap.Initial();
		pEdit->SetFontMap(&FontMap);

		CPDF_Rect rcEdit = rcClient;
		rcEdit.right = rcButton.left;
		rcEdit.Normalize();
		
		pEdit->SetPlateRect(rcEdit);
		pEdit->SetAlignmentV(1);

		FX_FLOAT fFontSize = GetFontSize();
		if (IsFloatZero(fFontSize))
			pEdit->SetAutoFontSize(TRUE);
		else
			pEdit->SetFontSize(fFontSize);
		
		pEdit->Initialize();
		
		if (sValue)
			pEdit->SetText(sValue);
		else
		{
			int32_t nCurSel = pField->GetSelectedIndex(0);

			if (nCurSel < 0)
				pEdit->SetText(pField->GetValue().c_str());
			else
				pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
		}

		CPDF_Rect rcContent = pEdit->GetContentRect();

		CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,0.0f));
		if (sEdit.GetLength() > 0)
		{
			sBody << "/Tx BMC\n" << "q\n";
			if (rcContent.Width() > rcEdit.Width() ||
				rcContent.Height() > rcEdit.Height())
			{
				sBody << rcEdit.left << " " << rcEdit.bottom << " " 
					<< rcEdit.Width() << " " << rcEdit.Height() << " re\nW\nn\n";
			}

			CPWL_Color crText = GetTextPWLColor();	
			sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n";
		}

		IFX_Edit::DelEdit(pEdit);
	}

	sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);

	CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();

	WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
}

void CPDFSDK_Widget::ResetAppearance_ListBox()
{
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);
	CPDF_FormField* pField = pControl->GetField();
	ASSERT(pField != NULL);

	CPDF_Rect rcClient = GetClientRect();

	CFX_ByteTextBuf sBody, sLines;

	if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
	{
		pEdit->EnableRefresh(FALSE);

		CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
		ASSERT(pDoc != NULL);
		CPDFDoc_Environment* pEnv = pDoc->GetEnv();

		CBA_FontMap FontMap(this,pEnv->GetSysHandler());
		FontMap.Initial();
		pEdit->SetFontMap(&FontMap);

		pEdit->SetPlateRect(CPDF_Rect(rcClient.left,0.0f,rcClient.right,0.0f));	
		
		FX_FLOAT fFontSize = GetFontSize();

		if (IsFloatZero(fFontSize))
			pEdit->SetFontSize(12.0f);
		else
			pEdit->SetFontSize(fFontSize);
		
		pEdit->Initialize();

		CFX_ByteTextBuf sList;
		FX_FLOAT fy = rcClient.top;

		int32_t nTop = pField->GetTopVisibleIndex();
		int32_t nCount = pField->CountOptions();
		int32_t nSelCount = pField->CountSelectedItems();

		for (int32_t i=nTop; i<nCount; i++)
		{
			FX_BOOL bSelected = FALSE;				
			for (int32_t j=0; j<nSelCount; j++)
			{
				if (pField->GetSelectedIndex(j) == i)
				{
					bSelected = TRUE;
					break;
				}
			}

			pEdit->SetText(pField->GetOptionLabel(i).c_str());

			CPDF_Rect rcContent = pEdit->GetContentRect();
			FX_FLOAT fItemHeight = rcContent.Height();

			if (bSelected)
			{
				CPDF_Rect rcItem = CPDF_Rect(rcClient.left,fy-fItemHeight,rcClient.right,fy);
				sList << "q\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB,0,51.0f/255.0f,113.0f/255.0f),TRUE)
					<< rcItem.left << " " << rcItem.bottom << " " << rcItem.Width() << " " << rcItem.Height() << " re f\n" << "Q\n";

				sList << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY,1),TRUE) << 
					CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,fy)) << "ET\n";
			}
			else
			{
				CPWL_Color crText = GetTextPWLColor();
				sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText,TRUE) << 
				CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,fy)) << "ET\n";
			}

			fy -= fItemHeight;
		}
					
		if (sList.GetSize() > 0)
		{
			sBody << "/Tx BMC\n" << "q\n" << rcClient.left << " " << rcClient.bottom << " " 
					<< rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
			sBody << sList << "Q\nEMC\n";
		}

		IFX_Edit::DelEdit(pEdit);
	}

	CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();

	WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
}

void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue)
{
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);
	CPDF_FormField* pField = pControl->GetField();
	ASSERT(pField != NULL);

	CFX_ByteTextBuf sBody, sLines;
	
	if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
	{
		pEdit->EnableRefresh(FALSE);

		CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
		ASSERT(pDoc != NULL);
		CPDFDoc_Environment* pEnv = pDoc->GetEnv();

		CBA_FontMap FontMap(this,pEnv->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pBaseForm->GetEnv()));
		FontMap.Initial();
		pEdit->SetFontMap(&FontMap);

		CPDF_Rect rcClient = GetClientRect();
		pEdit->SetPlateRect(rcClient);
		pEdit->SetAlignmentH(pControl->GetControlAlignment());
		
		FX_DWORD dwFieldFlags = pField->GetFieldFlags();
		FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;

		if (bMultiLine)
		{
			pEdit->SetMultiLine(TRUE);
			pEdit->SetAutoReturn(TRUE);
		}
		else
		{
			pEdit->SetAlignmentV(1);
		}

		FX_WORD subWord = 0;
		if ((dwFieldFlags >> 13) & 1)
		{
			subWord = '*';
			pEdit->SetPasswordChar(subWord);
		}

		int nMaxLen = pField->GetMaxLen();
		FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
		FX_FLOAT fFontSize = GetFontSize();	

		if (nMaxLen > 0)
		{
			if (bCharArray)
			{
				pEdit->SetCharArray(nMaxLen);

				if (IsFloatZero(fFontSize))
				{
					fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(FontMap.GetPDFFont(0),rcClient,nMaxLen);
				}
			}
			else
			{
				if (sValue)
					nMaxLen = wcslen((const wchar_t*)sValue); 
				pEdit->SetLimitChar(nMaxLen);
			}
		}

		if (IsFloatZero(fFontSize))
			pEdit->SetAutoFontSize(TRUE);
		else
			pEdit->SetFontSize(fFontSize);

		pEdit->Initialize();
		
		if (sValue)
			pEdit->SetText(sValue);
		else
			pEdit->SetText(pField->GetValue().c_str());

		CPDF_Rect rcContent = pEdit->GetContentRect();

		CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,0.0f),
																	NULL,!bCharArray,subWord);

		if (sEdit.GetLength() > 0)
		{
			sBody << "/Tx BMC\n" << "q\n";
			if (rcContent.Width() > rcClient.Width() ||
				rcContent.Height() > rcClient.Height())
			{
				sBody << rcClient.left << " " << rcClient.bottom << " " 
					<< rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
			}
			CPWL_Color crText = GetTextPWLColor();	
			sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n";
		}

		if (bCharArray)
		{
			switch (GetBorderStyle())
			{
			case BBS_SOLID:
				{
					CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE);
					if (sColor.GetLength() > 0)
					{
						sLines << "q\n" << GetBorderWidth() << " w\n" 
							<< CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE) << " 2 J 0 j\n";					

						for (int32_t i=1;i<nMaxLen;i++)
						{
							sLines << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
								<< rcClient.bottom << " m\n"
								<< rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
								<< rcClient.top << " l S\n";						
						}

						sLines << "Q\n";		
					}
				}
				break;
			case BBS_DASH:
				{
					CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE);
					if (sColor.GetLength() > 0)
					{
						CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);

						sLines << "q\n" << GetBorderWidth() << " w\n" 
							<< CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE)
							<< "[" << dsBorder.nDash << " " 
							<< dsBorder.nGap << "] " 
							<< dsBorder.nPhase << " d\n";

						for (int32_t i=1;i<nMaxLen;i++)					
						{
							sLines << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
								<< rcClient.bottom << " m\n"
								<< rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
								<< rcClient.top << " l S\n";	
						}

						sLines << "Q\n";
					}
				}
				break;
			}
		}

		IFX_Edit::DelEdit(pEdit);
	}

	CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
	WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
}

CPDF_Rect CPDFSDK_Widget::GetClientRect() const
{
	CPDF_Rect rcWindow = GetRotatedRect();
	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
	switch (GetBorderStyle())
	{
	case BBS_BEVELED:
	case BBS_INSET:
		fBorderWidth *= 2.0f;
		break;
	}

	return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
}

CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const
{
	CPDF_Rect rectAnnot = GetRect();
	FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
	FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;

	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);

	CPDF_Rect rcPDFWindow;
	switch(abs(pControl->GetRotation() % 360))
	{
		case 0:
		case 180:
		default:
			rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight);	
			break;
		case 90:
		case 270:
			rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth);
			break;
	}

	return rcPDFWindow;
}

CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const
{
	CPWL_Color crBackground = GetFillPWLColor();
	if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
		return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
	else
		return "";
}

CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const
{
	CPDF_Rect rcWindow = GetRotatedRect();
	CPWL_Color crBorder = GetBorderPWLColor();
	CPWL_Color crBackground = GetFillPWLColor();
	CPWL_Color crLeftTop, crRightBottom;

	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
	int32_t nBorderStyle = 0;
	CPWL_Dash dsBorder(3,0,0);

	switch (GetBorderStyle())
	{
	case BBS_DASH:
		nBorderStyle = PBS_DASH;
		dsBorder = CPWL_Dash(3, 3, 0);
		break;
	case BBS_BEVELED:
		nBorderStyle = PBS_BEVELED;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
		crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
		break;
	case BBS_INSET:
		nBorderStyle = PBS_INSET;
		fBorderWidth *= 2;
		crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
		crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
		break;
	case BBS_UNDERLINE:
		nBorderStyle = PBS_UNDERLINED;
		break;
	default: 
		nBorderStyle = PBS_SOLID;
		break;
	}

	return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, 
		crRightBottom, nBorderStyle, dsBorder);
}

CPDF_Matrix CPDFSDK_Widget::GetMatrix() const
{
	CPDF_Matrix mt;
	CPDF_FormControl* pControl = GetFormControl();
	ASSERT(pControl != NULL);

	CPDF_Rect rcAnnot = GetRect();
	FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
	FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
	


	switch (abs(pControl->GetRotation() % 360))
	{
		case 0:
		default:
			mt = CPDF_Matrix(1, 0, 0, 1, 0, 0);
			break;
		case 90:
			mt = CPDF_Matrix(0, 1, -1, 0, fWidth, 0);
			break;
		case 180:
			mt = CPDF_Matrix(-1, 0, 0, -1, fWidth, fHeight);
			break;
		case 270:
			mt = CPDF_Matrix(0, -1, 1, 0, 0, fHeight);
			break;
	}

	return mt;
}

CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const
{
	CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);

	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);

	CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
	if (da.HasColor())
	{
		int32_t iColorType;
		FX_FLOAT fc[4];
		da.GetColor(iColorType, fc);
		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
	}

	return crText;
}

CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const
{
	CPWL_Color crBorder;

	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);

	int32_t iColorType;
	FX_FLOAT fc[4];
	pFormCtrl->GetOriginalBorderColor(iColorType, fc);
	if (iColorType > 0)
		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	return crBorder;
}

CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const
{
	CPWL_Color crFill;

	CPDF_FormControl* pFormCtrl = GetFormControl();
	ASSERT(pFormCtrl != NULL);

	int32_t iColorType;
	FX_FLOAT fc[4];
	pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
	if (iColorType > 0)
		crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

	return crFill;
}

void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage)
{
	ASSERT(pImage != NULL);

	CPDF_Document* pDoc = m_pPageView->GetPDFDocument();//pDocument->GetDocument();
	ASSERT(pDoc != NULL);

	CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");
	ASSERT(pAPDict != NULL);

	CPDF_Stream* pStream = pAPDict->GetStream(sAPType);
	ASSERT(pStream != NULL);

	CPDF_Dictionary* pStreamDict = pStream->GetDict();
	ASSERT(pStreamDict != NULL);

	CFX_ByteString sImageAlias = "IMG";

	if (CPDF_Dictionary* pImageDict = pImage->GetDict())
	{
		sImageAlias = pImageDict->GetString("Name");
		if (sImageAlias.IsEmpty())
			sImageAlias = "IMG";
	}	

	CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
	if (!pStreamResList)
	{
		pStreamResList = new CPDF_Dictionary();
		pStreamDict->SetAt("Resources", pStreamResList);
	}

	if (pStreamResList)
	{
		CPDF_Dictionary* pXObject = new CPDF_Dictionary;
		pXObject->SetAtReference(sImageAlias, pDoc, pImage);
		pStreamResList->SetAt("XObject", pXObject);
	}
}

void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType)
{
	if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP"))
	{
		pAPDict->RemoveAt(sAPType);
	}
}

FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, PDFSDK_FieldAction& data, CPDFSDK_PageView* pPageView)
{
	CPDF_Action action = GetAAction(type);

	if (action && action.GetType() != CPDF_Action::Unknown)
	{
 		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
 		ASSERT(pDocument != NULL);
 
 		CPDFDoc_Environment* pEnv = pDocument->GetEnv();
 		ASSERT(pEnv != NULL);

		CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();/*(CPDFSDK_ActionHandler*)pApp->GetActionHandler();*/
 		ASSERT(pActionHandler != NULL);
 
 		return pActionHandler->DoAction_Field(action, type, pDocument, GetFormField(), data);
	}

	return FALSE;
}

CPDF_Action	CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT)
{
	switch (eAAT)
	{
	case CPDF_AAction::CursorEnter:
	case CPDF_AAction::CursorExit:
	case CPDF_AAction::ButtonDown:
	case CPDF_AAction::ButtonUp:
	case CPDF_AAction::GetFocus:
	case CPDF_AAction::LoseFocus:
	case CPDF_AAction::PageOpen:
	case CPDF_AAction::PageClose:
	case CPDF_AAction::PageVisible:
	case CPDF_AAction::PageInvisible:
		return CPDFSDK_Annot::GetAAction(eAAT);

	case CPDF_AAction::KeyStroke:
	case CPDF_AAction::Format:
	case CPDF_AAction::Validate:
	case CPDF_AAction::Calculate:
		{
			CPDF_FormField* pField = GetFormField();
			if (CPDF_AAction aa = pField->GetAdditionalAction())
				return aa.GetAction(eAAT);

			return CPDFSDK_Annot::GetAAction(eAAT);
		}
	default:
		break;
	}

	return CPDF_Action();
}


CFX_WideString CPDFSDK_Widget::GetAlternateName() const
{
	CPDF_FormField*	pFormField = GetFormField();
	ASSERT(pFormField != NULL);

	return pFormField->GetAlternateName();
}

int32_t	CPDFSDK_Widget::GetAppearanceAge() const
{
	return m_nAppAge;
}

int32_t CPDFSDK_Widget::GetValueAge() const
{
	return m_nValueAge;
}


FX_BOOL	CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY)
{
	CPDF_Annot* pAnnot = GetPDFAnnot();
	CFX_FloatRect annotRect;
	pAnnot->GetRect(annotRect);
	if(annotRect.Contains(pageX, pageY))
	{
		if (!IsVisible()) return FALSE;
		
		int nFieldFlags = GetFieldFlags();
		if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) 
			return FALSE;
		
		return TRUE;
	}
	return FALSE;
}

CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
	:m_pDocument(pDocument),
	m_pInterForm(NULL),
	m_bCalculate(TRUE),
	m_bBusy(FALSE)
{
	ASSERT(m_pDocument != NULL);
	m_pInterForm = new CPDF_InterForm(m_pDocument->GetDocument(), FALSE);
	ASSERT(m_pInterForm != NULL);
	m_pInterForm->SetFormNotify(this);

	for(int i=0; i<6; i++)
		m_bNeedHightlight[i] = FALSE;
	m_iHighlightAlpha = 0;
}

CPDFSDK_InterForm::~CPDFSDK_InterForm()
{
	ASSERT(m_pInterForm != NULL);
	delete m_pInterForm;
	m_pInterForm = NULL;

	m_Map.RemoveAll();
}

void CPDFSDK_InterForm::Destroy()
{
	delete this;
}

CPDF_InterForm* CPDFSDK_InterForm::GetInterForm()
{
	return m_pInterForm;
}

CPDFSDK_Document* CPDFSDK_InterForm::GetDocument()
{
	return m_pDocument;
}

FX_BOOL CPDFSDK_InterForm::HighlightWidgets()
{
	return FALSE;
}

CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const
{
    nonstd::unique_ptr<CBA_AnnotIterator> pIterator(
        new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));

    if (bNext) {
        return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
    }
    return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
}

CPDFSDK_Widget*	CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const
{
	if(!pControl || !m_pInterForm) return NULL;
	
	CPDFSDK_Widget* pWidget = NULL;
	m_Map.Lookup(pControl, pWidget);

	if (pWidget) return pWidget;

	CPDF_Dictionary* pControlDict = pControl->GetWidget();
	ASSERT(pControlDict != NULL);

	ASSERT(m_pDocument != NULL);
	CPDF_Document* pDocument = m_pDocument->GetDocument();

	CPDFSDK_PageView* pPage = NULL;

	if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("P"))
	{
		int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
		if (nPageIndex >= 0)
		{
			pPage = m_pDocument->GetPageView(nPageIndex);
		}
	}

	if (!pPage) 
	{
		int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
		if (nPageIndex >= 0)
		{
			pPage = m_pDocument->GetPageView(nPageIndex);
		}
	}

	if (pPage)
		return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);

	return NULL;
}

void CPDFSDK_InterForm::GetWidgets(const CFX_WideString& sFieldName, CFX_PtrArray& widgets)
{
	ASSERT(m_pInterForm != NULL);

	for (int i=0,sz=m_pInterForm->CountFields(sFieldName); i<sz; i++)
	{
		CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
		ASSERT(pFormField != NULL);

		GetWidgets(pFormField, widgets);	
	}
}

void CPDFSDK_InterForm::GetWidgets(CPDF_FormField* pField, CFX_PtrArray& widgets)
{
	ASSERT(pField != NULL);

	for (int i=0,isz=pField->CountControls(); i<isz; i++)
	{
		CPDF_FormControl* pFormCtrl = pField->GetControl(i);
		ASSERT(pFormCtrl != NULL);

		CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);

		if (pWidget)
			widgets.Add(pWidget);
	}
}

int CPDFSDK_InterForm::GetPageIndexByAnnotDict(CPDF_Document* pDocument, CPDF_Dictionary* pAnnotDict) const
{
	ASSERT(pDocument != NULL);
	ASSERT(pAnnotDict != NULL);

	for (int i=0,sz=pDocument->GetPageCount(); i<sz; i++)
	{
		if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i))
		{			
			if (CPDF_Array* pAnnots = pPageDict->GetArray("Annots"))
			{
				for (int j=0,jsz=pAnnots->GetCount(); j<jsz; j++)
				{
					CPDF_Object* pDict = pAnnots->GetElementValue(j);
					if (pAnnotDict == pDict)
					{
						return i;
					}
				}
			}
		}
	}

	return -1;
}

void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget)
{
	m_Map.SetAt(pControl, pWidget);
}

void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl)
{
	m_Map.RemoveKey(pControl);
}

void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled)
{
	m_bCalculate = bEnabled;
}

FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const
{
	return m_bCalculate;
}

#ifdef _WIN32
CPDF_Stream* CPDFSDK_InterForm::LoadImageFromFile(const CFX_WideString& sFile)
{
	ASSERT(m_pDocument != NULL);
	CPDF_Document* pDocument = m_pDocument->GetDocument();
	ASSERT(pDocument != NULL);

	CPDF_Stream* pRetStream = NULL;

	if (CFX_DIBitmap* pBmp = CFX_WindowsDIB::LoadFromFile(sFile.c_str()))
	{
		int nWidth = pBmp->GetWidth();
		int nHeight = pBmp->GetHeight();

		CPDF_Image Image(pDocument);
		Image.SetImage(pBmp, FALSE);
		CPDF_Stream* pImageStream = Image.GetStream();
		if (pImageStream)
		{
			if (pImageStream->GetObjNum() == 0)
				pDocument->AddIndirectObject(pImageStream);

			CPDF_Dictionary* pStreamDict = new CPDF_Dictionary();
			pStreamDict->SetAtName("Subtype", "Form");
			pStreamDict->SetAtName("Name", "IMG");
			CPDF_Array* pMatrix = new CPDF_Array();
			pStreamDict->SetAt("Matrix", pMatrix);
			pMatrix->AddInteger(1);
			pMatrix->AddInteger(0);
			pMatrix->AddInteger(0);
			pMatrix->AddInteger(1);
			pMatrix->AddInteger(-nWidth / 2);
			pMatrix->AddInteger(-nHeight / 2);
			CPDF_Dictionary* pResource = new CPDF_Dictionary();
			pStreamDict->SetAt("Resources", pResource);
			CPDF_Dictionary* pXObject = new CPDF_Dictionary();
			pResource->SetAt("XObject", pXObject);
			pXObject->SetAtReference("Img", pDocument, pImageStream);
			CPDF_Array* pProcSet = new CPDF_Array();
			pResource->SetAt("ProcSet", pProcSet);
			pProcSet->AddName("PDF");
			pProcSet->AddName("ImageC");
			pStreamDict->SetAtName("Type", "XObject");
			CPDF_Array* pBBox = new CPDF_Array();
			pStreamDict->SetAt("BBox", pBBox);
			pBBox->AddInteger(0);
			pBBox->AddInteger(0);
			pBBox->AddInteger(nWidth);
			pBBox->AddInteger(nHeight);
			pStreamDict->SetAtInteger("FormType", 1);

			pRetStream = new CPDF_Stream(NULL, 0, NULL);
			CFX_ByteString csStream;
			csStream.Format("q\n%d 0 0 %d 0 0 cm\n/Img Do\nQ", nWidth, nHeight);
			pRetStream->InitStream((uint8_t*)csStream.c_str(), csStream.GetLength(), pStreamDict);
			pDocument->AddIndirectObject(pRetStream);
		}

		delete pBmp;
	}

	return pRetStream;
}
#endif

void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField)
{
	ASSERT(m_pDocument != NULL);
	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
	ASSERT(pEnv);
	if(!pEnv->IsJSInitiated())
		return;

	if (m_bBusy) return;

	m_bBusy = TRUE;

	if (IsCalculateEnabled())
	{
		IFXJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
		ASSERT(pRuntime != NULL);

		pRuntime->SetReaderDocument(m_pDocument);

		int nSize = m_pInterForm->CountFieldsInCalculationOrder();
		for (int i=0; i<nSize; i++)
		{
			if(CPDF_FormField* pField = m_pInterForm->GetFieldInCalculationOrder(i))
			{
//			ASSERT(pField != NULL);
				int nType = pField->GetFieldType();
				if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
				{
					CPDF_AAction aAction = pField->GetAdditionalAction();
					if (aAction && aAction.ActionExist(CPDF_AAction::Calculate))
					{
						CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
						if (action)
						{
							CFX_WideString csJS = action.GetJavaScript();
							if (!csJS.IsEmpty())
							{
								IFXJS_Context* pContext = pRuntime->NewContext();
								ASSERT(pContext != NULL);
								
								CFX_WideString sOldValue = pField->GetValue();
								CFX_WideString sValue = sOldValue;
								FX_BOOL bRC = TRUE;
								pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
								
								CFX_WideString sInfo;
								FX_BOOL bRet = pContext->RunScript(csJS, sInfo);
								pRuntime->ReleaseContext(pContext);
								
								if (bRet)
								{
									if (bRC)
									{
										if (sValue.Compare(sOldValue) != 0)
											pField->SetValue(sValue, TRUE);
									}
								}
							}
						}
					}
				}
			}
		}

		
	}

	m_bBusy = FALSE;
}

CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, FX_BOOL& bFormated)
{
	ASSERT(m_pDocument != NULL);
	ASSERT(pFormField != NULL);

	CFX_WideString sValue = pFormField->GetValue();
	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
	ASSERT(pEnv);
	if(!pEnv->IsJSInitiated())
	{
		bFormated = FALSE;
		return sValue;
	} 

	IFXJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
	ASSERT(pRuntime != NULL);
	
	pRuntime->SetReaderDocument(m_pDocument);

	if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX)
	{
		if (pFormField->CountSelectedItems() > 0)
		{
			int index = pFormField->GetSelectedIndex(0);
			if (index >= 0)
				sValue = pFormField->GetOptionLabel(index);
		}
	}

	bFormated = FALSE;

	CPDF_AAction aAction = pFormField->GetAdditionalAction();
	if (aAction != NULL && aAction.ActionExist(CPDF_AAction::Format)) 
	{
		CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
		if (action)
		{			
			CFX_WideString script = action.GetJavaScript();
			if (!script.IsEmpty())
			{
				CFX_WideString Value = sValue;

				IFXJS_Context* pContext = pRuntime->NewContext();
				ASSERT(pContext != NULL);

				pContext->OnField_Format(pFormField, Value, TRUE);
			
				CFX_WideString sInfo;
 				FX_BOOL bRet = pContext->RunScript(script, sInfo);
				pRuntime->ReleaseContext(pContext);

				if (bRet)
				{
					sValue = Value;
					bFormated = TRUE;
				}
			}
		}
	}

	return sValue;
}

void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, const FX_WCHAR* sValue, FX_BOOL bValueChanged)
{
	ASSERT(pFormField != NULL);

	for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
	{
		CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
		ASSERT(pFormCtrl != NULL);

		ASSERT(m_pInterForm != NULL);
		if(CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
			pWidget->ResetAppearance(sValue, bValueChanged);
	}
}

void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField)
{
	ASSERT(pFormField != NULL);

	for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
	{
		CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
		ASSERT(pFormCtrl != NULL);

		if(CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
		{
			CPDFDoc_Environment * pEnv = m_pDocument->GetEnv();
			CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
			
			CPDF_Page * pPage = pWidget->GetPDFPage();
			CPDFSDK_PageView * pPageView = m_pDocument->GetPageView(pPage,FALSE);

			FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);

			pEnv->FFI_Invalidate(pPage,rcBBox.left, rcBBox.top, rcBBox.right, rcBBox.bottom);
		}
	}
}

void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC)
{
	ASSERT(pFormField != NULL);

 	CPDF_AAction aAction = pFormField->GetAdditionalAction();
 	if (aAction != NULL && aAction.ActionExist(CPDF_AAction::KeyStroke)) 
 	{
 		CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
 		if (action)
 		{			 
 			ASSERT(m_pDocument != NULL);
 			CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
 			ASSERT(pEnv != NULL);

			CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
			ASSERT(pActionHandler != NULL);
	
			PDFSDK_FieldAction fa;
			fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
 			fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
			fa.sValue = csValue;

   			pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke, 
   				m_pDocument, pFormField, fa);
   			bRC = fa.bRC;
 		}
 	}
}

void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC)
{
	ASSERT(pFormField != NULL);

 	CPDF_AAction aAction = pFormField->GetAdditionalAction();
 	if (aAction != NULL && aAction.ActionExist(CPDF_AAction::Validate)) 
 	{
 		CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
		if (action)
 		{		
			ASSERT(m_pDocument != NULL);
			CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
			ASSERT(pEnv != NULL);
			
			CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
			ASSERT(pActionHandler != NULL);

			PDFSDK_FieldAction fa;
			fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
			fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
			fa.sValue = csValue;

			pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate, m_pDocument, pFormField, fa);
			bRC = fa.bRC;
 	 
		}
 	}
}

/* ----------------------------- action ----------------------------- */

FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action)
{
	ASSERT(action);

	CPDF_ActionFields af = action.GetWidgets();
	CFX_PtrArray fieldObjects;
	af.GetAllFields(fieldObjects);
	CFX_PtrArray widgetArray;
	CFX_PtrArray fields;
	GetFieldFromObjects(fieldObjects, fields);

	FX_BOOL bHide = action.GetHideStatus();

	FX_BOOL bChanged = FALSE;
	
	for (int i=0, sz=fields.GetSize(); i<sz; i++)
	{
		CPDF_FormField* pField = (CPDF_FormField*)fields[i];
		ASSERT(pField != NULL);

	
		for (int j=0,jsz=pField->CountControls(); j<jsz; j++)
		{
			CPDF_FormControl* pControl = pField->GetControl(j);
			ASSERT(pControl != NULL);

			if (CPDFSDK_Widget* pWidget = GetWidget(pControl))
			{
				int nFlags = pWidget->GetFlags();
				if (bHide)
				{
					nFlags &= (~ANNOTFLAG_INVISIBLE);
					nFlags &= (~ANNOTFLAG_NOVIEW);
					nFlags |= (ANNOTFLAG_HIDDEN);
				}
				else
				{
					nFlags &= (~ANNOTFLAG_INVISIBLE);
					nFlags &= (~ANNOTFLAG_HIDDEN);
					nFlags &= (~ANNOTFLAG_NOVIEW);
				}
				pWidget->SetFlags(nFlags);

 				CPDFSDK_PageView* pPageView = pWidget->GetPageView();
 				ASSERT(pPageView != NULL);
 
 				pPageView->UpdateView(pWidget);

				bChanged = TRUE;
			}
		}
	}

	return bChanged;
}

FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action)
{
	ASSERT(action);
	ASSERT(m_pInterForm != NULL);

	CFX_WideString sDestination = action.GetFilePath();
	if (sDestination.IsEmpty()) return FALSE;

	CPDF_Dictionary* pActionDict = action.GetDict();
	if (pActionDict->KeyExist("Fields"))
	{
		CPDF_ActionFields af = action.GetWidgets();
		FX_DWORD dwFlags = action.GetFlags();
		
		CFX_PtrArray fieldObjects;
		af.GetAllFields(fieldObjects);
		CFX_PtrArray fields;
		GetFieldFromObjects(fieldObjects, fields);
		
		if (fields.GetSize() != 0)
		{
			FX_BOOL bIncludeOrExclude = !(dwFlags & 0x01);
			if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
			{
				return FALSE;
			}
			return SubmitFields(sDestination, fields, bIncludeOrExclude, FALSE);
		}
		else
		{
			if ( m_pInterForm->CheckRequiredFields())
			{
				return FALSE;
			}

			return SubmitForm(sDestination, FALSE);
		}
	}
	else
	{
		if ( m_pInterForm->CheckRequiredFields())
		{
			return FALSE;
		}

		return SubmitForm(sDestination, FALSE);
	}
}

FX_BOOL CPDFSDK_InterForm::SubmitFields(const CFX_WideString& csDestination, const CFX_PtrArray& fields,
									FX_BOOL bIncludeOrExclude, FX_BOOL bUrlEncoded)
{
	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
	ASSERT(pEnv != NULL);

	CFX_ByteTextBuf textBuf;
	ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);

	uint8_t* pBuffer = textBuf.GetBuffer();
	FX_STRSIZE nBufSize = textBuf.GetLength();
	
	if (bUrlEncoded)
	{
		if(!FDFToURLEncodedData(pBuffer, nBufSize))
			return FALSE;
	}

	pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
	
	return TRUE;
}

void CPDFSDK_InterForm::DoFDFBuffer(CFX_ByteString sBuffer)
{
	ASSERT(m_pDocument != NULL);

	if (CFDF_Document *pFDFDocument = CFDF_Document::ParseMemory((const unsigned char *)sBuffer.GetBuffer(sBuffer.GetLength()), sBuffer.GetLength()))
	{						
		CPDF_Dictionary* pRootDic = pFDFDocument->GetRoot();
		if(pRootDic)
		{
			CPDF_Dictionary * pFDFDict=pRootDic->GetDict("FDF");
			if(pFDFDict)
			{		
				CPDF_Dictionary * pJSDict = pFDFDict->GetDict("JavaScript");
				if(pJSDict)
				{
					CFX_WideString csJS;
				
					CPDF_Object* pJS = pJSDict->GetElementValue("Before");
					if (pJS != NULL)
					{
						int iType = pJS->GetType();
						if (iType == PDFOBJ_STRING)
							csJS = pJSDict->GetUnicodeText("Before");
						else if (iType == PDFOBJ_STREAM)
							csJS = pJS->GetUnicodeText();
					}
					
				}
			}
		}
		delete pFDFDocument;
	}

	sBuffer.ReleaseBuffer();
}

FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, CFX_WideString csTxtFile)
{
	return TRUE;
}

FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf, FX_STRSIZE& nBufSize)
{
 	CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
 	if (pFDF)
 	{
 		CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
 		if (pMainDict == NULL) return FALSE;
 		
 		// Get fields
 		CPDF_Array* pFields = pMainDict->GetArray("Fields");
 		if (pFields == NULL) return FALSE;
		
		CFX_ByteTextBuf fdfEncodedData;

 		for (FX_DWORD i = 0; i < pFields->GetCount(); i ++) 
 		{
 			CPDF_Dictionary* pField = pFields->GetDict(i);
 			if (pField == NULL) continue;
 			CFX_WideString name;
 			name = pField->GetUnicodeText("T");
 			CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
 			CFX_ByteString csBValue = pField->GetString("V");
 			CFX_WideString csWValue = PDF_DecodeText(csBValue);
 			CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);

			fdfEncodedData = fdfEncodedData<<name_b.GetBuffer(name_b.GetLength());
  			name_b.ReleaseBuffer();
			fdfEncodedData = fdfEncodedData<<"=";
			fdfEncodedData = fdfEncodedData<<csValue_b.GetBuffer(csValue_b.GetLength());
  			csValue_b.ReleaseBuffer();
  			if(i != pFields->GetCount()-1)
  				fdfEncodedData = fdfEncodedData<<"&";
 		}

		nBufSize = fdfEncodedData.GetLength();
		pBuf = FX_Alloc(uint8_t, nBufSize);
		FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
 	}
	return TRUE;
}

FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(const CFX_PtrArray& fields,FX_BOOL bIncludeOrExclude, CFX_ByteTextBuf& textBuf)
{
	ASSERT(m_pDocument != NULL);
	ASSERT(m_pInterForm != NULL);
	
	CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath(),(CFX_PtrArray&)fields, bIncludeOrExclude);
	if (!pFDF) return FALSE;
	FX_BOOL bRet = pFDF->WriteBuf(textBuf); // = FALSE;//
	delete pFDF;
	
	return bRet;
}

CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(const CFX_WideString& sFileExt)
{
	CFX_WideString sFileName;
	return L"";
}

FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded)
{
 	if (sDestination.IsEmpty()) return FALSE;

	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
	ASSERT(pEnv != NULL);

	if(NULL == m_pDocument) return FALSE;
	CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
	
	if(NULL == m_pInterForm) return FALSE;
	CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath);
	if (NULL == pFDFDoc) return FALSE;

	CFX_ByteTextBuf FdfBuffer;
	FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
	delete pFDFDoc;
	if (!bRet) return FALSE;

	uint8_t* pBuffer = FdfBuffer.GetBuffer();
	FX_STRSIZE nBufSize = FdfBuffer.GetLength();
	
	if (bUrlEncoded)
	{
		if(!FDFToURLEncodedData(pBuffer, nBufSize))
			return FALSE;
	}

	pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
	
	if (bUrlEncoded && pBuffer)
	{
		FX_Free(pBuffer);
		pBuffer = NULL;	
	}

	return TRUE;
}

FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf)
{

	ASSERT(m_pInterForm != NULL);
	ASSERT(m_pDocument != NULL);
	
	CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
	if (!pFDF) return FALSE;
	
	FX_BOOL bRet = pFDF->WriteBuf(textBuf);
	delete pFDF;
	
	return bRet;
}


FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action)
{
	ASSERT(action);

	CPDF_Dictionary* pActionDict = action.GetDict();
	if (pActionDict->KeyExist("Fields"))
	{
		CPDF_ActionFields af = action.GetWidgets();
		FX_DWORD dwFlags = action.GetFlags();

		CFX_PtrArray fieldObjects;
		af.GetAllFields(fieldObjects);
		CFX_PtrArray fields;
		GetFieldFromObjects(fieldObjects, fields);
		return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), TRUE);
	}

	return m_pInterForm->ResetForm(TRUE);
}

FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action)
{
	return FALSE;
}

void CPDFSDK_InterForm::GetFieldFromObjects(const CFX_PtrArray& objects, CFX_PtrArray& fields)
{
	ASSERT(m_pInterForm != NULL);

	int iCount = objects.GetSize();
	for (int i = 0; i < iCount; i ++)
	{
		CPDF_Object* pObject = (CPDF_Object*)objects[i];
		if (pObject == NULL) continue;
		
		int iType = pObject->GetType();
		if (iType == PDFOBJ_STRING)
		{
			CFX_WideString csName = pObject->GetUnicodeText();
			CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
			if (pField != NULL)
				fields.Add(pField);
		}
		else if (iType == PDFOBJ_DICTIONARY)
		{
			if (m_pInterForm->IsValidFormField(pObject))
				fields.Add(pObject);
		}
	}
}

/* ----------------------------- CPDF_FormNotify ----------------------------- */

int	CPDFSDK_InterForm::BeforeValueChange(const CPDF_FormField* pField, CFX_WideString& csValue)
{
	ASSERT(pField != NULL);

	CPDF_FormField* pFormField = (CPDF_FormField*)pField;

	int nType = pFormField->GetFieldType();
	if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
	{
		FX_BOOL bRC = TRUE;
		OnKeyStrokeCommit(pFormField, csValue, bRC);
		if (bRC) 
		{
			OnValidate(pFormField, csValue, bRC);
			if (bRC)
				return 1;
			else
				return -1;
		}
		else
			return -1;
	}
	else
		return 0;
}

int	CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField)
{
	ASSERT(pField != NULL);

	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
	int nType = pFormField->GetFieldType();

	if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
	{
		OnCalculate(pFormField);
		FX_BOOL bFormated = FALSE;
		CFX_WideString sValue = OnFormat(pFormField, bFormated);
		if (bFormated)
			ResetFieldAppearance(pFormField, sValue.c_str(), TRUE);
		else
			ResetFieldAppearance(pFormField, NULL, TRUE);
		UpdateField(pFormField);
	}

	return 0;
}

int	CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField, CFX_WideString& csValue)
{
	ASSERT(pField != NULL);

	CPDF_FormField* pFormField = (CPDF_FormField*)pField;

	int nType = pFormField->GetFieldType();
	if (nType == FIELDTYPE_LISTBOX)
	{
		FX_BOOL bRC = TRUE;
		OnKeyStrokeCommit(pFormField, csValue, bRC);
		if (bRC) 
		{
			OnValidate(pFormField, csValue, bRC);
			if (bRC)
				return 1;
			else
				return -1;
		}
		else
			return -1;
	}
	else
		return 0;
}

int	CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField)
{
	ASSERT(pField != NULL);

	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
	int nType = pFormField->GetFieldType();

	if (nType == FIELDTYPE_LISTBOX)
	{
		OnCalculate(pFormField);
		ResetFieldAppearance(pFormField, NULL, TRUE);
		UpdateField(pFormField);
	}

	return 0;
}

int	CPDFSDK_InterForm::AfterCheckedStatusChange(const CPDF_FormField* pField, const CFX_ByteArray& statusArray)
{
	ASSERT(pField != NULL);

	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
	int nType = pFormField->GetFieldType();

	if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON)
	{
		OnCalculate(pFormField);
		UpdateField(pFormField);
	}

	return 0;
}

int	CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm)
{
	return 0;
}

int	CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm)
{
    OnCalculate(nullptr);
    return 0;
}

int	CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm)
{
	return 0;
}

int	CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm)
{
    OnCalculate(nullptr);
    return 0;
}

FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType)
{
	if(nFieldType <1 || nFieldType > 6)
		return FALSE;
	return m_bNeedHightlight[nFieldType-1];
}

void CPDFSDK_InterForm::RemoveAllHighLight()
{
	memset((void*)m_bNeedHightlight, 0, 6*sizeof(FX_BOOL));
}
void   CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType)
{
	if(nFieldType <0 || nFieldType > 6) return;
	switch(nFieldType)
	{
	case 0:
		{
			for(int i=0; i<6; i++)
			{
				m_aHighlightColor[i] = clr;
				m_bNeedHightlight[i] = TRUE;
			}
			break;
		}
	default:
		{
			m_aHighlightColor[nFieldType-1] = clr;
			m_bNeedHightlight[nFieldType-1] = TRUE;
			break;
		}
	}
	
}

FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType)
{
	if(nFieldType <0 || nFieldType >6) return FXSYS_RGB(255,255,255);
	if(nFieldType == 0)
		return m_aHighlightColor[0];
	else
		return m_aHighlightColor[nFieldType-1];
}

/* ------------------------- CBA_AnnotIterator ------------------------- */

CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, const CFX_ByteString& sType, const CFX_ByteString& sSubType)
	:m_pPageView(pPageView),
	m_sType(sType),
	m_sSubType(sSubType),
	m_nTabs(BAI_STRUCTURE)
{
	ASSERT(m_pPageView != NULL);

	CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
	ASSERT(pPDFPage != NULL);
	ASSERT(pPDFPage->m_pFormDict != NULL);

	CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs");

	if (sTabs == "R")
	{
		m_nTabs = BAI_ROW;
	}
	else if (sTabs == "C")
	{
		m_nTabs = BAI_COLUMN;
	}
	else
	{
		m_nTabs = BAI_STRUCTURE;
	}

	GenerateResults();
}

CBA_AnnotIterator::~CBA_AnnotIterator()
{
	m_Annots.RemoveAll();
}

CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot()
{
	if (m_Annots.GetSize() > 0)
		return m_Annots[0];
	
	return NULL;
}

CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot()
{
	if (m_Annots.GetSize() > 0)
		return m_Annots[m_Annots.GetSize() - 1];

	return NULL;
}

CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot)
{
	for (int i=0,sz=m_Annots.GetSize(); i<sz; i++)
	{
		if (m_Annots[i] == pAnnot)
		{
			if (i+1 < sz)
				return m_Annots[i+1];
			else
				return m_Annots[0];
		}
	}

	return NULL;
}

CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot)
{
	for (int i=0,sz=m_Annots.GetSize(); i<sz; i++)
	{
		if (m_Annots[i] == pAnnot)
		{
			if (i-1 >= 0)
				return m_Annots[i-1];
			else
				return m_Annots[sz-1];
		}
	}

	return NULL;
}

int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
{
	ASSERT(p1 != NULL);
	ASSERT(p2 != NULL);

	CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
	CPDF_Rect rcAnnot2 = GetAnnotRect(p2);

	if (rcAnnot1.left < rcAnnot2.left)
		return -1;
	if (rcAnnot1.left > rcAnnot2.left)
		return 1;
	return 0;
}


int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
{
	ASSERT(p1 != NULL);
	ASSERT(p2 != NULL);

	CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
	CPDF_Rect rcAnnot2 = GetAnnotRect(p2);

	if (rcAnnot1.top < rcAnnot2.top)
		return -1;
	if (rcAnnot1.top > rcAnnot2.top)
		return 1;
	return 0;
}

void CBA_AnnotIterator::GenerateResults()
{
	ASSERT(m_pPageView != NULL);

	switch (m_nTabs)
	{
	case BAI_STRUCTURE:
		{
			for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
			{
				CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
				ASSERT(pAnnot != NULL);

				if (pAnnot->GetType() == m_sType 
					&& pAnnot->GetSubType() == m_sSubType)
					m_Annots.Add(pAnnot);
			}
		}
		break;
	case BAI_ROW:
		{
			CPDFSDK_SortAnnots sa;

			{
				
				for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
				{
					CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
					ASSERT(pAnnot != NULL);

					if (pAnnot->GetType() == m_sType 
						&& pAnnot->GetSubType() == m_sSubType)
						sa.Add(pAnnot);
				}
			}

			if (sa.GetSize() > 0)
			{
				sa.Sort(CBA_AnnotIterator::CompareByLeft);
			}

			while (sa.GetSize() > 0)
			{
				int nLeftTopIndex = -1;

				{
					FX_FLOAT fTop = 0.0f;

					for (int i=sa.GetSize()-1; i>=0; i--)
					{
						CPDFSDK_Annot* pAnnot = sa.GetAt(i);
						ASSERT(pAnnot != NULL);

						CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);

						if (rcAnnot.top > fTop)
						{
							nLeftTopIndex = i;
							fTop = rcAnnot.top;
						}
					}
				}

				if (nLeftTopIndex >= 0)
				{
					CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
					ASSERT(pLeftTopAnnot != NULL);

					CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
					
					m_Annots.Add(pLeftTopAnnot);
					sa.RemoveAt(nLeftTopIndex);

					CFX_ArrayTemplate<int> aSelect;

					{
						for (int i=0,sz=sa.GetSize(); i<sz; i++)
						{
							CPDFSDK_Annot* pAnnot = sa.GetAt(i);
							ASSERT(pAnnot != NULL);

							CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);

							FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;

							if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
								aSelect.Add(i);
						}
					}

					{
						for (int i=0,sz=aSelect.GetSize(); i<sz; i++)
						{
							m_Annots.Add(sa[aSelect[i]]);
						}
					}

					{
						for (int i=aSelect.GetSize()-1; i>=0; i--)
						{
							sa.RemoveAt(aSelect[i]);
						}
					}

					aSelect.RemoveAll();
				}
			}
			sa.RemoveAll();
		}
		break;
	case BAI_COLUMN:
		{
			CPDFSDK_SortAnnots sa;

			{
				for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
				{
					CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
					ASSERT(pAnnot != NULL);

					if (pAnnot->GetType() == m_sType 
						&& pAnnot->GetSubType() == m_sSubType)
						sa.Add(pAnnot);
				}
			}

			if (sa.GetSize() > 0)
			{
				sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE);
			}

			while (sa.GetSize() > 0)
			{
				int nLeftTopIndex = -1;

				{
					FX_FLOAT fLeft = -1.0f;

					for (int i=sa.GetSize()-1; i>=0; i--)
					{
						CPDFSDK_Annot* pAnnot = sa.GetAt(i);
						ASSERT(pAnnot != NULL);

						CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);

						if (fLeft < 0)
						{
							nLeftTopIndex = 0;
							fLeft = rcAnnot.left;
						}
						else if (rcAnnot.left < fLeft)
						{
							nLeftTopIndex = i;
							fLeft = rcAnnot.left;
						}
					}
				}

				if (nLeftTopIndex >= 0)
				{
					CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
					ASSERT(pLeftTopAnnot != NULL);

					CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
					
					m_Annots.Add(pLeftTopAnnot);
					sa.RemoveAt(nLeftTopIndex);

					CFX_ArrayTemplate<int> aSelect;

					{
						for (int i=0,sz=sa.GetSize(); i<sz; i++)
						{
							CPDFSDK_Annot* pAnnot = sa.GetAt(i);
							ASSERT(pAnnot != NULL);

							CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);

							FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;

							if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
								aSelect.Add(i);
						}
					}

					{
						for (int i=0,sz=aSelect.GetSize(); i<sz; i++)
						{
							m_Annots.Add(sa[aSelect[i]]);
						}
					}

					{
						for (int i=aSelect.GetSize()-1; i>=0; i--)
						{
							sa.RemoveAt(aSelect[i]);
						}
					}

					aSelect.RemoveAll();
				}
			}
			sa.RemoveAll();
		}
		break;
	}
}

CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot)
{
	ASSERT(pAnnot != NULL);

	CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
	ASSERT(pPDFAnnot != NULL);

	CPDF_Rect rcAnnot;
	pPDFAnnot->GetRect(rcAnnot);

	return rcAnnot;
}

