// 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/fxedit/fxet_edit.h"
#include "fpdfsdk/include/fxedit/fxet_list.h"
#include "fpdfsdk/include/fxedit/fxet_stub.h"

/* ------------------------------- CFX_ListItem
 * ---------------------------------- */

CFX_ListItem::CFX_ListItem()
    : m_pEdit(NULL),
      m_bSelected(FALSE),
      m_bCaret(FALSE),
      m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) {
  m_pEdit = IFX_Edit::NewEdit();
  ASSERT(m_pEdit != NULL);

  m_pEdit->SetAlignmentV(1);
  m_pEdit->Initialize();
}

CFX_ListItem::~CFX_ListItem() {
  IFX_Edit::DelEdit(m_pEdit);
}

void CFX_ListItem::SetFontMap(IFX_Edit_FontMap* pFontMap) {
  if (m_pEdit)
    m_pEdit->SetFontMap(pFontMap);
}

IFX_Edit* CFX_ListItem::GetEdit() const {
  return m_pEdit;
}

IFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
  if (m_pEdit)
    return m_pEdit->GetIterator();

  return NULL;
}

void CFX_ListItem::SetRect(const CLST_Rect& rect) {
  m_rcListItem = rect;
}

CLST_Rect CFX_ListItem::GetRect() const {
  return m_rcListItem;
}

FX_BOOL CFX_ListItem::IsSelected() const {
  return m_bSelected;
}

void CFX_ListItem::SetSelect(FX_BOOL bSelected) {
  m_bSelected = bSelected;
}

FX_BOOL CFX_ListItem::IsCaret() const {
  return m_bCaret;
}

void CFX_ListItem::SetCaret(FX_BOOL bCaret) {
  m_bCaret = bCaret;
}

void CFX_ListItem::SetText(const FX_WCHAR* text) {
  if (m_pEdit)
    m_pEdit->SetText(text);
}

void CFX_ListItem::SetFontSize(FX_FLOAT fFontSize) {
  if (m_pEdit)
    m_pEdit->SetFontSize(fFontSize);
}

FX_FLOAT CFX_ListItem::GetItemHeight() const {
  if (m_pEdit)
    return m_pEdit->GetContentRect().Height();

  return 0.0f;
}

FX_WORD CFX_ListItem::GetFirstChar() const {
  CPVT_Word word;

  if (IFX_Edit_Iterator* pIterator = GetIterator()) {
    pIterator->SetAt(1);
    pIterator->GetWord(word);
  }

  return word.Word;
}

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

  return L"";
}

/* ------------------------------------ CFX_List
 * --------------------------------- */

CFX_List::CFX_List()
    : m_fFontSize(0.0f), m_pFontMap(NULL), m_bMultiple(FALSE) {}

CFX_List::~CFX_List() {
  Empty();
}

void CFX_List::Empty() {
  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
    delete m_aListItems.GetAt(i);

  m_aListItems.RemoveAll();
}

void CFX_List::SetFontMap(IFX_Edit_FontMap* pFontMap) {
  m_pFontMap = pFontMap;
}

void CFX_List::SetFontSize(FX_FLOAT fFontSize) {
  m_fFontSize = fFontSize;
}

void CFX_List::AddItem(const FX_WCHAR* str) {
  CFX_ListItem* pListItem = new CFX_ListItem();
  pListItem->SetFontMap(m_pFontMap);
  pListItem->SetFontSize(m_fFontSize);
  pListItem->SetText(str);
  m_aListItems.Add(pListItem);
}

void CFX_List::ReArrange(int32_t nItemIndex) {
  FX_FLOAT fPosY = 0.0f;

  if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
    fPosY = pPrevItem->GetRect().bottom;

  for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
      FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
      pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
      fPosY += fListItemHeight;
    }
  }

  SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
}

IFX_Edit* CFX_List::GetItemEdit(int32_t nIndex) const {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
    return pListItem->GetEdit();
  }

  return NULL;
}

int32_t CFX_List::GetCount() const {
  return m_aListItems.GetSize();
}

CPDF_Rect CFX_List::GetPlateRect() const {
  return CFX_ListContainer::GetPlateRect();
}

CPDF_Rect CFX_List::GetContentRect() const {
  return InnerToOuter(CFX_ListContainer::GetContentRect());
}

FX_FLOAT CFX_List::GetFontSize() const {
  return m_fFontSize;
}

