// 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 "xfa/fwl/lightwidget/cfwl_combobox.h"

#include <utility>

#include "xfa/fwl/core/fwl_error.h"
#include "xfa/fwl/core/ifwl_widget.h"

CFWL_ComboBox* CFWL_ComboBox::Create() {
  return new CFWL_ComboBox;
}

FWL_ERR CFWL_ComboBox::Initialize(const CFWL_WidgetProperties* pProperties) {
  if (m_pIface)
    return FWL_ERR_Indefinite;
  if (pProperties) {
    *m_pProperties = *pProperties;
  }
  std::unique_ptr<IFWL_ComboBox> pComboBox(IFWL_ComboBox::Create(
      m_pProperties->MakeWidgetImpProperties(&m_comboBoxData)));
  FWL_ERR ret = pComboBox->Initialize();
  if (ret != FWL_ERR_Succeeded) {
    return ret;
  }
  m_pIface = pComboBox.release();
  CFWL_Widget::Initialize();
  return FWL_ERR_Succeeded;
}

int32_t CFWL_ComboBox::AddString(const CFX_WideStringC& wsText) {
  std::unique_ptr<CFWL_ComboBoxItem> pItem(new CFWL_ComboBoxItem);
  pItem->m_wsText = wsText;
  pItem->m_dwStyles = 0;
  m_comboBoxData.m_ItemArray.push_back(std::move(pItem));
  return m_comboBoxData.m_ItemArray.size() - 1;
}

int32_t CFWL_ComboBox::AddString(const CFX_WideStringC& wsText,
                                 CFX_DIBitmap* pIcon) {
  std::unique_ptr<CFWL_ComboBoxItem> pItem(new CFWL_ComboBoxItem);
  pItem->m_wsText = wsText;
  pItem->m_dwStyles = 0;
  pItem->m_pDIB = pIcon;
  m_comboBoxData.m_ItemArray.push_back(std::move(pItem));
  return m_comboBoxData.m_ItemArray.size() - 1;
}

bool CFWL_ComboBox::RemoveAt(int32_t iIndex) {
  if (iIndex < 0 ||
      static_cast<size_t>(iIndex) >= m_comboBoxData.m_ItemArray.size()) {
    return false;
  }
  m_comboBoxData.m_ItemArray.erase(m_comboBoxData.m_ItemArray.begin() + iIndex);
  return true;
}

void CFWL_ComboBox::RemoveAll() {
  m_comboBoxData.m_ItemArray.clear();
}

int32_t CFWL_ComboBox::CountItems() {
  return m_comboBoxData.CountItems(GetWidget());
}

FWL_ERR CFWL_ComboBox::GetTextByIndex(int32_t iIndex, CFX_WideString& wsText) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(
      m_comboBoxData.GetItem(m_pIface, iIndex));
  if (!pItem)
    return FWL_ERR_Indefinite;
  wsText = pItem->m_wsText;
  return FWL_ERR_Succeeded;
}

int32_t CFWL_ComboBox::GetCurSel() {
  if (!m_pIface)
    return -1;
  return static_cast<IFWL_ComboBox*>(m_pIface)->GetCurSel();
}

FWL_ERR CFWL_ComboBox::SetCurSel(int32_t iSel) {
  if (!m_pIface)
    return FWL_ERR_Indefinite;
  return static_cast<IFWL_ComboBox*>(m_pIface)->SetCurSel(iSel);
}

FWL_ERR CFWL_ComboBox::SetEditText(const CFX_WideString& wsText) {
  if (!m_pIface)
    return FWL_ERR_Indefinite;
  return static_cast<IFWL_ComboBox*>(m_pIface)->SetEditText(wsText);
}

int32_t CFWL_ComboBox::GetEditTextLength() const {
  if (!m_pIface)
    return 0;
  return static_cast<IFWL_ComboBox*>(m_pIface)->GetEditTextLength();
}

FWL_ERR CFWL_ComboBox::GetEditText(CFX_WideString& wsText,
                                   int32_t nStart,
                                   int32_t nCount) const {
  if (!m_pIface)
    return FWL_ERR_Indefinite;
  return static_cast<IFWL_ComboBox*>(m_pIface)
      ->GetEditText(wsText, nStart, nCount);
}

FWL_ERR CFWL_ComboBox::SetEditSelRange(int32_t nStart, int32_t nCount) {
  if (!m_pIface)
    return FWL_ERR_Indefinite;
  return static_cast<IFWL_ComboBox*>(m_pIface)->SetEditSelRange(nStart, nCount);
}

int32_t CFWL_ComboBox::GetEditSelRange(int32_t nIndex, int32_t& nStart) {
  if (!m_pIface)
    return 0;
  return static_cast<IFWL_ComboBox*>(m_pIface)->GetEditSelRange(nIndex, nStart);
}

int32_t CFWL_ComboBox::GetEditLimit() {
  if (!m_pIface)
    return 0;
  return static_cast<IFWL_ComboBox*>(m_pIface)->GetEditLimit();
}

