// 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/fxfa/app/xfa_ffchoicelist.h"

#include <algorithm>
#include <vector>

#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
#include "xfa/fwl/cfwl_app.h"
#include "xfa/fwl/cfwl_combobox.h"
#include "xfa/fwl/cfwl_edit.h"
#include "xfa/fwl/cfwl_eventselectchanged.h"
#include "xfa/fwl/cfwl_listbox.h"
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fwl/cfwl_widgetproperties.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"

CXFA_FFListBox::CXFA_FFListBox(CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {}

CXFA_FFListBox::~CXFA_FFListBox() {
  if (m_pNormalWidget) {
    CFWL_NoteDriver* pNoteDriver =
        m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
    pNoteDriver->UnregisterEventTarget(m_pNormalWidget);
  }
}

bool CXFA_FFListBox::LoadWidget() {
  CFWL_ListBox* pListBox = new CFWL_ListBox(
      GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr);
  pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll | FWL_WGTSTYLE_NoBackground,
                         0xFFFFFFFF);
  m_pNormalWidget = (CFWL_Widget*)pListBox;
  m_pNormalWidget->SetLayoutItem(this);

  CFWL_NoteDriver* pNoteDriver =
      m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  for (const auto& label : m_pDataAcc->GetChoiceListItems(false))
    pListBox->AddString(label.AsStringC());

  uint32_t dwExtendedStyle = FWL_STYLEEXT_LTB_ShowScrollBarFocus;
  if (m_pDataAcc->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect)
    dwExtendedStyle |= FWL_STYLEEXT_LTB_MultiSelection;

  dwExtendedStyle |= GetAlignment();
  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
  for (int32_t selected : m_pDataAcc->GetSelectedItems())
    pListBox->SetSelItem(pListBox->GetItem(nullptr, selected), true);

  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}

bool CXFA_FFListBox::OnKillFocus(CXFA_FFWidget* pNewFocus) {
  if (!ProcessCommittedData())
    UpdateFWLData();
  CXFA_FFField::OnKillFocus(pNewFocus);
  return true;
}

bool CXFA_FFListBox::CommitData() {
  CFWL_ListBox* pListBox = static_cast<CFWL_ListBox*>(m_pNormalWidget);
  std::vector<int32_t> iSelArray;
  int32_t iSels = pListBox->CountSelItems();
  for (int32_t i = 0; i < iSels; ++i)
    iSelArray.push_back(pListBox->GetSelIndex(i));
  m_pDataAcc->SetSelectedItems(iSelArray, true, false, true);
  return true;
}

bool CXFA_FFListBox::IsDataChanged() {
  std::vector<int32_t> iSelArray = m_pDataAcc->GetSelectedItems();
  int32_t iOldSels = pdfium::CollectionSize<int32_t>(iSelArray);
  auto* pListBox = static_cast<CFWL_ListBox*>(m_pNormalWidget);
  int32_t iSels = pListBox->CountSelItems();
  if (iOldSels != iSels)
    return true;

  for (int32_t i = 0; i < iSels; ++i) {
    CFWL_ListItem* hlistItem = pListBox->GetItem(nullptr, iSelArray[i]);
    if (!(hlistItem->GetStates() & FWL_ITEMSTATE_LTB_Selected))
      return true;
  }
  return false;
}

