// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_CPP_INSTANCE_H_
#define PPAPI_CPP_INSTANCE_H_

/// @file
/// This file defines the C++ wrapper for an instance.

#include <map>
#include <string>

#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/ppb_console.h"
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/view.h"

// Windows defines 'PostMessage', so we have to undef it.
#ifdef PostMessage
#undef PostMessage
#endif

struct PP_InputEvent;

/// The C++ interface to the Pepper API.
namespace pp {

class Graphics2D;
class Graphics3D;
class InputEvent;
class InstanceHandle;
class Rect;
class URLLoader;
class Var;

class Instance {
 public:
  /// Default constructor. Construction of an instance should only be done in
  /// response to a browser request in <code>Module::CreateInstance</code>.
  /// Otherwise, the instance will lack the proper bookkeeping in the browser
  /// and in the C++ wrapper.
  ///
  /// Init() will be called immediately after the constructor. This allows you
  /// to perform initialization tasks that can fail and to report that failure
  /// to the browser.
  explicit Instance(PP_Instance instance);

  /// Destructor. When the instance is removed from the web page,
  /// the <code>pp::Instance</code> object will be deleted. You should never
  /// delete the <code>Instance</code> object yourself since the lifetime is
  /// handled by the C++ wrapper and is controlled by the browser's calls to
  /// the <code>PPP_Instance</code> interface.
  ///
  /// The <code>PP_Instance</code> identifier will still be valid during this
  /// call so the instance can perform cleanup-related tasks. Once this function
  /// returns, the <code>PP_Instance</code> handle will be invalid. This means
  /// that you can't do any asynchronous operations such as network requests or
  /// file writes from this destructor since they will be immediately canceled.
  ///
  /// <strong>Note:</strong> This function may be skipped in certain
  /// call so the instance can perform cleanup-related tasks. Once this function
  /// returns, the <code>PP_Instance</code> handle will be invalid. This means
  /// that you can't do any asynchronous operations such as network requests or
  /// file writes from this destructor since they will be immediately canceled.
  virtual ~Instance();

  /// This function returns the <code>PP_Instance</code> identifying this
  /// object.
  ///
  /// @return A <code>PP_Instance</code> identifying this object.
  PP_Instance pp_instance() const { return pp_instance_; }

  /// Init() initializes this instance with the provided arguments. This
  /// function will be called immediately after the instance object is
  /// constructed.
  ///
  /// @param[in] argc The number of arguments contained in <code>argn</code>
  /// and <code>argv</code>.
  ///
  /// @param[in] argn An array of argument names.  These argument names are
  /// supplied in the \<embed\> tag, for example:
  /// <code>\<embed id="nacl_module" dimensions="2"\></code> will produce two
  /// argument names: "id" and "dimensions".
  ///
  /// @param[in] argv An array of argument values.  These are the values of the
  /// arguments listed in the \<embed\> tag, for example
  /// <code>\<embed id="nacl_module" dimensions="2"\></code> will produce two
  /// argument values: "nacl_module" and "2".  The indices of these values
  /// match the indices of the corresponding names in <code>argn</code>.
  ///
  /// @return true on success. Returning false causes the instance to be
  /// deleted and no other functions to be called.
  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);

  /// @{
  /// @name PPP_Instance methods for the module to override:

  /// DidChangeView() is called when the view information for the Instance
  /// has changed. See the <code>View</code> object for information.
  ///
  /// Most implementations will want to check if the size and user visibility
  /// changed, and either resize themselves or start/stop generating updates.
  ///
  /// You should not call the default implementation. For
  /// backwards-compatibility, it will call the deprecated version of
  /// DidChangeView below.
  virtual void DidChangeView(const View& view);

  /// Deprecated backwards-compatible version of <code>DidChangeView()</code>.
  /// New code should derive from the version that takes a
  /// <code>ViewChanged</code> object rather than this version. This function
  /// is called by the default implementation of the newer
  /// <code>DidChangeView</code> function for source compatibility with older
  /// code.
  ///
  /// A typical implementation will check the size of the <code>position</code>
  /// argument and reallocate the graphics context when a different size is
  /// received. Note that this function will be called for scroll events where
  /// the size doesn't change, so you should always check that the size is
  /// actually different before doing any reallocations.
  ///
  /// @param[in] position The location on the page of the instance. The
  /// position is relative to the top left corner of the viewport, which changes
  /// as the page is scrolled. Generally the size of this value will be used to
  /// create a graphics device, and the position is ignored (most things are
  /// relative to the instance so the absolute position isn't useful in most
  /// cases).
  ///
  /// @param[in] clip The visible region of the instance. This is relative to
  /// the top left of the instance's coordinate system (not the page).  If the
  /// instance is invisible, <code>clip</code> will be (0, 0, 0, 0).
  ///
  /// It's recommended to check for invisible instances and to stop
  /// generating graphics updates in this case to save system resources. It's
  /// not usually worthwhile, however, to generate partial updates according to
  /// the clip when the instance is partially visible. Instead, update the
  /// entire region. The time saved doing partial paints is usually not
  /// significant and it can create artifacts when scrolling (this notification
  /// is sent asynchronously from scrolling so there can be flashes of old
  /// content in the exposed regions).
  virtual void DidChangeView(const Rect& position, const Rect& clip);