int32_t CFX_List::GetItemIndex(const CPDF_Point& point) const {
  CPDF_Point pt = OuterToInner(point);

  FX_BOOL bFirst = TRUE;
  FX_BOOL bLast = TRUE;

  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
      CLST_Rect rcListItem = pListItem->GetRect();

      if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
        bFirst = FALSE;
      }

      if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
        bLast = FALSE;
      }

      if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
        return i;
      }
    }
  }

  if (bFirst)
    return 0;
  if (bLast)
    return m_aListItems.GetSize() - 1;

  return -1;
}

FX_FLOAT CFX_List::GetFirstHeight() const {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
    return pListItem->GetItemHeight();
  }

  return 1.0f;
}

int32_t CFX_List::GetFirstSelected() const {
  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
      if (pListItem->IsSelected())
        return i;
    }
  }
  return -1;
}

int32_t CFX_List::GetLastSelected() const {
  for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
      if (pListItem->IsSelected())
        return i;
    }
  }
  return -1;
}

FX_WCHAR CFX_List::Toupper(FX_WCHAR c) const {
  if ((c >= 'a') && (c <= 'z'))
    c = c - ('a' - 'A');
  return c;
}

int32_t CFX_List::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
  int32_t nCircleIndex = nIndex;

  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
    nCircleIndex++;
    if (nCircleIndex >= sz)
      nCircleIndex = 0;

    if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
      if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
        return nCircleIndex;
    }
  }

  return nCircleIndex;
}

CPDF_Rect CFX_List::GetItemRect(int32_t nIndex) const {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
    CPDF_Rect rcItem = pListItem->GetRect();
    rcItem.left = 0.0f;
    rcItem.right = GetPlateRect().Width();
    return InnerToOuter(rcItem);
  }

  return CPDF_Rect();
}

FX_BOOL CFX_List::IsItemSelected(int32_t nIndex) const {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
    return pListItem->IsSelected();
  }

  return FALSE;
}

void CFX_List::SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected) {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
    pListItem->SetSelect(bSelected);
  }
}

void CFX_List::SetItemCaret(int32_t nItemIndex, FX_BOOL bCaret) {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
    pListItem->SetCaret(bCaret);
  }
}

void CFX_List::SetMultipleSel(FX_BOOL bMultiple) {
  m_bMultiple = bMultiple;
}

FX_BOOL CFX_List::IsMultipleSel() const {
  return m_bMultiple;
}

FX_BOOL CFX_List::IsValid(int32_t nItemIndex) const {
  return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
}

CFX_WideString CFX_List::GetItemText(int32_t nIndex) const {
  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
    return pListItem->GetText();
  }

  return L"";
}

/* ------------------------------------ CPLST_Select
 * ---------------------------------- */

CPLST_Select::CPLST_Select() {}

CPLST_Select::~CPLST_Select() {
  for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++)
    delete m_aItems.GetAt(i);

  m_aItems.RemoveAll();
}

void CPLST_Select::Add(int32_t nItemIndex) {
  int32_t nIndex = Find(nItemIndex);

  if (nIndex < 0)
    m_aItems.Add(new CPLST_Select_Item(nItemIndex, 1));
  else {
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex)) {
      pItem->nState = 1;
    }
  }
}

void CPLST_Select::Add(int32_t nBeginIndex, int32_t nEndIndex) {
  if (nBeginIndex > nEndIndex) {
    int32_t nTemp = nEndIndex;
    nEndIndex = nBeginIndex;
    nBeginIndex = nTemp;
  }

  for (int32_t i = nBeginIndex; i <= nEndIndex; i++)
    Add(i);
}

void CPLST_Select::Sub(int32_t nItemIndex) {
  for (int32_t i = m_aItems.GetSize() - 1; i >= 0; i--) {
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i))
      if (pItem->nItemIndex == nItemIndex)
        pItem->nState = -1;
  }
}

void CPLST_Select::Sub(int32_t nBeginIndex, int32_t nEndIndex) {
  if (nBeginIndex > nEndIndex) {
    int32_t nTemp = nEndIndex;
    nEndIndex = nBeginIndex;
    nBeginIndex = nTemp;
  }

  for (int32_t i = nBeginIndex; i <= nEndIndex; i++)
    Sub(i);
}

int32_t CPLST_Select::Find(int32_t nItemIndex) const {
  for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++) {
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
      if (pItem->nItemIndex == nItemIndex)
        return i;
    }
  }

  return -1;
}

FX_BOOL CPLST_Select::IsExist(int32_t nItemIndex) const {
  return Find(nItemIndex) >= 0;
}

int32_t CPLST_Select::GetCount() const {
  return m_aItems.GetSize();
}

