// 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/pdfwindow/PWL_IconList.h"

#include "fpdfsdk/pdfwindow/PWL_Label.h"
#include "fpdfsdk/pdfwindow/PWL_ListCtrl.h"
#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
#include "fpdfsdk/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
#include "public/fpdf_fwlevent.h"

#define PWL_IconList_ITEM_ICON_LEFTMARGIN 10.0f
#define PWL_IconList_ITEM_WIDTH 20.0f
#define PWL_IconList_ITEM_HEIGHT 20.0f
#define PWL_IconList_ITEM_SPACE 4.0f

CPWL_IconList_Item::CPWL_IconList_Item()
    : m_nIconIndex(-1), m_pData(NULL), m_bSelected(FALSE), m_pText(NULL) {}

CPWL_IconList_Item::~CPWL_IconList_Item() {}

CFX_ByteString CPWL_IconList_Item::GetClassName() const {
  return "CPWL_IconList_Item";
}

FX_FLOAT CPWL_IconList_Item::GetItemHeight(FX_FLOAT fLimitWidth) {
  return PWL_IconList_ITEM_HEIGHT;
}

void CPWL_IconList_Item::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                            CFX_Matrix* pUser2Device) {
  CFX_FloatRect rcClient = GetClientRect();

  if (m_bSelected) {
    if (IsEnabled()) {
      CPWL_Utils::DrawFillRect(
          pDevice, pUser2Device, rcClient,
          CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_SELBACKCOLOR,
                                        GetTransparency()));
    } else {
      CPWL_Utils::DrawFillRect(
          pDevice, pUser2Device, rcClient,
          CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_LIGHTGRAYCOLOR,
                                        GetTransparency()));
    }
  }

  CFX_FloatRect rcIcon = rcClient;
  rcIcon.left += PWL_IconList_ITEM_ICON_LEFTMARGIN;
  rcIcon.right = rcIcon.left + PWL_IconList_ITEM_WIDTH;

  CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nIconIndex, rcIcon,
                                m_crIcon, m_pText->GetTextColor(),
                                GetTransparency());
}

void CPWL_IconList_Item::SetSelect(FX_BOOL bSelected) {
  m_bSelected = bSelected;

  if (bSelected)
    m_pText->SetTextColor(PWL_DEFAULT_WHITECOLOR);
  else
    m_pText->SetTextColor(PWL_DEFAULT_BLACKCOLOR);
}

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

void CPWL_IconList_Item::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  m_pText = new CPWL_Label;

  PWL_CREATEPARAM lcp = cp;
  lcp.pParentWnd = this;
  lcp.dwFlags = PWS_CHILD | PWS_VISIBLE | PES_LEFT | PES_CENTER;
  lcp.sTextColor = PWL_DEFAULT_BLACKCOLOR;
  lcp.fFontSize = 12;
  m_pText->Create(lcp);
}

void CPWL_IconList_Item::SetData(void* pData) {
  m_pData = pData;
}

void CPWL_IconList_Item::SetIcon(int32_t nIconIndex) {
  m_nIconIndex = nIconIndex;
}

void CPWL_IconList_Item::SetText(const CFX_WideString& str) {
  m_pText->SetText(str.c_str());
}

CFX_WideString CPWL_IconList_Item::GetText() const {
  return m_pText->GetText();
}

void CPWL_IconList_Item::RePosChildWnd() {
  CFX_FloatRect rcClient = GetClientRect();

  rcClient.left +=
      (PWL_IconList_ITEM_ICON_LEFTMARGIN + PWL_IconList_ITEM_WIDTH +
       PWL_IconList_ITEM_ICON_LEFTMARGIN);

  m_pText->Move(rcClient, TRUE, FALSE);
}

void CPWL_IconList_Item::SetIconFillColor(const CPWL_Color& color) {
  m_crIcon = color;
}

void CPWL_IconList_Item::OnEnabled() {
  if (m_bSelected)
    m_pText->SetTextColor(PWL_DEFAULT_WHITECOLOR);
  else
    m_pText->SetTextColor(PWL_DEFAULT_BLACKCOLOR);

  InvalidateRect();
}

void CPWL_IconList_Item::OnDisabled() {
  m_pText->SetTextColor(PWL_DEFAULT_HEAVYGRAYCOLOR);

  InvalidateRect();
}

CPWL_IconList_Content::CPWL_IconList_Content(int32_t nListCount)
    : m_nSelectIndex(-1),
      m_bMouseDown(FALSE),
      m_nListCount(nListCount) {}

CPWL_IconList_Content::~CPWL_IconList_Content() {}

