// Copyright 2014 The PDFium Authors
// 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 CXFA_FFDoc;
class CXFA_FWLAdapterWidgetMgr;
class CXFA_FontMgr;
class IFX_SeekableReadStream;

namespace pdfium {
class CXFA_FWLTheme;
}  // namespace pdfium

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;
  pdfium::IFWL_ThemeProvider* GetThemeProvider() override;
  cppgc::Heap* GetHeap() override;

  bool LoadFWLTheme(CXFA_FFDoc* doc);
  CFWL_WidgetMgr* GetFWLWidgetMgr() const { return fwlapp_->GetWidgetMgr(); }
  CallbackIface* GetAppProvider() const { return provider_; }
  CFWL_App* GetFWLApp() const { return fwlapp_; }
  CXFA_FontMgr* GetXFAFontMgr() const { return xfafont_mgr_; }

 private:
  explicit CXFA_FFApp(CallbackIface* pProvider);

  UnownedPtr<CallbackIface> const provider_;
  cppgc::Member<CXFA_FontMgr> xfafont_mgr_;
  cppgc::Member<CXFA_FWLAdapterWidgetMgr> adapter_widget_mgr_;
  cppgc::Member<pdfium::CXFA_FWLTheme> fwltheme_;
  cppgc::Member<CFWL_App> fwlapp_;
};

#endif  // XFA_FXFA_CXFA_FFAPP_H_