  /// DidChangeFocus() is called when an instance has gained or lost focus.
  /// Having focus means that keyboard events will be sent to the instance.
  /// An instance's default condition is that it will not have focus.
  ///
  /// The focus flag takes into account both browser tab and window focus as
  /// well as focus of the plugin element on the page. In order to be deemed
  /// to have focus, the browser window must be topmost, the tab must be
  /// selected in the window, and the instance must be the focused element on
  /// the page.
  ///
  /// <strong>Note:</strong>Clicks on instances will give focus only if you
  /// handle the click event. Return <code>true</code> from
  /// <code>HandleInputEvent</code> in <code>PPP_InputEvent</code> (or use
  /// unfiltered events) to signal that the click event was handled. Otherwise,
  /// the browser will bubble the event and give focus to the element on the
  /// page that actually did end up consuming it. If you're not getting focus,
  /// check to make sure you're either requesting them via
  /// <code>RequestInputEvents()<code> (which implicitly marks all input events
  /// as consumed) or via <code>RequestFilteringInputEvents()</code> and
  /// returning true from your event handler.
  ///
  /// @param[in] has_focus Indicates the new focused state of the instance.
  virtual void DidChangeFocus(bool has_focus);

  /// HandleInputEvent() handles input events from the browser. The default
  /// implementation does nothing and returns false.
  ///
  /// In order to receive input events, you must register for them by calling
  /// RequestInputEvents() or RequestFilteringInputEvents(). By
  /// default, no events are delivered.
  ///
  /// If the event was handled, it will not be forwarded to the web page or
  /// browser. If it was not handled, it will bubble according to the normal
  /// rules. So it is important that an instance respond accurately with whether
  /// event propagation should continue.
  ///
  /// Event propagation also controls focus. If you handle an event like a mouse
  /// event, typically the instance will be given focus. Returning false from
  /// a filtered event handler or not registering for an event type means that
  /// the click will be given to a lower part of the page and your instance will
  /// not receive focus. This allows an instance to be partially transparent,
  /// where clicks on the transparent areas will behave like clicks to the
  /// underlying page.
  ///
  /// In general, you should try to keep input event handling short. Especially
  /// for filtered input events, the browser or page may be blocked waiting for
  /// you to respond.
  ///
  /// The caller of this function will maintain a reference to the input event
  /// resource during this call. Unless you take a reference to the resource
  /// to hold it for later, you don't need to release it.
  ///
  /// <strong>Note: </strong>If you're not receiving input events, make sure
  /// you register for the event classes you want by calling
  /// <code>RequestInputEvents</code> or
  /// <code>RequestFilteringInputEvents</code>. If you're still not receiving
  /// keyboard input events, make sure you're returning true (or using a
  /// non-filtered event handler) for mouse events. Otherwise, the instance will
  /// not receive focus and keyboard events will not be sent.
  ///
  /// Refer to <code>RequestInputEvents</code> and
  /// <code>RequestFilteringInputEvents</code> for further information.
  ///
  /// @param[in] event The event to handle.
  ///
  /// @return true if the event was handled, false if not. If you have
  /// registered to filter this class of events by calling
  /// <code>RequestFilteringInputEvents</code>, and you return false,
  /// the event will be forwarded to the page (and eventually the browser)
  /// for the default handling. For non-filtered events, the return value
  /// will be ignored.
  virtual bool HandleInputEvent(const pp::InputEvent& event);

