// 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 "fpdfsdk/include/pdfwindow/PWL_Note.h"

#include "core/include/fxge/fx_ge.h"
#include "fpdfsdk/include/pdfwindow/PWL_Button.h"
#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
#include "fpdfsdk/include/pdfwindow/PWL_Label.h"
#include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h"
#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"

#define POPUP_ITEM_HEAD_BOTTOM 3.0f
#define POPUP_ITEM_BOTTOMWIDTH 1.0f
#define POPUP_ITEM_SIDEMARGIN 3.0f
#define POPUP_ITEM_SPACE 4.0f
#define POPUP_ITEM_TEXT_INDENT 2.0f
#define POPUP_ITEM_BORDERCOLOR \
  CPWL_Color(COLORTYPE_RGB, 80 / 255.0f, 80 / 255.0f, 80 / 255.0f)

#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
#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))

CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) {}

CPWL_Note_Options::~CPWL_Note_Options() {}

void CPWL_Note_Options::SetTextColor(const CPWL_Color& color) {
  CPWL_Wnd::SetTextColor(color);

  if (m_pText)
    m_pText->SetTextColor(color);
}

void CPWL_Note_Options::RePosChildWnd() {
  if (IsValid()) {
    CFX_FloatRect rcClient = GetClientRect();

    if (rcClient.Width() > 15.0f) {
      rcClient.right -= 15.0f;
      m_pText->Move(rcClient, TRUE, FALSE);
      m_pText->SetVisible(TRUE);
    } else {
      m_pText->Move(CFX_FloatRect(0, 0, 0, 0), TRUE, FALSE);
      m_pText->SetVisible(FALSE);
    }
  }
}

void CPWL_Note_Options::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  m_pText = new CPWL_Label;
  PWL_CREATEPARAM tcp = cp;
  tcp.pParentWnd = this;
  tcp.dwFlags = PWS_CHILD | PWS_VISIBLE;
  m_pText->Create(tcp);
}

void CPWL_Note_Options::SetText(const CFX_WideString& sText) {
  m_pText->SetText(sText.c_str());
}

void CPWL_Note_Options::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                           CFX_Matrix* pUser2Device) {
  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);

  CFX_FloatRect rcClient = GetClientRect();
  rcClient.left = rcClient.right - 15.0f;

  CFX_FloatPoint ptCenter =
      CFX_FloatPoint((rcClient.left + rcClient.right) * 0.5f,
                     (rcClient.top + rcClient.bottom) * 0.5f);

  CFX_FloatPoint pt1(ptCenter.x - 2.0f, ptCenter.y + 2.0f * 0.5f);
  CFX_FloatPoint pt2(ptCenter.x + 2.0f, ptCenter.y + 2.0f * 0.5f);
  CFX_FloatPoint pt3(ptCenter.x, ptCenter.y - 3.0f * 0.5f);

  CFX_PathData path;

  path.SetPointCount(4);
  path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
  path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
  path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
  path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);

  pDevice->DrawPath(
      &path, pUser2Device, NULL,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), 0,
      FXFILL_ALTERNATE);
}

CFX_FloatRect CPWL_Note_Options::GetContentRect() const {
  CFX_FloatRect rcText = m_pText->GetContentRect();
  rcText.right += 15.0f;
  return rcText;
}

CPWL_Note_Edit::CPWL_Note_Edit()
    : m_bEnableNotify(TRUE),
      m_fOldItemHeight(0.0f),
      m_bSizeChanged(FALSE),
      m_fOldMin(0.0f),
      m_fOldMax(0.0f) {}

CPWL_Note_Edit::~CPWL_Note_Edit() {}

void CPWL_Note_Edit::RePosChildWnd() {
  m_bEnableNotify = FALSE;
  CPWL_Edit::RePosChildWnd();
  m_bEnableNotify = TRUE;

  m_fOldItemHeight = GetContentRect().Height();
}

void CPWL_Note_Edit::SetText(const FX_WCHAR* csText) {
  m_bEnableNotify = FALSE;
  CPWL_Edit::SetText(csText);
  m_bEnableNotify = TRUE;
  m_fOldItemHeight = GetContentRect().Height();
}

void CPWL_Note_Edit::OnSetFocus() {
  m_bEnableNotify = FALSE;
  CPWL_Edit::OnSetFocus();
  m_bEnableNotify = TRUE;

  EnableSpellCheck(TRUE);
}

void CPWL_Note_Edit::OnKillFocus() {
  EnableSpellCheck(FALSE);

  if (CPWL_Wnd* pParent = GetParentWindow()) {
    if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
      ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");

      CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pGrand;

      pNoteItem->OnContentsValidate();
    }
  }

  CPWL_Edit::OnKillFocus();
}

void CPWL_Note_Edit::OnNotify(CPWL_Wnd* pWnd,
                              FX_DWORD msg,
                              intptr_t wParam,
                              intptr_t lParam) {
  if (m_bEnableNotify) {
    if (wParam == SBT_VSCROLL) {
      switch (msg) {
        case PNM_SETSCROLLINFO:
          if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
            if (!IsFloatEqual(pInfo->fContentMax, m_fOldMax) ||
                !IsFloatEqual(pInfo->fContentMin, m_fOldMin)) {
              m_bSizeChanged = TRUE;
              if (CPWL_Wnd* pParent = GetParentWindow()) {
                pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
              }

              m_fOldMax = pInfo->fContentMax;
              m_fOldMin = pInfo->fContentMin;
              return;
            }
          }
      }
    }
  }

  CPWL_Edit::OnNotify(pWnd, msg, wParam, lParam);

  if (m_bEnableNotify) {
    switch (msg) {
      case PNM_SETCARETINFO:
        if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
          PWL_CARET_INFO newInfo = *pInfo;
          newInfo.bVisible = TRUE;
          newInfo.ptHead = ChildToParent(pInfo->ptHead);
          newInfo.ptFoot = ChildToParent(pInfo->ptFoot);

          if (CPWL_Wnd* pParent = GetParentWindow()) {
            pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
          }
        }
        break;
    }
  }
}

