// 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_CORE_FWL_NOTEIMP_H_
#define XFA_FWL_CORE_FWL_NOTEIMP_H_

#include "xfa/fwl/core/ifwl_notedriver.h"
#include "xfa/fwl/core/ifwl_noteloop.h"
#include "xfa/fxgraphics/include/cfx_graphics.h"

class CFWL_CoreToolTipDP;
class CFWL_MsgActivate;
class CFWL_MsgDeactivate;
class CFWL_MsgDropFiles;
class CFWL_MsgKey;
class CFWL_MsgKillFocus;
class CFWL_MsgMouse;
class CFWL_MsgMouseWheel;
class CFWL_MsgSetFocus;
class CFWL_MsgSize;
class CFWL_MsgWindowMove;
class CFWL_ToolTipImp;
class CFWL_WidgetImp;
class IFWL_ToolTipTarget;

class CFWL_NoteLoop : public IFWL_NoteLoop {
 public:
  CFWL_NoteLoop(CFWL_WidgetImp* pForm = NULL);

  // IFWL_NoteLoop:
  ~CFWL_NoteLoop() override {}
  FX_BOOL PreProcessMessage(CFWL_Message* pMessage) override;
  FWL_ERR Idle(int32_t count) override;

  CFWL_WidgetImp* GetForm();
  FX_BOOL ContinueModal();
  FWL_ERR EndModalLoop();
  FX_BOOL TranslateAccelerator(CFWL_Message* pMessage);
  FWL_ERR SetMainForm(CFWL_WidgetImp* pForm);

 protected:
  void GenerateCommondEvent(uint32_t dwCommand);

  CFWL_WidgetImp* m_pForm;
  FX_BOOL m_bContinueModal;
};

class CFWL_NoteDriver : public IFWL_NoteDriver {
 public:
  CFWL_NoteDriver();
  ~CFWL_NoteDriver() override;

  // IFWL_NoteDriver:
  FX_BOOL SendNote(CFWL_Note* pNote) override;
  FWL_ERR RegisterEventTarget(IFWL_Widget* pListener,
                              IFWL_Widget* pEventSource = NULL,
                              uint32_t dwFilter = FWL_EVENT_ALL_MASK) override;
  FWL_ERR UnregisterEventTarget(IFWL_Widget* pListener) override;
  void ClearEventTargets(FX_BOOL bRemoveAll) override;
  int32_t GetQueueMaxSize() const override;
  FWL_ERR SetQueueMaxSize(const int32_t size) override;
  IFWL_NoteThread* GetOwnerThread() const override;
  FWL_ERR PushNoteLoop(IFWL_NoteLoop* pNoteLoop) override;
  IFWL_NoteLoop* PopNoteLoop() override;
  IFWL_Widget* GetFocus() override;
  FX_BOOL SetFocus(IFWL_Widget* pFocus, FX_BOOL bNotify = FALSE) override;
  void SetGrab(IFWL_Widget* pGrab, FX_BOOL bSet) override;
  FWL_ERR Run() override;

  IFWL_Widget* GetHover();
  void SetHover(IFWL_Widget* pHover);
  void NotifyTargetHide(IFWL_Widget* pNoteTarget);
  void NotifyTargetDestroy(IFWL_Widget* pNoteTarget);
  void NotifyFullScreenMode(IFWL_Widget* pNoteTarget, FX_BOOL bFullScreen);
  FWL_ERR RegisterForm(CFWL_WidgetImp* pForm);
  FWL_ERR UnRegisterForm(CFWL_WidgetImp* pForm);
  FX_BOOL QueueMessage(CFWL_Message* pMessage);
  FX_BOOL UnqueueMessage(CFWL_NoteLoop* pNoteLoop);
  CFWL_NoteLoop* GetTopLoop();
  int32_t CountLoop();
  void SetHook(FWLMessageHookCallback callback, void* info);
  FX_BOOL ProcessMessage(CFWL_Message* pMessage);

