// Copyright 2016 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_CFWL_MESSAGE_H_
#define XFA_FWL_CORE_CFWL_MESSAGE_H_

#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
#include "xfa/fwl/core/fwl_error.h"

enum class CFWL_MessageType {
  None = 0,

  Activate,
  Close,
  Cursor,
  Deactivate,
  DropFiles,
  Key,
  KillFocus,
  Mouse,
  MouseWheel,
  Post,
  SetFocus,
  Size,
  TaskClicked,
  WindowMove,
  WindowWillMove
};

enum class FWL_MouseCommand {
  LeftButtonDown,
  LeftButtonUp,
  LeftButtonDblClk,
  RightButtonDown,
  RightButtonUp,
  RightButtonDblClk,
  MiddleButtonDown,
  MiddleButtonUp,
  MiddleButtonDblClk,
  Move,
  Enter,
  Leave,
  Hover
};

enum class FWL_KeyCommand { KeyDown, KeyUp, Char };

class IFWL_Widget;

class CFWL_Message {
 public:
  CFWL_Message();
  virtual ~CFWL_Message();

  virtual CFWL_Message* Clone();
  virtual CFWL_MessageType GetClassID() const;

  uint32_t Release();
  CFWL_Message* Retain();

  IFWL_Widget* m_pSrcTarget;
  IFWL_Widget* m_pDstTarget;
  uint32_t m_dwExtend;

 private:
  uint32_t m_dwRefCount;
};

inline CFWL_Message::CFWL_Message()
    : m_pSrcTarget(nullptr),
      m_pDstTarget(nullptr),
      m_dwExtend(0),
      m_dwRefCount(1) {}

inline CFWL_Message::~CFWL_Message() {}

inline CFWL_Message* CFWL_Message::Clone() {
  return nullptr;
}

inline CFWL_MessageType CFWL_Message::GetClassID() const {
  return CFWL_MessageType::None;
}

inline uint32_t CFWL_Message::Release() {
  m_dwRefCount--;
  uint32_t dwRefCount = m_dwRefCount;
  if (!m_dwRefCount)
    delete this;
  return dwRefCount;
}

inline CFWL_Message* CFWL_Message::Retain() {
  m_dwRefCount++;
  return this;
}

#define FWL_MESSAGE_CLASS_DEF(classname, msgType, ...)              \
  class classname : public CFWL_Message {                           \
   public:                                                          \
    classname();                                                    \
    ~classname() override;                                          \
    CFWL_Message* Clone() override;                                 \
    CFWL_MessageType GetClassID() const override;                   \
    __VA_ARGS__                                                     \
  };

#define FWL_MESSAGE_FUNCTION_DEF(classname, msgType, ...)                   \
  inline classname::classname() {}                                          \
  inline classname::~classname() {}                                         \
  inline CFWL_Message* classname::Clone() { return new classname(*this); }  \
  inline CFWL_MessageType classname::GetClassID() const { return msgType; } \
  __VA_ARGS__

#define FWL_MESSAGE_DEF(classname, msgType, ...)         \
  FWL_MESSAGE_CLASS_DEF(classname, msgType, __VA_ARGS__) \
  FWL_MESSAGE_FUNCTION_DEF(classname, msgType)

FWL_MESSAGE_DEF(CFWL_MsgActivate, CFWL_MessageType::Activate)

FWL_MESSAGE_DEF(CFWL_MsgDeactivate, CFWL_MessageType::Deactivate)

FWL_MESSAGE_DEF(CFWL_MsgMouse, CFWL_MessageType::Mouse, FX_FLOAT m_fx;
                FX_FLOAT m_fy;
                uint32_t m_dwFlags;
                FWL_MouseCommand m_dwCmd;)

FWL_MESSAGE_DEF(CFWL_MsgMouseWheel, CFWL_MessageType::MouseWheel, FX_FLOAT m_fx;
                FX_FLOAT m_fy;
                FX_FLOAT m_fDeltaX;
                FX_FLOAT m_fDeltaY;
                uint32_t m_dwFlags;)

FWL_MESSAGE_DEF(CFWL_MsgSetFocus,
                CFWL_MessageType::SetFocus,
                IFWL_Widget* m_pKillFocus;)

FWL_MESSAGE_DEF(CFWL_MsgKillFocus,
                CFWL_MessageType::KillFocus,
                IFWL_Widget* m_pSetFocus;)

FWL_MESSAGE_DEF(CFWL_MsgKey, CFWL_MessageType::Key, uint32_t m_dwKeyCode;
                uint32_t m_dwFlags;
                FWL_KeyCommand m_dwCmd;)

FWL_MESSAGE_DEF(CFWL_MsgCursor, CFWL_MessageType::Cursor)

FWL_MESSAGE_DEF(CFWL_MsgSize, CFWL_MessageType::Size, int32_t m_iWidth;
                int32_t m_iHeight;)

FWL_MESSAGE_DEF(CFWL_MsgWindowMove, CFWL_MessageType::WindowMove, FX_FLOAT m_fx;
                FX_FLOAT m_fy;)

FWL_MESSAGE_CLASS_DEF(CFWL_MsgDropFiles,
                      CFWL_MessageType::DropFiles,
                      CFWL_MsgDropFiles(const CFWL_MsgDropFiles& copy);
                      FX_FLOAT m_fx;
                      FX_FLOAT m_fy;
                      CFX_WideStringArray m_files;)
FWL_MESSAGE_FUNCTION_DEF(
    CFWL_MsgDropFiles,
    CFWL_MessageType::DropFiles,
    inline CFWL_MsgDropFiles::CFWL_MsgDropFiles(const CFWL_MsgDropFiles& copy) {
      m_pDstTarget = copy.m_pDstTarget;
      m_pSrcTarget = copy.m_pSrcTarget;
      m_fx = copy.m_fx;
      m_fy = copy.m_fy;
      m_files.Append(copy.m_files);
    })

FWL_MESSAGE_DEF(CFWL_MsgTaskClicked,
                CFWL_MessageType::TaskClicked,
                FX_FLOAT m_fx;
                FX_FLOAT m_fy;)

FWL_MESSAGE_DEF(CFWL_MsgClose, CFWL_MessageType::Close)

FWL_MESSAGE_DEF(CFWL_MsgWindowWillMove, CFWL_MessageType::WindowWillMove)

#endif  // XFA_FWL_CORE_CFWL_MESSAGE_H_