void CPWL_IconList_Content::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  for (int32_t i = 0; i < m_nListCount; i++) {
    CPWL_IconList_Item* pNewItem = new CPWL_IconList_Item();

    PWL_CREATEPARAM icp = cp;
    icp.pParentWnd = this;
    icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_NOREFRESHCLIP;
    pNewItem->Create(icp);
  }

  SetItemSpace(PWL_IconList_ITEM_SPACE);
  ResetContent(0);

  if (CPWL_Wnd* pParent = GetParentWindow()) {
    CFX_FloatRect rcScroll = GetScrollArea();
    GetScrollPos();

    PWL_SCROLL_INFO sInfo;
    sInfo.fContentMin = rcScroll.bottom;
    sInfo.fContentMax = rcScroll.top;
    sInfo.fPlateWidth = GetClientRect().Height();
    sInfo.fSmallStep = 13.0f;
    sInfo.fBigStep = sInfo.fPlateWidth;

    pParent->OnNotify(this, PNM_SETSCROLLINFO, SBT_VSCROLL, (intptr_t)&sInfo);
  }
}

FX_BOOL CPWL_IconList_Content::OnLButtonDown(const CFX_FloatPoint& point,
                                             uint32_t nFlag) {
  SetFocus();

  SetCapture();
  m_bMouseDown = TRUE;

  int32_t nItemIndex = FindItemIndex(point);
  SetSelect(nItemIndex);
  ScrollToItem(nItemIndex);

  return TRUE;
}

FX_BOOL CPWL_IconList_Content::OnLButtonUp(const CFX_FloatPoint& point,
                                           uint32_t nFlag) {
  m_bMouseDown = FALSE;
  ReleaseCapture();

  return TRUE;
}

FX_BOOL CPWL_IconList_Content::OnMouseMove(const CFX_FloatPoint& point,
                                           uint32_t nFlag) {
  if (m_bMouseDown) {
    int32_t nItemIndex = FindItemIndex(point);
    SetSelect(nItemIndex);
    ScrollToItem(nItemIndex);
  }

  return TRUE;
}

FX_BOOL CPWL_IconList_Content::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
  switch (nChar) {
    case FWL_VKEY_Up:
      if (m_nSelectIndex > 0) {
        int32_t nItemIndex = m_nSelectIndex - 1;
        SetSelect(nItemIndex);
        ScrollToItem(nItemIndex);
      }
      return TRUE;
    case FWL_VKEY_Down:
      if (m_nSelectIndex < m_nListCount - 1) {
        int32_t nItemIndex = m_nSelectIndex + 1;
        SetSelect(nItemIndex);
        ScrollToItem(nItemIndex);
      }
      return TRUE;
  }

  return FALSE;
}

int32_t CPWL_IconList_Content::FindItemIndex(const CFX_FloatPoint& point) {
  int32_t nIndex = 0;
  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
      CFX_FloatRect rcWnd = pChild->ChildToParent(pChild->GetWindowRect());

      if (point.y < rcWnd.top) {
        nIndex = i;
      }
    }
  }

  return nIndex;
}

void CPWL_IconList_Content::ScrollToItem(int32_t nItemIndex) {
  CFX_FloatRect rcClient = GetClientRect();

  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex)) {
    CFX_FloatRect rcOrigin = pItem->GetWindowRect();
    CFX_FloatRect rcWnd = pItem->ChildToParent(rcOrigin);

    if (!(rcWnd.bottom > rcClient.bottom && rcWnd.top < rcClient.top)) {
      CFX_FloatPoint ptScroll = GetScrollPos();

      if (rcWnd.top > rcClient.top) {
        ptScroll.y = rcOrigin.top;
      } else if (rcWnd.bottom < rcClient.bottom) {
        ptScroll.y = rcOrigin.bottom + rcClient.Height();
      }

      SetScrollPos(ptScroll);
      ResetFace();
      InvalidateRect();
      if (CPWL_Wnd* pParent = GetParentWindow()) {
        pParent->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
                          (intptr_t)&ptScroll.y);
      }
    }
  }
}

void CPWL_IconList_Content::SetSelect(int32_t nIndex) {
  if (m_nSelectIndex == nIndex)
    return;

  SelectItem(m_nSelectIndex, FALSE);
  SelectItem(nIndex, TRUE);
  m_nSelectIndex = nIndex;
}

int32_t CPWL_IconList_Content::GetSelect() const {
  return m_nSelectIndex;
}

void CPWL_IconList_Content::SelectItem(int32_t nItemIndex, FX_BOOL bSelect) {
  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex)) {
    pItem->SetSelect(bSelect);
    pItem->InvalidateRect();
  }
}

CPWL_IconList_Item* CPWL_IconList_Content::GetListItem(
    int32_t nItemIndex) const {
  if (nItemIndex >= 0 && nItemIndex < m_aChildren.GetSize()) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(nItemIndex)) {
      if (pChild->GetClassName() == "CPWL_IconList_Item") {
        return (CPWL_IconList_Item*)pChild;
      }
    }
  }

  return NULL;
}

void CPWL_IconList_Content::SetListData(int32_t nItemIndex, void* pData) {
  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    pItem->SetData(pData);
}

void CPWL_IconList_Content::SetListIcon(int32_t nItemIndex,
                                        int32_t nIconIndex) {
  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    pItem->SetIcon(nIconIndex);
}

