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

#include "xfa/fwl/core/cfwl_message.h"
#include "xfa/fwl/core/fwl_appimp.h"
#include "xfa/fwl/core/fwl_noteimp.h"
#include "xfa/fwl/core/fwl_targetimp.h"
#include "xfa/fwl/core/fwl_threadimp.h"
#include "xfa/fwl/core/fwl_widgetimp.h"
#include "xfa/fwl/core/ifwl_adapternative.h"
#include "xfa/fwl/core/ifwl_adapterwidgetmgr.h"
#include "xfa/fwl/core/ifwl_app.h"
#include "xfa/fwl/core/ifwl_form.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;
  }
  uint32_t 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(uint32_t 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
struct FWL_NEEDREPAINTHITDATA {
  CFX_PointF hitPoint;
  FX_BOOL bNotNeedRepaint;
  FX_BOOL bNotContainByDirty;
};

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];
  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;
}
