// 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/core/cfwl_widgetmgr.h"

#include "xfa/fwl/core/cfwl_message.h"
#include "xfa/fwl/core/fwl_noteimp.h"
#include "xfa/fwl/core/ifwl_app.h"
#include "xfa/fwl/core/ifwl_form.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
#include "xfa/fxfa/xfa_ffapp.h"

namespace {

const int kNeedRepaintHitPoints = 12;
const int kNeedRepaintHitPiece = 3;

struct FWL_NEEDREPAINTHITDATA {
  CFX_PointF hitPoint;
  bool bNotNeedRepaint;
  bool bNotContainByDirty;
};

}  // namespace

FX_BOOL FWL_UseOffscreen(IFWL_Widget* pWidget) {
#if (_FX_OS_ == _FX_MACOSX_)
  return FALSE;
#else
  return pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen;
#endif
}

// static
CFWL_WidgetMgr* CFWL_WidgetMgr::GetInstance() {
  IFWL_App* pApp = FWL_GetApp();
  return pApp ? pApp->GetWidgetMgr() : nullptr;
}

CFWL_WidgetMgr::CFWL_WidgetMgr(CXFA_FFApp* pAdapterNative)
    : m_dwCapability(0),
      m_pDelegate(new CFWL_WidgetMgrDelegate(this)),
      m_pAdapter(pAdapterNative->GetWidgetMgr(m_pDelegate.get())) {
  ASSERT(m_pAdapter);
  m_mapWidgetItem[nullptr].reset(new CFWL_WidgetMgrItem);
#if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
  m_rtScreen.Reset();
#endif
}

CFWL_WidgetMgr::~CFWL_WidgetMgr() {}

IFWL_Widget* CFWL_WidgetMgr::GetParentWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  return pItem && pItem->pParent ? pItem->pParent->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  return pItem && pItem->pOwner ? pItem->pOwner->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  pItem = pItem ? pItem->pPrevious : nullptr;  // Not self.
  while (pItem && pItem->pPrevious)
    pItem = pItem->pPrevious;

  return pItem ? pItem->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  return pItem && pItem->pPrevious ? pItem->pPrevious->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  return pItem && pItem->pNext ? pItem->pNext->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetLastSiblingWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  pItem = pItem ? pItem->pNext : nullptr;  // Not self.
  while (pItem && pItem->pNext)
    pItem = pItem->pNext;

  return pItem ? pItem->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  return pItem && pItem->pChild ? pItem->pChild->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  pItem = pItem ? pItem->pChild : nullptr;
  while (pItem && pItem->pNext)
    pItem = pItem->pNext;

  return pItem ? pItem->pWidget : nullptr;
}

IFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(IFWL_Widget* pWidget) const {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  while (pItem) {
    if (IsAbleNative(pItem->pWidget))
      return pItem->pWidget;
    pItem = pItem->pParent;
  }
  return nullptr;
}

