// Copyright (c) 2009 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 CHROME_FRAME_CHROME_FRAME_NPAPI_H_
#define CHROME_FRAME_CHROME_FRAME_NPAPI_H_

#include <atlbase.h>
#include <atlwin.h>
#include <string>

#include "chrome_frame/chrome_frame_automation.h"
#include "chrome_frame/chrome_frame_plugin.h"
#include "chrome_frame/np_browser_functions.h"
#include "chrome_frame/np_event_listener.h"
#include "chrome_frame/np_proxy_service.h"
#include "chrome_frame/npapi_url_request.h"

class MessageLoop;
class nsICookieService;
class nsIURI;

// ChromeFrameNPAPI: Implementation of the NPAPI plugin, which is responsible
// for hosting a chrome frame, i.e. an iframe like widget which hosts the the
// chrome window. This object delegates to Chrome.exe  (via the Chrome
// IPC-based automation mechanism) for the actual rendering.
class ChromeFrameNPAPI
    : public CWindowImpl<ChromeFrameNPAPI>,
      public ChromeFramePlugin<ChromeFrameNPAPI>,
      public NpEventDelegate {
 public:
  typedef ChromeFramePlugin<ChromeFrameNPAPI> Base;

  // NPObject structure which is exposed by us.
  struct ChromeFrameNPObject : public NPObject {
    NPP npp;
    ChromeFrameNPAPI* chrome_frame_plugin_instance;
  };

  typedef enum {
    PLUGIN_PROPERTY_VERSION,
    PLUGIN_PROPERTY_SRC,
    PLUGIN_PROPERTY_ONLOAD,
    PLUGIN_PROPERTY_ONERROR,
    PLUGIN_PROPERTY_ONMESSAGE,
    PLUGIN_PROPERTY_READYSTATE,
    PLUGIN_PROPERTY_ONPRIVATEMESSAGE,
    PLUGIN_PROPERTY_USECHROMENETWORK,
    PLUGIN_PROPERTY_COUNT  // must be last
  } PluginPropertyId;

  static const int kWmSwitchFocusToChromeFrame = WM_APP + 0x100;

  static NPClass plugin_class_;
  static NPClass* PluginClass() {
    return &plugin_class_;
  }

  ChromeFrameNPAPI();
  ~ChromeFrameNPAPI();

  bool Initialize(NPMIMEType mime_type, NPP instance, uint16 mode,
                  int16 argc, char* argn[], char* argv[]);
  void Uninitialize();

  bool SetWindow(NPWindow* window_info);
  void UrlNotify(const char* url, NPReason reason, void* notify_data);
  NPError NewStream(NPMIMEType type, NPStream* stream, NPBool seekable,
                    uint16* stream_type);
  int32 WriteReady(NPStream* stream);
  int32 Write(NPStream* stream, int32 offset, int32 len, void* buffer);
  NPError DestroyStream(NPStream* stream, NPReason reason);

  void Print(NPPrint* print_info);

  // NPObject functions, which ensure that the plugin object is scriptable.
  static bool HasMethod(NPObject* obj, NPIdentifier name);
  static bool Invoke(NPObject* header, NPIdentifier name,
                     const NPVariant* args, uint32_t arg_count,
                     NPVariant* result);
  static NPObject* AllocateObject(NPP instance, NPClass* class_name);
  static void DeallocateObject(NPObject* header);

  // Called by the scripting environment when the native code is shutdown.
  // Any attempt to message a NPObject instance after the invalidate callback
  // has been called will result in undefined behavior, even if the native code
  // is still retaining those NPObject instances.
  static void Invalidate(NPObject* header);

  // The following functions need to be implemented to ensure that FF3
  // invokes methods on the plugin. If these methods are not implemented
  // then invokes on the plugin NPObject from the script fail with a
  // bad NPObject error.
  static bool HasProperty(NPObject* obj, NPIdentifier name);
  static bool GetProperty(NPObject* obj, NPIdentifier name, NPVariant *variant);
  static bool SetProperty(NPObject* obj, NPIdentifier name,
                          const NPVariant *variant);

  // Returns the ChromeFrameNPAPI object pointer from the NPP instance structure
  // passed in by the browser.
  static ChromeFrameNPAPI* ChromeFrameInstanceFromPluginInstance(NPP instance);

  // Returns the ChromeFrameNPAPI object pointer from the NPObject structure
  // which represents our plugin class.
  static ChromeFrameNPAPI* ChromeFrameInstanceFromNPObject(void* object);

BEGIN_MSG_MAP(ChromeFrameNPAPI)
  MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  CHAIN_MSG_MAP(Base)
END_MSG_MAP()

  LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam,
                     BOOL& handled);  // NO_LINT

  // Implementation of NpEventDelegate
  virtual void OnEvent(const char* event_name);

  void OnFocus();
  void OnBlur();

  // Implementation of SetProperty, public to allow unittesting.
  bool SetProperty(NPIdentifier name, const NPVariant *variant);
  // Implementation of GetProperty, public to allow unittesting.
  bool GetProperty(NPIdentifier name, NPVariant *variant);

  // Initialize string->identifier mapping, public to allow unittesting.
  static void InitializeIdentifiers();

  bool PreProcessContextMenu(HMENU menu);
  bool HandleContextMenuCommand(UINT cmd, const IPC::ContextMenuParams& params);
 protected:
  // Handler for accelerator messages passed on from the hosted chrome
  // instance.
  virtual void OnAcceleratorPressed(int tab_handle, const MSG& accel_message);
  virtual void OnTabbedOut(int tab_handle, bool reverse);
  virtual void OnOpenURL(int tab_handle, const GURL& url,
                         const GURL& referrer, int open_disposition);
  virtual void OnLoad(int tab_handle, const GURL& url);
  virtual void OnMessageFromChromeFrame(int tab_handle,
                                        const std::string& message,
                                        const std::string& origin,
                                        const std::string& target);
  // ChromeFrameDelegate overrides
  virtual void OnLoadFailed(int error_code, const std::string& url);
  virtual void OnAutomationServerReady();
  virtual void OnAutomationServerLaunchFailed(
      AutomationLaunchResult reason, const std::string& server_version);
  virtual void OnExtensionInstalled(const FilePath& path,
      void* user_data, AutomationMsg_ExtensionResponseValues response);
  virtual void OnGetEnabledExtensionsComplete(
      void* user_data,
      const std::vector<FilePath>& extension_directories);

 private:
  void SubscribeToFocusEvents();
  void UnsubscribeFromFocusEvents();

  // Equivalent of:
  // event = window.document.createEvent("Event");
  // event.initEvent(type, bubbles, cancelable);
  // and then returns the event object.
  bool CreateEvent(const std::string& type, bool bubbles, bool cancelable,
                   NPObject** basic_event);

  // Creates and initializes an event object of type "message".
  // Used for postMessage.
  bool CreateMessageEvent(bool bubbles, bool cancelable,
      const std::string& data, const std::string& origin,
      NPObject** message_event);

  // Calls chrome_frame.dispatchEvent to fire events to event listeners.
  void DispatchEvent(NPObject* event);

  // Returns a pointer to the <object> element in the page that
  // hosts the plugin.  Note that this is the parent element of the <embed>
  // element.  The <embed> element doesn't support some of the events that
  // we require, so we use the object element for receiving events.
  bool GetObjectElement(nsIDOMElement** element);

  // Prototype for all methods that can be invoked from script.
  typedef bool (ChromeFrameNPAPI::*PluginMethod)(NPObject* npobject,
                                                 const NPVariant* args,
                                                 uint32_t arg_count,
                                                 NPVariant* result);

  // Implementations of scriptable methods.

  bool NavigateToURL(const NPVariant* args, uint32_t arg_count,
                     NPVariant* result);

  bool postMessage(NPObject* npobject, const NPVariant* args,
                   uint32_t arg_count, NPVariant* result);

  // This method is only available when the control is in privileged mode.
  bool postPrivateMessage(NPObject* npobject, const NPVariant* args,
                          uint32_t arg_count, NPVariant* result);

  // This method is only available when the control is in privileged mode.
  bool installExtension(NPObject* npobject, const NPVariant* args,
                        uint32_t arg_count, NPVariant* result);

  // This method is only available when the control is in privileged mode.
  bool loadExtension(NPObject* npobject, const NPVariant* args,
                     uint32_t arg_count, NPVariant* result);

  // This method is only available when the control is in privileged mode.
  bool enableExtensionAutomation(NPObject* npobject, const NPVariant* args,
                                 uint32_t arg_count, NPVariant* result);

  // This method is only available when the control is in privileged mode.
  bool getEnabledExtensions(NPObject* npobject, const NPVariant* args,
                            uint32_t arg_count, NPVariant* result);

  // Pointers to method implementations.
  static PluginMethod plugin_methods_[];

  // NPObject method ids exposed by the plugin.
  static NPIdentifier plugin_method_identifiers_[];

  // NPObject method names exposed by the plugin.
  static const NPUTF8* plugin_method_identifier_names_[];

  // NPObject property ids exposed by the plugin.
  static NPIdentifier plugin_property_identifiers_[];

  // NPObject property names exposed by the plugin.
  static const NPUTF8*
      plugin_property_identifier_names_[];

  virtual void OnFinalMessage(HWND window);

  // Helper function to invoke a function on a NPObject.
  bool InvokeDefault(NPObject* object, const std::string& param,
                     NPVariant* result);

  bool InvokeDefault(NPObject* object, const NPVariant& param,
                     NPVariant* result);

  bool InvokeDefault(NPObject* object, unsigned param_count,
                     const NPVariant* params, NPVariant* result);

  // Helper function to convert javascript code to a NPObject we can
  // invoke on.
  virtual NPObject* JavascriptToNPObject(const std::string& function_name);

  // Helper function to execute a script.
  // Returns S_OK on success.
  bool ExecuteScript(const std::string& script, NPVariant* result);

  // Returns true if the script passed in is a valid function in the DOM.
  bool IsValidJavascriptFunction(const std::string& script);

  // Converts the data parameter to an NPVariant and forwards the call to the
  // other FireEvent method.
  void FireEvent(const std::string& event_type, const std::string& data);

  // Creates an event object, assigns the data parameter to a |data| property
  // on the event object and then calls DispatchEvent to fire the event to
  // listeners.  event_type is the name of the event being fired.
  void FireEvent(const std::string& event_type, const NPVariant& data);

  // Returns a new prefs service. Virtual to allow overriding in unittests.
  virtual NpProxyService* CreatePrefService();

  // Returns our associated windows' location.
  virtual std::string GetLocation();

  // Returns true iff we're successfully able to query for the browser's
  // incognito mode, and the browser returns true.
  virtual bool GetBrowserIncognitoMode();

  // Returns the window script object for the page.
  // This function will cache the window object to avoid calling
  // npapi::GetValue which can cause problems in Opera.
  NPObject* GetWindowObject() const;

  virtual void SetReadyState(READYSTATE new_state) {
    ready_state_ = new_state;
    NPVariant var;
    INT32_TO_NPVARIANT(ready_state_, var);
    FireEvent("readystatechanged", var);
  }

  // Host function to compile-time asserts over members of this class.
  static void CompileAsserts();

  static LRESULT CALLBACK DropKillFocusHook(int code, WPARAM wparam,
                                            LPARAM lparam);  // NO_LINT

  // The plugins opaque instance handle
  NPP instance_;

  // The plugin instantiation mode (NP_FULL or NP_EMBED)
  int16 mode_;
  // The plugins mime type.
  std::string mime_type_;

  // Set to true if we need a full page plugin.
  bool force_full_page_plugin_;

  scoped_refptr<NpProxyService> pref_service_;

  // Used to receive focus and blur events from the object element
  // that hosts the plugin.
  scoped_refptr<NpEventListener> focus_listener_;

  // In some cases the IPC channel proxy object is instantiated on the UI
  // thread in FF. It then tries to use the IPC logger, which relies on
  // the message loop being around. Declaring a dummy message loop
  // is a hack to get around this. Eventually the automation code needs to
  // be fixed to ensure that the channel proxy always gets created on a thread
  // with a message loop.
  static MessageLoop* message_loop_;
  static int instance_count_;

  // The following members contain the NPObject pointers representing the
  // onload/onerror/onmessage handlers on the page.
  ScopedNpObject<NPObject> onerror_handler_;
  ScopedNpObject<NPObject> onmessage_handler_;
  ScopedNpObject<NPObject> onprivatemessage_handler_;

  // As a workaround for a problem in Opera we cache the window object.
  // The problem stems from two things: window messages aren't always removed
  // from the message queue and messages can be pumped inside GetValue.
  // This can cause an infinite recursion of processing the same message
  // repeatedly.
  mutable ScopedNpObject<NPObject> window_object_;

  // Note since 'onload' is a registered event name, the browser will
  // automagically create a code block for the handling code and hook it
  // up to the CF object via addEventListener.
  // See this list of known event types:
  // http://www.w3.org/TR/DOM-Level-3-Events/events.html#Event-types

  READYSTATE ready_state_;


  // Popups are enabled
  bool enabled_popups_;

  // The value of src property keeping the current URL.
  std::string src_;
  // Used to fetch network resources when host network stack is in use.
  NPAPIUrlRequestManager url_fetcher_;

  // Set if we receive a navigation request before initializing Chrome.
  bool navigate_after_initialization_;
};

#endif  // CHROME_FRAME_CHROME_FRAME_NPAPI_H_