  /// HandleDocumentLoad() is called after Init() for a full-frame
  /// instance that was instantiated based on the MIME type of a DOMWindow
  /// navigation. This situation only applies to modules that are
  /// pre-registered to handle certain MIME types. If you haven't specifically
  /// registered to handle a MIME type or aren't positive this applies to you,
  /// your implementation of this function can just return false.
  ///
  /// The given url_loader corresponds to a <code>URLLoader</code> object that
  /// is already opened. Its response headers may be queried using
  /// GetResponseInfo(). If you want to use the <code>URLLoader</code> to read
  /// data, you will need to save a copy of it or the underlying resource will
  /// be freed when this function returns and the load will be canceled.
  ///
  /// This method returns false if the module cannot handle the data. In
  /// response to this method, the module should call ReadResponseBody() to read
  /// the incoming data.
  ///
  /// @param[in] url_loader An open <code>URLLoader</code> instance.
  ///
  /// @return true if the data was handled, false otherwise.
  virtual bool HandleDocumentLoad(const URLLoader& url_loader);

  /// HandleMessage() is a function that the browser calls when PostMessage()
  /// is invoked on the DOM element for the instance in JavaScript. Note
  /// that PostMessage() in the JavaScript interface is asynchronous, meaning
  /// JavaScript execution will not be blocked while HandleMessage() is
  /// processing the message.
  ///
  /// When converting JavaScript arrays, any object properties whose name
  /// is not an array index are ignored. When passing arrays and objects, the
  /// entire reference graph will be converted and transferred. If the reference
  /// graph has cycles, the message will not be sent and an error will be logged
  /// to the console.
  ///
  /// <strong>Example:</strong>
  ///
  /// The following JavaScript code invokes <code>HandleMessage</code>, passing
  /// the instance on which it was invoked, with <code>message</code> being a
  /// string <code>Var</code> containing "Hello world!"
  ///
  /// @code{.html}
  ///
  /// <body>
  ///   <object id="plugin"
  ///           type="application/x-ppapi-postMessage-example"/>
  ///   <script type="text/javascript">
  ///     document.getElementById('plugin').postMessage("Hello world!");
  ///   </script>
  /// </body>
  ///
  /// @endcode
  ///
  /// Refer to PostMessage() for sending messages to JavaScript.
  ///
  /// @param[in] message A <code>Var</code> which has been converted from a
  /// JavaScript value. JavaScript array/object types are supported from Chrome
  /// M29 onward. All JavaScript values are copied when passing them to the
  /// plugin.
  virtual void HandleMessage(const Var& message);

  /// @}

  /// @{
  /// @name PPB_Instance methods for querying the browser:

  /// BindGraphics() binds the given graphics as the current display surface.
  /// The contents of this device is what will be displayed in the instance's
  /// area on the web page. The device must be a 2D or a 3D device.
  ///
  /// You can pass an <code>is_null()</code> (default constructed) Graphics2D
  /// as the device parameter to unbind all devices from the given instance.
  /// The instance will then appear transparent. Re-binding the same device
  /// will return <code>true</code> and will do nothing.
  ///
  /// Any previously-bound device will be released. It is an error to bind
  /// a device when it is already bound to another instance. If you want
  /// to move a device between instances, first unbind it from the old one, and
  /// then rebind it to the new one.
  ///
  /// Binding a device will invalidate that portion of the web page to flush the
  /// contents of the new device to the screen.
  ///
  /// @param[in] graphics A <code>Graphics2D</code> to bind.
  ///
  /// @return true if bind was successful or false if the device was not the
  /// correct type. On success, a reference to the device will be held by the
  /// instance, so the caller can release its reference if it chooses.
  bool BindGraphics(const Graphics2D& graphics);

  /// Binds the given Graphics3D as the current display surface.
  /// Refer to <code>BindGraphics(const Graphics2D& graphics)</code> for
  /// further information.
  ///
  /// @param[in] graphics A <code>Graphics3D</code> to bind.
  ///
  /// @return true if bind was successful or false if the device was not the
  /// correct type. On success, a reference to the device will be held by the
  /// instance, so the caller can release its reference if it chooses.
  bool BindGraphics(const Graphics3D& graphics);

  /// IsFullFrame() determines if the instance is full-frame (repr).
  /// Such an instance represents the entire document in a frame rather than an
  /// embedded resource. This can happen if the user does a top-level
  /// navigation or the page specifies an iframe to a resource with a MIME
  /// type registered by the module.
  ///
  /// @return true if the instance is full-frame, false if not.
  bool IsFullFrame();