FX_BOOL CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget* pWidget, int32_t nIndex) {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  if (!pItem)
    return FALSE;
  if (!pItem->pParent)
    return FALSE;
  CFWL_WidgetMgrItem* pChild = pItem->pParent->pChild;
  int32_t i = 0;
  while (pChild) {
    if (pChild == pItem) {
      if (i == nIndex) {
        return TRUE;
      }
      if (pChild->pPrevious) {
        pChild->pPrevious->pNext = pChild->pNext;
      }
      if (pChild->pNext) {
        pChild->pNext->pPrevious = pChild->pPrevious;
      }
      if (pItem->pParent->pChild == pItem) {
        pItem->pParent->pChild = pItem->pNext;
      }
      pItem->pNext = nullptr;
      pItem->pPrevious = nullptr;
      break;
    }
    if (!pChild->pNext) {
      break;
    }
    pChild = pChild->pNext;
    ++i;
  }
  pChild = pItem->pParent->pChild;
  if (pChild) {
    if (nIndex < 0) {
      while (pChild->pNext) {
        pChild = pChild->pNext;
      }
      pChild->pNext = pItem;
      pItem->pPrevious = pChild;
      pItem->pNext = nullptr;
      return TRUE;
    }
    i = 0;
    while (i < nIndex && pChild->pNext) {
      pChild = pChild->pNext;
      ++i;
    }
    if (!pChild->pNext) {
      pChild->pNext = pItem;
      pItem->pPrevious = pChild;
      pItem->pNext = nullptr;
      return TRUE;
    }
    if (pChild->pPrevious) {
      pItem->pPrevious = pChild->pPrevious;
      pChild->pPrevious->pNext = pItem;
    }
    pChild->pPrevious = pItem;
    pItem->pNext = pChild;
    if (pItem->pParent->pChild == pChild) {
      pItem->pParent->pChild = pItem;
    }
  } else {
    pItem->pParent->pChild = pItem;
    pItem->pPrevious = nullptr;
    pItem->pNext = nullptr;
  }
  return TRUE;
}
FWL_Error CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget,
                                        const CFX_RectF* pRect) {
  if (!m_pAdapter)
    return FWL_Error::Indefinite;
  IFWL_Widget* pNative = pWidget;
  CFX_RectF rect(*pRect);
  if (IsFormDisabled()) {
    IFWL_Widget* pOuter = pWidget->GetOuter();
    while (pOuter) {
      CFX_RectF rtTemp;
      pNative->GetWidgetRect(rtTemp);
      rect.left += rtTemp.left;
      rect.top += rtTemp.top;
      pNative = pOuter;
      pOuter = pOuter->GetOuter();
    }
  } else if (!IsAbleNative(pWidget)) {
    pNative = GetSystemFormWidget(pWidget);
    if (!pNative)
      return FWL_Error::Indefinite;
    pWidget->TransformTo(pNative, rect.left, rect.top);
  }
  AddRedrawCounts(pNative);
  return m_pAdapter->RepaintWidget(pNative, &rect);
}
void CFWL_WidgetMgr::AddWidget(IFWL_Widget* pWidget) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(nullptr);
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  if (!pItem) {
    pItem = new CFWL_WidgetMgrItem(pWidget);
    m_mapWidgetItem[pWidget].reset(pItem);
  }
  if (pItem->pParent && pItem->pParent != pParentItem) {
    if (pItem->pPrevious) {
      pItem->pPrevious->pNext = pItem->pNext;
    }
    if (pItem->pNext) {
      pItem->pNext->pPrevious = pItem->pPrevious;
    }
    if (pItem->pParent->pChild == pItem) {
      pItem->pParent->pChild = pItem->pNext;
    }
  }
  pItem->pParent = pParentItem;
  SetWidgetIndex(pWidget, -1);
}
void CFWL_WidgetMgr::InsertWidget(IFWL_Widget* pParent,
                                  IFWL_Widget* pChild,
                                  int32_t nIndex) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
  if (!pParentItem) {
    pParentItem = new CFWL_WidgetMgrItem(pParent);
    m_mapWidgetItem[pParent].reset(pParentItem);
    pParentItem->pParent = GetWidgetMgrItem(nullptr);
    SetWidgetIndex(pParent, -1);
  }
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild);
  if (!pItem) {
    pItem = new CFWL_WidgetMgrItem(pChild);
    m_mapWidgetItem[pChild].reset(pItem);
  }
  if (pItem->pParent && pItem->pParent != pParentItem) {
    if (pItem->pPrevious) {
      pItem->pPrevious->pNext = pItem->pNext;
    }
    if (pItem->pNext) {
      pItem->pNext->pPrevious = pItem->pPrevious;
    }
    if (pItem->pParent->pChild == pItem) {
      pItem->pParent->pChild = pItem->pNext;
    }
  }
  pItem->pParent = pParentItem;
  SetWidgetIndex(pChild, nIndex);
}
void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget* pWidget) {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  if (!pItem) {
    return;
  }
  if (pItem->pPrevious) {
    pItem->pPrevious->pNext = pItem->pNext;
  }
  if (pItem->pNext) {
    pItem->pNext->pPrevious = pItem->pPrevious;
  }
  if (pItem->pParent && pItem->pParent->pChild == pItem) {
    pItem->pParent->pChild = pItem->pNext;
  }
  CFWL_WidgetMgrItem* pChild = pItem->pChild;
  while (pChild) {
    CFWL_WidgetMgrItem* pNext = pChild->pNext;
    RemoveWidget(pChild->pWidget);
    pChild = pNext;
  }
  m_mapWidgetItem.erase(pWidget);
}
void CFWL_WidgetMgr::SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pOwner);
  if (!pParentItem) {
    pParentItem = new CFWL_WidgetMgrItem(pOwner);
    m_mapWidgetItem[pOwner].reset(pParentItem);
    pParentItem->pParent = GetWidgetMgrItem(nullptr);
    SetWidgetIndex(pOwner, -1);
  }
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pOwned);
  if (!pItem) {
    pItem = new CFWL_WidgetMgrItem(pOwned);
    m_mapWidgetItem[pOwned].reset(pItem);
  }
  pItem->pOwner = pParentItem;
}
void CFWL_WidgetMgr::SetParent(IFWL_Widget* pParent, IFWL_Widget* pChild) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild);
  if (!pItem)
    return;
  if (pItem->pParent && pItem->pParent != pParentItem) {
    if (pItem->pPrevious) {
      pItem->pPrevious->pNext = pItem->pNext;
    }
    if (pItem->pNext) {
      pItem->pNext->pPrevious = pItem->pPrevious;
    }
    if (pItem->pParent->pChild == pItem) {
      pItem->pParent->pChild = pItem->pNext;
    }
    pItem->pNext = nullptr;
    pItem->pPrevious = nullptr;
  }
  pItem->pParent = pParentItem;
  SetWidgetIndex(pChild, -1);
}