FX_FLOAT CPWL_Note_Edit::GetItemHeight(FX_FLOAT fLimitWidth) {
  if (fLimitWidth > 0) {
    if (!m_bSizeChanged)
      return m_fOldItemHeight;

    m_bSizeChanged = FALSE;

    EnableNotify(FALSE);
    EnableRefresh(FALSE);
    m_pEdit->EnableNotify(FALSE);

    Move(CFX_FloatRect(0, 0, fLimitWidth, 0), TRUE, FALSE);
    FX_FLOAT fRet = GetContentRect().Height();

    m_pEdit->EnableNotify(TRUE);
    EnableNotify(TRUE);
    EnableRefresh(TRUE);

    return fRet;
  }

  return 0;
}

FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() {
  return POPUP_ITEM_TEXT_INDENT;
}

FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() {
  return POPUP_ITEM_TEXT_INDENT;
}

CPWL_Note_LBBox::CPWL_Note_LBBox() {}

CPWL_Note_LBBox::~CPWL_Note_LBBox() {}

void CPWL_Note_LBBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                         CFX_Matrix* pUser2Device) {
  CFX_FloatRect rcClient = GetClientRect();

  CFX_GraphStateData gsd;
  gsd.m_LineWidth = 1.0f;

  CFX_PathData pathCross;

  pathCross.SetPointCount(4);
  pathCross.SetPoint(0, rcClient.left, rcClient.top, FXPT_MOVETO);
  pathCross.SetPoint(1, rcClient.right, rcClient.bottom, FXPT_LINETO);
  pathCross.SetPoint(2, rcClient.left,
                     rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO);
  pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f,
                     rcClient.bottom, FXPT_LINETO);

  pDevice->DrawPath(
      &pathCross, pUser2Device, &gsd, 0,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      FXFILL_ALTERNATE);
}

CPWL_Note_RBBox::CPWL_Note_RBBox() {}

CPWL_Note_RBBox::~CPWL_Note_RBBox() {}

void CPWL_Note_RBBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                         CFX_Matrix* pUser2Device) {
  CFX_FloatRect rcClient = GetClientRect();

  CFX_GraphStateData gsd;
  gsd.m_LineWidth = 1.0f;

  CFX_PathData pathCross;

  pathCross.SetPointCount(4);
  pathCross.SetPoint(0, rcClient.right, rcClient.top, FXPT_MOVETO);
  pathCross.SetPoint(1, rcClient.left, rcClient.bottom, FXPT_LINETO);
  pathCross.SetPoint(2, rcClient.right,
                     rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO);
  pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f,
                     rcClient.bottom, FXPT_LINETO);

  pDevice->DrawPath(
      &pathCross, pUser2Device, &gsd, 0,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      FXFILL_ALTERNATE);
}

CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) {}

CPWL_Note_Icon::~CPWL_Note_Icon() {}

void CPWL_Note_Icon::SetIconType(int32_t nType) {
  m_nType = nType;
}

void CPWL_Note_Icon::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                        CFX_Matrix* pUser2Device) {
  CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nType, GetClientRect(),
                                GetBackgroundColor(), PWL_DEFAULT_BLACKCOLOR,
                                GetTransparency());
}

CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) {}

CPWL_Note_CloseBox::~CPWL_Note_CloseBox() {}

void CPWL_Note_CloseBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                            CFX_Matrix* pUser2Device) {
  CPWL_Button::DrawThisAppearance(pDevice, pUser2Device);

  CFX_FloatRect rcClient = GetClientRect();
  rcClient = CPWL_Utils::DeflateRect(rcClient, 2.0f);

  CFX_GraphStateData gsd;
  gsd.m_LineWidth = 1.0f;

  CFX_PathData pathCross;

  if (m_bMouseDown) {
    rcClient.left += 0.5f;
    rcClient.right += 0.5f;
    rcClient.top -= 0.5f;
    rcClient.bottom -= 0.5f;
  }

  pathCross.SetPointCount(4);
  pathCross.SetPoint(0, rcClient.left, rcClient.bottom, FXPT_MOVETO);
  pathCross.SetPoint(1, rcClient.right, rcClient.top, FXPT_LINETO);
  pathCross.SetPoint(2, rcClient.left, rcClient.top, FXPT_MOVETO);
  pathCross.SetPoint(3, rcClient.right, rcClient.bottom, FXPT_LINETO);

  pDevice->DrawPath(
      &pathCross, pUser2Device, &gsd, 0,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      FXFILL_ALTERNATE);
}

FX_BOOL CPWL_Note_CloseBox::OnLButtonDown(const CFX_FloatPoint& point,
                                          FX_DWORD nFlag) {
  SetBorderStyle(PBS_INSET);
  InvalidateRect(NULL);

  m_bMouseDown = TRUE;

  return CPWL_Button::OnLButtonDown(point, nFlag);
}

FX_BOOL CPWL_Note_CloseBox::OnLButtonUp(const CFX_FloatPoint& point,
                                        FX_DWORD nFlag) {
  m_bMouseDown = FALSE;

  SetBorderStyle(PBS_BEVELED);
  InvalidateRect(NULL);

  return CPWL_Button::OnLButtonUp(point, nFlag);
}

CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) {}

CPWL_Note_Contents::~CPWL_Note_Contents() {}

CFX_ByteString CPWL_Note_Contents::GetClassName() const {
  return "CPWL_Note_Contents";
}

void CPWL_Note_Contents::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  m_pEdit = new CPWL_Note_Edit;
  PWL_CREATEPARAM ecp = cp;
  ecp.pParentWnd = this;
  ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_MULTILINE | PES_AUTORETURN |
                PES_TEXTOVERFLOW | PES_UNDO | PES_SPELLCHECK;

  m_pEdit->EnableNotify(FALSE);
  m_pEdit->Create(ecp);
  m_pEdit->EnableNotify(TRUE);
}

void CPWL_Note_Contents::SetText(const CFX_WideString& sText) {
  if (m_pEdit) {
    m_pEdit->EnableNotify(FALSE);
    m_pEdit->SetText(sText.c_str());
    m_pEdit->EnableNotify(TRUE);
    OnNotify(m_pEdit, PNM_NOTEEDITCHANGED, 0, 0);
  }
}

