// Copyright (c) 2011 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_DELEGATE_H_
#define CHROME_FRAME_CHROME_FRAME_DELEGATE_H_

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

#include "base/callback.h"
#include "base/file_path.h"
#include "base/location.h"
#include "base/pending_task.h"
#include "base/synchronization/lock.h"
#include "chrome/common/automation_constants.h"
#include "ipc/ipc_message.h"

class GURL;
struct AttachExternalTabParams;
struct AutomationURLRequest;
struct ContextMenuModel;
struct MiniContextMenuParams;
struct NavigationInfo;

namespace net {
class URLRequestStatus;
}

namespace gfx {
class Rect;
}

// A common interface supported by all the browser specific ChromeFrame
// implementations.
class ChromeFrameDelegate {
 public:
  typedef HWND WindowType;

  virtual WindowType GetWindow() const = 0;
  virtual void GetBounds(RECT* bounds) = 0;
  virtual std::string GetDocumentUrl() = 0;
  virtual void OnAutomationServerReady() = 0;
  virtual void OnAutomationServerLaunchFailed(
      AutomationLaunchResult reason, const std::string& server_version) = 0;
  virtual bool OnMessageReceived(const IPC::Message& msg) = 0;
  virtual void OnChannelError() = 0;

  // This remains in interface since we call it if Navigate()
  // returns immediate error.
  virtual void OnLoadFailed(int error_code, const std::string& url) = 0;

  // Returns true if this instance is alive and well for processing automation
  // messages.
  virtual bool IsValid() const = 0;

  // To be called when the top-most window of an application hosting
  // ChromeFrame is moved.
  virtual void OnHostMoved() = 0;

 protected:
  virtual ~ChromeFrameDelegate() {}
};

extern UINT kAutomationServerReady;
extern UINT kMessageFromChromeFrame;

class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
 public:
  virtual WindowType GetWindow() { return NULL; }
  virtual void GetBounds(RECT* bounds) {}
  virtual std::string GetDocumentUrl() { return std::string(); }
  virtual void OnAutomationServerReady() {}
  virtual void OnAutomationServerLaunchFailed(
      AutomationLaunchResult reason, const std::string& server_version) {}
  virtual void OnLoadFailed(int error_code, const std::string& url) {}
  virtual bool OnMessageReceived(const IPC::Message& msg);
  virtual void OnChannelError() {}

  static bool IsTabMessage(const IPC::Message& message);

  virtual bool IsValid() const {
    return true;
  }

  virtual void OnHostMoved() {}

 protected:
  // Protected methods to be overridden.
  virtual void OnNavigationStateChanged(
      int flags, const NavigationInfo& nav_info) {}
  virtual void OnUpdateTargetUrl(const std::wstring& new_target_url) {}
  virtual void OnAcceleratorPressed(const MSG& accel_message) {}
  virtual void OnTabbedOut(bool reverse) {}
  virtual void OnOpenURL(
      const GURL& url, const GURL& referrer, int open_disposition) {}
  virtual void OnDidNavigate(const NavigationInfo& navigation_info) {}
  virtual void OnNavigationFailed(int error_code, const GURL& gurl) {}
  virtual void OnLoad(const GURL& url) {}
  virtual void OnMoveWindow(const gfx::Rect& pos) {}
  virtual void OnMessageFromChromeFrame(const std::string& message,
                                        const std::string& origin,
                                        const std::string& target) {}
  virtual void OnHandleContextMenu(const ContextMenuModel& context_menu_model,
                                   int align_flags,
                                   const MiniContextMenuParams& params) {}
  virtual void OnRequestStart(
      int request_id, const AutomationURLRequest& request) {}
  virtual void OnRequestRead(int request_id, int bytes_to_read) {}
  virtual void OnRequestEnd(int request_id,
                            const net::URLRequestStatus& status) {}
  virtual void OnDownloadRequestInHost(int request_id) {}
  virtual void OnSetCookieAsync(const GURL& url, const std::string& cookie) {}
  virtual void OnAttachExternalTab(
      const AttachExternalTabParams& attach_params) {}
  virtual void OnGoToHistoryEntryOffset(int offset) {}

  virtual void OnGetCookiesFromHost(const GURL& url, int cookie_id) {}
  virtual void OnCloseTab() {}
};

// This interface enables tasks to be marshaled to desired threads.
class TaskMarshaller {  // NOLINT
 public:
  virtual void PostTask(const tracked_objects::Location& from_here,
                        const base::Closure& task) = 0;
};

// T is expected to be something CWindowImpl derived, or at least to have
// PostMessage(UINT, WPARAM) method. Do not forget to CHAIN_MSG_MAP
template <class T> class TaskMarshallerThroughWindowsMessages
    : public TaskMarshaller {
 public:
  TaskMarshallerThroughWindowsMessages() {}
  virtual void PostTask(const tracked_objects::Location& posted_from,
                        const base::Closure& task) OVERRIDE {
    T* this_ptr = static_cast<T*>(this);
    if (this_ptr->IsWindow()) {
      this_ptr->AddRef();
      base::PendingTask* pending_task =
          new base::PendingTask(posted_from, task);
      PushTask(pending_task);
      this_ptr->PostMessage(MSG_EXECUTE_TASK,
                            reinterpret_cast<WPARAM>(pending_task));
    } else {
      DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
    }
  }

 protected:
  ~TaskMarshallerThroughWindowsMessages() {
    DeleteAllPendingTasks();
  }

  void DeleteAllPendingTasks() {
    base::AutoLock lock(lock_);
    DVLOG_IF(1, !pending_tasks_.empty()) << "Destroying "
                                         << pending_tasks_.size()
                                         << " pending tasks";
    while (!pending_tasks_.empty()) {
      base::PendingTask* task = pending_tasks_.front();
      pending_tasks_.pop();
      delete task;
    }
  }

  BEGIN_MSG_MAP(PostMessageMarshaller)
    MESSAGE_HANDLER(MSG_EXECUTE_TASK, ExecuteTask)
  END_MSG_MAP()

 private:
  enum { MSG_EXECUTE_TASK = WM_APP + 6 };
  inline LRESULT ExecuteTask(UINT, WPARAM wparam, LPARAM,
                             BOOL& handled) {  // NOLINT
    base::PendingTask* pending_task =
        reinterpret_cast<base::PendingTask*>(wparam);
    if (pending_task && PopTask(pending_task)) {
      pending_task->task.Run();
      delete pending_task;
    }

    T* this_ptr = static_cast<T*>(this);
    this_ptr->Release();
    return 0;
  }

  inline void PushTask(base::PendingTask* pending_task) {
    base::AutoLock lock(lock_);
    pending_tasks_.push(pending_task);
  }

  // If |pending_task| is front of the queue, removes the task and returns true,
  // otherwise we assume this is an already destroyed task (but Window message
  // had remained in the thread queue).
  inline bool PopTask(base::PendingTask* pending_task) {
    base::AutoLock lock(lock_);
    if (!pending_tasks_.empty() && pending_task == pending_tasks_.front()) {
      pending_tasks_.pop();
      return true;
    }

    return false;
  }

  base::Lock lock_;
  std::queue<base::PendingTask*> pending_tasks_;
};

#endif  // CHROME_FRAME_CHROME_FRAME_DELEGATE_H_