uint32_t CXFA_FFListBox::GetAlignment() {
  uint32_t dwExtendedStyle = 0;
  if (CXFA_Para para = m_pDataAcc->GetPara()) {
    int32_t iHorz = para.GetHorizontalAlign();
    switch (iHorz) {
      case XFA_ATTRIBUTEENUM_Center:
        dwExtendedStyle |= FWL_STYLEEXT_LTB_CenterAlign;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        break;
      case XFA_ATTRIBUTEENUM_Radix:
        break;
      case XFA_ATTRIBUTEENUM_Right:
        dwExtendedStyle |= FWL_STYLEEXT_LTB_RightAlign;
        break;
      default:
        dwExtendedStyle |= FWL_STYLEEXT_LTB_LeftAlign;
        break;
    }
  }
  return dwExtendedStyle;
}
bool CXFA_FFListBox::UpdateFWLData() {
  if (!m_pNormalWidget)
    return false;

  auto* pListBox = static_cast<CFWL_ListBox*>(m_pNormalWidget);
  std::vector<int32_t> iSelArray = m_pDataAcc->GetSelectedItems();
  std::vector<CFWL_ListItem*> selItemArray(iSelArray.size());
  std::transform(iSelArray.begin(), iSelArray.end(), selItemArray.begin(),
                 [pListBox](int32_t val) { return pListBox->GetSelItem(val); });

  pListBox->SetSelItem(pListBox->GetSelItem(-1), false);
  for (CFWL_ListItem* pItem : selItemArray)
    pListBox->SetSelItem(pItem, true);

  m_pNormalWidget->Update();
  return true;
}
void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget,
                                     const std::vector<int32_t>& arrSels) {
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_Change;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
  CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget;
  int32_t iSels = pListBox->CountSelItems();
  if (iSels > 0) {
    CFWL_ListItem* item = pListBox->GetSelItem(0);
    eParam.m_wsNewText = item ? item->GetText() : L"";
  }

  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
}
void CXFA_FFListBox::SetItemState(int32_t nIndex, bool bSelected) {
  CFWL_ListItem* item = ((CFWL_ListBox*)m_pNormalWidget)->GetSelItem(nIndex);
  ((CFWL_ListBox*)m_pNormalWidget)->SetSelItem(item, bSelected);
  m_pNormalWidget->Update();
  AddInvalidateRect();
}
void CXFA_FFListBox::InsertItem(const CFX_WideStringC& wsLabel,
                                int32_t nIndex) {
  CFX_WideString wsTemp(wsLabel);
  ((CFWL_ListBox*)m_pNormalWidget)->AddString(wsTemp.AsStringC());
  m_pNormalWidget->Update();
  AddInvalidateRect();
}
void CXFA_FFListBox::DeleteItem(int32_t nIndex) {
  CFWL_ListBox* listBox = static_cast<CFWL_ListBox*>(m_pNormalWidget);
  if (nIndex < 0)
    listBox->DeleteAll();
  else
    listBox->DeleteString(listBox->GetItem(nullptr, nIndex));

  listBox->Update();
  AddInvalidateRect();
}

void CXFA_FFListBox::OnProcessMessage(CFWL_Message* pMessage) {
  m_pOldDelegate->OnProcessMessage(pMessage);
}

void CXFA_FFListBox::OnProcessEvent(CFWL_Event* pEvent) {
  CXFA_FFField::OnProcessEvent(pEvent);
  switch (pEvent->GetType()) {
    case CFWL_Event::Type::SelectChanged: {
      std::vector<int32_t> arrSels;
      OnSelectChanged(m_pNormalWidget, arrSels);
      break;
    }
    default:
      break;
  }
  m_pOldDelegate->OnProcessEvent(pEvent);
}
void CXFA_FFListBox::OnDrawWidget(CFX_Graphics* pGraphics,
                                  const CFX_Matrix* pMatrix) {
  m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
}

CXFA_FFComboBox::CXFA_FFComboBox(CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {}

CXFA_FFComboBox::~CXFA_FFComboBox() {}

CFX_RectF CXFA_FFComboBox::GetBBox(uint32_t dwStatus, bool bDrawFocus) {
  if (bDrawFocus)
    return CFX_RectF();
  return CXFA_FFWidget::GetBBox(dwStatus);
}

bool CXFA_FFComboBox::PtInActiveRect(const CFX_PointF& point) {
  auto* pComboBox = static_cast<CFWL_ComboBox*>(m_pNormalWidget);
  return pComboBox && pComboBox->GetBBox().Contains(point);
}

bool CXFA_FFComboBox::LoadWidget() {
  CFWL_ComboBox* pComboBox = new CFWL_ComboBox(GetFWLApp());
  m_pNormalWidget = (CFWL_Widget*)pComboBox;
  m_pNormalWidget->SetLayoutItem(this);

  CFWL_NoteDriver* pNoteDriver =
      m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  for (const auto& label : m_pDataAcc->GetChoiceListItems(false))
    pComboBox->AddString(label.AsStringC());

  std::vector<int32_t> iSelArray = m_pDataAcc->GetSelectedItems();
  if (!iSelArray.empty()) {
    pComboBox->SetCurSel(iSelArray.front());
  } else {
    CFX_WideString wsText;
    m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw);
    pComboBox->SetEditText(wsText);
  }
  UpdateWidgetProperty();
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}
void CXFA_FFComboBox::UpdateWidgetProperty() {
  CFWL_ComboBox* pComboBox = (CFWL_ComboBox*)m_pNormalWidget;
  if (!pComboBox) {
    return;
  }
  uint32_t dwExtendedStyle = 0;
  uint32_t dwEditStyles =
      FWL_STYLEEXT_EDT_ReadOnly | FWL_STYLEEXT_EDT_LastLineHeight;
  dwExtendedStyle |= UpdateUIProperty();
  if (m_pDataAcc->IsChoiceListAllowTextEntry()) {
    dwEditStyles &= ~FWL_STYLEEXT_EDT_ReadOnly;
    dwExtendedStyle |= FWL_STYLEEXT_CMB_DropDown;
  }
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
    dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
    dwExtendedStyle |= FWL_STYLEEXT_CMB_ReadOnly;
  }
  dwExtendedStyle |= GetAlignment();
  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
    dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
  }
  pComboBox->EditModifyStylesEx(dwEditStyles, 0xFFFFFFFF);
}