FX_BOOL CFWL_WidgetMgr::IsChild(IFWL_Widget* pChild, IFWL_Widget* pParent) {
  IFWL_Widget* pTemp = pChild;
  do {
    if (pTemp == pParent)
      return TRUE;
    pTemp = GetParentWidget(pTemp);
  } while (pTemp);
  return FALSE;
}

FWL_Error CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget* pWidget,
                                               const CFX_RectF& rect) {
  if (FWL_UseOffscreen(pWidget)) {
    CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
    pItem->iRedrawCounter++;
    if (pItem->pOffscreen) {
      CFX_RenderDevice* pDevice = pItem->pOffscreen->GetRenderDevice();
      if (pDevice && pDevice->GetBitmap()) {
        CFX_DIBitmap* pBitmap = pDevice->GetBitmap();
        if (pBitmap->GetWidth() - rect.width > 1 ||
            pBitmap->GetHeight() - rect.height > 1) {
          pItem->pOffscreen.reset();
        }
      }
    }
#if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
    pItem->bOutsideChanged = !m_rtScreen.Contains(rect);
#endif
  }
  return FWL_Error::Succeeded;
}

IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent,
                                              FX_FLOAT x,
                                              FX_FLOAT y) {
  if (!parent)
    return nullptr;
  FX_FLOAT x1;
  FX_FLOAT y1;
  IFWL_Widget* child = GetLastChildWidget(parent);
  while (child) {
    if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) {
      x1 = x;
      y1 = y;
      CFX_Matrix matrixOnParent;
      child->GetMatrix(matrixOnParent);
      CFX_Matrix m;
      m.SetIdentity();
      m.SetReverse(matrixOnParent);
      m.TransformPoint(x1, y1);
      CFX_RectF bounds;
      child->GetWidgetRect(bounds);
      if (bounds.Contains(x1, y1)) {
        x1 -= bounds.left;
        y1 -= bounds.top;
        return GetWidgetAtPoint(child, x1, y1);
      }
    }
    child = GetPriorSiblingWidget(child);
  }
  return parent;
}

void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget* pForm,
                                       FX_FLOAT fx,
                                       FX_FLOAT fy) {
  if (FWL_UseOffscreen(pForm))
    GetWidgetMgrItem(pForm)->pOffscreen.reset();
}

IFWL_Widget* CFWL_WidgetMgr::nextTab(IFWL_Widget* parent,
                                     IFWL_Widget* focus,
                                     FX_BOOL& bFind) {
  CFWL_WidgetMgr* pMgr = CFWL_WidgetMgr::GetInstance();
  IFWL_Widget* child = pMgr->GetFirstChildWidget(parent);
  while (child) {
    if (focus == child)
      bFind = TRUE;

    if ((child->GetStyles() & FWL_WGTSTYLE_TabStop) &&
        (!focus || (focus != child && bFind))) {
      return child;
    }
    IFWL_Widget* bRet = nextTab(child, focus, bFind);
    if (bRet)
      return bRet;

    child = pMgr->GetNextSiblingWidget(child);
  }
  return nullptr;
}

