// Copyright (c) 2010 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 "pdf/pdf.h"

#include <stdint.h>

#if defined(OS_WIN)
#include <windows.h>
#endif

#include "base/command_line.h"
#include "base/logging.h"
#include "pdf/out_of_process_instance.h"
#include "ppapi/c/ppp.h"
#include "ppapi/cpp/private/internal_module.h"
#include "ppapi/cpp/private/pdf.h"
#include "v8/include/v8.h"

namespace chrome_pdf {

namespace {

bool g_sdk_initialized_via_pepper = false;

}  // namespace

PDFModule::PDFModule() {
}

PDFModule::~PDFModule() {
  if (g_sdk_initialized_via_pepper) {
    ShutdownSDK();
    g_sdk_initialized_via_pepper = false;
  }
}

bool PDFModule::Init() {
  return true;
}

pp::Instance* PDFModule::CreateInstance(PP_Instance instance) {
  if (!g_sdk_initialized_via_pepper) {
    v8::StartupData natives;
    v8::StartupData snapshot;
    pp::PDF::GetV8ExternalSnapshotData(pp::InstanceHandle(instance),
                                       &natives.data, &natives.raw_size,
                                       &snapshot.data, &snapshot.raw_size);
    if (natives.data) {
      v8::V8::SetNativesDataBlob(&natives);
      v8::V8::SetSnapshotDataBlob(&snapshot);
    }
    if (!InitializeSDK())
      return nullptr;
    g_sdk_initialized_via_pepper = true;
  }

  return new OutOfProcessInstance(instance);
}


// Implementation of Global PPP functions ---------------------------------
int32_t PPP_InitializeModule(PP_Module module_id,
                             PPB_GetInterface get_browser_interface) {
  std::unique_ptr<PDFModule> module(new PDFModule);
  if (!module->InternalInit(module_id, get_browser_interface))
    return PP_ERROR_FAILED;

  pp::InternalSetModuleSingleton(module.release());
  return PP_OK;
}

void PPP_ShutdownModule() {
  delete pp::Module::Get();
  pp::InternalSetModuleSingleton(nullptr);
}

const void* PPP_GetInterface(const char* interface_name) {
  auto* module = pp::Module::Get();
  return module ? module->GetPluginInterface(interface_name) : nullptr;
}

#if defined(OS_WIN)
bool RenderPDFPageToDC(const void* pdf_buffer,
                       int buffer_size,
                       int page_number,
                       HDC dc,
                       int dpi,
                       int bounds_origin_x,
                       int bounds_origin_y,
                       int bounds_width,
                       int bounds_height,
                       bool fit_to_bounds,
                       bool stretch_to_bounds,
                       bool keep_aspect_ratio,
                       bool center_in_bounds,
                       bool autorotate) {
  if (!g_sdk_initialized_via_pepper) {
    if (!InitializeSDK()) {
      return false;
    }
  }
  PDFEngineExports* engine_exports = PDFEngineExports::Get();
  PDFEngineExports::RenderingSettings settings(
      dpi, dpi,
      pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, bounds_height),
      fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds,
      autorotate);
  bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size,
                                               page_number, settings, dc);
  if (!g_sdk_initialized_via_pepper)
    ShutdownSDK();

  return ret;
}

void SetPDFEnsureTypefaceCharactersAccessible(
    PDFEnsureTypefaceCharactersAccessible func) {
  PDFEngineExports::Get()->SetPDFEnsureTypefaceCharactersAccessible(func);
}

void SetPDFUseGDIPrinting(bool enable) {
  PDFEngineExports::Get()->SetPDFUseGDIPrinting(enable);
}
#endif  // defined(OS_WIN)

bool GetPDFDocInfo(const void* pdf_buffer,
                   int buffer_size, int* page_count,
                   double* max_page_width) {
  if (!g_sdk_initialized_via_pepper) {
    if (!InitializeSDK())
      return false;
  }
  PDFEngineExports* engine_exports = PDFEngineExports::Get();
  bool ret = engine_exports->GetPDFDocInfo(
      pdf_buffer, buffer_size, page_count, max_page_width);
  if (!g_sdk_initialized_via_pepper)
    ShutdownSDK();

  return ret;
}

bool GetPDFPageSizeByIndex(const void* pdf_buffer,
                           int pdf_buffer_size, int page_number,
                           double* width, double* height) {
  if (!g_sdk_initialized_via_pepper) {
    if (!chrome_pdf::InitializeSDK())
      return false;
  }
  chrome_pdf::PDFEngineExports* engine_exports =
      chrome_pdf::PDFEngineExports::Get();
  bool ret = engine_exports->GetPDFPageSizeByIndex(
      pdf_buffer, pdf_buffer_size, page_number, width, height);
  if (!g_sdk_initialized_via_pepper)
    chrome_pdf::ShutdownSDK();
  return ret;
}

bool RenderPDFPageToBitmap(const void* pdf_buffer,
                           int pdf_buffer_size,
                           int page_number,
                           void* bitmap_buffer,
                           int bitmap_width,
                           int bitmap_height,
                           int dpi,
                           bool autorotate) {
  if (!g_sdk_initialized_via_pepper) {
    if (!InitializeSDK())
      return false;
  }
  PDFEngineExports* engine_exports = PDFEngineExports::Get();
  PDFEngineExports::RenderingSettings settings(
      dpi, dpi, pp::Rect(bitmap_width, bitmap_height), true, false, true, true,
      autorotate);
  bool ret = engine_exports->RenderPDFPageToBitmap(
      pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer);
  if (!g_sdk_initialized_via_pepper)
    ShutdownSDK();

  return ret;
}

}  // namespace chrome_pdf