bool CXFA_FFComboBox::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
  if (!CXFA_FFField::OnRButtonUp(dwFlags, point))
    return false;

  GetDoc()->GetDocEnvironment()->PopupMenu(this, point);
  return true;
}

bool CXFA_FFComboBox::OnKillFocus(CXFA_FFWidget* pNewWidget) {
  bool flag = ProcessCommittedData();
  if (!flag) {
    UpdateFWLData();
  }
  CXFA_FFField::OnKillFocus(pNewWidget);
  return true;
}
void CXFA_FFComboBox::OpenDropDownList() {
  ((CFWL_ComboBox*)m_pNormalWidget)->OpenDropDownList(true);
}
bool CXFA_FFComboBox::CommitData() {
  return m_pDataAcc->SetValue(m_wsNewValue, XFA_VALUEPICTURE_Raw);
}
bool CXFA_FFComboBox::IsDataChanged() {
  CFWL_ComboBox* pFWLcombobox = ((CFWL_ComboBox*)m_pNormalWidget);
  CFX_WideString wsText = pFWLcombobox->GetEditText();
  int32_t iCursel = pFWLcombobox->GetCurSel();
  if (iCursel >= 0) {
    CFX_WideString wsSel = pFWLcombobox->GetTextByIndex(iCursel);
    if (wsSel == wsText)
      m_pDataAcc->GetChoiceListItem(wsText, iCursel, true);
  }

  CFX_WideString wsOldValue;
  m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Raw);
  if (wsOldValue != wsText) {
    m_wsNewValue = wsText;
    return true;
  }
  return false;
}
void CXFA_FFComboBox::FWLEventSelChange(CXFA_EventParam* pParam) {
  pParam->m_eType = XFA_EVENT_Change;
  pParam->m_pTarget = m_pDataAcc;
  CFWL_ComboBox* pFWLcombobox = ((CFWL_ComboBox*)m_pNormalWidget);
  pParam->m_wsNewText = pFWLcombobox->GetEditText();
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, pParam);
}
uint32_t CXFA_FFComboBox::GetAlignment() {
  uint32_t dwExtendedStyle = 0;
  if (CXFA_Para para = m_pDataAcc->GetPara()) {
    int32_t iHorz = para.GetHorizontalAlign();
    switch (iHorz) {
      case XFA_ATTRIBUTEENUM_Center:
        dwExtendedStyle |=
            FWL_STYLEEXT_CMB_EditHCenter | FWL_STYLEEXT_CMB_ListItemCenterAlign;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditJustified;
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        break;
      case XFA_ATTRIBUTEENUM_Radix:
        break;
      case XFA_ATTRIBUTEENUM_Right:
        break;
      default:
        dwExtendedStyle |=
            FWL_STYLEEXT_CMB_EditHNear | FWL_STYLEEXT_CMB_ListItemLeftAlign;
        break;
    }
    int32_t iVert = para.GetVerticalAlign();
    switch (iVert) {
      case XFA_ATTRIBUTEENUM_Middle:
        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVCenter;
        break;
      case XFA_ATTRIBUTEENUM_Bottom:
        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVFar;
        break;
      default:
        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVNear;
        break;
    }
  }
  return dwExtendedStyle;
}

bool CXFA_FFComboBox::UpdateFWLData() {
  auto* pComboBox = static_cast<CFWL_ComboBox*>(m_pNormalWidget);
  if (!pComboBox)
    return false;

  std::vector<int32_t> iSelArray = m_pDataAcc->GetSelectedItems();
  if (!iSelArray.empty()) {
    pComboBox->SetCurSel(iSelArray.front());
  } else {
    CFX_WideString wsText;
    pComboBox->SetCurSel(-1);
    m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw);
    pComboBox->SetEditText(wsText);
  }
  pComboBox->Update();
  return true;
}

