// 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/graphics_2d_resource.h"

#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_point.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_size.h"
#include "ppapi/c/ppb_graphics_2d.h"
#include "ppapi/proxy/dispatch_reply_message.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"

namespace ppapi {
namespace proxy {

Graphics2DResource::Graphics2DResource(Connection connection,
                                       PP_Instance instance,
                                       const PP_Size& size,
                                       PP_Bool is_always_opaque)
    : PluginResource(connection, instance),
      size_(size),
      is_always_opaque_(is_always_opaque),
      scale_(1.0f) {
  // These checks are copied from PPB_ImageData_Impl::Init to make tests passed.
  // Let's remove/refactor this when start to refactor ImageData.
  bool bad_args = size.width <= 0 || size.height <= 0 ||
      static_cast<int64>(size.width) * static_cast<int64>(size.height) >=
          std::numeric_limits<int32>::max() / 4;
  if (!bad_args && !sent_create_to_renderer()) {
    SendCreate(RENDERER,
        PpapiHostMsg_Graphics2D_Create(size, is_always_opaque));
  }
}

Graphics2DResource::~Graphics2DResource() {
}

PP_Bool Graphics2DResource::Describe(PP_Size* size, PP_Bool* is_always_opaque) {
  *size = size_;
  *is_always_opaque = is_always_opaque_;
  return PP_TRUE;
}

thunk::PPB_Graphics2D_API* Graphics2DResource::AsPPB_Graphics2D_API() {
  return this;
}

void Graphics2DResource::PaintImageData(PP_Resource image_data,
                                        const PP_Point* top_left,
                                        const PP_Rect* src_rect) {
  Resource* image_object =
      PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data);
  if (!image_object || pp_instance() != image_object->pp_instance()) {
    Log(PP_LOGLEVEL_ERROR,
        "Graphics2DResource.PaintImageData: Bad image resource.");
    return;
  }

  PP_Rect dummy;
  memset(&dummy, 0, sizeof(PP_Rect));
  Post(RENDERER, PpapiHostMsg_Graphics2D_PaintImageData(
      image_object->host_resource(), *top_left,
      !!src_rect, src_rect ? *src_rect : dummy));
}

void Graphics2DResource::Scroll(const PP_Rect* clip_rect,
                                const PP_Point* amount) {
  PP_Rect dummy;
  memset(&dummy, 0, sizeof(PP_Rect));
  Post(RENDERER, PpapiHostMsg_Graphics2D_Scroll(
      !!clip_rect, clip_rect ? *clip_rect : dummy, *amount));
}

void Graphics2DResource::ReplaceContents(PP_Resource image_data) {
  thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_image(
      image_data, true);
  if (enter_image.failed())
    return;

  // Check that the PP_Instance matches.
  Resource* image_object =
      PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data);
  if (!image_object || pp_instance() != image_object->pp_instance()) {
    Log(PP_LOGLEVEL_ERROR,
        "Graphics2DResource.PaintImageData: Bad image resource.");
    return;
  }
  enter_image.object()->SetIsCandidateForReuse();

  Post(RENDERER, PpapiHostMsg_Graphics2D_ReplaceContents(
      image_object->host_resource()));
}

PP_Bool Graphics2DResource::SetScale(float scale) {
  if (scale <= 0.0f)
    return PP_FALSE;
  Post(RENDERER, PpapiHostMsg_Graphics2D_Dev_SetScale(scale));
  scale_ = scale;
  return PP_TRUE;
}

float Graphics2DResource::GetScale() {
  return scale_;
}

int32_t Graphics2DResource::Flush(scoped_refptr<TrackedCallback> callback) {
  // If host is not even created, return failure immediately.  This can happen
  // when failed to initialize (in constructor).
  if (!sent_create_to_renderer())
    return PP_ERROR_FAILED;

  if (TrackedCallback::IsPending(current_flush_callback_))
    return PP_ERROR_INPROGRESS;  // Can't have >1 flush pending.
  current_flush_callback_ = callback;

  Call<PpapiPluginMsg_Graphics2D_FlushAck>(
      RENDERER,
      PpapiHostMsg_Graphics2D_Flush(),
      base::Bind(&Graphics2DResource::OnPluginMsgFlushACK, this));
  return PP_OK_COMPLETIONPENDING;
}

bool Graphics2DResource::ReadImageData(PP_Resource image,
                                       const PP_Point* top_left) {
  if (!top_left)
    return false;
  int32_t result = SyncCall<PpapiPluginMsg_Graphics2D_ReadImageDataAck>(
      RENDERER,
      PpapiHostMsg_Graphics2D_ReadImageData(image, *top_left));
  return result == PP_OK;
}

void Graphics2DResource::OnPluginMsgFlushACK(
    const ResourceMessageReplyParams& params) {
  current_flush_callback_->Run(params.result());
}

}  // namespace proxy
}  // namespace ppapi
