// Copyright 2014 The PDFium Authors
// 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/pwl/cpwl_list_ctrl.h"

#include <algorithm>
#include <utility>

#include "core/fpdfdoc/cpvt_word.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/stl_util.h"
#include "fpdfsdk/pwl/cpwl_edit_impl.h"
#include "fpdfsdk/pwl/cpwl_list_box.h"
#include "third_party/base/numerics/safe_conversions.h"

CPWL_ListCtrl::NotifyIface::~NotifyIface() = default;

CPWL_ListCtrl::Item::Item() : m_pEdit(std::make_unique<CPWL_EditImpl>()) {
  m_pEdit->SetAlignmentV(1);
  m_pEdit->Initialize();
}

CPWL_ListCtrl::Item::~Item() = default;

void CPWL_ListCtrl::Item::SetFontMap(IPVT_FontMap* pFontMap) {
  m_pEdit->SetFontMap(pFontMap);
}

void CPWL_ListCtrl::Item::SetText(const WideString& text) {
  m_pEdit->SetText(text);
  m_pEdit->Paint();
}

void CPWL_ListCtrl::Item::SetFontSize(float fFontSize) {
  m_pEdit->SetFontSize(fFontSize);
  m_pEdit->Paint();
}

float CPWL_ListCtrl::Item::GetItemHeight() const {
  return m_pEdit->GetContentRect().Height();
}

uint16_t CPWL_ListCtrl::Item::GetFirstChar() const {
  CPVT_Word word;
  CPWL_EditImpl::Iterator* pIterator = m_pEdit->GetIterator();
  pIterator->SetAt(1);
  pIterator->GetWord(word);
  return word.Word;
}

WideString CPWL_ListCtrl::Item::GetText() const {
  return m_pEdit->GetText();
}

CPWL_ListCtrl::SelectState::SelectState() = default;

CPWL_ListCtrl::SelectState::~SelectState() = default;

void CPWL_ListCtrl::SelectState::Add(int32_t nItemIndex) {
  m_Items[nItemIndex] = SELECTING;
}

void CPWL_ListCtrl::SelectState::Add(int32_t nBeginIndex, int32_t nEndIndex) {
  if (nBeginIndex > nEndIndex)
    std::swap(nBeginIndex, nEndIndex);

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

void CPWL_ListCtrl::SelectState::Sub(int32_t nItemIndex) {
  auto it = m_Items.find(nItemIndex);
  if (it != m_Items.end())
    it->second = DESELECTING;
}

void CPWL_ListCtrl::SelectState::Sub(int32_t nBeginIndex, int32_t nEndIndex) {
  if (nBeginIndex > nEndIndex)
    std::swap(nBeginIndex, nEndIndex);

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

void CPWL_ListCtrl::SelectState::DeselectAll() {
  for (auto& item : m_Items)
    item.second = DESELECTING;
}

void CPWL_ListCtrl::SelectState::Done() {
  auto it = m_Items.begin();
  while (it != m_Items.end()) {
    if (it->second == DESELECTING)
      it = m_Items.erase(it);
    else
      (it++)->second = NORMAL;
  }
}

CPWL_ListCtrl::CPWL_ListCtrl() = default;

CPWL_ListCtrl::~CPWL_ListCtrl() {
  m_ListItems.clear();
  InvalidateItem(-1);
}

CFX_PointF CPWL_ListCtrl::InToOut(const CFX_PointF& point) const {
  CFX_FloatRect rcPlate = m_rcPlate;
  return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
                    point.y - (m_ptScrollPos.y - rcPlate.top));
}

CFX_PointF CPWL_ListCtrl::OutToIn(const CFX_PointF& point) const {
  CFX_FloatRect rcPlate = m_rcPlate;
  return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
                    point.y + (m_ptScrollPos.y - rcPlate.top));
}

CFX_FloatRect CPWL_ListCtrl::InToOut(const CFX_FloatRect& rect) const {
  CFX_PointF ptLeftBottom = InToOut(CFX_PointF(rect.left, rect.bottom));
  CFX_PointF ptRightTop = InToOut(CFX_PointF(rect.right, rect.top));
  return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
                       ptRightTop.y);
}