CFX_WideString CPWL_Note_Contents::GetText() const {
  if (m_pEdit)
    return m_pEdit->GetText();

  return L"";
}

CPWL_NoteItem* CPWL_Note_Contents::CreateSubItem() {
  CPWL_NoteItem* pNoteItem = new CPWL_NoteItem;
  PWL_CREATEPARAM icp = GetCreationParam();
  icp.pParentWnd = this;
  icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND;
  pNoteItem->Create(icp);

  pNoteItem->OnCreateNoteItem();

  pNoteItem->ResetSubjectName(m_aChildren.GetSize() - 1);

  FX_SYSTEMTIME st;
  if (IFX_SystemHandler* pSH = GetSystemHandler())
    st = pSH->GetLocalTime();
  pNoteItem->SetDateTime(st);

  pNoteItem->SetContents(L"");

  OnNotify(pNoteItem, PNM_NOTEEDITCHANGED, 0, 0);

  return pNoteItem;
}

int32_t CPWL_Note_Contents::CountSubItems() const {
  return m_aChildren.GetSize() - 1;
}

IPWL_NoteItem* CPWL_Note_Contents::GetSubItems(int32_t index) const {
  int32_t nIndex = index + 1;

  if (nIndex > 0 && nIndex < m_aChildren.GetSize()) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(nIndex)) {
      ASSERT(pChild->GetClassName() == "CPWL_NoteItem");
      CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild;
      return pItem;
    }
  }
  return NULL;
}

void CPWL_Note_Contents::DeleteSubItem(IPWL_NoteItem* pNoteItem) {
  int32_t nIndex = GetItemIndex((CPWL_NoteItem*)pNoteItem);

  if (nIndex > 0) {
    if (CPWL_NoteItem* pPWLNoteItem = (CPWL_NoteItem*)pNoteItem) {
      pPWLNoteItem->KillFocus();
      pPWLNoteItem->Destroy();
      delete pPWLNoteItem;
    }

    for (int32_t i = nIndex, sz = m_aChildren.GetSize(); i < sz; i++) {
      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
        ASSERT(pChild->GetClassName() == "CPWL_NoteItem");
        CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild;
        pItem->ResetSubjectName(i);
      }
    }

    OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
  }
}

IPWL_NoteItem* CPWL_Note_Contents::GetHitNoteItem(const CFX_FloatPoint& point) {
  CFX_FloatPoint pt = ParentToChild(point);

  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
      if (pChild->GetClassName() == "CPWL_NoteItem") {
        CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
        if (IPWL_NoteItem* pRet = pNoteItem->GetHitNoteItem(pt))
          return pRet;
      }
    }
  }
  return NULL;
}

void CPWL_Note_Contents::OnNotify(CPWL_Wnd* pWnd,
                                  FX_DWORD msg,
                                  intptr_t wParam,
                                  intptr_t lParam) {
  switch (msg) {
    case PNM_NOTEEDITCHANGED: {
      int32_t nIndex = GetItemIndex(pWnd);
      if (nIndex < 0)
        nIndex = 0;

      m_pEdit->EnableNotify(FALSE);
      ResetContent(nIndex);
      m_pEdit->EnableNotify(TRUE);

      for (int32_t i = nIndex + 1, sz = m_aChildren.GetSize(); i < sz; i++) {
        if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
          pChild->OnNotify(this, PNM_NOTERESET, 0, 0);
      }

      if (CPWL_Wnd* pParent = GetParentWindow()) {
        pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
      }
    }
      return;
    case PNM_SCROLLWINDOW:
      SetScrollPos(CFX_FloatPoint(0.0f, *(FX_FLOAT*)lParam));
      ResetFace();
      InvalidateRect(NULL);
      return;
    case PNM_SETCARETINFO:
      if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
        PWL_CARET_INFO newInfo = *pInfo;
        newInfo.bVisible = TRUE;
        newInfo.ptHead = ChildToParent(pInfo->ptHead);
        newInfo.ptFoot = ChildToParent(pInfo->ptFoot);

        if (CPWL_Wnd* pParent = GetParentWindow()) {
          pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
        }
      }
      return;
    case PNM_NOTERESET: {
      m_pEdit->EnableNotify(FALSE);
      ResetContent(0);
      m_pEdit->EnableNotify(TRUE);

      for (int32_t i = 1, sz = m_aChildren.GetSize(); i < sz; i++) {
        if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
          pChild->OnNotify(this, PNM_NOTERESET, 0, 0);
      }

      m_pEdit->EnableNotify(FALSE);
      ResetContent(0);
      m_pEdit->EnableNotify(TRUE);
    }
      return;
  }

  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
}

FX_BOOL CPWL_Note_Contents::OnLButtonDown(const CFX_FloatPoint& point,
                                          FX_DWORD nFlag) {
  if (CPWL_Wnd::OnLButtonDown(point, nFlag))
    return TRUE;

  if (!m_pEdit->IsFocused()) {
    m_pEdit->SetFocus();
  }

  return TRUE;
}

void CPWL_Note_Contents::SetEditFocus(FX_BOOL bLast) {
  if (!m_pEdit->IsFocused()) {
    m_pEdit->SetFocus();
    m_pEdit->SetCaret(bLast ? m_pEdit->GetTotalWords() : 0);
  }
}

CPWL_Edit* CPWL_Note_Contents::GetEdit() const {
  return m_pEdit;
}

void CPWL_Note_Contents::EnableModify(FX_BOOL bEnabled) {
  if (!bEnabled)
    m_pEdit->AddFlag(PWS_READONLY);
  else
    m_pEdit->RemoveFlag(PWS_READONLY);

  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
      if (pChild->GetClassName() == "CPWL_NoteItem") {
        CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
        pNoteItem->EnableModify(bEnabled);
      }
    }
  }
}

void CPWL_Note_Contents::EnableRead(FX_BOOL bEnabled) {
  if (!bEnabled)
    m_pEdit->AddFlag(PES_NOREAD);
  else
    m_pEdit->RemoveFlag(PES_NOREAD);

  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
      if (pChild->GetClassName() == "CPWL_NoteItem") {
        CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
        pNoteItem->EnableRead(bEnabled);
      }
    }
  }
}

