// 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_FXFA_CXFA_FFAPP_H_
#define XFA_FXFA_CXFA_FFAPP_H_

#include "core/fxcrt/unowned_ptr.h"
#include "core/fxcrt/widestring.h"
#include "fxjs/gc/heap.h"
#include "v8/include/cppgc/garbage-collected.h"
#include "v8/include/cppgc/member.h"
#include "xfa/fwl/cfwl_app.h"

class CFWL_WidgetMgr;
class CXFA_FFDoc;
class CXFA_FWLAdapterWidgetMgr;
class CXFA_FWLTheme;
class CXFA_FontMgr;
class IFX_SeekableReadStream;

class CXFA_FFApp final : public cppgc::GarbageCollected<CXFA_FFApp>,
                         public CFWL_App::AdapterIface {
 public:
  class CallbackIface {
   public:
    virtual ~CallbackIface() = default;

    /**
     * Returns the language of the running host application. Such as zh_CN
     */
    virtual WideString GetLanguage() = 0;

    /**
     * Returns the platform of the machine running the script. Such as WIN
     */
    virtual WideString GetPlatform() = 0;

    /**
     * Get application name, such as Phantom.
     */
    virtual WideString GetAppName() = 0;

    /**
     * Get application message box title.
     */
    virtual WideString GetAppTitle() const = 0;

    /**
     * Causes the system to play a sound.
     * @param[in] dwType The system code for the appropriate sound.0 (Error)1
     * (Warning)2 (Question)3 (Status)4 (Default)
     */
    virtual void Beep(uint32_t dwType) = 0;

    /**
     * Displays a message box.
     * @param[in] wsMessage    - Message string to display in box.
     * @param[in] wsTitle      - Title string for box.
     * @param[in] dwIconType   - Icon type, refer to XFA_MBICON.
     * @param[in] dwButtonType - Button type, refer to XFA_MESSAGEBUTTON.
     * @return A valid integer representing the value of the button pressed by
     * the user, refer to XFA_ID.
     */
    virtual int32_t MsgBox(const WideString& wsMessage,
                           const WideString& wsTitle,
                           uint32_t dwIconType,
                           uint32_t dwButtonType) = 0;

    /**
     * Get a response from the user.
     * @param[in] wsQuestion      - Message string to display in box.
     * @param[in] wsTitle         - Title string for box.
     * @param[in] wsDefaultAnswer - Initial contents for answer.
     * @param[in] bMask           - Mask the user input with asterisks when
     * true,
     * @return A string containing the user's response.
     */
    virtual WideString Response(const WideString& wsQuestion,
                                const WideString& wsTitle,
                                const WideString& wsDefaultAnswer,
                                bool bMask) = 0;

    /**
     * Download something from somewhere.
     * @param[in] wsURL - http, ftp, such as
     * "http://www.w3.org/TR/REC-xml-names/".
     */
    virtual RetainPtr<IFX_SeekableReadStream> DownloadURL(
        const WideString& wsURL) = 0;

    /**
     * POST data to the given url.
     * @param[in] wsURL         the URL being uploaded.
     * @param[in] wsData        the data being uploaded.
     * @param[in] wsContentType the content type of data including text/html,
     * text/xml, text/plain, multipart/form-data,
     *                          application/x-www-form-urlencoded,
     * application/octet-stream, any valid MIME type.
     * @param[in] wsEncode      the encode of data including UTF-8, UTF-16,
     * ISO8859-1, any recognized [IANA]character encoding
     * @param[in] wsHeader      any additional HTTP headers to be included in
     * the post.
     * @param[out] wsResponse   decoded response from server.
     * @return true Server permitted the post request, false otherwise.
     */
    virtual bool PostRequestURL(const WideString& wsURL,
                                const WideString& wsData,
                                const WideString& wsContentType,
                                const WideString& wsEncode,
                                const WideString& wsHeader,
                                WideString& wsResponse) = 0;

    /**
     * PUT data to the given url.
     * @param[in] wsURL         the URL being uploaded.
     * @param[in] wsData            the data being uploaded.
     * @param[in] wsEncode      the encode of data including UTF-8, UTF-16,
     * ISO8859-1, any recognized [IANA]character encoding
     * @return true Server permitted the post request, false otherwise.
     */
    virtual bool PutRequestURL(const WideString& wsURL,
                               const WideString& wsData,
                               const WideString& wsEncode) = 0;

    virtual CFX_Timer::HandlerIface* GetTimerHandler() const = 0;
    virtual cppgc::Heap* GetGCHeap() const = 0;
  };

  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
  ~CXFA_FFApp() override;

  // CFWL_App::AdapterIface:
  void Trace(cppgc::Visitor* visitor) const override;
  CFWL_WidgetMgr::AdapterIface* GetWidgetMgrAdapter() override;
  CFX_Timer::HandlerIface* GetTimerHandler() override;
  IFWL_ThemeProvider* GetThemeProvider() override;
  cppgc::Heap* GetHeap() override;

  bool LoadFWLTheme(CXFA_FFDoc* doc);
  CFWL_WidgetMgr* GetFWLWidgetMgr() const { return m_pFWLApp->GetWidgetMgr(); }
  CallbackIface* GetAppProvider() const { return m_pProvider.Get(); }
  CFWL_App* GetFWLApp() const { return m_pFWLApp; }
  CXFA_FontMgr* GetXFAFontMgr() const { return m_pXFAFontMgr; }

 private:
  explicit CXFA_FFApp(CallbackIface* pProvider);

  UnownedPtr<CallbackIface> const m_pProvider;
  cppgc::Member<CXFA_FontMgr> m_pXFAFontMgr;
  cppgc::Member<CXFA_FWLAdapterWidgetMgr> m_pAdapterWidgetMgr;
  cppgc::Member<CXFA_FWLTheme> m_pFWLTheme;
  cppgc::Member<CFWL_App> m_pFWLApp;
};

#endif  // XFA_FXFA_CXFA_FFAPP_H_