int32_t CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget* pFirst) {
  int32_t iRet = 0;
  IFWL_Widget* pChild = pFirst;
  while (pChild) {
    pChild = GetNextSiblingWidget(pChild);
    ++iRet;
  }
  return iRet;
}
IFWL_Widget* CFWL_WidgetMgr::GetSiblingRadioButton(IFWL_Widget* pWidget,
                                                   FX_BOOL bNext) {
  return nullptr;
}
IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(
    IFWL_Widget* pRadioButton) {
  IFWL_Widget* pNext = pRadioButton;
  while (pNext) {
    if (pNext->GetStyles() & FWL_WGTSTYLE_Group)
      return pNext;
    pNext = GetSiblingRadioButton(pNext, FALSE);
  }
  pNext = GetLastSiblingWidget(pRadioButton);
  while ((pNext = GetSiblingRadioButton(pNext, FALSE)) != nullptr &&
         pNext != pRadioButton) {
    if (pNext->GetStyles() & FWL_WGTSTYLE_Group)
      return pNext;
  }
  pNext = GetFirstSiblingWidget(pRadioButton);
  return GetSiblingRadioButton(pNext, TRUE);
}
void CFWL_WidgetMgr::GetSameGroupRadioButton(
    IFWL_Widget* pRadioButton,
    CFX_ArrayTemplate<IFWL_Widget*>& group) {
  IFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton);
  if (!pFirst) {
    pFirst = pRadioButton;
  }
  int32_t iGroup = CountRadioButtonGroup(pFirst);
  if (iGroup < 2) {
    IFWL_Widget* pNext = pFirst;
    while ((pNext = GetSiblingRadioButton(pNext, TRUE)) != nullptr) {
      group.Add(pNext);
    }
    return;
  }
  IFWL_Widget* pNext = GetRadioButtonGroupHeader(pRadioButton);
  do {
    group.Add(pNext);
    pNext = GetSiblingRadioButton(pNext, TRUE);
    if (!pNext)
      pNext = GetSiblingRadioButton(pFirst, TRUE);
  } while (pNext && ((pNext->GetStyles() & FWL_WGTSTYLE_Group) == 0));
}
IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget* pParent) {
  if ((pParent->GetClassID() == FWL_Type::PushButton) &&
      (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
    return pParent;
  }
  IFWL_Widget* child =
      CFWL_WidgetMgr::GetInstance()->GetFirstChildWidget(pParent);
  while (child) {
    if ((child->GetClassID() == FWL_Type::PushButton) &&
        (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
      return child;
    }
    IFWL_Widget* find = GetDefaultButton(child);
    if (find) {
      return find;
    }
    child = CFWL_WidgetMgr::GetInstance()->GetNextSiblingWidget(child);
  }
  return nullptr;
}
void CFWL_WidgetMgr::AddRedrawCounts(IFWL_Widget* pWidget) {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  (pItem->iRedrawCounter)++;
}
void CFWL_WidgetMgr::ResetRedrawCounts(IFWL_Widget* pWidget) {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  pItem->iRedrawCounter = 0;
}
CFWL_WidgetMgrItem* CFWL_WidgetMgr::GetWidgetMgrItem(
    IFWL_Widget* pWidget) const {
  auto it = m_mapWidgetItem.find(pWidget);
  return it != m_mapWidgetItem.end()
             ? static_cast<CFWL_WidgetMgrItem*>(it->second.get())
             : nullptr;
}
int32_t CFWL_WidgetMgr::TravelWidgetMgr(CFWL_WidgetMgrItem* pParent,
                                        int32_t* pIndex,
                                        CFWL_WidgetMgrItem* pItem,
                                        IFWL_Widget** pWidget) {
  if (!pParent) {
    return 0;
  }
  int32_t iCount = 0;
  CFWL_WidgetMgrItem* pChild = pParent->pChild;
  while (pChild) {
    iCount++;
    if (pIndex) {
      if (*pIndex == 0) {
        *pWidget = pChild->pWidget;
        return iCount;
      }
      pIndex--;
    }
    if (pItem && pItem == pChild) {
      return iCount - 1;
    }
    pChild = pChild->pNext;
  }
  if (pIndex) {
    return 0;
  } else if (pItem) {
    return -1;
  }
  return iCount - 1;
}

FX_BOOL CFWL_WidgetMgr::IsAbleNative(IFWL_Widget* pWidget) const {
  if (!pWidget)
    return FALSE;
  if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) {
    return FALSE;
  }
  uint32_t dwStyles = pWidget->GetStyles();
  return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
          FWL_WGTSTYLE_OverLapper) ||
         (dwStyles & FWL_WGTSTYLE_Popup);
}

