// 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/src/foxitlib.h"
#include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
#include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
#include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
#include "xfa/src/fwl/src/core/include/fwl_appimp.h"

FX_BOOL FWL_UseOffscreen(IFWL_Widget* pWidget) {
#if (_FX_OS_ == _FX_MACOSX_)
  return FALSE;
#else
  return pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen;
#endif
}
IFWL_WidgetMgr* FWL_GetWidgetMgr() {
  IFWL_App* pApp = FWL_GetApp();
  if (!pApp)
    return NULL;
  return pApp->GetWidgetMgr();
}
CFWL_WidgetMgr::CFWL_WidgetMgr(IFWL_AdapterNative* pAdapterNative)
    : m_dwCapability(0) {
  m_pDelegate = new CFWL_WidgetMgrDelegate(this);
  m_pAdapter = pAdapterNative->GetWidgetMgr(m_pDelegate);
  FXSYS_assert(m_pAdapter);
  CFWL_WidgetMgrItem* pRoot = new CFWL_WidgetMgrItem;
  m_mapWidgetItem.SetAt(NULL, pRoot);
#if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
  m_rtScreen.Reset();
#endif
}
CFWL_WidgetMgr::~CFWL_WidgetMgr() {
  FX_POSITION ps = m_mapWidgetItem.GetStartPosition();
  while (ps) {
    void* pWidget;
    CFWL_WidgetMgrItem* pItem;
    m_mapWidgetItem.GetNextAssoc(ps, pWidget, (void*&)pItem);
    delete pItem;
  }
  m_mapWidgetItem.RemoveAll();
  if (m_pDelegate) {
    delete m_pDelegate;
    m_pDelegate = NULL;
  }
}
int32_t CFWL_WidgetMgr::CountWidgets(IFWL_Widget* pParent) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
  return TravelWidgetMgr(pParentItem, NULL, NULL);
}
IFWL_Widget* CFWL_WidgetMgr::GetWidget(int32_t nIndex, IFWL_Widget* pParent) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
  IFWL_Widget* pWidget = NULL;
  TravelWidgetMgr(pParentItem, &nIndex, NULL, &pWidget);
  return pWidget;
}
IFWL_Widget* CFWL_WidgetMgr::GetWidget(IFWL_Widget* pWidget,
                                       FWL_WGTRELATION eRelation) {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  if (!pItem) {
    return NULL;
  }
  IFWL_Widget* pRet = NULL;
  switch (eRelation) {
    case FWL_WGTRELATION_Parent: {
      pRet = pItem->pParent ? pItem->pParent->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_Owner: {
      pRet = pItem->pOwner ? pItem->pOwner->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_FirstSibling: {
      pItem = pItem->pPrevious;
      while (pItem && pItem->pPrevious) {
        pItem = pItem->pPrevious;
      }
      pRet = pItem ? pItem->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_PriorSibling: {
      pRet = pItem->pPrevious ? pItem->pPrevious->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_NextSibling: {
      pRet = pItem->pNext ? pItem->pNext->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_LastSibling: {
      pItem = pItem->pNext;
      while (pItem && pItem->pNext) {
        pItem = pItem->pNext;
      }
      pRet = pItem ? pItem->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_FirstChild: {
      pRet = pItem->pChild ? pItem->pChild->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_LastChild: {
      pItem = pItem->pChild;
      while (pItem && pItem->pNext) {
        pItem = pItem->pNext;
      }
      pRet = pItem ? pItem->pWidget : NULL;
      break;
    }
    case FWL_WGTRELATION_SystemForm: {
      while (pItem) {
        if (IsAbleNative(pItem->pWidget)) {
          pRet = pItem->pWidget;
          break;
        }
        pItem = pItem->pParent;
      }
      break;
    }
    default: {}
  }
  return pRet;
}
int32_t CFWL_WidgetMgr::GetWidgetIndex(IFWL_Widget* pWidget) {
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  if (!pItem)
    return -1;
  return TravelWidgetMgr(pItem->pParent, NULL, pItem);
}
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 = NULL;
      pItem->pPrevious = NULL;
      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 = NULL;
      return TRUE;
    }
    i = 0;
    while (i < nIndex && pChild->pNext) {
      pChild = pChild->pNext;
      ++i;
    }
    if (!pChild->pNext) {
      pChild->pNext = pItem;
      pItem->pPrevious = pChild;
      pItem->pNext = NULL;
      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 = NULL;
    pItem->pNext = NULL;
  }
  return TRUE;
}
FWL_ERR CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget,
                                      const CFX_RectF* pRect) {
  if (!m_pAdapter)
    return FWL_ERR_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 = GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
    if (!pNative)
      return FWL_ERR_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(NULL);
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
  if (!pItem) {
    pItem = new CFWL_WidgetMgrItem;
    pItem->pWidget = pWidget;
    m_mapWidgetItem.SetAt(pWidget, 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;
    pParentItem->pWidget = pParent;
    m_mapWidgetItem.SetAt(pParent, pParentItem);
    CFWL_WidgetMgrItem* pRoot = GetWidgetMgrItem(NULL);
    pParentItem->pParent = pRoot;
    SetWidgetIndex(pParent, -1);
  }
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild);
  if (!pItem) {
    pItem = new CFWL_WidgetMgrItem;
    pItem->pWidget = pChild;
    m_mapWidgetItem.SetAt(pChild, 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.RemoveKey(pWidget);
  delete pItem;
}
void CFWL_WidgetMgr::SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned) {
  CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pOwner);
  if (!pParentItem) {
    pParentItem = new CFWL_WidgetMgrItem;
    pParentItem->pWidget = pOwner;
    m_mapWidgetItem.SetAt(pOwner, pParentItem);
    CFWL_WidgetMgrItem* pRoot = GetWidgetMgrItem(NULL);
    pParentItem->pParent = pRoot;
    SetWidgetIndex(pOwner, -1);
  }
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pOwned);
  if (!pItem) {
    pItem = new CFWL_WidgetMgrItem;
    pItem->pWidget = pOwned;
    m_mapWidgetItem.SetAt(pOwned, 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 = NULL;
    pItem->pPrevious = NULL;
  }
  pItem->pParent = pParentItem;
  SetWidgetIndex(pChild, -1);
  if (!m_pAdapter)
    return;
  m_pAdapter->SetParentWidget(pChild, pParent);
}
FX_BOOL CFWL_WidgetMgr::IsChild(IFWL_Widget* pChild, IFWL_Widget* pParent) {
  IFWL_Widget* pTemp = pChild;
  do {
    if (pTemp == pParent) {
      return TRUE;
    }
    pTemp = GetWidget(pTemp, FWL_WGTRELATION_Parent);
  } while (pTemp);
  return FALSE;
}
FWL_ERR CFWL_WidgetMgr::CreateWidget_Native(IFWL_Widget* pWidget) {
  if (!IsAbleNative(pWidget)) {
    return FWL_ERR_Succeeded;
  }
  return m_pAdapter->CreateWidget(pWidget, pWidget->GetOwner());
}
FWL_ERR CFWL_WidgetMgr::DestroyWidget_Native(IFWL_Widget* pWidget) {
  if (!IsAbleNative(pWidget)) {
    return FWL_ERR_Succeeded;
  }
  return m_pAdapter->DestroyWidget(pWidget);
}
FWL_ERR CFWL_WidgetMgr::GetWidgetRect_Native(IFWL_Widget* pWidget,
                                             CFX_RectF& rect) {
  if (!IsAbleNative(pWidget)) {
    return FWL_ERR_Succeeded;
  }
  return m_pAdapter->GetWidgetRect(pWidget, rect);
}
FWL_ERR 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) {
          delete pItem->pOffscreen;
          pItem->pOffscreen = NULL;
        }
      }
    }
#if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
    pItem->bOutsideChanged = !m_rtScreen.Contains(rect);
#endif
  }
  return m_pAdapter->SetWidgetRect(pWidget, rect);
}
FWL_ERR CFWL_WidgetMgr::SetWidgetPosition_Native(IFWL_Widget* pWidget,
                                                 FX_FLOAT fx,
                                                 FX_FLOAT fy) {
  return m_pAdapter->SetWidgetPosition(pWidget, fx, fy);
}
FWL_ERR CFWL_WidgetMgr::SetWidgetIcon_Native(IFWL_Widget* pWidget,
                                             const CFX_DIBitmap* pIcon,
                                             FX_BOOL bBig) {
  return m_pAdapter->SetWidgetIcon(pWidget, pIcon, bBig);
}
FWL_ERR CFWL_WidgetMgr::SetWidgetCaption_Native(
    IFWL_Widget* pWidget,
    const CFX_WideStringC& wsCaption) {
  return m_pAdapter->SetWidgetCaption(pWidget, wsCaption);
}
FWL_ERR CFWL_WidgetMgr::SetBorderRegion_Native(IFWL_Widget* pWidget,
                                               CFX_Path* pPath) {
  return m_pAdapter->SetBorderRegion(pWidget, pPath);
}
FWL_ERR CFWL_WidgetMgr::ShowWidget_Native(IFWL_Widget* pWidget) {
  return m_pAdapter->ShowWidget(pWidget);
}
FWL_ERR CFWL_WidgetMgr::HideWidget_Native(IFWL_Widget* pWidget) {
  return m_pAdapter->HideWidget(pWidget);
}
FWL_ERR CFWL_WidgetMgr::SetNormal_Native(IFWL_Widget* pWidget) {
  return m_pAdapter->SetNormal(pWidget);
}
FWL_ERR CFWL_WidgetMgr::SetMaximize_Native(IFWL_Widget* pWidget) {
  return m_pAdapter->SetMaximize(pWidget);
}
FWL_ERR CFWL_WidgetMgr::SetMinimize_Native(IFWL_Widget* pWidget) {
  return m_pAdapter->SetMinimize(pWidget);
}
FX_BOOL CFWL_WidgetMgr::CheckMessage_Native() {
  return m_pAdapter->CheckMessage();
}
FWL_ERR CFWL_WidgetMgr::DispatchMessage_Native() {
  return m_pAdapter->DispatchMessage();
}
FX_BOOL CFWL_WidgetMgr::IsIdleMessage_Native() {
  return m_pAdapter->IsIdleMessage();
}
FWL_ERR CFWL_WidgetMgr::Exit_Native(int32_t iExitCode) {
  return m_pAdapter->Exit(iExitCode);
}
FWL_ERR CFWL_WidgetMgr::CreateWidgetWithNativeId_Native(IFWL_Widget* pWidget,
                                                        void* vp) {
  return m_pAdapter->CreateWidgetWithNativeId(pWidget, vp);
}
IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent,
                                              FX_FLOAT x,
                                              FX_FLOAT y) {
  if (!parent)
    return NULL;
  FX_FLOAT x1;
  FX_FLOAT y1;
  IFWL_Widget* child = GetWidget(parent, FWL_WGTRELATION_LastChild);
  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 = GetWidget(child, FWL_WGTRELATION_PriorSibling);
  }
  return parent;
}
void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget* pForm,
                                       FX_FLOAT fx,
                                       FX_FLOAT fy) {
  if (!FWL_UseOffscreen(pForm)) {
    return;
  }
  CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pForm);
  if (pItem->pOffscreen) {
    delete pItem->pOffscreen;
    pItem->pOffscreen = NULL;
  }
}
IFWL_Widget* CFWL_WidgetMgr::nextTab(IFWL_Widget* parent,
                                     IFWL_Widget* focus,
                                     FX_BOOL& bFind) {
  IFWL_Widget* child =
      FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
  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 = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
  }
  return NULL;
}
int32_t CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget* pFirst) {
  int32_t iRet = 0;
  IFWL_Widget* pChild = pFirst;
  while (pChild) {
    if ((pChild->GetStyles() & FWL_WGTSTYLE_Group) &&
        pChild->GetClassID() == 3811304691) {
      iRet++;
    }
    pChild = GetWidget(pChild, FWL_WGTRELATION_NextSibling);
  }
  return iRet;
}
IFWL_Widget* CFWL_WidgetMgr::GetSiblingRadioButton(IFWL_Widget* pWidget,
                                                   FX_BOOL bNext) {
  while ((pWidget = GetWidget(pWidget, bNext ? FWL_WGTRELATION_NextSibling
                                             : FWL_WGTRELATION_PriorSibling)) !=
         NULL) {
    if (pWidget->GetClassID() == 3811304691) {
      return pWidget;
    }
  }
  return NULL;
}
IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(
    IFWL_Widget* pRadioButton) {
  if (pRadioButton->GetStyles() & FWL_WGTSTYLE_Group) {
    return pRadioButton;
  }
  IFWL_Widget* pNext = pRadioButton;
  while ((pNext = GetSiblingRadioButton(pNext, FALSE)) != NULL) {
    if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
      return pNext;
    }
  }
  pNext = GetWidget(pRadioButton, FWL_WGTRELATION_LastSibling);
  if ((pNext->GetStyles() & FWL_WGTSTYLE_Group) &&
      pNext->GetClassID() == 3811304691) {
    return pNext;
  }
  while ((pNext = GetSiblingRadioButton(pNext, FALSE)) && pNext &&
         pNext != pRadioButton) {
    if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
      return pNext;
    }
  }
  pNext = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
  if (pNext && (pNext->GetStyles() == FWL_WGTSTYLE_Group) &&
      pNext->GetClassID() == 3811304691) {
    return pNext;
  }
  return GetSiblingRadioButton(pNext, TRUE);
}
void CFWL_WidgetMgr::GetSameGroupRadioButton(IFWL_Widget* pRadioButton,
                                             CFX_PtrArray& group) {
  IFWL_Widget* pFirst = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
  if (!pFirst) {
    pFirst = pRadioButton;
  }
  int32_t iGroup = CountRadioButtonGroup(pFirst);
  if (iGroup < 2) {
    if (pFirst->GetClassID() == 3811304691) {
      group.Add(pFirst);
    }
    IFWL_Widget* pNext = pFirst;
    while ((pNext = GetSiblingRadioButton(pNext, TRUE)) != NULL) {
      group.Add(pNext);
    }
    return;
  }
  IFWL_Widget* pNext = GetRadioButtonGroupHeader(pRadioButton);
  do {
    group.Add(pNext);
    pNext = GetSiblingRadioButton(pNext, TRUE);
    if (!pNext) {
      if (pFirst->GetClassID() == 3811304691) {
        pNext = pFirst;
      } else {
        pNext = GetSiblingRadioButton(pFirst, TRUE);
      }
    }
  } while (pNext && ((pNext->GetStyles() & FWL_WGTSTYLE_Group) == 0));
}
IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget* pParent) {
  if ((pParent->GetClassID() == 3521614244) &&
      (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
    return pParent;
  }
  IFWL_Widget* child =
      FWL_GetWidgetMgr()->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
  while (child) {
    if ((child->GetClassID() == 3521614244) &&
        (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
      return child;
    }
    IFWL_Widget* find = GetDefaultButton(child);
    if (find) {
      return find;
    }
    child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
  }
  return NULL;
}
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) {
  return static_cast<CFWL_WidgetMgrItem*>(m_mapWidgetItem.GetValueAt(pWidget));
}
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) {
  if (!pWidget)
    return FALSE;
  if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) {
    return FALSE;
  }
  FX_DWORD dwStyles = pWidget->GetStyles();
  return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
          FWL_WGTSTYLE_OverLapper) ||
         (dwStyles & FWL_WGTSTYLE_Popup);
}
FX_BOOL CFWL_WidgetMgr::IsThreadEnabled() {
  return !(m_dwCapability & FWL_WGTMGR_DisableThread);
}
FX_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) {
  IFWL_AdapterWidgetMgr* pSDApapter = GetAdapterWidgetMgr();
  return pSDApapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor,
                                 rtPopup);
}
CFWL_WidgetMgrDelegate::CFWL_WidgetMgrDelegate(CFWL_WidgetMgr* pWidgetMgr)
    : m_pWidgetMgr(pWidgetMgr) {}