CPWL_NoteItem::CPWL_NoteItem()
    : m_pSubject(NULL),
      m_pDateTime(NULL),
      m_pContents(NULL),
      m_pPrivateData(NULL),
      m_sAuthor(L""),
      m_fOldItemHeight(0.0f),
      m_bSizeChanged(FALSE),
      m_bAllowModify(TRUE) {}

CPWL_NoteItem::~CPWL_NoteItem() {}

CFX_ByteString CPWL_NoteItem::GetClassName() const {
  return "CPWL_NoteItem";
}

void CPWL_NoteItem::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  CPWL_Color sTextColor;

  if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor()))
    sTextColor = PWL_DEFAULT_WHITECOLOR;
  else
    sTextColor = PWL_DEFAULT_BLACKCOLOR;

  m_pSubject = new CPWL_Label;
  PWL_CREATEPARAM scp = cp;
  scp.pParentWnd = this;
  scp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP;
  scp.sTextColor = sTextColor;
  m_pSubject->Create(scp);

  m_pDateTime = new CPWL_Label;
  PWL_CREATEPARAM dcp = cp;
  dcp.pParentWnd = this;
  dcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_RIGHT | PES_TOP;
  dcp.sTextColor = sTextColor;
  m_pDateTime->Create(dcp);

  m_pContents = new CPWL_Note_Contents;
  PWL_CREATEPARAM ccp = cp;
  ccp.pParentWnd = this;
  ccp.sBackgroundColor =
      CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f);
  ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BACKGROUND;
  m_pContents->Create(ccp);
  m_pContents->SetItemSpace(POPUP_ITEM_SPACE);
  m_pContents->SetTopSpace(POPUP_ITEM_SPACE);
  m_pContents->SetBottomSpace(POPUP_ITEM_SPACE);
}

void CPWL_NoteItem::RePosChildWnd() {
  if (IsValid()) {
    CFX_FloatRect rcClient = GetClientRect();

    CFX_FloatRect rcSubject = rcClient;
    rcSubject.left += POPUP_ITEM_TEXT_INDENT;
    rcSubject.top = rcClient.top;
    rcSubject.right =
        PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f,
                rcClient.right);
    rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height();
    rcSubject.Normalize();
    m_pSubject->Move(rcSubject, TRUE, FALSE);
    m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject));

    CFX_FloatRect rcDate = rcClient;
    rcDate.right -= POPUP_ITEM_TEXT_INDENT;
    rcDate.left =
        PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f,
                rcSubject.right);
    rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height();
    rcDate.Normalize();
    m_pDateTime->Move(rcDate, TRUE, FALSE);
    m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate));

    CFX_FloatRect rcContents = rcClient;
    rcContents.left += 1.0f;
    rcContents.right -= 1.0f;
    rcContents.top = rcDate.bottom - POPUP_ITEM_HEAD_BOTTOM;
    rcContents.bottom += POPUP_ITEM_BOTTOMWIDTH;
    rcContents.Normalize();
    m_pContents->Move(rcContents, TRUE, FALSE);
    m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents));
  }

  SetClipRect(CPWL_Utils::InflateRect(GetWindowRect(), 1.0f));
}

void CPWL_NoteItem::SetPrivateData(void* pData) {
  m_pPrivateData = pData;
}

void CPWL_NoteItem::SetBkColor(const CPWL_Color& color) {
  CPWL_Color sBK = color;
  SetBackgroundColor(sBK);

  CPWL_Color sTextColor;

  if (CPWL_Utils::IsBlackOrWhite(sBK))
    sTextColor = PWL_DEFAULT_WHITECOLOR;
  else
    sTextColor = PWL_DEFAULT_BLACKCOLOR;

  SetTextColor(sTextColor);
  if (m_pSubject)
    m_pSubject->SetTextColor(sTextColor);
  if (m_pDateTime)
    m_pDateTime->SetTextColor(sTextColor);

  InvalidateRect(nullptr);

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetBkColor(this);
  }
}

void CPWL_NoteItem::SetSubjectName(const CFX_WideString& sName) {
  if (m_pSubject) {
    m_pSubject->SetText(sName.c_str());
  }

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetSubjectName(this);
  }
}

void CPWL_NoteItem::SetAuthorName(const CFX_WideString& sName) {
  m_sAuthor = sName;
  ResetSubjectName(-1);

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetAuthorName(this);
  }
}

void CPWL_NoteItem::ResetSubjectName(int32_t nItemIndex) {
  if (nItemIndex < 0) {
    if (CPWL_Wnd* pParent = GetParentWindow()) {
      ASSERT(pParent->GetClassName() == "CPWL_Note_Contents");

      CPWL_Note_Contents* pContents = (CPWL_Note_Contents*)pParent;
      nItemIndex = pContents->GetItemIndex(this);
    }
  }

  const CPWL_Note* pNote = GetNote();
  CFX_WideString sSubject;
  sSubject.Format(pNote->GetReplyString().c_str(), nItemIndex);

  if (!m_sAuthor.IsEmpty()) {
    sSubject += L" - ";
    sSubject += m_sAuthor;
  }
  SetSubjectName(sSubject);
  RePosChildWnd();
}

void CPWL_NoteItem::SetDateTime(FX_SYSTEMTIME time) {
  m_dtNote = time;

  CFX_WideString swTime;
  swTime.Format(L"%04d-%02d-%02d %02d:%02d:%02d", time.wYear, time.wMonth,
                time.wDay, time.wHour, time.wMinute, time.wSecond);
  if (m_pDateTime) {
    m_pDateTime->SetText(swTime.c_str());
  }

  RePosChildWnd();

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetDateTime(this);
  }
}

void CPWL_NoteItem::SetContents(const CFX_WideString& sContents) {
  if (m_pContents) {
    m_pContents->SetText(sContents);
  }

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetContents(this);
  }
}