CFX_FloatRect CPWL_ListCtrl::OutToIn(const CFX_FloatRect& rect) const {
  CFX_PointF ptLeftBottom = OutToIn(CFX_PointF(rect.left, rect.bottom));
  CFX_PointF ptRightTop = OutToIn(CFX_PointF(rect.right, rect.top));
  return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
                       ptRightTop.y);
}

CFX_PointF CPWL_ListCtrl::InnerToOuter(const CFX_PointF& point) const {
  return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
}

CFX_PointF CPWL_ListCtrl::OuterToInner(const CFX_PointF& point) const {
  return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
}

CFX_FloatRect CPWL_ListCtrl::InnerToOuter(const CFX_FloatRect& rect) const {
  CFX_PointF ptLeftTop = InnerToOuter(CFX_PointF(rect.left, rect.top));
  CFX_PointF ptRightBottom = InnerToOuter(CFX_PointF(rect.right, rect.bottom));
  return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
                       ptLeftTop.y);
}

CFX_FloatRect CPWL_ListCtrl::OuterToInner(const CFX_FloatRect& rect) const {
  CFX_PointF ptLeftTop = OuterToInner(CFX_PointF(rect.left, rect.top));
  CFX_PointF ptRightBottom = OuterToInner(CFX_PointF(rect.right, rect.bottom));
  return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
                       ptLeftTop.y);
}

void CPWL_ListCtrl::OnMouseDown(const CFX_PointF& point,
                                bool bShift,
                                bool bCtrl) {
  int32_t nHitIndex = GetItemIndex(point);

  if (IsMultipleSel()) {
    if (bCtrl) {
      if (IsItemSelected(nHitIndex)) {
        m_SelectState.Sub(nHitIndex);
        SelectItems();
        m_bCtrlSel = false;
      } else {
        m_SelectState.Add(nHitIndex);
        SelectItems();
        m_bCtrlSel = true;
      }

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

      m_nFootIndex = nHitIndex;
    }

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

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

void CPWL_ListCtrl::OnMouseMove(const CFX_PointF& point,
                                bool bShift,
                                bool bCtrl) {
  int32_t nHitIndex = GetItemIndex(point);

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

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

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

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

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

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

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

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

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

void CPWL_ListCtrl::OnVK_LEFT(bool bShift, bool bCtrl) {
  OnVK(0, bShift, bCtrl);
}

void CPWL_ListCtrl::OnVK_RIGHT(bool bShift, bool bCtrl) {
  OnVK(GetCount() - 1, bShift, bCtrl);
}

void CPWL_ListCtrl::OnVK_HOME(bool bShift, bool bCtrl) {
  OnVK(0, bShift, bCtrl);
}

void CPWL_ListCtrl::OnVK_END(bool bShift, bool bCtrl) {
  OnVK(GetCount() - 1, bShift, bCtrl);
}

bool CPWL_ListCtrl::OnChar(uint16_t nChar, bool bShift, bool bCtrl) {
  int32_t nIndex = GetLastSelected();
  int32_t nFindIndex = FindNext(nIndex, nChar);

  if (nFindIndex != nIndex) {
    OnVK(nFindIndex, bShift, bCtrl);
    return true;
  }
  return false;
}

void CPWL_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) {
  m_rcPlate = rect;
  m_ptScrollPos.x = rect.left;
  SetScrollPos(CFX_PointF(rect.left, rect.top));
  ReArrange(0);
  InvalidateItem(-1);
}

CFX_FloatRect CPWL_ListCtrl::GetItemRect(int32_t nIndex) const {
  return InToOut(GetItemRectInternal(nIndex));
}

CFX_FloatRect CPWL_ListCtrl::GetItemRectInternal(int32_t nIndex) const {
  if (!IsValid(nIndex))
    return CFX_FloatRect();

  CFX_FloatRect rcItem = m_ListItems[nIndex]->GetRect();
  rcItem.left = 0.0f;
  rcItem.right = m_rcPlate.Width();
  return InnerToOuter(rcItem);
}

void CPWL_ListCtrl::AddString(const WideString& str) {
  AddItem(str);
  ReArrange(GetCount() - 1);
}

void CPWL_ListCtrl::SetMultipleSelect(int32_t nItemIndex, bool bSelected) {
  if (!IsValid(nItemIndex))
    return;

  if (bSelected != IsItemSelected(nItemIndex)) {
    if (bSelected) {
      SetItemSelect(nItemIndex, true);
      InvalidateItem(nItemIndex);
    } else {
      SetItemSelect(nItemIndex, false);
      InvalidateItem(nItemIndex);
    }
  }
}

void CPWL_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 CPWL_ListCtrl::SetCaret(int32_t nItemIndex) {
  if (!IsValid(nItemIndex))
    return;

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

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

void CPWL_ListCtrl::InvalidateItem(int32_t nItemIndex) {
  if (m_pNotify) {
    if (nItemIndex == -1) {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = true;
        CFX_FloatRect rcRefresh = m_rcPlate;
        m_pNotify->OnInvalidateRect(rcRefresh);
        m_bNotifyFlag = false;
      }
    } else {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = true;
        CFX_FloatRect rcRefresh = GetItemRect(nItemIndex);
        rcRefresh.left -= 1.0f;
        rcRefresh.right += 1.0f;
        rcRefresh.bottom -= 1.0f;
        rcRefresh.top += 1.0f;

        m_pNotify->OnInvalidateRect(rcRefresh);
        m_bNotifyFlag = false;
      }
    }
  }
}

void CPWL_ListCtrl::SelectItems() {
  for (const auto& item : m_SelectState) {
    if (item.second != SelectState::NORMAL)
      SetMultipleSelect(item.first, item.second == SelectState::SELECTING);
  }
  m_SelectState.Done();
}

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

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

void CPWL_ListCtrl::Deselect(int32_t nItemIndex) {
  if (!IsItemSelected(nItemIndex))
    return;

  SetMultipleSelect(nItemIndex, false);

  if (!IsMultipleSel())
    m_nSelItem = -1;
}

bool CPWL_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
  CFX_FloatRect rcPlate = m_rcPlate;
  CFX_FloatRect rcItem = GetItemRect(nItemIndex);

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

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

  CFX_FloatRect rcPlate = m_rcPlate;
  CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex);
  CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);

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

