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

#include "core/include/fxge/fx_ge.h"
#include "fpdfsdk/pdfwindow/PWL_Button.h"
#include "fpdfsdk/pdfwindow/PWL_Caret.h"
#include "fpdfsdk/pdfwindow/PWL_Edit.h"
#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
#include "fpdfsdk/pdfwindow/PWL_Label.h"
#include "fpdfsdk/pdfwindow/PWL_ListCtrl.h"
#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
#include "fpdfsdk/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/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,
                              uint32_t 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,
                                          uint32_t 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,
                                        uint32_t 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,
                                  uint32_t 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,
                                          uint32_t 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,
                                     uint32_t 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,
                                   uint32_t 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,
                             uint32_t 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,
                                uint32_t 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,
                         uint32_t 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, uint32_t 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, uint32_t 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;
}