int32_t CPLST_Select::GetItemIndex(int32_t nIndex) const {
  if (nIndex >= 0 && nIndex < m_aItems.GetSize())
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex))
      return pItem->nItemIndex;

  return -1;
}

int32_t CPLST_Select::GetState(int32_t nIndex) const {
  if (nIndex >= 0 && nIndex < m_aItems.GetSize())
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex))
      return pItem->nState;

  return 0;
}

void CPLST_Select::DeselectAll() {
  for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++) {
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
      pItem->nState = -1;
    }
  }
}

void CPLST_Select::Done() {
  for (int32_t i = m_aItems.GetSize() - 1; i >= 0; i--) {
    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
      if (pItem->nState == -1) {
        delete pItem;
        m_aItems.RemoveAt(i);
      } else {
        pItem->nState = 0;
      }
    }
  }
}

/* ------------------------------------ CFX_ListCtrl
 * --------------------------------- */

CFX_ListCtrl::CFX_ListCtrl()
    : m_pNotify(NULL),
      m_bNotifyFlag(FALSE),
      m_ptScrollPos(0.0f, 0.0f),
      m_nSelItem(-1),
      m_nFootIndex(-1),
      m_bCtrlSel(FALSE),
      m_nCaretIndex(-1) {}

CFX_ListCtrl::~CFX_ListCtrl() {}

void CFX_ListCtrl::SetNotify(IFX_List_Notify* pNotify) {
  m_pNotify = pNotify;
}

CPDF_Point CFX_ListCtrl::InToOut(const CPDF_Point& point) const {
  CPDF_Rect rcPlate = GetPlateRect();

  return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
                    point.y - (m_ptScrollPos.y - rcPlate.top));
}

CPDF_Point CFX_ListCtrl::OutToIn(const CPDF_Point& point) const {
  CPDF_Rect rcPlate = GetPlateRect();

  return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
                    point.y + (m_ptScrollPos.y - rcPlate.top));
}

CPDF_Rect CFX_ListCtrl::InToOut(const CPDF_Rect& rect) const {
  CPDF_Point ptLeftBottom = InToOut(CPDF_Point(rect.left, rect.bottom));
  CPDF_Point ptRightTop = InToOut(CPDF_Point(rect.right, rect.top));

  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
}

CPDF_Rect CFX_ListCtrl::OutToIn(const CPDF_Rect& rect) const {
  CPDF_Point ptLeftBottom = OutToIn(CPDF_Point(rect.left, rect.bottom));
  CPDF_Point ptRightTop = OutToIn(CPDF_Point(rect.right, rect.top));

  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
}

void CFX_ListCtrl::OnMouseDown(const CPDF_Point& point,
                               FX_BOOL bShift,
                               FX_BOOL bCtrl) {
  int32_t nHitIndex = GetItemIndex(point);

  if (IsMultipleSel()) {
    if (bCtrl) {
      if (IsItemSelected(nHitIndex)) {
        m_aSelItems.Sub(nHitIndex);
        SelectItems();
        m_bCtrlSel = FALSE;
      } else {
        m_aSelItems.Add(nHitIndex);
        SelectItems();
        m_bCtrlSel = TRUE;
      }

      m_nFootIndex = nHitIndex;
    } else if (bShift) {
      m_aSelItems.DeselectAll();
      m_aSelItems.Add(m_nFootIndex, nHitIndex);
      SelectItems();
    } else {
      m_aSelItems.DeselectAll();
      m_aSelItems.Add(nHitIndex);
      SelectItems();

      m_nFootIndex = nHitIndex;
    }

    SetCaret(nHitIndex);
  } else {
    SetSingleSelect(nHitIndex);
  }

  if (!IsItemVisible(nHitIndex))
    ScrollToListItem(nHitIndex);
}

void CFX_ListCtrl::OnMouseMove(const CPDF_Point& point,
                               FX_BOOL bShift,
                               FX_BOOL bCtrl) {
  int32_t nHitIndex = GetItemIndex(point);

  if (IsMultipleSel()) {
    if (bCtrl) {
      if (m_bCtrlSel)
        m_aSelItems.Add(m_nFootIndex, nHitIndex);
      else
        m_aSelItems.Sub(m_nFootIndex, nHitIndex);

      SelectItems();
    } else {
      m_aSelItems.DeselectAll();
      m_aSelItems.Add(m_nFootIndex, nHitIndex);
      SelectItems();
    }

    SetCaret(nHitIndex);
  } else {
    SetSingleSelect(nHitIndex);
  }

  if (!IsItemVisible(nHitIndex))
    ScrollToListItem(nHitIndex);
}

