// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../include/fsdk_define.h"
#include "../include/fsdk_mgr.h"
#include "../include/fsdk_baseannot.h"


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

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

FX_WORD _gAfxGetYearDays(int16_t year)
{
    return (_gAfxIsLeapYear(year) == true ? 366 : 365);
}

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

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

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

    default:
        mDays = 0;
        break;
    }

    return mDays;
}

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

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

    FromPDFDateTimeString(dtStr);
}

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

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


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

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

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

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

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

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

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

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

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

    if (d1 > d3) return true;
    if (d2 > d4) return true;
    return false;
}

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

    if (d1 >= d3) return true;
    if (d2 >= d4) return true;
    return false;
}

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

    if (d1 < d3) return true;
    if (d2 < d4) return true;
    return false;
}

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

    if (d1 <= d3) return true;
    if (d2 <= d4) return true;
    return false;
}

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

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

    return mktime(&newtime);
}

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

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

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

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

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

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

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

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

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

    return  *this;
}

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

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

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

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

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

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

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

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

    return *this;
}

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

    int n;
    int days;

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

    return *this;
}


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

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

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

FX_DWORD CPDFSDK_Annot::GetFlags()
{
    ASSERT(m_pAnnot != NULL);

    return m_pAnnot->GetFlags();
}

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

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

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

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

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

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

CPDF_Dictionary* CPDFSDK_Annot::GetAnnotDict() const
{
    ASSERT(m_pAnnot != NULL);

    return m_pAnnot->GetAnnotDict();
}

void CPDFSDK_Annot::SetRect(const CPDF_Rect& rect)
{
    ASSERT(rect.right - rect.left >= GetMinWidth());
    ASSERT(rect.top - rect.bottom >= GetMinHeight());

    m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
}

CPDF_Rect CPDFSDK_Annot::GetRect() const
{
    ASSERT(m_pAnnot != NULL);

    CPDF_Rect rect;
    m_pAnnot->GetRect(rect);

    return rect;
}

CFX_ByteString CPDFSDK_Annot::GetType() const
{
    ASSERT(m_pAnnot != NULL);

    return m_pAnnot->GetSubType();
}

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

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

    m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, mode, pOptions);
}

bool CPDFSDK_Annot::IsAppearanceValid()
{
    return m_pAnnot->GetAnnotDict()->GetDict("AP") != NULL;
}

bool CPDFSDK_Annot::IsAppearanceValid(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;

    return true;
}

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

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

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

CFX_WideString CPDFSDK_Annot::GetContents() const
{
    return m_pAnnot->GetAnnotDict()->GetUnicodeText("Contents");
}

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

CFX_WideString CPDFSDK_Annot::GetAnnotName() const
{
    return m_pAnnot->GetAnnotDict()->GetUnicodeText("NM");
}

void CPDFSDK_Annot::SetModifiedDate(const FX_SYSTEMTIME& st)
{
    CPDFSDK_DateTime dt(st);
    CFX_ByteString str = dt.ToPDFDateTimeString();

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

FX_SYSTEMTIME CPDFSDK_Annot::GetModifiedDate() const
{
    FX_SYSTEMTIME systime;
    CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetString("M");

    CPDFSDK_DateTime dt(str);
    dt.ToSystemTime(systime);

    return systime;
}

void CPDFSDK_Annot::SetFlags(int nFlags)
{
    m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
}

int CPDFSDK_Annot::GetFlags() const
{
    return m_pAnnot->GetAnnotDict()->GetInteger("F");
}

void CPDFSDK_Annot::SetAppState(const CFX_ByteString& str)
{
    if (str.IsEmpty())
        m_pAnnot->GetAnnotDict()->RemoveAt("AS");
    else
        m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
}

CFX_ByteString CPDFSDK_Annot::GetAppState() const
{
    return m_pAnnot->GetAnnotDict()->GetString("AS");
}

void CPDFSDK_Annot::SetStructParent(int key)
{
    m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
}

int CPDFSDK_Annot::GetStructParent() const
{
    return m_pAnnot->GetAnnotDict()->GetInteger("StructParent");
}

//border
void CPDFSDK_Annot::SetBorderWidth(int nWidth)
{
    CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArray("Border");

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

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

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

int CPDFSDK_Annot::GetBorderWidth() const
{
    if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArray("Border")) {
        return pBorder->GetInteger(2);
    }
    if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS")) {
        return pBSDict->GetInteger("W", 1);
    }
    return 1;
}

