// Copyright 2013 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 "printing/printing_context_android.h"

#include <vector>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "jni/PrintingContext_jni.h"
#include "printing/metafile.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"
#include "third_party/icu/source/i18n/unicode/ulocdata.h"

namespace {

// 1 inch in mils.
const int kInchToMil = 1000;

inline int Round(double x) {
  return static_cast<int>(x + 0.5);
}

// Sets the page sizes for a |PrintSettings| object.  |width| and |height|
// arguments should be in device units.
void SetSizes(
    printing::PrintSettings* settings, int dpi, int width, int height) {
  gfx::Size physical_size_device_units(width, height);
  // Assume full page is printable for now.
  gfx::Rect printable_area_device_units(0, 0, width, height);

  settings->set_dpi(dpi);
  settings->SetPrinterPrintableArea(physical_size_device_units,
                                    printable_area_device_units,
                                    false);
}

void GetPageRanges(JNIEnv* env,
                   jintArray int_arr,
                   printing::PageRanges& range_vector) {
  std::vector<int> pages;
  base::android::JavaIntArrayToIntVector(env, int_arr, &pages);
  for (std::vector<int>::const_iterator it = pages.begin();
      it != pages.end();
      ++it) {
    printing::PageRange range;
    range.from = *it;
    range.to = *it;
    range_vector.push_back(range);
  }
}

}  // namespace

namespace printing {

// static
PrintingContext* PrintingContext::Create(const std::string& app_locale) {
  return new PrintingContextAndroid(app_locale);
}

// static
void PrintingContextAndroid::PdfWritingDone(int fd, bool success) {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_PrintingContext_pdfWritingDone(env, fd, success);
}

PrintingContextAndroid::PrintingContextAndroid(const std::string& app_locale)
    : PrintingContext(app_locale) {
  // The constructor is run in the IO thread.
}

PrintingContextAndroid::~PrintingContextAndroid() {
}

void PrintingContextAndroid::AskUserForSettings(
    gfx::NativeView parent_view,
    int max_pages,
    bool has_selection,
    const PrintSettingsCallback& callback) {
  // This method is always run in the UI thread.
  callback_ = callback;

  JNIEnv* env = base::android::AttachCurrentThread();
  if (j_printing_context_.is_null()) {
    j_printing_context_.Reset(Java_PrintingContext_create(
        env,
        reinterpret_cast<intptr_t>(this)));
  }

  Java_PrintingContext_pageCountEstimationDone(env,
                                               j_printing_context_.obj(),
                                               max_pages);
}

void PrintingContextAndroid::AskUserForSettingsReply(JNIEnv* env,
                                                     jobject obj,
                                                     jboolean success) {
  if (!success) {
    // TODO(cimamoglu): Differentiate between FAILED And CANCEL.
    callback_.Run(FAILED);
    return;
  }

  // We use device name variable to store the file descriptor.  This is hacky
  // but necessary. Since device name is not necessary for the upstream
  // printing code for Android, this is harmless.
  int fd = Java_PrintingContext_getFileDescriptor(env,
                                                  j_printing_context_.obj());
  settings_.set_device_name(base::IntToString16(fd));

  ScopedJavaLocalRef<jintArray> intArr =
      Java_PrintingContext_getPages(env, j_printing_context_.obj());
  if (intArr.obj() != NULL) {
    PageRanges range_vector;
    GetPageRanges(env, intArr.obj(), range_vector);
    settings_.set_ranges(range_vector);
  }

  int dpi = Java_PrintingContext_getDpi(env, j_printing_context_.obj());
  int width = Java_PrintingContext_getWidth(env, j_printing_context_.obj());
  int height = Java_PrintingContext_getHeight(env, j_printing_context_.obj());
  width = Round(ConvertUnitDouble(width, kInchToMil, 1.0) * dpi);
  height = Round(ConvertUnitDouble(height, kInchToMil, 1.0) * dpi);
  SetSizes(&settings_, dpi, width, height);

  callback_.Run(OK);
}

PrintingContext::Result PrintingContextAndroid::UseDefaultSettings() {
  DCHECK(!in_print_job_);

  ResetSettings();
  settings_.set_dpi(kDefaultPdfDpi);
  gfx::Size physical_size = GetPdfPaperSizeDeviceUnits();
  SetSizes(&settings_, kDefaultPdfDpi, physical_size.width(),
           physical_size.height());
  return OK;
}

gfx::Size PrintingContextAndroid::GetPdfPaperSizeDeviceUnits() {
  // NOTE: This implementation is the same as in PrintingContextNoSystemDialog.
  int32_t width = 0;
  int32_t height = 0;
  UErrorCode error = U_ZERO_ERROR;
  ulocdata_getPaperSize(app_locale_.c_str(), &height, &width, &error);
  if (error > U_ZERO_ERROR) {
    // If the call failed, assume a paper size of 8.5 x 11 inches.
    LOG(WARNING) << "ulocdata_getPaperSize failed, using 8.5 x 11, error: "
                 << error;
    width = static_cast<int>(
        kLetterWidthInch * settings_.device_units_per_inch());
    height = static_cast<int>(
        kLetterHeightInch  * settings_.device_units_per_inch());
  } else {
    // ulocdata_getPaperSize returns the width and height in mm.
    // Convert this to pixels based on the dpi.
    float multiplier = 100 * settings_.device_units_per_inch();
    multiplier /= kHundrethsMMPerInch;
    width *= multiplier;
    height *= multiplier;
  }
  return gfx::Size(width, height);
}

PrintingContext::Result PrintingContextAndroid::UpdatePrinterSettings(
    bool external_preview) {
  DCHECK(!in_print_job_);

  // Intentional No-op.

  return OK;
}

PrintingContext::Result PrintingContextAndroid::InitWithSettings(
    const PrintSettings& settings) {
  DCHECK(!in_print_job_);

  settings_ = settings;

  return OK;
}

PrintingContext::Result PrintingContextAndroid::NewDocument(
    const base::string16& document_name) {
  DCHECK(!in_print_job_);
  in_print_job_ = true;

  return OK;
}

PrintingContext::Result PrintingContextAndroid::NewPage() {
  if (abort_printing_)
    return CANCEL;
  DCHECK(in_print_job_);

  // Intentional No-op.

  return OK;
}

PrintingContext::Result PrintingContextAndroid::PageDone() {
  if (abort_printing_)
    return CANCEL;
  DCHECK(in_print_job_);

  // Intentional No-op.

  return OK;
}

PrintingContext::Result PrintingContextAndroid::DocumentDone() {
  if (abort_printing_)
    return CANCEL;
  DCHECK(in_print_job_);

  ResetSettings();
  return OK;
}

void PrintingContextAndroid::Cancel() {
  abort_printing_ = true;
  in_print_job_ = false;
}

void PrintingContextAndroid::ReleaseContext() {
  // Intentional No-op.
}

gfx::NativeDrawingContext PrintingContextAndroid::context() const {
  // Intentional No-op.
  return NULL;
}

// static
bool PrintingContextAndroid::RegisterPrintingContext(JNIEnv* env) {
   return RegisterNativesImpl(env);
}

}  // namespace printing