  /// RequestInputEvents() requests that input events corresponding to the
  /// given input events are delivered to the instance.
  ///
  /// By default, no input events are delivered. Call this function with the
  /// classes of events you are interested in to have them be delivered to
  /// the instance. Calling this function will override any previous setting for
  /// each specified class of input events (for example, if you previously
  /// called RequestFilteringInputEvents(), this function will set those events
  /// to non-filtering mode).
  ///
  /// Input events may have high overhead, so you should only request input
  /// events that your plugin will actually handle. For example, the browser may
  /// do optimizations for scroll or touch events that can be processed
  /// substantially faster if it knows there are no non-default receivers for
  /// that message. Requesting that such messages be delivered, even if they are
  /// processed very quickly, may have a noticeable effect on the performance of
  /// the page.
  ///
  /// When requesting input events through this function, the events will be
  /// delivered and <em>not</em> bubbled to the page. This means that even if
  /// you aren't interested in the message, no other parts of the page will get
  /// the message.
  ///
  /// <strong>Example:</strong>
  ///
  /// @code
  ///   RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
  ///   RequestFilteringInputEvents(
  ///       PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_KEYBOARD);
  ///
  /// @endcode
  ///
  /// @param event_classes A combination of flags from
  /// <code>PP_InputEvent_Class</code> that identifies the classes of events
  /// the instance is requesting. The flags are combined by logically ORing
  /// their values.
  ///
  /// @return <code>PP_OK</code> if the operation succeeded,
  /// <code>PP_ERROR_BADARGUMENT</code> if instance is invalid, or
  /// <code>PP_ERROR_NOTSUPPORTED</code> if one of the event class bits were
  /// illegal. In the case of an invalid bit, all valid bits will be applied
  /// and only the illegal bits will be ignored.
  int32_t RequestInputEvents(uint32_t event_classes);

  /// RequestFilteringInputEvents() requests that input events corresponding
  /// to the given input events are delivered to the instance for filtering.
  ///
  /// By default, no input events are delivered. In most cases you would
  /// register to receive events by calling RequestInputEvents(). In some cases,
  /// however, you may wish to filter events such that they can be bubbled up
  /// to the DOM. In this case, register for those classes of events using
  /// this function instead of RequestInputEvents(). Keyboard events must always
  /// be registered in filtering mode.
  ///
  /// Filtering input events requires significantly more overhead than just
  /// delivering them to the instance. As such, you should only request
  /// filtering in those cases where it's absolutely necessary. The reason is
  /// that it requires the browser to stop and block for the instance to handle
  /// the input event, rather than sending the input event asynchronously. This
  /// can have significant overhead.
  ///
  /// <strong>Example:</strong>
  ///
  /// @code
  ///
  ///   RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
  ///   RequestFilteringInputEvents(
  ///       PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_KEYBOARD);
  ///
  /// @endcode
  ///
  /// @param event_classes A combination of flags from
  /// <code>PP_InputEvent_Class</code> that identifies the classes of events
  /// the instance is requesting. The flags are combined by logically ORing
  /// their values.
  ///
  /// @return <code>PP_OK</code> if the operation succeeded,
  /// <code>PP_ERROR_BADARGUMENT</code> if instance is invalid, or
  /// <code>PP_ERROR_NOTSUPPORTED</code> if one of the event class bits were
  /// illegal. In the case of an invalid bit, all valid bits will be applied
  /// and only the illegal bits will be ignored.
  int32_t RequestFilteringInputEvents(uint32_t event_classes);

  /// ClearInputEventRequest() requests that input events corresponding to the
  /// given input classes no longer be delivered to the instance.
  ///
  /// By default, no input events are delivered. If you have previously
  /// requested input events using RequestInputEvents() or
  /// RequestFilteringInputEvents(), this function will unregister handling
  /// for the given instance. This will allow greater browser performance for
  /// those events.
  ///
  /// <strong>Note: </strong> You may still get some input events after
  /// clearing the flag if they were dispatched before the request was cleared.
  /// For example, if there are 3 mouse move events waiting to be delivered,
  /// and you clear the mouse event class during the processing of the first
  /// one, you'll still receive the next two. You just won't get more events
  /// generated.
  ///
  /// @param[in] event_classes A combination of flags from
  /// <code>PP_InputEvent_Class</code> that identifies the classes of events the
  /// instance is no longer interested in.
  void ClearInputEventRequest(uint32_t event_classes);