void CPWL_ListCtrl::SetScrollInfo() {
  if (m_pNotify) {
    CFX_FloatRect rcPlate = m_rcPlate;
    CFX_FloatRect rcContent = GetContentRectInternal();

    if (!m_bNotifyFlag) {
      m_bNotifyFlag = true;
      m_pNotify->OnSetScrollInfoY(rcPlate.bottom, rcPlate.top, rcContent.bottom,
                                  rcContent.top, GetFirstHeight(),
                                  rcPlate.Height());
      m_bNotifyFlag = false;
    }
  }
}

void CPWL_ListCtrl::SetScrollPos(const CFX_PointF& point) {
  SetScrollPosY(point.y);
}

void CPWL_ListCtrl::SetScrollPosY(float fy) {
  if (!FXSYS_IsFloatEqual(m_ptScrollPos.y, fy)) {
    CFX_FloatRect rcPlate = m_rcPlate;
    CFX_FloatRect rcContent = GetContentRectInternal();

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

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

    if (m_pNotify) {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = true;
        m_pNotify->OnSetScrollPosY(fy);
        m_bNotifyFlag = false;
      }
    }
  }
}

CFX_FloatRect CPWL_ListCtrl::GetContentRectInternal() const {
  return InnerToOuter(m_rcContent);
}

CFX_FloatRect CPWL_ListCtrl::GetContentRect() const {
  return InToOut(GetContentRectInternal());
}

void CPWL_ListCtrl::ReArrange(int32_t nItemIndex) {
  float fPosY = 0.0f;
  if (IsValid(nItemIndex - 1))
    fPosY = m_ListItems[nItemIndex - 1]->GetRect().bottom;

  for (const auto& pListItem : m_ListItems) {
    float fListItemHeight = pListItem->GetItemHeight();
    pListItem->SetRect(
        CFX_FloatRect(0.0f, fPosY + fListItemHeight, 0.0f, fPosY));
    fPosY += fListItemHeight;
  }
  m_rcContent = CFX_FloatRect(0.0f, fPosY, 0.0f, 0.0f);
  SetScrollInfo();
}