CPWL_NoteItem* CPWL_NoteItem::GetParentNoteItem() const {
  if (CPWL_Wnd* pParent = GetParentWindow()) {
    if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
      ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
      return (CPWL_NoteItem*)pGrand;
    }
  }

  return NULL;
}

IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const {
  return GetParentNoteItem();
}

CPWL_Edit* CPWL_NoteItem::GetEdit() const {
  if (m_pContents)
    return m_pContents->GetEdit();
  return NULL;
}

void* CPWL_NoteItem::GetPrivateData() const {
  return m_pPrivateData;
}

CFX_WideString CPWL_NoteItem::GetAuthorName() const {
  return m_sAuthor;
}

CPWL_Color CPWL_NoteItem::GetBkColor() const {
  return GetBackgroundColor();
}

CFX_WideString CPWL_NoteItem::GetContents() const {
  if (m_pContents)
    return m_pContents->GetText();

  return L"";
}

FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const {
  return m_dtNote;
}

CFX_WideString CPWL_NoteItem::GetSubjectName() const {
  if (m_pSubject)
    return m_pSubject->GetText();

  return L"";
}

CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() {
  if (m_pContents)
    return m_pContents->CreateSubItem();

  return NULL;
}

IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() {
  return CreateNoteItem();
}

int32_t CPWL_NoteItem::CountSubItems() const {
  if (m_pContents)
    return m_pContents->CountSubItems();

  return 0;
}

IPWL_NoteItem* CPWL_NoteItem::GetSubItems(int32_t index) const {
  if (m_pContents)
    return m_pContents->GetSubItems(index);

  return NULL;
}

void CPWL_NoteItem::DeleteSubItem(IPWL_NoteItem* pNoteItem) {
  KillFocus();

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnItemDelete(pNoteItem);
  }

  if (m_pContents)
    m_pContents->DeleteSubItem(pNoteItem);
}

IPWL_NoteItem* CPWL_NoteItem::GetHitNoteItem(const CFX_FloatPoint& point) {
  CFX_FloatPoint pt = ParentToChild(point);

  if (WndHitTest(pt)) {
    if (m_pContents) {
      if (IPWL_NoteItem* pNoteItem = m_pContents->GetHitNoteItem(pt))
        return pNoteItem;
    }

    return this;
  }

  return NULL;
}

IPWL_NoteItem* CPWL_NoteItem::GetFocusedNoteItem() const {
  if (const CPWL_Wnd* pWnd = GetFocused()) {
    if (pWnd->GetClassName() == "CPWL_Edit") {
      if (CPWL_Wnd* pParent = pWnd->GetParentWindow()) {
        ASSERT(pParent->GetClassName() == "CPWL_Note_Contents");

        if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
          ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
          return (CPWL_NoteItem*)pGrand;
        }
      }
    }
  }

  return NULL;
}

FX_FLOAT CPWL_NoteItem::GetItemHeight(FX_FLOAT fLimitWidth) {
  if (fLimitWidth > 0) {
    if (!m_bSizeChanged)
      return m_fOldItemHeight;

    m_bSizeChanged = FALSE;

    FX_FLOAT fRet = m_pDateTime->GetContentRect().Height();
    FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
    if (fLimitWidth > fBorderWidth * 2)
      fRet += m_pContents->GetContentsHeight(fLimitWidth - fBorderWidth * 2);
    fRet += POPUP_ITEM_HEAD_BOTTOM + POPUP_ITEM_BOTTOMWIDTH + fBorderWidth * 2;

    return m_fOldItemHeight = fRet;
  }

  return 0;
}

FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() {
  return POPUP_ITEM_SIDEMARGIN;
}

FX_FLOAT CPWL_NoteItem::GetItemRightMargin() {
  return POPUP_ITEM_SIDEMARGIN;
}

FX_BOOL CPWL_NoteItem::OnLButtonDown(const CFX_FloatPoint& point,
                                     FX_DWORD nFlag) {
  if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) {
    SetNoteFocus(FALSE);
  }

  CPWL_Wnd::OnLButtonDown(point, nFlag);

  return TRUE;
}

FX_BOOL CPWL_NoteItem::OnRButtonUp(const CFX_FloatPoint& point,
                                   FX_DWORD nFlag) {
  if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) {
    SetNoteFocus(FALSE);
    PopupNoteItemMenu(point);

    return TRUE;
  }

  return CPWL_Wnd::OnRButtonUp(point, nFlag);
}

void CPWL_NoteItem::OnNotify(CPWL_Wnd* pWnd,
                             FX_DWORD msg,
                             intptr_t wParam,
                             intptr_t lParam) {
  switch (msg) {
    case PNM_NOTEEDITCHANGED:
      m_bSizeChanged = TRUE;

      if (CPWL_Wnd* pParent = GetParentWindow()) {
        pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
      }
      return;
    case PNM_SETCARETINFO:
      if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
        PWL_CARET_INFO newInfo = *pInfo;
        newInfo.bVisible = TRUE;
        newInfo.ptHead = ChildToParent(pInfo->ptHead);
        newInfo.ptFoot = ChildToParent(pInfo->ptFoot);

        if (CPWL_Wnd* pParent = GetParentWindow()) {
          pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
        }
      }
      return;
    case PNM_NOTERESET:
      m_bSizeChanged = TRUE;
      m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);

      return;
  }

  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
}

void CPWL_NoteItem::PopupNoteItemMenu(const CFX_FloatPoint& point) {
  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    int32_t x, y;
    PWLtoWnd(point, x, y);
    if (IFX_SystemHandler* pSH = GetSystemHandler())
      pSH->ClientToScreen(GetAttachedHWnd(), x, y);
    pNotify->OnPopupMenu(this, x, y);
  }
}

const CPWL_Note* CPWL_NoteItem::GetNote() const {
  if (const CPWL_Wnd* pRoot = GetRootWnd()) {
    ASSERT(pRoot->GetClassName() == "CPWL_NoteItem");
    CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pRoot;
    if (pNoteItem->IsTopItem()) {
      return (CPWL_Note*)pNoteItem;
    }
  }

  return NULL;
}

IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const {
  if (const CPWL_Note* pNote = GetNote())
    return pNote->GetNoteNotify();

  return NULL;
}