void CFX_ListCtrl::OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) {
  if (IsMultipleSel()) {
    if (nItemIndex >= 0 && nItemIndex < GetCount()) {
      if (bCtrl) {
      } else if (bShift) {
        m_aSelItems.DeselectAll();
        m_aSelItems.Add(m_nFootIndex, nItemIndex);
        SelectItems();
      } else {
        m_aSelItems.DeselectAll();
        m_aSelItems.Add(nItemIndex);
        SelectItems();
        m_nFootIndex = nItemIndex;
      }

      SetCaret(nItemIndex);
    }
  } else {
    SetSingleSelect(nItemIndex);
  }

  if (!IsItemVisible(nItemIndex))
    ScrollToListItem(nItemIndex);
}

void CFX_ListCtrl::OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) {
  OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl);
}

void CFX_ListCtrl::OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) {
  OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl);
}

void CFX_ListCtrl::OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) {
  OnVK(0, bShift, bCtrl);
}

void CFX_ListCtrl::OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) {
  OnVK(GetCount() - 1, bShift, bCtrl);
}

void CFX_ListCtrl::OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) {
  OnVK(0, bShift, bCtrl);
}

void CFX_ListCtrl::OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) {
  OnVK(GetCount() - 1, bShift, bCtrl);
}

FX_BOOL CFX_ListCtrl::OnChar(FX_WORD nChar, FX_BOOL bShift, FX_BOOL bCtrl) {
  int32_t nIndex = GetLastSelected();
  int32_t nFindIndex = FindNext(nIndex, nChar);

  if (nFindIndex != nIndex) {
    OnVK(nFindIndex, bShift, bCtrl);
    return TRUE;
  }
  return FALSE;
}

/* -------- inner methods ------- */

void CFX_ListCtrl::SetPlateRect(const CPDF_Rect& rect) {
  CFX_ListContainer::SetPlateRect(rect);
  m_ptScrollPos.x = rect.left;
  SetScrollPos(CPDF_Point(rect.left, rect.top));
  ReArrange(0);
  InvalidateItem(-1);
}

CPDF_Rect CFX_ListCtrl::GetItemRect(int32_t nIndex) const {
  return InToOut(CFX_List::GetItemRect(nIndex));
}

void CFX_ListCtrl::AddString(const FX_WCHAR* string) {
  AddItem(string);
  ReArrange(GetCount() - 1);
}

void CFX_ListCtrl::SetMultipleSelect(int32_t nItemIndex, FX_BOOL bSelected) {
  if (!IsValid(nItemIndex))
    return;

  if (bSelected != IsItemSelected(nItemIndex)) {
    if (bSelected) {
      SetItemSelect(nItemIndex, TRUE);
      InvalidateItem(nItemIndex);
    } else {
      SetItemSelect(nItemIndex, FALSE);
      InvalidateItem(nItemIndex);
    }
  }
}

void CFX_ListCtrl::SetSingleSelect(int32_t nItemIndex) {
  if (!IsValid(nItemIndex))
    return;

  if (m_nSelItem != nItemIndex) {
    if (m_nSelItem >= 0) {
      SetItemSelect(m_nSelItem, FALSE);
      InvalidateItem(m_nSelItem);
    }

    SetItemSelect(nItemIndex, TRUE);
    InvalidateItem(nItemIndex);
    m_nSelItem = nItemIndex;
  }
}

void CFX_ListCtrl::SetCaret(int32_t nItemIndex) {
  if (!IsValid(nItemIndex))
    return;

  if (IsMultipleSel()) {
    int32_t nOldIndex = m_nCaretIndex;

    if (nOldIndex != nItemIndex) {
      m_nCaretIndex = nItemIndex;

      SetItemCaret(nOldIndex, FALSE);
      SetItemCaret(nItemIndex, TRUE);

      InvalidateItem(nOldIndex);
      InvalidateItem(nItemIndex);
    }
  }
}

void CFX_ListCtrl::InvalidateItem(int32_t nItemIndex) {
  if (m_pNotify) {
    if (nItemIndex == -1) {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = TRUE;
        CPDF_Rect rcRefresh = GetPlateRect();
        m_pNotify->IOnInvalidateRect(&rcRefresh);
        m_bNotifyFlag = FALSE;
      }
    } else {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = TRUE;
        CPDF_Rect rcRefresh = GetItemRect(nItemIndex);
        rcRefresh.left -= 1.0f;
        rcRefresh.right += 1.0f;
        rcRefresh.bottom -= 1.0f;
        rcRefresh.top += 1.0f;

        m_pNotify->IOnInvalidateRect(&rcRefresh);
        m_bNotifyFlag = FALSE;
      }
    }
  }
}