FWL_ERR CFWL_WidgetMgrDelegate::OnSetCapability(FX_DWORD dwCapability) {
  m_pWidgetMgr->m_dwCapability = dwCapability;
  return FWL_ERR_Succeeded;
}
int32_t CFWL_WidgetMgrDelegate::OnProcessMessageToForm(CFWL_Message* pMessage) {
  if (!pMessage)
    return 0;
  if (!pMessage->m_pDstTarget)
    return 0;
  IFWL_Widget* pDstWidget = pMessage->m_pDstTarget;
  IFWL_NoteThread* pNoteThread = pDstWidget->GetOwnerThread();
  if (!pNoteThread)
    return 0;
  CFWL_NoteDriver* pNoteDriver =
      static_cast<CFWL_NoteDriver*>(pNoteThread->GetNoteDriver());
  if (!pNoteDriver)
    return 0;
  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 FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetMgrDelegate::OnDrawWidget(IFWL_Widget* pWidget,
                                             CFX_Graphics* pGraphics,
                                             const CFX_Matrix* pMatrix) {
  if (!pWidget)
    return FWL_ERR_Indefinite;
  if (!pGraphics)
    return FWL_ERR_Indefinite;
  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 FWL_ERR_Succeeded;
  }
  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(NULL);
  pDelegate->OnDrawWidget(pTemp, pMatrix);
  pGraphics->GetClipRect(clipBounds);
  clipCopy = clipBounds;
#elif(_FX_OS_ == _FX_MACOSX_)
  if (m_pWidgetMgr->IsFormDisabled()) {
    IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL);
    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.
#ifdef FWL_UseMacSystemBorder
#else
#endif
    {
      IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL);
      pDelegate->OnDrawWidget(pTemp, pMatrix);
    }
  }