bool CFWL_WidgetMgr::IsThreadEnabled() {
  return !(m_dwCapability & FWL_WGTMGR_DisableThread);
}

bool CFWL_WidgetMgr::IsFormDisabled() {
  return !!(m_dwCapability & FWL_WGTMGR_DisableForm);
}

FX_BOOL CFWL_WidgetMgr::GetAdapterPopupPos(IFWL_Widget* pWidget,
                                           FX_FLOAT fMinHeight,
                                           FX_FLOAT fMaxHeight,
                                           const CFX_RectF& rtAnchor,
                                           CFX_RectF& rtPopup) {
  CXFA_FWLAdapterWidgetMgr* pSDApapter = GetAdapterWidgetMgr();
  return pSDApapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor,
                                 rtPopup);
}
CFWL_WidgetMgrDelegate::CFWL_WidgetMgrDelegate(CFWL_WidgetMgr* pWidgetMgr)
    : m_pWidgetMgr(pWidgetMgr) {}
FWL_Error CFWL_WidgetMgrDelegate::OnSetCapability(uint32_t dwCapability) {
  m_pWidgetMgr->m_dwCapability = dwCapability;
  return FWL_Error::Succeeded;
}

void CFWL_WidgetMgrDelegate::OnProcessMessageToForm(CFWL_Message* pMessage) {
  if (!pMessage)
    return;
  if (!pMessage->m_pDstTarget)
    return;

  IFWL_Widget* pDstWidget = pMessage->m_pDstTarget;
  IFWL_App* pApp = pDstWidget->GetOwnerApp();
  if (!pApp)
    return;

  CFWL_NoteDriver* pNoteDriver =
      static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
  if (!pNoteDriver)
    return;

  if (m_pWidgetMgr->IsThreadEnabled())
    pMessage = static_cast<CFWL_Message*>(pMessage->Clone());
  if (m_pWidgetMgr->IsFormDisabled())
    pNoteDriver->ProcessMessage(pMessage);
  else
    pNoteDriver->QueueMessage(pMessage);

#if (_FX_OS_ == _FX_MACOSX_)
  CFWL_NoteLoop* pTopLoop = pNoteDriver->GetTopLoop();
  if (pTopLoop)
    pNoteDriver->UnqueueMessage(pTopLoop);
#endif

  if (m_pWidgetMgr->IsThreadEnabled())
    pMessage->Release();

  return;
}

void CFWL_WidgetMgrDelegate::OnDrawWidget(IFWL_Widget* pWidget,
                                          CFX_Graphics* pGraphics,
                                          const CFX_Matrix* pMatrix) {
  if (!pWidget || !pGraphics)
    return;

  CFX_Graphics* pTemp = DrawWidgetBefore(pWidget, pGraphics, pMatrix);
  CFX_RectF clipCopy;
  pWidget->GetWidgetRect(clipCopy);
  clipCopy.left = clipCopy.top = 0;
  if (bUseOffscreenDirect(pWidget)) {
    DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
    return;
  }
  CFX_RectF clipBounds;

#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ || \
    _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_
  IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(nullptr);
  pDelegate->OnDrawWidget(pTemp, pMatrix);
  pGraphics->GetClipRect(clipBounds);
  clipCopy = clipBounds;
#elif _FX_OS_ == _FX_MACOSX_
  if (m_pWidgetMgr->IsFormDisabled()) {
    IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(nullptr);
    pDelegate->OnDrawWidget(pTemp, pMatrix);
    pGraphics->GetClipRect(clipBounds);
    clipCopy = clipBounds;
  } else {
    clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d);
    const_cast<CFX_Matrix*>(pMatrix)->SetIdentity();  // FIXME: const cast.
    IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(nullptr);
    pDelegate->OnDrawWidget(pTemp, pMatrix);
  }