 protected:
  FX_BOOL DispatchMessage(CFWL_Message* pMessage, IFWL_Widget* pMessageForm);
  FX_BOOL DoActivate(CFWL_MsgActivate* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoDeactivate(CFWL_MsgDeactivate* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoSetFocus(CFWL_MsgSetFocus* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoKillFocus(CFWL_MsgKillFocus* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoKey(CFWL_MsgKey* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoMouse(CFWL_MsgMouse* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoWheel(CFWL_MsgMouseWheel* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoSize(CFWL_MsgSize* pMsg);
  FX_BOOL DoWindowMove(CFWL_MsgWindowMove* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoDragFiles(CFWL_MsgDropFiles* pMsg, IFWL_Widget* pMessageForm);
  FX_BOOL DoMouseEx(CFWL_MsgMouse* pMsg, IFWL_Widget* pMessageForm);
  void MouseSecondary(CFWL_MsgMouse* pMsg);
  FX_BOOL IsValidMessage(CFWL_Message* pMessage);
  IFWL_Widget* GetMessageForm(IFWL_Widget* pDstTarget);
  void ClearInvalidEventTargets(FX_BOOL bRemoveAll);
  CFX_PtrArray m_forms;
  CFX_PtrArray m_noteQueue;
  CFX_PtrArray m_noteLoopQueue;
  CFX_MapPtrToPtr m_eventTargets;
  int32_t m_sendEventCalled;
  int32_t m_maxSize;
  FX_BOOL m_bFullScreen;
  IFWL_Widget* m_pHover;
  IFWL_Widget* m_pFocus;
  IFWL_Widget* m_pGrab;
  CFWL_NoteLoop* m_pNoteLoop;
  FWLMessageHookCallback m_hook;
  void* m_hookInfo;
};

typedef CFX_MapPtrTemplate<void*, uint32_t> CFWL_EventSource;

class CFWL_EventTarget {
 public:
  CFWL_EventTarget(CFWL_NoteDriver* pNoteDriver, IFWL_Widget* pListener)
      : m_pListener(pListener), m_pNoteDriver(pNoteDriver), m_bInvalid(FALSE) {}
  ~CFWL_EventTarget();
  int32_t SetEventSource(IFWL_Widget* pSource,
                         uint32_t dwFilter = FWL_EVENT_ALL_MASK);
  FX_BOOL ProcessEvent(CFWL_Event* pEvent);
  FX_BOOL IsFilterEvent(CFWL_Event* pEvent, uint32_t dwFilter);
  FX_BOOL IsInvalid() { return m_bInvalid; }
  void FlagInvalid() { m_bInvalid = TRUE; }

 protected:
  CFWL_EventSource m_eventSources;
  IFWL_Widget* m_pListener;
  CFWL_NoteDriver* m_pNoteDriver;
  FX_BOOL m_bInvalid;
};

class CFWL_ToolTipContainer {
 public:
  static CFWL_ToolTipContainer* getInstance();
  static void DeleteInstance();

  FX_ERR AddToolTipTarget(IFWL_ToolTipTarget* pTarget);
  FX_ERR RemoveToolTipTarget(IFWL_ToolTipTarget* pTarget);
  IFWL_ToolTipTarget* GetCurrentToolTipTarget();

  FX_BOOL HasToolTip(IFWL_Widget* pWidget);

  FX_BOOL ProcessEnter(CFWL_EvtMouse* pEvt, IFWL_Widget* pOwner);
  FX_BOOL ProcessLeave(CFWL_EvtMouse* pEvt);

  FX_ERR SetToolTipInitialDelay(int32_t iDelayTime);
  FX_ERR SetToolTipAutoPopDelay(int32_t iDelayTime);

 protected:
  CFWL_ToolTipContainer();
  virtual ~CFWL_ToolTipContainer();

  IFWL_ToolTipTarget* pCurTarget;
  CFWL_ToolTipImp* m_pToolTipImp;
  CFWL_CoreToolTipDP* m_ToolTipDp;
  CFX_PtrArray m_arrWidget;

 private:
  static CFWL_ToolTipContainer* s_pInstance;
};

#endif  // XFA_FWL_CORE_FWL_NOTEIMP_H_
