// 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;
        }
        return FALSE;
    }

    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());
}

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();
    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);
    }
    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()
{
    delete m_pInterForm;
    m_pInterForm = nullptr;
    m_Map.clear();
}

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 nullptr;

    CPDFSDK_Widget* pWidget = nullptr;
    const auto it = m_Map.find(pControl);
    if (it != m_Map.end())
        pWidget = it->second;

    if (pWidget)
        return pWidget;

    CPDF_Dictionary* pControlDict = pControl->GetWidget();
    CPDF_Document* pDocument = m_pDocument->GetDocument();
    CPDFSDK_PageView* pPage = nullptr;

    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 nullptr;
    return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
}

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[pControl] = pWidget;
}

void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl)
{
    m_Map.erase(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(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);
        }
    }
    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)
{
    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);
            return bRC ? 1 : -1;
        }
        return -1;
    }
    return 0;
}

int CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField)
{
    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)
{
    CPDF_FormField* pFormField = (CPDF_FormField*)pField;
    if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
        return 0;

    FX_BOOL bRC = TRUE;
    OnKeyStrokeCommit(pFormField, csValue, bRC);
    if (!bRC)
        return -1;

    OnValidate(pFormField, csValue, bRC);
    if (!bRC)
        return -1;

    return 1;
}

int CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField)
{
    CPDF_FormField* pFormField = (CPDF_FormField*)pField;
    if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX)
    {
        OnCalculate(pFormField);
        ResetFieldAppearance(pFormField, NULL, TRUE);
        UpdateField(pFormField);
    }
    return 0;
}

int CPDFSDK_InterForm::AfterCheckedStatusChange(const CPDF_FormField* pField, const CFX_ByteArray& statusArray)
{
    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];
    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)
            return (i + 1 < sz) ? m_Annots[i+1] : 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)
            return (i - 1 >= 0) ? m_Annots[i-1] : m_Annots[sz-1];
    }
    return NULL;
}

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

    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;
}