void CPWL_ListCtrl::SetTopItem(int32_t nIndex) {
  if (IsValid(nIndex)) {
    CFX_FloatRect rcItem = GetItemRectInternal(nIndex);
    SetScrollPosY(rcItem.top);
  }
}

int32_t CPWL_ListCtrl::GetTopItem() const {
  int32_t nItemIndex = GetItemIndex(GetBTPoint());
  if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1))
    nItemIndex += 1;

  return nItemIndex;
}

int32_t CPWL_ListCtrl::GetItemIndex(const CFX_PointF& point) const {
  CFX_PointF pt = OuterToInner(OutToIn(point));
  bool bFirst = true;
  bool bLast = true;
  for (const auto& pListItem : m_ListItems) {
    CFX_FloatRect rcListItem = pListItem->GetRect();
    if (FXSYS_IsFloatBigger(pt.y, rcListItem.top))
      bFirst = false;
    if (FXSYS_IsFloatSmaller(pt.y, rcListItem.bottom))
      bLast = false;
    if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
      return pdfium::base::checked_cast<int32_t>(&pListItem -
                                                 &m_ListItems.front());
    }
  }
  if (bFirst)
    return 0;
  if (bLast)
    return GetCount() - 1;
  return -1;
}

WideString CPWL_ListCtrl::GetText() const {
  if (IsMultipleSel())
    return GetItemText(m_nCaretIndex);
  return GetItemText(m_nSelItem);
}

void CPWL_ListCtrl::AddItem(const WideString& str) {
  auto pListItem = std::make_unique<Item>();
  pListItem->SetFontMap(m_pFontMap);
  pListItem->SetFontSize(m_fFontSize);
  pListItem->SetText(str);
  m_ListItems.push_back(std::move(pListItem));
}

CPWL_EditImpl* CPWL_ListCtrl::GetItemEdit(int32_t nIndex) const {
  if (!IsValid(nIndex))
    return nullptr;
  return m_ListItems[nIndex]->GetEdit();
}

int32_t CPWL_ListCtrl::GetCount() const {
  return fxcrt::CollectionSize<int32_t>(m_ListItems);
}

float CPWL_ListCtrl::GetFirstHeight() const {
  if (m_ListItems.empty())
    return 1.0f;
  return m_ListItems.front()->GetItemHeight();
}

int32_t CPWL_ListCtrl::GetFirstSelected() const {
  int32_t i = 0;
  for (const auto& pListItem : m_ListItems) {
    if (pListItem->IsSelected())
      return i;
    ++i;
  }
  return -1;
}

int32_t CPWL_ListCtrl::GetLastSelected() const {
  for (auto iter = m_ListItems.rbegin(); iter != m_ListItems.rend(); ++iter) {
    if ((*iter)->IsSelected())
      return pdfium::base::checked_cast<int32_t>(&*iter - &m_ListItems.front());
  }
  return -1;
}

int32_t CPWL_ListCtrl::FindNext(int32_t nIndex, wchar_t nChar) const {
  int32_t nCircleIndex = nIndex;
  int32_t sz = GetCount();
  for (int32_t i = 0; i < sz; i++) {
    nCircleIndex++;
    if (nCircleIndex >= sz)
      nCircleIndex = 0;

    if (Item* pListItem = m_ListItems[nCircleIndex].get()) {
      if (FXSYS_towupper(pListItem->GetFirstChar()) == FXSYS_towupper(nChar))
        return nCircleIndex;
    }
  }

  return nCircleIndex;
}

bool CPWL_ListCtrl::IsItemSelected(int32_t nIndex) const {
  return IsValid(nIndex) && m_ListItems[nIndex]->IsSelected();
}

void CPWL_ListCtrl::SetItemSelect(int32_t nIndex, bool bSelected) {
  if (IsValid(nIndex))
    m_ListItems[nIndex]->SetSelect(bSelected);
}

bool CPWL_ListCtrl::IsValid(int32_t nItemIndex) const {
  return fxcrt::IndexInBounds(m_ListItems, nItemIndex);
}

WideString CPWL_ListCtrl::GetItemText(int32_t nIndex) const {
  if (IsValid(nIndex))
    return m_ListItems[nIndex]->GetText();
  return WideString();
}
