// 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 "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Wnd.h"
#include "../../include/pdfwindow/PWL_ListCtrl.h"
#include "../../include/pdfwindow/PWL_IconList.h"
#include "../../include/pdfwindow/PWL_Utils.h"
#include "../../include/pdfwindow/PWL_ScrollBar.h"
#include "../../include/pdfwindow/PWL_Label.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::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,
                                            CPDF_Matrix* pUser2Device) {
  CPDF_Rect 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()));
    }
  }

  CPDF_Rect 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() {
  CPDF_Rect 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::CPWL_IconList_Content(int32_t nListCount)
    : m_nSelectIndex(-1),
      m_pNotify(NULL),
      m_bEnableNotify(TRUE),
      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()) {
    CPDF_Rect 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 CPDF_Point& point,
                                             FX_DWORD nFlag) {
  SetFocus();

  SetCapture();
  m_bMouseDown = TRUE;

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

  return TRUE;
}

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

  return TRUE;
}

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

  return TRUE;
}

FX_BOOL CPWL_IconList_Content::OnKeyDown(FX_WORD nChar, FX_DWORD 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 CPDF_Point& 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)) {
      CPDF_Rect rcWnd = pChild->ChildToParent(pChild->GetWindowRect());

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

  return nIndex;
}

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

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

    if (!(rcWnd.bottom > rcClient.bottom && rcWnd.top < rcClient.top)) {
      CPDF_Point 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) {
    SelectItem(m_nSelectIndex, FALSE);
    SelectItem(nIndex, TRUE);
    m_nSelectIndex = nIndex;

    if (IPWL_IconList_Notify* pNotify = GetNotify())
      pNotify->OnNoteListSelChanged(nIndex);
  }
}

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

IPWL_IconList_Notify* CPWL_IconList_Content::GetNotify() const {
  if (m_bEnableNotify)
    return m_pNotify;
  return NULL;
}

void CPWL_IconList_Content::SetNotify(IPWL_IconList_Notify* pNotify) {
  m_pNotify = pNotify;
}

void CPWL_IconList_Content::EnableNotify(FX_BOOL bNotify) {
  m_bEnableNotify = bNotify;
}

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::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,
                             FX_DWORD 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(CPDF_Point(0.0f, 0.0f));
            }

            pScrollBar->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
          }
        }
        return;
      case PNM_SCROLLWINDOW:
        if (m_pListContent) {
          m_pListContent->SetScrollPos(CPDF_Point(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::SetNotify(IPWL_IconList_Notify* pNotify) {
  m_pListContent->SetNotify(pNotify);
}

void CPWL_IconList::EnableNotify(FX_BOOL bNotify) {
  m_pListContent->EnableNotify(bNotify);
}

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 CPDF_Point& point,
                                    FX_DWORD nFlag) {
  CPDF_Point ptScroll = m_pListContent->GetScrollPos();
  CPDF_Rect rcScroll = m_pListContent->GetScrollArea();
  CPDF_Rect rcContents = m_pListContent->GetClientRect();

  if (rcScroll.top - rcScroll.bottom > rcContents.Height()) {
    CPDF_Point 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;
}