FWL_ERR CFWL_ComboBox::SetEditLimit(int32_t nLimit) {
  if (!m_pIface)
    return FWL_ERR_Indefinite;
  return static_cast<IFWL_ComboBox*>(m_pIface)->SetEditLimit(nLimit);
}

FWL_ERR CFWL_ComboBox::EditDoClipboard(int32_t iCmd) {
  if (!m_pIface)
    return FWL_ERR_Indefinite;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditDoClipboard(iCmd);
}

FX_BOOL CFWL_ComboBox::EditRedo(const CFX_ByteStringC& bsRecord) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditRedo(bsRecord);
}

FX_BOOL CFWL_ComboBox::EditUndo(const CFX_ByteStringC& bsRecord) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditUndo(bsRecord);
}

FWL_ERR CFWL_ComboBox::SetMaxListHeight(FX_FLOAT fMaxHeight) {
  m_comboBoxData.m_fMaxListHeight = fMaxHeight;
  return FWL_ERR_Succeeded;
}

FWL_ERR CFWL_ComboBox::SetItemData(int32_t iIndex, void* pData) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(
      m_comboBoxData.GetItem(m_pIface, iIndex));
  if (!pItem)
    return FWL_ERR_Indefinite;
  pItem->m_pData = pData;
  return FWL_ERR_Succeeded;
}

void* CFWL_ComboBox::GetItemData(int32_t iIndex) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(
      m_comboBoxData.GetItem(m_pIface, iIndex));
  if (!pItem)
    return NULL;
  return pItem->m_pData;
}

FWL_ERR CFWL_ComboBox::SetListTheme(IFWL_ThemeProvider* pTheme) {
  return static_cast<IFWL_ComboBox*>(m_pIface)->GetListBoxt()->SetThemeProvider(
      pTheme);
}

FX_BOOL CFWL_ComboBox::AfterFocusShowDropList() {
  return static_cast<IFWL_ComboBox*>(m_pIface)->AfterFocusShowDropList();
}

FWL_ERR CFWL_ComboBox::OpenDropDownList(FX_BOOL bActivate) {
  return static_cast<IFWL_ComboBox*>(m_pIface)->OpenDropDownList(bActivate);
}

FX_BOOL CFWL_ComboBox::EditCanUndo() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCanUndo();
}

FX_BOOL CFWL_ComboBox::EditCanRedo() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCanRedo();
}

FX_BOOL CFWL_ComboBox::EditUndo() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditUndo();
}

FX_BOOL CFWL_ComboBox::EditRedo() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditRedo();
}

FX_BOOL CFWL_ComboBox::EditCanCopy() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCanCopy();
}

FX_BOOL CFWL_ComboBox::EditCanCut() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCanCut();
}

FX_BOOL CFWL_ComboBox::EditCanSelectAll() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCanSelectAll();
}

FX_BOOL CFWL_ComboBox::EditCopy(CFX_WideString& wsCopy) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCopy(wsCopy);
}

FX_BOOL CFWL_ComboBox::EditCut(CFX_WideString& wsCut) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditCut(wsCut);
}

FX_BOOL CFWL_ComboBox::EditPaste(const CFX_WideString& wsPaste) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditPaste(wsPaste);
}

FX_BOOL CFWL_ComboBox::EditSelectAll() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditSelectAll();
}

FX_BOOL CFWL_ComboBox::EditDelete() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditDelete();
}

FX_BOOL CFWL_ComboBox::EditDeSelect() {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->EditDeSelect();
}

FWL_ERR CFWL_ComboBox::GetBBox(CFX_RectF& rect) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)->GetBBox(rect);
}

FWL_ERR CFWL_ComboBox::EditModifyStylesEx(uint32_t dwStylesExAdded,
                                          uint32_t dwStylesExRemoved) {
  if (!m_pIface)
    return FALSE;
  return static_cast<IFWL_ComboBox*>(m_pIface)
      ->EditModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
}

CFWL_ComboBox::CFWL_ComboBox() {}

CFWL_ComboBox::~CFWL_ComboBox() {}

CFWL_ComboBox::CFWL_ComboBoxDP::CFWL_ComboBoxDP() {
  m_fItemHeight = 0;
  m_fMaxListHeight = 0;
}

CFWL_ComboBox::CFWL_ComboBoxDP::~CFWL_ComboBoxDP() {}

int32_t CFWL_ComboBox::CFWL_ComboBoxDP::CountItems(IFWL_Widget* pWidget) {
  return m_ItemArray.size();
}

FWL_HLISTITEM CFWL_ComboBox::CFWL_ComboBoxDP::GetItem(IFWL_Widget* pWidget,
                                                      int32_t nIndex) {
  if (nIndex < 0 || static_cast<size_t>(nIndex) >= m_ItemArray.size())
    return nullptr;

  return reinterpret_cast<FWL_HLISTITEM>(m_ItemArray[nIndex].get());
}