void CPWL_NoteItem::OnCreateNoteItem() {
  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnItemCreate(this);
  }
}

void CPWL_NoteItem::OnContentsValidate() {
  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetContents(this);
  }
}

void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) {
  m_pContents->SetEditFocus(bLast);
}

void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) {
  m_pContents->EnableModify(bEnabled);
  m_bAllowModify = bEnabled;
}

void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) {
  m_pContents->EnableRead(bEnabled);
}

CPWL_Note::CPWL_Note(IPopup_Note* pPopupNote,
                     IPWL_NoteNotify* pNoteNotify,
                     IPWL_NoteHandler* pNoteHandler)
    : m_pAuthor(NULL),
      m_pIcon(NULL),
      m_pCloseBox(NULL),
      m_pLBBox(NULL),
      m_pRBBox(NULL),
      m_pContentsBar(NULL),
      m_pOptions(NULL),
      m_pNoteNotify(pNoteNotify),
      m_bResizing(FALSE),
      m_bEnableNotify(TRUE) {}

CPWL_Note::~CPWL_Note() {}

IPWL_NoteItem* CPWL_Note::Reply() {
  return CreateNoteItem();
}

void CPWL_Note::EnableNotify(FX_BOOL bEnabled) {
  m_bEnableNotify = bEnabled;
}

void CPWL_Note::RePosChildWnd() {
  RePosNoteChildren();
  m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
  ResetScrollBar();
  m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
  OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
  if (const CPWL_Wnd* pWnd = GetFocused()) {
    if (pWnd->GetClassName() == "CPWL_Edit") {
      CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
      pEdit->SetCaret(pEdit->GetCaret());
    }
  }
}

FX_BOOL CPWL_Note::ResetScrollBar() {
  FX_BOOL bScrollChanged = FALSE;

  if (ScrollBarShouldVisible()) {
    if (!m_pContentsBar->IsVisible()) {
      m_pContentsBar->SetVisible(TRUE);
      if (m_pContentsBar->IsVisible()) {
        m_pContentsBar->InvalidateRect(NULL);
        bScrollChanged = TRUE;
      }
    }
  } else {
    if (m_pContentsBar->IsVisible()) {
      m_pContentsBar->SetVisible(FALSE);
      m_pContentsBar->InvalidateRect(NULL);

      bScrollChanged = TRUE;
    }
  }

  if (bScrollChanged) {
    CFX_FloatRect rcNote = GetClientRect();
    CFX_FloatRect rcContents = m_pContents->GetWindowRect();
    rcContents.right = rcNote.right - 3.0f;
    if (m_pContentsBar->IsVisible())
      rcContents.right -= PWL_SCROLLBAR_WIDTH;
    m_pContents->Move(rcContents, TRUE, TRUE);
    m_pContents->SetScrollPos(CFX_FloatPoint(0.0f, 0.0f));
    m_pContents->InvalidateRect(NULL);
  }

  return bScrollChanged;
}

FX_BOOL CPWL_Note::ScrollBarShouldVisible() {
  CFX_FloatRect rcContentsFact = m_pContents->GetScrollArea();
  CFX_FloatRect rcContentsClient = m_pContents->GetClientRect();

  return rcContentsFact.Height() > rcContentsClient.Height();
}

void CPWL_Note::SetOptionsText(const CFX_WideString& sText) {
  if (m_pOptions)
    m_pOptions->SetText(sText);

  RePosNoteChildren();
}

void CPWL_Note::RePosNoteChildren() {
  if (m_bResizing)
    return;

  m_bResizing = TRUE;

  if (IsValid()) {
    CFX_FloatRect rcClient = GetClientRect();

    CFX_FloatRect rcIcon = rcClient;
    rcIcon.top -= 2.0f;
    rcIcon.right = rcIcon.left + 14.0f;
    rcIcon.bottom = rcIcon.top - 14.0f;
    rcIcon.Normalize();
    m_pIcon->Move(rcIcon, TRUE, FALSE);
    m_pIcon->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcIcon));

    CFX_FloatRect rcCloseBox = rcClient;
    rcCloseBox.right -= 1.0f;
    rcCloseBox.top -= 1.0f;
    rcCloseBox.left = rcCloseBox.right - 14.0f;
    rcCloseBox.bottom = rcCloseBox.top - 14.0f;
    rcCloseBox.Normalize();
    m_pCloseBox->Move(rcCloseBox, TRUE, FALSE);
    m_pCloseBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcCloseBox));

    CFX_FloatRect rcDate = rcClient;
    rcDate.right = rcCloseBox.left - POPUP_ITEM_TEXT_INDENT;
    rcDate.left =
        PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f,
                rcIcon.right + 1.0f);
    rcDate.top = rcClient.top - 2.0f;
    rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height();
    rcDate.Normalize();
    m_pDateTime->Move(rcDate, TRUE, FALSE);
    m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate));

    CFX_FloatRect rcSubject = rcClient;
    rcSubject.top = rcClient.top - 2.0f;
    rcSubject.left = rcIcon.right + POPUP_ITEM_TEXT_INDENT;
    rcSubject.right =
        PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f,
                rcDate.left - 1.0f);
    rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height();
    rcSubject.Normalize();
    m_pSubject->Move(rcSubject, TRUE, FALSE);
    m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject));

    CFX_FloatRect rcOptions = rcClient;
    rcOptions.left =
        PWL_MAX(rcOptions.right - m_pOptions->GetContentRect().Width(),
                rcIcon.right + 1.0f);
    rcOptions.top = rcSubject.bottom - 4.0f;
    rcOptions.bottom = rcOptions.top - m_pOptions->GetContentRect().Height();
    rcOptions.Normalize();
    m_pOptions->Move(rcOptions, TRUE, FALSE);
    m_pOptions->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcOptions));

    CFX_FloatRect rcAuthor = rcClient;
    rcAuthor.top = rcSubject.bottom - 4.0f;
    rcAuthor.left = rcSubject.left;
    rcAuthor.right =
        PWL_MIN(rcSubject.left + m_pAuthor->GetContentRect().Width() + 1.0f,
                rcOptions.left - 1.0f);
    rcAuthor.bottom = rcAuthor.top - m_pAuthor->GetContentRect().Height();
    rcAuthor.Normalize();
    m_pAuthor->Move(rcAuthor, TRUE, FALSE);
    m_pAuthor->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcAuthor));

    CFX_FloatRect rcLBBox = rcClient;
    rcLBBox.top = rcLBBox.bottom + 7.0f;
    rcLBBox.right = rcLBBox.left + 7.0f;
    rcLBBox.Normalize();
    m_pLBBox->Move(rcLBBox, TRUE, FALSE);
    m_pLBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcLBBox));

    CFX_FloatRect rcRBBox = rcClient;
    rcRBBox.top = rcRBBox.bottom + 7.0f;
    rcRBBox.left = rcRBBox.right - 7.0f;
    rcRBBox.Normalize();
    m_pRBBox->Move(rcRBBox, TRUE, FALSE);
    m_pRBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcRBBox));

    CFX_FloatRect rcContents = rcClient;
    rcContents.top = rcAuthor.bottom - POPUP_ITEM_HEAD_BOTTOM;
    rcContents.left += 3.0f;
    rcContents.right -= 3.0f;
    if (m_pContentsBar->IsVisible())
      rcContents.right -= PWL_SCROLLBAR_WIDTH;
    rcContents.bottom += 14.0f;
    rcContents.Normalize();
    m_pContents->Move(rcContents, FALSE, FALSE);
    m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents));

    CFX_FloatRect rcContentsBar = rcContents;
    rcContentsBar.right = rcClient.right - 3.0f;
    rcContentsBar.left = rcContentsBar.right - PWL_SCROLLBAR_WIDTH;
    rcContentsBar.Normalize();
    m_pContentsBar->Move(rcContentsBar, TRUE, FALSE);
  }

  m_bResizing = FALSE;
}

