// 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.

#include "content/renderer/browser_plugin/browser_plugin_manager.h"

#include <memory>

#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/frame_messages.h"
#include "content/public/renderer/browser_plugin_delegate.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/render_thread_impl.h"
#include "ipc/ipc_message_macros.h"

namespace content {

// static
BrowserPluginManager* BrowserPluginManager::Get() {
  if (!RenderThreadImpl::current())
    return nullptr;
  return RenderThreadImpl::current()->browser_plugin_manager();
}

BrowserPluginManager::BrowserPluginManager() {
}

BrowserPluginManager::~BrowserPluginManager() {
}

void BrowserPluginManager::AddBrowserPlugin(
    int browser_plugin_instance_id,
    BrowserPlugin* browser_plugin) {
  instances_.AddWithID(browser_plugin, browser_plugin_instance_id);
}

void BrowserPluginManager::RemoveBrowserPlugin(int browser_plugin_instance_id) {
  instances_.Remove(browser_plugin_instance_id);
}

BrowserPlugin* BrowserPluginManager::GetBrowserPlugin(
    int browser_plugin_instance_id) const {
  return instances_.Lookup(browser_plugin_instance_id);
}

int BrowserPluginManager::GetNextInstanceID() {
  return RenderThreadImpl::current()->GenerateRoutingID();
}

void BrowserPluginManager::UpdateFocusState() {
  IDMap<BrowserPlugin>::iterator iter(&instances_);
  while (!iter.IsAtEnd()) {
    iter.GetCurrentValue()->UpdateGuestFocusState(blink::WebFocusTypeNone);
    iter.Advance();
  }
}

void BrowserPluginManager::Attach(int browser_plugin_instance_id) {
  BrowserPlugin* plugin = GetBrowserPlugin(browser_plugin_instance_id);
  if (plugin)
    plugin->Attach();
}

void BrowserPluginManager::Detach(int browser_plugin_instance_id) {
  BrowserPlugin* plugin = GetBrowserPlugin(browser_plugin_instance_id);
  if (plugin)
    plugin->Detach();
}

BrowserPlugin* BrowserPluginManager::CreateBrowserPlugin(
    RenderFrame* render_frame,
    const base::WeakPtr<BrowserPluginDelegate>& delegate) {
  return new BrowserPlugin(render_frame, delegate);
}

void BrowserPluginManager::DidCommitCompositorFrame(
    int render_frame_routing_id) {
  IDMap<BrowserPlugin>::iterator iter(&instances_);
  while (!iter.IsAtEnd()) {
    if (iter.GetCurrentValue()->render_frame_routing_id() ==
        render_frame_routing_id) {
      iter.GetCurrentValue()->DidCommitCompositorFrame();
    }
    iter.Advance();
  }
}

bool BrowserPluginManager::OnControlMessageReceived(
    const IPC::Message& message) {
  if (!BrowserPlugin::ShouldForwardToBrowserPlugin(message))
    return false;

  int browser_plugin_instance_id = browser_plugin::kInstanceIDNone;
  // All allowed messages must have |browser_plugin_instance_id| as their
  // first parameter.
  base::PickleIterator iter(message);
  bool success = iter.ReadInt(&browser_plugin_instance_id);
  DCHECK(success);
  BrowserPlugin* plugin = GetBrowserPlugin(browser_plugin_instance_id);
  return plugin && plugin->OnMessageReceived(message);
}

bool BrowserPluginManager::Send(IPC::Message* msg) {
  return RenderThreadImpl::current()->Send(msg);
}

}  // namespace content
