// 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

#ifndef XFA_FWL_CFWL_WIDGETMGR_H_
#define XFA_FWL_CFWL_WIDGETMGR_H_

#include <map>
#include <memory>

#include "core/fxcrt/fx_system.h"
#include "xfa/fxgraphics/cxfa_graphics.h"

class CFWL_Message;
class CXFA_Graphics;
class CFX_Matrix;
class CFWL_Widget;

class CFWL_WidgetMgr {
 public:
  class AdapterIface {
   public:
    virtual ~AdapterIface() {}
    virtual void RepaintWidget(CFWL_Widget* pWidget) = 0;
    virtual bool GetPopupPos(CFWL_Widget* pWidget,
                             float fMinHeight,
                             float fMaxHeight,
                             const CFX_RectF& rtAnchor,
                             CFX_RectF* pPopupRect) = 0;
  };

  explicit CFWL_WidgetMgr(AdapterIface* pAdapterNative);
  ~CFWL_WidgetMgr();

  static CFWL_Widget* NextTab(CFWL_Widget* parent, CFWL_Widget* focus);

  void OnProcessMessageToForm(std::unique_ptr<CFWL_Message> pMessage);
  void OnDrawWidget(CFWL_Widget* pWidget,
                    CXFA_Graphics* pGraphics,
                    const CFX_Matrix& matrix);

  CFWL_Widget* GetParentWidget(const CFWL_Widget* pWidget) const;
  CFWL_Widget* GetOwnerWidget(const CFWL_Widget* pWidget) const;
  CFWL_Widget* GetNextSiblingWidget(CFWL_Widget* pWidget) const;
  CFWL_Widget* GetFirstChildWidget(CFWL_Widget* pWidget) const;
  CFWL_Widget* GetSystemFormWidget(CFWL_Widget* pWidget) const;

  void RepaintWidget(CFWL_Widget* pWidget, const CFX_RectF& pRect);

  void InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild);
  void RemoveWidget(CFWL_Widget* pWidget);
  void SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild);

  CFWL_Widget* GetWidgetAtPoint(CFWL_Widget* pParent,
                                const CFX_PointF& point) const;

  CFWL_Widget* GetDefaultButton(CFWL_Widget* pParent) const;
  void AddRedrawCounts(CFWL_Widget* pWidget);

  void GetAdapterPopupPos(CFWL_Widget* pWidget,
                          float fMinHeight,
                          float fMaxHeight,
                          const CFX_RectF& rtAnchor,
                          CFX_RectF* pPopupRect) const;

 private:
  class Item {
   public:
    Item();
    explicit Item(CFWL_Widget* widget);
    ~Item();

    Item* pParent = nullptr;
    Item* pOwner = nullptr;
    Item* pChild = nullptr;
    Item* pPrevious = nullptr;
    Item* pNext = nullptr;
    CFWL_Widget* const pWidget;
    std::unique_ptr<CXFA_Graphics> pOffscreen;
    int32_t iRedrawCounter = 0;
  };

  CFWL_Widget* GetFirstSiblingWidget(CFWL_Widget* pWidget) const;
  CFWL_Widget* GetPriorSiblingWidget(CFWL_Widget* pWidget) const;
  CFWL_Widget* GetLastChildWidget(CFWL_Widget* pWidget) const;
  Item* GetWidgetMgrItem(const CFWL_Widget* pWidget) const;

  void AppendWidget(CFWL_Widget* pWidget);
  void ResetRedrawCounts(CFWL_Widget* pWidget);
  void DrawChild(CFWL_Widget* pParent,
                 const CFX_RectF& rtClip,
                 CXFA_Graphics* pGraphics,
                 const CFX_Matrix* pMatrix);

  bool IsAbleNative(CFWL_Widget* pWidget) const;

  std::map<const CFWL_Widget*, std::unique_ptr<Item>> m_mapWidgetItem;
  UnownedPtr<AdapterIface> const m_pAdapter;
};

#endif  // XFA_FWL_CFWL_WIDGETMGR_H_