void CPWL_Note::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  CPWL_NoteItem::CreateChildWnd(cp);

  CPWL_Color sTextColor;

  if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor()))
    sTextColor = PWL_DEFAULT_WHITECOLOR;
  else
    sTextColor = PWL_DEFAULT_BLACKCOLOR;

  m_pAuthor = new CPWL_Label;
  PWL_CREATEPARAM acp = cp;
  acp.pParentWnd = this;
  acp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP;
  acp.sTextColor = sTextColor;
  m_pAuthor->Create(acp);

  m_pCloseBox = new CPWL_Note_CloseBox;
  PWL_CREATEPARAM ccp = cp;
  ccp.pParentWnd = this;
  ccp.dwBorderWidth = 2;
  ccp.nBorderStyle = PBS_BEVELED;
  ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER;
  ccp.sTextColor = sTextColor;
  m_pCloseBox->Create(ccp);

  m_pIcon = new CPWL_Note_Icon;
  PWL_CREATEPARAM icp = cp;
  icp.pParentWnd = this;
  icp.dwFlags = PWS_VISIBLE | PWS_CHILD;
  m_pIcon->Create(icp);

  m_pOptions = new CPWL_Note_Options;
  PWL_CREATEPARAM ocp = cp;
  ocp.pParentWnd = this;
  ocp.dwFlags = PWS_CHILD | PWS_VISIBLE;
  ocp.sTextColor = sTextColor;
  m_pOptions->Create(ocp);

  m_pLBBox = new CPWL_Note_LBBox;
  PWL_CREATEPARAM lcp = cp;
  lcp.pParentWnd = this;
  lcp.dwFlags = PWS_VISIBLE | PWS_CHILD;
  lcp.eCursorType = FXCT_NESW;
  lcp.sTextColor = sTextColor;
  m_pLBBox->Create(lcp);

  m_pRBBox = new CPWL_Note_RBBox;
  PWL_CREATEPARAM rcp = cp;
  rcp.pParentWnd = this;
  rcp.dwFlags = PWS_VISIBLE | PWS_CHILD;
  rcp.eCursorType = FXCT_NWSE;
  rcp.sTextColor = sTextColor;
  m_pRBBox->Create(rcp);

  m_pContentsBar = new CPWL_ScrollBar(SBT_VSCROLL);
  PWL_CREATEPARAM scp = cp;
  scp.pParentWnd = this;
  scp.sBackgroundColor =
      CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f);
  scp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND;
  m_pContentsBar->Create(scp);
  m_pContentsBar->SetNotifyForever(TRUE);
}

void CPWL_Note::SetSubjectName(const CFX_WideString& sName) {
  CPWL_NoteItem::SetSubjectName(sName);
  RePosChildWnd();
}

void CPWL_Note::SetAuthorName(const CFX_WideString& sName) {
  if (m_pAuthor) {
    m_pAuthor->SetText(sName.c_str());
    RePosChildWnd();
  }

  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
    pNotify->OnSetAuthorName(this);
  }
}

CFX_WideString CPWL_Note::GetAuthorName() const {
  if (m_pAuthor)
    return m_pAuthor->GetText();

  return L"";
}

FX_BOOL CPWL_Note::OnMouseWheel(short zDelta,
                                const CFX_FloatPoint& point,
                                FX_DWORD nFlag) {
  CFX_FloatPoint ptScroll = m_pContents->GetScrollPos();
  CFX_FloatRect rcScroll = m_pContents->GetScrollArea();
  CFX_FloatRect rcContents = m_pContents->GetClientRect();

  if (rcScroll.top - rcScroll.bottom > rcContents.Height()) {
    CFX_FloatPoint ptNew = ptScroll;

    if (zDelta > 0)
      ptNew.y += 30;
    else
      ptNew.y -= 30;

    if (ptNew.y > rcScroll.top)
      ptNew.y = rcScroll.top;
    if (ptNew.y < rcScroll.bottom + rcContents.Height())
      ptNew.y = rcScroll.bottom + rcContents.Height();
    if (ptNew.y < rcScroll.bottom)
      ptNew.y = rcScroll.bottom;

    if (ptNew.y != ptScroll.y) {
      m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
      m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
                            (intptr_t)&ptNew.y);
      m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
                               (intptr_t)&ptNew.y);

      return TRUE;
    }
  }

  return FALSE;
}