#endif  // _FX_OS_ == _FX_MACOSX_

  if (!m_pWidgetMgr->IsFormDisabled()) {
    CFX_RectF rtClient;
    pWidget->GetClientRect(rtClient);
    clipBounds.Intersect(rtClient);
  }
  if (!clipBounds.IsEmpty())
    DrawChild(pWidget, clipBounds, pTemp, pMatrix);

  DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
  m_pWidgetMgr->ResetRedrawCounts(pWidget);
}

void CFWL_WidgetMgrDelegate::DrawChild(IFWL_Widget* parent,
                                       const CFX_RectF& rtClip,
                                       CFX_Graphics* pGraphics,
                                       const CFX_Matrix* pMatrix) {
  if (!parent)
    return;

  FX_BOOL bFormDisable = m_pWidgetMgr->IsFormDisabled();
  IFWL_Widget* pNextChild = m_pWidgetMgr->GetFirstChildWidget(parent);
  while (pNextChild) {
    IFWL_Widget* child = pNextChild;
    pNextChild = m_pWidgetMgr->GetNextSiblingWidget(child);
    if (child->GetStates() & FWL_WGTSTATE_Invisible)
      continue;

    CFX_RectF rtWidget;
    child->GetWidgetRect(rtWidget);
    if (rtWidget.IsEmpty())
      continue;

    CFX_Matrix widgetMatrix;
    CFX_RectF clipBounds(rtWidget);
    if (!bFormDisable)
      child->GetMatrix(widgetMatrix, TRUE);
    if (pMatrix)
      widgetMatrix.Concat(*pMatrix);

    if (!bFormDisable) {
      widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top);
      clipBounds.Intersect(rtClip);
      if (clipBounds.IsEmpty())
        continue;

      pGraphics->SaveGraphState();
      pGraphics->SetClipRect(clipBounds);
    }
    widgetMatrix.Translate(rtWidget.left, rtWidget.top, TRUE);
    IFWL_WidgetDelegate* pDelegate = child->SetDelegate(nullptr);
    if (pDelegate) {
      if (m_pWidgetMgr->IsFormDisabled() ||
          IsNeedRepaint(child, &widgetMatrix, rtClip)) {
        pDelegate->OnDrawWidget(pGraphics, &widgetMatrix);
      }
    }
    if (!bFormDisable)
      pGraphics->RestoreGraphState();

    DrawChild(child, clipBounds, pGraphics,
              bFormDisable ? &widgetMatrix : pMatrix);
    child = m_pWidgetMgr->GetNextSiblingWidget(child);
  }
}

CFX_Graphics* CFWL_WidgetMgrDelegate::DrawWidgetBefore(
    IFWL_Widget* pWidget,
    CFX_Graphics* pGraphics,
    const CFX_Matrix* pMatrix) {
  if (!FWL_UseOffscreen(pWidget))
    return pGraphics;

  CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
  if (!pItem->pOffscreen) {
    pItem->pOffscreen.reset(new CFX_Graphics);
    CFX_RectF rect;
    pWidget->GetWidgetRect(rect);
    pItem->pOffscreen->Create((int32_t)rect.width, (int32_t)rect.height,
                              FXDIB_Argb);
  }
  CFX_RectF rect;
  pGraphics->GetClipRect(rect);
  pItem->pOffscreen->SetClipRect(rect);
  return pItem->pOffscreen.get();
}

void CFWL_WidgetMgrDelegate::DrawWidgetAfter(IFWL_Widget* pWidget,
                                             CFX_Graphics* pGraphics,
                                             CFX_RectF& rtClip,
                                             const CFX_Matrix* pMatrix) {
  if (FWL_UseOffscreen(pWidget)) {
    CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
    pGraphics->Transfer(pItem->pOffscreen.get(), rtClip.left, rtClip.top,
                        rtClip, pMatrix);
#ifdef _WIN32
    pItem->pOffscreen->ClearClip();
#endif
  }
  CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
  pItem->iRedrawCounter = 0;
}