bool CXFA_FFComboBox::CanUndo() {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditCanUndo();
}
bool CXFA_FFComboBox::CanRedo() {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditCanRedo();
}
bool CXFA_FFComboBox::Undo() {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditUndo();
}
bool CXFA_FFComboBox::Redo() {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditRedo();
}
bool CXFA_FFComboBox::CanCopy() {
  return ((CFWL_ComboBox*)m_pNormalWidget)->EditCanCopy();
}
bool CXFA_FFComboBox::CanCut() {
  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
    return false;
  }
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditCanCut();
}
bool CXFA_FFComboBox::CanPaste() {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         (m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open);
}
bool CXFA_FFComboBox::CanSelectAll() {
  return ((CFWL_ComboBox*)m_pNormalWidget)->EditCanSelectAll();
}
bool CXFA_FFComboBox::Copy(CFX_WideString& wsCopy) {
  return ((CFWL_ComboBox*)m_pNormalWidget)->EditCopy(wsCopy);
}
bool CXFA_FFComboBox::Cut(CFX_WideString& wsCut) {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditCut(wsCut);
}
bool CXFA_FFComboBox::Paste(const CFX_WideString& wsPaste) {
  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
         ((CFWL_ComboBox*)m_pNormalWidget)->EditPaste(wsPaste);
}
void CXFA_FFComboBox::SelectAll() {
  ((CFWL_ComboBox*)m_pNormalWidget)->EditSelectAll();
}
void CXFA_FFComboBox::Delete() {
  ((CFWL_ComboBox*)m_pNormalWidget)->EditDelete();
}
void CXFA_FFComboBox::DeSelect() {
  ((CFWL_ComboBox*)m_pNormalWidget)->EditDeSelect();
}
void CXFA_FFComboBox::SetItemState(int32_t nIndex, bool bSelected) {
  if (bSelected) {
    ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(nIndex);
  } else {
    ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(-1);
  }
  m_pNormalWidget->Update();
  AddInvalidateRect();
}
void CXFA_FFComboBox::InsertItem(const CFX_WideStringC& wsLabel,
                                 int32_t nIndex) {
  ((CFWL_ComboBox*)m_pNormalWidget)->AddString(wsLabel);
  m_pNormalWidget->Update();
  AddInvalidateRect();
}
void CXFA_FFComboBox::DeleteItem(int32_t nIndex) {
  if (nIndex < 0) {
    ((CFWL_ComboBox*)m_pNormalWidget)->RemoveAll();
  } else {
    ((CFWL_ComboBox*)m_pNormalWidget)->RemoveAt(nIndex);
  }
  m_pNormalWidget->Update();
  AddInvalidateRect();
}
void CXFA_FFComboBox::OnTextChanged(CFWL_Widget* pWidget,
                                    const CFX_WideString& wsChanged) {
  CXFA_EventParam eParam;
  m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
  eParam.m_wsChange = wsChanged;
  FWLEventSelChange(&eParam);
}
void CXFA_FFComboBox::OnSelectChanged(CFWL_Widget* pWidget, bool bLButtonUp) {
  CXFA_EventParam eParam;
  m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
  FWLEventSelChange(&eParam);
  if (m_pDataAcc->GetChoiceListCommitOn() == XFA_ATTRIBUTEENUM_Select &&
      bLButtonUp) {
    m_pDocView->SetFocusWidgetAcc(nullptr);
  }
}
void CXFA_FFComboBox::OnPreOpen(CFWL_Widget* pWidget) {
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_PreOpen;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PreOpen, &eParam);
}
void CXFA_FFComboBox::OnPostOpen(CFWL_Widget* pWidget) {
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_PostOpen;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PostOpen, &eParam);
}

void CXFA_FFComboBox::OnProcessMessage(CFWL_Message* pMessage) {
  m_pOldDelegate->OnProcessMessage(pMessage);
}

void CXFA_FFComboBox::OnProcessEvent(CFWL_Event* pEvent) {
  CXFA_FFField::OnProcessEvent(pEvent);
  switch (pEvent->GetType()) {
    case CFWL_Event::Type::SelectChanged: {
      CFWL_EventSelectChanged* postEvent =
          static_cast<CFWL_EventSelectChanged*>(pEvent);
      OnSelectChanged(m_pNormalWidget, postEvent->bLButtonUp);
      break;
    }
    case CFWL_Event::Type::EditChanged: {
      CFX_WideString wsChanged;
      OnTextChanged(m_pNormalWidget, wsChanged);
      break;
    }
    case CFWL_Event::Type::PreDropDown: {
      OnPreOpen(m_pNormalWidget);
      break;
    }
    case CFWL_Event::Type::PostDropDown: {
      OnPostOpen(m_pNormalWidget);
      break;
    }
    default:
      break;
  }
  m_pOldDelegate->OnProcessEvent(pEvent);
}

void CXFA_FFComboBox::OnDrawWidget(CFX_Graphics* pGraphics,
                                   const CFX_Matrix* pMatrix) {
  m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
}