void CPWL_IconList_Content::SetListString(int32_t nItemIndex,
                                          const CFX_WideString& str) {
  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    pItem->SetText(str);
}

CFX_WideString CPWL_IconList_Content::GetListString(int32_t nItemIndex) const {
  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    return pItem->GetText();

  return L"";
}

void CPWL_IconList_Content::SetIconFillColor(const CPWL_Color& color) {
  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
      if (pChild->GetClassName() == "CPWL_IconList_Item") {
        CPWL_IconList_Item* pItem = (CPWL_IconList_Item*)pChild;
        pItem->SetIconFillColor(color);
        pItem->InvalidateRect();
      }
    }
  }
}

CPWL_IconList::CPWL_IconList(int32_t nListCount)
    : m_pListContent(NULL), m_nListCount(nListCount) {}

CPWL_IconList::~CPWL_IconList() {}

void CPWL_IconList::RePosChildWnd() {
  CPWL_Wnd::RePosChildWnd();

  if (m_pListContent)
    m_pListContent->Move(GetClientRect(), TRUE, FALSE);
}

void CPWL_IconList::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  m_pListContent = new CPWL_IconList_Content(m_nListCount);

  PWL_CREATEPARAM ccp = cp;
  ccp.pParentWnd = this;
  ccp.dwFlags = PWS_CHILD | PWS_VISIBLE;
  m_pListContent->Create(ccp);
}

void CPWL_IconList::OnCreated() {
  if (CPWL_ScrollBar* pScrollBar = GetVScrollBar()) {
    pScrollBar->RemoveFlag(PWS_AUTOTRANSPARENT);
    pScrollBar->SetTransparency(255);
    pScrollBar->SetNotifyForever(TRUE);
  }
}

void CPWL_IconList::OnNotify(CPWL_Wnd* pWnd,
                             uint32_t msg,
                             intptr_t wParam,
                             intptr_t lParam) {
  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);

  if (wParam == SBT_VSCROLL) {
    switch (msg) {
      case PNM_SETSCROLLINFO:
        if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
          if (CPWL_ScrollBar* pScrollBar = GetVScrollBar()) {
            if (pInfo->fContentMax - pInfo->fContentMin > pInfo->fPlateWidth) {
              if (!pScrollBar->IsVisible()) {
                pScrollBar->SetVisible(TRUE);
                RePosChildWnd();
              } else {
              }
            } else {
              if (pScrollBar->IsVisible()) {
                pScrollBar->SetVisible(FALSE);
                RePosChildWnd();
              }

              if (m_pListContent)
                m_pListContent->SetScrollPos(CFX_FloatPoint(0.0f, 0.0f));
            }

            pScrollBar->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
          }
        }
        return;
      case PNM_SCROLLWINDOW:
        if (m_pListContent) {
          m_pListContent->SetScrollPos(
              CFX_FloatPoint(0.0f, *(FX_FLOAT*)lParam));
          m_pListContent->ResetFace();
          m_pListContent->InvalidateRect(NULL);
        }
        return;
      case PNM_SETSCROLLPOS:
        if (CPWL_ScrollBar* pScrollBar = GetVScrollBar())
          pScrollBar->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
        return;
    }
  }
}

void CPWL_IconList::SetSelect(int32_t nIndex) {
  m_pListContent->SetSelect(nIndex);
}

void CPWL_IconList::SetTopItem(int32_t nIndex) {
  m_pListContent->ScrollToItem(nIndex);
}

int32_t CPWL_IconList::GetSelect() const {
  return m_pListContent->GetSelect();
}

void CPWL_IconList::SetListData(int32_t nItemIndex, void* pData) {
  m_pListContent->SetListData(nItemIndex, pData);
}

void CPWL_IconList::SetListIcon(int32_t nItemIndex, int32_t nIconIndex) {
  m_pListContent->SetListIcon(nItemIndex, nIconIndex);
}

void CPWL_IconList::SetListString(int32_t nItemIndex,
                                  const CFX_WideString& str) {
  m_pListContent->SetListString(nItemIndex, str);
}

CFX_WideString CPWL_IconList::GetListString(int32_t nItemIndex) const {
  return m_pListContent->GetListString(nItemIndex);
}

void CPWL_IconList::SetIconFillColor(const CPWL_Color& color) {
  m_pListContent->SetIconFillColor(color);
}

FX_BOOL CPWL_IconList::OnMouseWheel(short zDelta,
                                    const CFX_FloatPoint& point,
                                    uint32_t nFlag) {
  CFX_FloatPoint ptScroll = m_pListContent->GetScrollPos();
  CFX_FloatRect rcScroll = m_pListContent->GetScrollArea();
  CFX_FloatRect rcContents = m_pListContent->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_pListContent->SetScrollPos(ptNew);
      m_pListContent->ResetFace();
      m_pListContent->InvalidateRect(NULL);

      if (CPWL_ScrollBar* pScrollBar = GetVScrollBar())
        pScrollBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
                             (intptr_t)&ptNew.y);

      return TRUE;
    }
  }

  return FALSE;
}