  /// PostMessage() asynchronously invokes any listeners for message events on
  /// the DOM element for the given instance. A call to PostMessage() will
  /// not block while the message is processed.
  ///
  /// <strong>Example:</strong>
  ///
  /// @code{.html}
  ///
  /// <body>
  ///   <object id="plugin"
  ///           type="application/x-ppapi-postMessage-example"/>
  ///   <script type="text/javascript">
  ///     var plugin = document.getElementById('plugin');
  ///     plugin.addEventListener("message",
  ///                             function(message) { alert(message.data); },
  ///                             false);
  ///   </script>
  /// </body>
  ///
  /// @endcode
  ///
  /// The instance then invokes PostMessage() as follows:
  ///
  /// @code
  ///
  ///  PostMessage(pp::Var("Hello world!"));
  ///
  /// @endcode
  ///
  /// The browser will pop-up an alert saying "Hello world!"
  ///
  /// When passing array or dictionary <code>PP_Var</code>s, the entire
  /// reference graph will be converted and transferred. If the reference graph
  /// has cycles, the message will not be sent and an error will be logged to
  /// the console.
  ///
  /// Listeners for message events in JavaScript code will receive an object
  /// conforming to the HTML 5 <code>MessageEvent</code> interface.
  /// Specifically, the value of message will be contained as a property called
  /// data in the received <code>MessageEvent</code>.
  ///
  /// This messaging system is similar to the system used for listening for
  /// messages from Web Workers. Refer to
  /// <code>http://www.whatwg.org/specs/web-workers/current-work/</code> for
  /// further information.
  ///
  /// Refer to HandleMessage() for receiving events from JavaScript.
  ///
  /// @param[in] message A <code>Var</code> containing the data to be sent to
  /// JavaScript. Message can have a numeric, boolean, or string value.
  /// Array/Dictionary types are supported from Chrome M29 onward.
  /// All var types are copied when passing them to JavaScript.
  void PostMessage(const Var& message);

  /// @}

  /// @{
  /// @name PPB_Console methods for logging to the console:

  /// Logs the given message to the JavaScript console associated with the
  /// given plugin instance with the given logging level. The name of the plugin
  /// issuing the log message will be automatically prepended to the message.
  /// The value may be any type of Var.
  void LogToConsole(PP_LogLevel level, const Var& value);

  /// Logs a message to the console with the given source information rather
  /// than using the internal PPAPI plugin name. The name must be a string var.
  ///
  /// The regular log function will automatically prepend the name of your
  /// plugin to the message as the "source" of the message. Some plugins may
  /// wish to override this. For example, if your plugin is a Python
  /// interpreter, you would want log messages to contain the source .py file
  /// doing the log statement rather than have "python" show up in the console.
  void LogToConsoleWithSource(PP_LogLevel level,
                              const Var& source,
                              const Var& value);

  /// @}

  /// AddPerInstanceObject() associates an instance with an interface,
  /// creating an object.
  ///
  /// Many optional interfaces are associated with a plugin instance. For
  /// example, the find in PPP_Find interface receives updates on a per-instance
  /// basis. This "per-instance" tracking allows such objects to associate
  /// themselves with an instance as "the" handler for that interface name.
  ///
  /// In the case of the find example, the find object registers with its
  /// associated instance in its constructor and unregisters in its destructor.
  /// Then whenever it gets updates with a PP_Instance parameter, it can
  /// map back to the find object corresponding to that given PP_Instance by
  /// calling GetPerInstanceObject.
  ///
  /// This lookup is done on a per-interface-name basis. This means you can
  /// only have one object of a given interface name associated with an
  /// instance.
  ///
  /// If you are adding a handler for an additional interface, be sure to
  /// register with the module (AddPluginInterface) for your interface name to
  /// get the C calls in the first place.
  ///
  /// Refer to RemovePerInstanceObject() and GetPerInstanceObject() for further
  /// information.
  ///
  /// @param[in] interface_name The name of the interface to associate with the
  /// instance
  /// @param[in] object
  void AddPerInstanceObject(const std::string& interface_name, void* object);

  // {PENDING: summarize Remove method here}
  ///
  /// Refer to AddPerInstanceObject() for further information.
  ///
  /// @param[in] interface_name The name of the interface to associate with the
  /// instance
  /// @param[in] object
  void RemovePerInstanceObject(const std::string& interface_name, void* object);

  /// Static version of AddPerInstanceObject that takes an InstanceHandle. As
  /// with all other instance functions, this must only be called on the main
  /// thread.
  static void RemovePerInstanceObject(const InstanceHandle& instance,
                                      const std::string& interface_name,
                                      void* object);

  /// Look up an object previously associated with an instance. Returns NULL
  /// if the instance is invalid or there is no object for the given interface
  /// name on the instance.
  ///
  /// Refer to AddPerInstanceObject() for further information.
  ///
  /// @param[in] instance
  /// @param[in] interface_name The name of the interface to associate with the
  /// instance.
  static void* GetPerInstanceObject(PP_Instance instance,
                                    const std::string& interface_name);

 private:
  PP_Instance pp_instance_;

  typedef std::map<std::string, void*> InterfaceNameToObjectMap;
  InterfaceNameToObjectMap interface_name_to_objects_;
};

}  // namespace pp

#endif  // PPAPI_CPP_INSTANCE_H_