void CFX_ListCtrl::SelectItems() {
  for (int32_t i = 0, sz = m_aSelItems.GetCount(); i < sz; i++) {
    int32_t nItemIndex = m_aSelItems.GetItemIndex(i);
    int32_t nState = m_aSelItems.GetState(i);

    switch (nState) {
      case 1:
        SetMultipleSelect(nItemIndex, TRUE);
        break;
      case -1:
        SetMultipleSelect(nItemIndex, FALSE);
        break;
    }
  }

  m_aSelItems.Done();
}

void CFX_ListCtrl::Select(int32_t nItemIndex) {
  if (!IsValid(nItemIndex))
    return;

  if (IsMultipleSel()) {
    m_aSelItems.Add(nItemIndex);
    SelectItems();
  } else
    SetSingleSelect(nItemIndex);
}

FX_BOOL CFX_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
  CPDF_Rect rcPlate = GetPlateRect();
  CPDF_Rect rcItem = GetItemRect(nItemIndex);

  return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top;
}

void CFX_ListCtrl::ScrollToListItem(int32_t nItemIndex) {
  if (!IsValid(nItemIndex))
    return;

  CPDF_Rect rcPlate = GetPlateRect();
  CPDF_Rect rcItem = CFX_List::GetItemRect(nItemIndex);
  CPDF_Rect rcItemCtrl = GetItemRect(nItemIndex);

  if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
    if (FX_EDIT_IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
      SetScrollPosY(rcItem.bottom + rcPlate.Height());
    }
  } else if (FX_EDIT_IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
    if (FX_EDIT_IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
      SetScrollPosY(rcItem.top);
    }
  }
}

void CFX_ListCtrl::SetScrollInfo() {
  if (m_pNotify) {
    CPDF_Rect rcPlate = GetPlateRect();
    CPDF_Rect rcContent = CFX_List::GetContentRect();

    if (!m_bNotifyFlag) {
      m_bNotifyFlag = TRUE;
      m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
                                   rcContent.bottom, rcContent.top,
                                   GetFirstHeight(), rcPlate.Height());
      m_bNotifyFlag = FALSE;
    }
  }
}

void CFX_ListCtrl::SetScrollPos(const CPDF_Point& point) {
  SetScrollPosY(point.y);
}

void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
  if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
    CPDF_Rect rcPlate = GetPlateRect();
    CPDF_Rect rcContent = CFX_List::GetContentRect();

    if (rcPlate.Height() > rcContent.Height()) {
      fy = rcPlate.top;
    } else {
      if (FX_EDIT_IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
        fy = rcContent.bottom + rcPlate.Height();
      } else if (FX_EDIT_IsFloatBigger(fy, rcContent.top)) {
        fy = rcContent.top;
      }
    }

    m_ptScrollPos.y = fy;
    InvalidateItem(-1);

    if (m_pNotify) {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = TRUE;
        m_pNotify->IOnSetScrollPosY(fy);
        m_bNotifyFlag = FALSE;
      }
    }
  }
}

CPDF_Rect CFX_ListCtrl::GetContentRect() const {
  return InToOut(CFX_List::GetContentRect());
}

void CFX_ListCtrl::ReArrange(int32_t nItemIndex) {
  CFX_List::ReArrange(nItemIndex);
  SetScrollInfo();
}

void CFX_ListCtrl::SetTopItem(int32_t nIndex) {
  if (IsValid(nIndex)) {
    GetPlateRect();
    CPDF_Rect rcItem = CFX_List::GetItemRect(nIndex);
    SetScrollPosY(rcItem.top);
  }
}

int32_t CFX_ListCtrl::GetTopItem() const {
  int32_t nItemIndex = GetItemIndex(GetBTPoint());

  if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1))
    nItemIndex += 1;

  return nItemIndex;
}

void CFX_ListCtrl::Empty() {
  CFX_List::Empty();
  InvalidateItem(-1);
}

void CFX_ListCtrl::Cancel() {
  m_aSelItems.DeselectAll();
}

int32_t CFX_ListCtrl::GetItemIndex(const CPDF_Point& point) const {
  return CFX_List::GetItemIndex(OutToIn(point));
}

CFX_WideString CFX_ListCtrl::GetText() const {
  if (IsMultipleSel())
    return GetItemText(m_nCaretIndex);
  return GetItemText(m_nSelItem);
}