void CPDFSDK_Annot::SetBorderStyle(int nStyle)
{
    CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
    if (!pBSDict)
    {
        pBSDict = new CPDF_Dictionary;
        m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
    }

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

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

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

    return BBS_SOLID;
}

void CPDFSDK_Annot::SetBorderDash(const CFX_IntArray& array)
{
    CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
    if (!pBSDict)
    {
        pBSDict = new CPDF_Dictionary;
        m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
    }

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

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

void CPDFSDK_Annot::GetBorderDash(CFX_IntArray& array) const
{
    CPDF_Array* pDash = NULL;

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

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

void CPDFSDK_Annot::SetColor(FX_COLORREF color)
{
    CPDF_Array* pArray = new CPDF_Array;
    pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
    pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
    pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
    m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
}

void CPDFSDK_Annot::RemoveColor()
{
    m_pAnnot->GetAnnotDict()->RemoveAt("C");
}

bool CPDFSDK_Annot::GetColor(FX_COLORREF& color) const
{
    if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArray("C"))
    {
        int nCount = pEntry->GetCount();
        if (nCount == 1)
        {
            FX_FLOAT g = pEntry->GetNumber(0) * 255;

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

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

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

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

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

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

            return true;
        }
    }

    return false;
}


void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox,
                                const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
                                const CFX_ByteString& sAPState)
{
    CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");

    if (!pAPDict)
    {
        pAPDict = new CPDF_Dictionary;
        m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
    }

    CPDF_Stream* pStream = NULL;
    CPDF_Dictionary* pParentDict = NULL;

    if (sAPState.IsEmpty())
    {
        pParentDict = pAPDict;
        pStream = pAPDict->GetStream(sAPType);
    }
    else
    {
        CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType);
        if (!pAPTypeDict)
        {
            pAPTypeDict = new CPDF_Dictionary;
            pAPDict->SetAt(sAPType, pAPTypeDict);
        }

        pParentDict = pAPTypeDict;
        pStream = pAPTypeDict->GetStream(sAPState);
    }

    if (!pStream)
    {
        CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
        pStream = new CPDF_Stream(NULL, 0, NULL);
        int32_t objnum = pDoc->AddIndirectObject(pStream);
        pParentDict->SetAtReference(sAPType, pDoc, objnum);
    }

    CPDF_Dictionary *pStreamDict = pStream->GetDict();
    if (!pStreamDict)
    {
        pStreamDict = new CPDF_Dictionary;
        pStreamDict->SetAtName("Type", "XObject");
        pStreamDict->SetAtName("Subtype", "Form");
        pStreamDict->SetAtInteger("FormType", 1);
        pStream->InitStream(NULL,0,pStreamDict);
    }

    if (pStreamDict)
    {
        pStreamDict->SetAtMatrix("Matrix",matrix);
        pStreamDict->SetAtRect("BBox", rcBBox);
    }

    pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), false, false);
}

#define BA_ANNOT_MINWIDTH           1
#define BA_ANNOT_MINHEIGHT          1

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

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

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

CPDF_Action CPDFSDK_Annot::GetAction() const
{
    return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDict("A"));
}

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

void CPDFSDK_Annot::RemoveAction()
{
    m_pAnnot->GetAnnotDict()->RemoveAt("A");
}

CPDF_AAction CPDFSDK_Annot::GetAAction() const
{
    return m_pAnnot->GetAnnotDict()->GetDict("AA");
}

void CPDFSDK_Annot::SetAAction(const CPDF_AAction& aa)
{
    ASSERT(aa != NULL);

    if ((CPDF_AAction&)aa != m_pAnnot->GetAnnotDict()->GetDict("AA"))
        m_pAnnot->GetAnnotDict()->SetAt("AA", (CPDF_AAction&)aa);
}

void CPDFSDK_Annot::RemoveAAction()
{
    m_pAnnot->GetAnnotDict()->RemoveAt("AA");
}

CPDF_Action CPDFSDK_Annot::GetAAction(CPDF_AAction::AActionType eAAT)
{
    CPDF_AAction AAction = GetAAction();

    if (AAction.ActionExist(eAAT))
        return AAction.GetAction(eAAT);

    if (eAAT == CPDF_AAction::ButtonUp)
        return GetAction();

    return CPDF_Action();
}

void  CPDFSDK_Annot::Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, CPDF_RenderOptions* pOptions)
{

    m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
    m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, CPDF_Annot::Normal, NULL);

    return ;
}

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