#endif
  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);
  return FWL_ERR_Succeeded;
}
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->GetWidget(parent, FWL_WGTRELATION_FirstChild);
  while (pNextChild) {
    IFWL_Widget* child = pNextChild;
    pNextChild = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
    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(NULL);
    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->GetWidget(child, FWL_WGTRELATION_NextSibling);
  }
}
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 = 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;
}
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, rtClip.left, rtClip.top, rtClip,
                        pMatrix);
#ifdef _WIN32
    pItem->pOffscreen->ClearClip();
#endif
  }
  CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
  pItem->iRedrawCounter = 0;
}
#define FWL_NEEDREPAINTHIT_Point 12
#define FWL_NEEDREPAINTHIT_Piece 3
typedef struct _FWL_NeedRepaintHitData {
  CFX_PointF hitPoint;
  FX_BOOL bNotNeedRepaint;
  FX_BOOL bNotContainByDirty;
} FWL_NeedRepaintHitData;
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 =
      FWL_GetWidgetMgr()->GetWidget(pWidget, FWL_WGTRELATION_FirstChild);
  if (!pChild) {
    return TRUE;
  }
  if (pChild->GetClassID() == 3150298670) {
    CFX_RectF rtTemp;
    pChild->GetWidgetRect(rtTemp);
    if (rtTemp.width >= rtWidget.width && rtTemp.height >= rtWidget.height) {
      pChild =
          FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_FirstChild);
      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[FWL_NEEDREPAINTHIT_Point];
  static int32_t iSize = sizeof(FWL_NeedRepaintHitData);
  FXSYS_memset(hitPoint, 0, iSize);
  FX_FLOAT fxPiece = rtWidget.width / FWL_NEEDREPAINTHIT_Piece;
  FX_FLOAT fyPiece = rtWidget.height / FWL_NEEDREPAINTHIT_Piece;
  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 < FWL_NEEDREPAINTHIT_Point; 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;
      }
    }
  } while ((pChild = FWL_GetWidgetMgr()->GetWidget(
                pChild, FWL_WGTRELATION_NextSibling)) != NULL);
  if (!bChildIntersectWithDirty) {
    return TRUE;
  }
  if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
    return TRUE;
  }
  if (rtChilds.IsEmpty()) {
    return TRUE;
  }
  int32_t repaintPoint = FWL_NEEDREPAINTHIT_Point;
  for (int32_t i = 0; i < FWL_NEEDREPAINTHIT_Point; 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;
}
static void FWL_WriteBMP(CFX_DIBitmap* pBitmap, const FX_CHAR* filename) {
  FILE* file = fopen(filename, "wb");
  if (file == NULL) {
    return;
  }
  int size = 14 + 40 + pBitmap->GetPitch() * pBitmap->GetHeight();
  unsigned char buffer[40];
  buffer[0] = 'B';
  buffer[1] = 'M';
  buffer[2] = (unsigned char)size;
  buffer[3] = (unsigned char)(size >> 8);
  buffer[4] = (unsigned char)(size >> 16);
  buffer[5] = (unsigned char)(size >> 24);
  buffer[6] = buffer[7] = buffer[8] = buffer[9] = 0;
  buffer[10] = 54;
  buffer[11] = buffer[12] = buffer[13] = 0;
  fwrite(buffer, 14, 1, file);
  memset(buffer, 0, 40);
  buffer[0] = 40;
  buffer[4] = (unsigned char)pBitmap->GetWidth();
  buffer[5] = (unsigned char)(pBitmap->GetWidth() >> 8);
  buffer[6] = (unsigned char)(pBitmap->GetWidth() >> 16);
  buffer[7] = (unsigned char)(pBitmap->GetWidth() >> 24);
  buffer[8] = (unsigned char)(-pBitmap->GetHeight());
  buffer[9] = (unsigned char)((-pBitmap->GetHeight()) >> 8);
  buffer[10] = (unsigned char)((-pBitmap->GetHeight()) >> 16);
  buffer[11] = (unsigned char)((-pBitmap->GetHeight()) >> 24);
  buffer[12] = 1;
  buffer[14] = pBitmap->GetBPP();
  fwrite(buffer, 40, 1, file);
  for (int row = 0; row < pBitmap->GetHeight(); row++) {
    uint8_t* scan_line = pBitmap->GetBuffer() + row * pBitmap->GetPitch();
    fwrite(scan_line, pBitmap->GetPitch(), 1, file);
  }
  fclose(file);
}
FWL_ERR FWL_WidgetMgrSnapshot(IFWL_Widget* pWidget,
                              const CFX_WideString* saveFile,
                              const CFX_Matrix* pMatrix) {
  CFX_RectF r;
  pWidget->GetWidgetRect(r);
  CFX_Graphics gs;
  gs.Create((int32_t)r.width, (int32_t)r.height, FXDIB_Argb);
  CFWL_WidgetMgr* widgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
  CFWL_WidgetMgrDelegate* delegate = widgetMgr->GetDelegate();
  delegate->OnDrawWidget(pWidget, &gs, pMatrix);
  CFX_DIBitmap* dib = gs.GetRenderDevice()->GetBitmap();
  FWL_WriteBMP(dib, saveFile->UTF8Encode());
  return FWL_ERR_Succeeded;
}
FX_BOOL FWL_WidgetIsChild(IFWL_Widget* parent, IFWL_Widget* find) {
  if (!find) {
    return FALSE;
  }
  IFWL_Widget* child =
      FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
  while (child) {
    if (child == find) {
      return TRUE;
    }
    if (FWL_WidgetIsChild(child, find)) {
      return TRUE;
    }
    child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
  }
  return FALSE;
}
