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