FX_BOOL CFWL_WidgetMgrDelegate::IsNeedRepaint(IFWL_Widget* pWidget,
                                              CFX_Matrix* pMatrix,
                                              const CFX_RectF& rtDirty) {
  CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
  if (pItem && pItem->iRedrawCounter > 0) {
    pItem->iRedrawCounter = 0;
    return TRUE;
  }
  CFX_RectF rtWidget;
  pWidget->GetWidgetRect(rtWidget);
  rtWidget.left = rtWidget.top = 0;
  pMatrix->TransformRect(rtWidget);
  if (!rtWidget.IntersectWith(rtDirty))
    return FALSE;

  IFWL_Widget* pChild =
      CFWL_WidgetMgr::GetInstance()->GetFirstChildWidget(pWidget);
  if (!pChild)
    return TRUE;

  CFX_RectF rtChilds;
  rtChilds.Empty();
  FX_BOOL bChildIntersectWithDirty = FALSE;
  FX_BOOL bOrginPtIntersectWidthChild = FALSE;
  FX_BOOL bOrginPtIntersectWidthDirty =
      rtDirty.Contains(rtWidget.left, rtWidget.top);
  static FWL_NEEDREPAINTHITDATA hitPoint[kNeedRepaintHitPoints];
  FXSYS_memset(hitPoint, 0, sizeof(hitPoint));
  FX_FLOAT fxPiece = rtWidget.width / kNeedRepaintHitPiece;
  FX_FLOAT fyPiece = rtWidget.height / kNeedRepaintHitPiece;
  hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left;
  hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x =
      hitPoint[10].hitPoint.x = fxPiece + rtWidget.left;
  hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x =
      hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left;
  hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x =
      rtWidget.width + rtWidget.left;
  hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top;
  hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y =
      hitPoint[5].hitPoint.y = fyPiece + rtWidget.top;
  hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y =
      hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top;
  hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y =
      rtWidget.height + rtWidget.top;
  do {
    CFX_RectF rect;
    pChild->GetWidgetRect(rect);
    CFX_RectF r = rect;
    r.left += rtWidget.left;
    r.top += rtWidget.top;
    if (r.IsEmpty())
      continue;
    if (r.Contains(rtDirty))
      return FALSE;
    if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty))
      bChildIntersectWithDirty = TRUE;
    if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild)
      bOrginPtIntersectWidthChild = rect.Contains(0, 0);

    if (rtChilds.IsEmpty())
      rtChilds = rect;
    else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible))
      rtChilds.Union(rect);

    for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) {
      if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint)
        continue;
      if (!rtDirty.Contains(hitPoint[i].hitPoint)) {
        hitPoint[i].bNotContainByDirty = true;
        continue;
      }
      if (r.Contains(hitPoint[i].hitPoint))
        hitPoint[i].bNotNeedRepaint = true;
    }
    pChild = CFWL_WidgetMgr::GetInstance()->GetNextSiblingWidget(pChild);
  } while (pChild);

  if (!bChildIntersectWithDirty)
    return TRUE;
  if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild)
    return TRUE;
  if (rtChilds.IsEmpty())
    return TRUE;

  int32_t repaintPoint = kNeedRepaintHitPoints;
  for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) {
    if (hitPoint[i].bNotNeedRepaint)
      repaintPoint--;
  }
  if (repaintPoint > 0)
    return TRUE;

  pMatrix->TransformRect(rtChilds);
  if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget))
    return FALSE;
  return TRUE;
}

FX_BOOL CFWL_WidgetMgrDelegate::bUseOffscreenDirect(IFWL_Widget* pWidget) {
  CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
  if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen))
    return FALSE;

#if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
  if (pItem->bOutsideChanged) {
    CFX_RectF r;
    pWidget->GetWidgetRect(r);
    CFX_RectF temp(m_pWidgetMgr->m_rtScreen);
    temp.Deflate(50, 50);
    if (!temp.Contains(r))
      return FALSE;

    pItem->bOutsideChanged = FALSE;
  }
#endif

  return pItem->iRedrawCounter == 0;
}

CFWL_WidgetMgrItem::CFWL_WidgetMgrItem() : CFWL_WidgetMgrItem(nullptr) {}

CFWL_WidgetMgrItem::CFWL_WidgetMgrItem(IFWL_Widget* widget)
    : pParent(nullptr),
      pOwner(nullptr),
      pChild(nullptr),
      pPrevious(nullptr),
      pNext(nullptr),
      pWidget(widget),
      iRedrawCounter(0)
#if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
      ,
      bOutsideChanged(FALSE)
#endif
{
}

CFWL_WidgetMgrItem::~CFWL_WidgetMgrItem() {}