int32_t CFWL_ComboBox::CFWL_ComboBoxDP::GetItemIndex(IFWL_Widget* pWidget,
                                                     FWL_HLISTITEM hItem) {
  auto it = std::find_if(
      m_ItemArray.begin(), m_ItemArray.end(),
      [hItem](const std::unique_ptr<CFWL_ComboBoxItem>& candidate) {
        return candidate.get() == reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
      });
  return it != m_ItemArray.end() ? it - m_ItemArray.begin() : -1;
}

FX_BOOL CFWL_ComboBox::CFWL_ComboBoxDP::SetItemIndex(IFWL_Widget* pWidget,
                                                     FWL_HLISTITEM hItem,
                                                     int32_t nIndex) {
  if (nIndex < 0 || static_cast<size_t>(nIndex) >= m_ItemArray.size())
    return FALSE;

  m_ItemArray[nIndex].reset(reinterpret_cast<CFWL_ComboBoxItem*>(hItem));
  return TRUE;
}

uint32_t CFWL_ComboBox::CFWL_ComboBoxDP::GetItemStyles(IFWL_Widget* pWidget,
                                                       FWL_HLISTITEM hItem) {
  if (!hItem)
    return 0;
  return reinterpret_cast<CFWL_ComboBoxItem*>(hItem)->m_dwStyles;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::GetItemText(IFWL_Widget* pWidget,
                                                    FWL_HLISTITEM hItem,
                                                    CFX_WideString& wsText) {
  if (!hItem)
    return FWL_ERR_Indefinite;
  wsText = reinterpret_cast<CFWL_ComboBoxItem*>(hItem)->m_wsText;
  return FWL_ERR_Succeeded;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::GetItemRect(IFWL_Widget* pWidget,
                                                    FWL_HLISTITEM hItem,
                                                    CFX_RectF& rtItem) {
  if (!hItem)
    return FWL_ERR_Indefinite;
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
  rtItem.Set(pItem->m_rtItem.left, pItem->m_rtItem.top, pItem->m_rtItem.width,
             pItem->m_rtItem.height);
  return FWL_ERR_Succeeded;
}

void* CFWL_ComboBox::CFWL_ComboBoxDP::GetItemData(IFWL_Widget* pWidget,
                                                  FWL_HLISTITEM hItem) {
  if (!hItem)
    return NULL;
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
  return pItem->m_pData;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemStyles(IFWL_Widget* pWidget,
                                                      FWL_HLISTITEM hItem,
                                                      uint32_t dwStyle) {
  if (!hItem)
    return FWL_ERR_Indefinite;
  reinterpret_cast<CFWL_ComboBoxItem*>(hItem)->m_dwStyles = dwStyle;
  return FWL_ERR_Succeeded;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemText(IFWL_Widget* pWidget,
                                                    FWL_HLISTITEM hItem,
                                                    const FX_WCHAR* pszText) {
  if (!hItem)
    return FWL_ERR_Indefinite;
  reinterpret_cast<CFWL_ComboBoxItem*>(hItem)->m_wsText = pszText;
  return FWL_ERR_Succeeded;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemRect(IFWL_Widget* pWidget,
                                                    FWL_HLISTITEM hItem,
                                                    const CFX_RectF& rtItem) {
  if (!hItem)
    return FWL_ERR_Indefinite;
  reinterpret_cast<CFWL_ComboBoxItem*>(hItem)->m_rtItem = rtItem;
  return FWL_ERR_Succeeded;
}

FX_FLOAT CFWL_ComboBox::CFWL_ComboBoxDP::GetItemHeight(IFWL_Widget* pWidget) {
  return m_fItemHeight;
}

CFX_DIBitmap* CFWL_ComboBox::CFWL_ComboBoxDP::GetItemIcon(IFWL_Widget* pWidget,
                                                          FWL_HLISTITEM hItem) {
  if (!hItem)
    return NULL;
  return reinterpret_cast<CFWL_ComboBoxItem*>(hItem)->m_pDIB;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::GetItemCheckRect(IFWL_Widget* pWidget,
                                                         FWL_HLISTITEM hItem,
                                                         CFX_RectF& rtCheck) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
  rtCheck = pItem->m_rtCheckBox;
  return FWL_ERR_Succeeded;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemCheckRect(
    IFWL_Widget* pWidget,
    FWL_HLISTITEM hItem,
    const CFX_RectF& rtCheck) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
  pItem->m_rtCheckBox = rtCheck;
  return FWL_ERR_Succeeded;
}

uint32_t CFWL_ComboBox::CFWL_ComboBoxDP::GetItemCheckState(
    IFWL_Widget* pWidget,
    FWL_HLISTITEM hItem) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
  return pItem->m_dwCheckState;
}

FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemCheckState(
    IFWL_Widget* pWidget,
    FWL_HLISTITEM hItem,
    uint32_t dwCheckState) {
  CFWL_ComboBoxItem* pItem = reinterpret_cast<CFWL_ComboBoxItem*>(hItem);
  pItem->m_dwCheckState = dwCheckState;
  return FWL_ERR_Succeeded;
}

FX_FLOAT CFWL_ComboBox::CFWL_ComboBoxDP::GetListHeight(IFWL_Widget* pWidget) {
  return m_fMaxListHeight;
}
