// 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 "ppapi/proxy/ppp_input_event_proxy.h"

#include "ppapi/c/ppp_input_event.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppb_input_event_shared.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_input_event_api.h"

using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_InputEvent_API;

namespace ppapi {
namespace proxy {

namespace {

#if !defined(OS_NACL)
PP_Bool HandleInputEvent(PP_Instance instance, PP_Resource input_event) {
  EnterResourceNoLock<PPB_InputEvent_API> enter(input_event, false);
  if (enter.failed()) {
    NOTREACHED();
    return PP_FALSE;
  }
  const InputEventData& data = enter.object()->GetInputEventData();
  HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
  if (!dispatcher) {
    NOTREACHED();
    return PP_FALSE;
  }

  // Need to send different messages depending on whether filtering is needed.
  PP_Bool result = PP_FALSE;
  if (data.is_filtered) {
    dispatcher->Send(new PpapiMsg_PPPInputEvent_HandleFilteredInputEvent(
        API_ID_PPP_INPUT_EVENT, instance, data, &result));
  } else {
    dispatcher->Send(new PpapiMsg_PPPInputEvent_HandleInputEvent(
        API_ID_PPP_INPUT_EVENT, instance, data));
  }
  return result;
}

static const PPP_InputEvent input_event_interface = {
  &HandleInputEvent
};
#else
// The NaCl plugin doesn't need the host side interface - stub it out.
static const PPP_InputEvent input_event_interface = {};
#endif  // !defined(OS_NACL)

}  // namespace

PPP_InputEvent_Proxy::PPP_InputEvent_Proxy(Dispatcher* dispatcher)
    : InterfaceProxy(dispatcher),
      ppp_input_event_impl_(NULL) {
  if (dispatcher->IsPlugin()) {
    ppp_input_event_impl_ = static_cast<const PPP_InputEvent*>(
        dispatcher->local_get_interface()(PPP_INPUT_EVENT_INTERFACE));
  }
}

PPP_InputEvent_Proxy::~PPP_InputEvent_Proxy() {
}

// static
const PPP_InputEvent* PPP_InputEvent_Proxy::GetProxyInterface() {
  return &input_event_interface;
}

bool PPP_InputEvent_Proxy::OnMessageReceived(const IPC::Message& msg) {
  if (!dispatcher()->IsPlugin())
    return false;

  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(PPP_InputEvent_Proxy, msg)
    IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleInputEvent,
                        OnMsgHandleInputEvent)
    IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent,
                        OnMsgHandleFilteredInputEvent)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void PPP_InputEvent_Proxy::OnMsgHandleInputEvent(PP_Instance instance,
                                                 const InputEventData& data) {
  scoped_refptr<PPB_InputEvent_Shared> resource(new PPB_InputEvent_Shared(
      OBJECT_IS_PROXY, instance, data));
  CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent,
                    instance,
                    resource->pp_resource());
}

void PPP_InputEvent_Proxy::OnMsgHandleFilteredInputEvent(
    PP_Instance instance,
    const InputEventData& data,
    PP_Bool* result) {
  scoped_refptr<PPB_InputEvent_Shared> resource(new PPB_InputEvent_Shared(
      OBJECT_IS_PROXY, instance, data));
  *result = CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent,
                              instance,
                              resource->pp_resource());
}

}  // namespace proxy
}  // namespace ppapi
