// 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_Thread* pThread = pDstWidget->GetOwnerThread();
  if (!pThread)
    return 0;
  CFWL_NoteDriver* pNoteDriver =
      static_cast<CFWL_NoteDriver*>(pThread->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;
}