void CPWL_Note::OnNotify(CPWL_Wnd* pWnd,
                         FX_DWORD msg,
                         intptr_t wParam,
                         intptr_t lParam) {
  switch (msg) {
    case PNM_NOTEEDITCHANGED: {
      CFX_FloatRect rcScroll = m_pContents->GetScrollArea();

      PWL_SCROLL_INFO sInfo;
      sInfo.fContentMin = rcScroll.bottom;
      sInfo.fContentMax = rcScroll.top;
      sInfo.fPlateWidth = m_pContents->GetClientRect().Height();
      sInfo.fSmallStep = 13.0f;
      sInfo.fBigStep = sInfo.fPlateWidth;

      if (FXSYS_memcmp(&m_OldScrollInfo, &sInfo, sizeof(PWL_SCROLL_INFO)) !=
          0) {
        FX_BOOL bScrollChanged = FALSE;

        if (lParam < 3) {
          bScrollChanged = ResetScrollBar();
          if (bScrollChanged) {
            lParam++;
            m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
            OnNotify(this, PNM_NOTEEDITCHANGED, 0, lParam);
          }
        }

        if (!bScrollChanged) {
          if (m_pContentsBar->IsVisible()) {
            m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLINFO, SBT_VSCROLL,
                                     (intptr_t)&sInfo);
            m_OldScrollInfo = sInfo;

            CFX_FloatPoint ptScroll = m_pContents->GetScrollPos();
            CFX_FloatPoint ptOld = ptScroll;

            if (ptScroll.y > sInfo.fContentMax)
              ptScroll.y = sInfo.fContentMax;
            if (ptScroll.y < sInfo.fContentMin + sInfo.fPlateWidth)
              ptScroll.y = sInfo.fContentMin + sInfo.fPlateWidth;
            if (ptScroll.y < sInfo.fContentMin)
              ptScroll.y = sInfo.fContentMin;

            if (ptOld.y != ptScroll.y) {
              m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
                                       (intptr_t)&ptScroll.y);
              m_pContentsBar->InvalidateRect(NULL);
              m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
                                    (intptr_t)&ptScroll.y);
            }
          }
        }
      }
    }

      m_pContents->InvalidateRect(NULL);

      return;
    case PNM_SCROLLWINDOW:
      if (m_pContents)
        m_pContents->OnNotify(pWnd, msg, wParam, lParam);
      return;
    case PNM_SETSCROLLPOS:
      if (m_pContentsBar)
        m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
      return;
  }

  if (msg == PNM_SETCARETINFO && IsValid()) {
    if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
      if (m_pContents) {
        CFX_FloatRect rcClient = m_pContents->GetClientRect();
        if (pInfo->ptHead.y > rcClient.top) {
          CFX_FloatPoint pt = m_pContents->OutToIn(pInfo->ptHead);
          m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
                                (intptr_t)&pt.y);

          CFX_FloatPoint ptScroll = m_pContents->GetScrollPos();
          m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
                                   (intptr_t)&ptScroll.y);

          return;
        }

        if (pInfo->ptFoot.y < rcClient.bottom) {
          CFX_FloatPoint pt = m_pContents->OutToIn(pInfo->ptFoot);
          pt.y += rcClient.Height();
          m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
                                (intptr_t)&pt.y);

          CFX_FloatPoint ptScroll = m_pContents->GetScrollPos();
          m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
                                   (intptr_t)&ptScroll.y);

          return;
        }
      }
    }
  }

  CPWL_NoteItem::OnNotify(pWnd, msg, wParam, lParam);
}

void CPWL_Note::SetBkColor(const CPWL_Color& color) {
  CPWL_NoteItem::SetBkColor(color);

  CPWL_Color sBK = color;
  CPWL_Color sTextColor;
  if (CPWL_Utils::IsBlackOrWhite(sBK))
    sTextColor = PWL_DEFAULT_WHITECOLOR;
  else
    sTextColor = PWL_DEFAULT_BLACKCOLOR;

  if (m_pCloseBox)
    m_pCloseBox->SetTextColor(sTextColor);
  if (m_pAuthor)
    m_pAuthor->SetTextColor(sTextColor);
  if (m_pOptions)
    m_pOptions->SetTextColor(sTextColor);
  if (m_pLBBox)
    m_pLBBox->SetTextColor(sTextColor);
  if (m_pRBBox)
    m_pRBBox->SetTextColor(sTextColor);
}

FX_BOOL CPWL_Note::OnLButtonDown(const CFX_FloatPoint& point, FX_DWORD nFlag) {
  if (m_pOptions->WndHitTest(m_pOptions->ParentToChild(point))) {
    if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
      int32_t x, y;
      PWLtoWnd(point, x, y);
      if (IFX_SystemHandler* pSH = GetSystemHandler())
        pSH->ClientToScreen(GetAttachedHWnd(), x, y);
      KillFocus();
      pNotify->OnPopupMenu(x, y);

      return TRUE;
    }
  }

  return CPWL_Wnd::OnLButtonDown(point, nFlag);
}

FX_BOOL CPWL_Note::OnRButtonUp(const CFX_FloatPoint& point, FX_DWORD nFlag) {
  return CPWL_Wnd::OnRButtonUp(point, nFlag);
}

const CPWL_Note* CPWL_Note::GetNote() const {
  return this;
}

IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const {
  return m_bEnableNotify ? m_pNoteNotify : nullptr;
}

void CPWL_Note::SetIconType(int32_t nType) {
  if (m_pIcon)
    m_pIcon->SetIconType(nType);
}

void CPWL_Note::EnableModify(FX_BOOL bEnabled) {
  m_pContents->EnableModify(bEnabled);
}

void CPWL_Note::EnableRead(FX_BOOL bEnabled) {
  m_pContents->EnableRead(bEnabled);
}

CFX_WideString CPWL_Note::GetReplyString() const {
  return m_sReplyString;
}

void CPWL_Note::SetReplyString(const CFX_WideString& str) {
  m_sReplyString = str;
}
