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

#include <gtk/gtk.h>
#include <gtk/gtkunixprint.h>

#include "base/logging.h"
#include "base/values.h"
#include "printing/metafile.h"
#include "printing/print_dialog_gtk_interface.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"

namespace {

// Function pointer for creating print dialogs. |callback| is only used when
// |show_dialog| is true.
printing::PrintDialogGtkInterface* (*create_dialog_func_)(
    printing::PrintingContextGtk* context) = NULL;

}  // namespace

namespace printing {

// static
PrintingContext* PrintingContext::Create(const std::string& app_locale) {
  return static_cast<PrintingContext*>(new PrintingContextGtk(app_locale));
}

PrintingContextGtk::PrintingContextGtk(const std::string& app_locale)
    : PrintingContext(app_locale),
      print_dialog_(NULL) {
}

PrintingContextGtk::~PrintingContextGtk() {
  ReleaseContext();

  if (print_dialog_)
    print_dialog_->ReleaseDialog();
}

// static
void PrintingContextGtk::SetCreatePrintDialogFunction(
    PrintDialogGtkInterface* (*create_dialog_func)(
        PrintingContextGtk* context)) {
  DCHECK(create_dialog_func);
  DCHECK(!create_dialog_func_);
  create_dialog_func_ = create_dialog_func;
}

void PrintingContextGtk::PrintDocument(const Metafile* metafile) {
  DCHECK(print_dialog_);
  DCHECK(metafile);
  print_dialog_->PrintDocument(metafile, document_name_);
}

void PrintingContextGtk::AskUserForSettings(
    gfx::NativeView parent_view,
    int max_pages,
    bool has_selection,
    const PrintSettingsCallback& callback) {
  print_dialog_->ShowDialog(parent_view, has_selection, callback);
}

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

  ResetSettings();
  if (!print_dialog_) {
    print_dialog_ = create_dialog_func_(this);
    print_dialog_->AddRefToDialog();
  }
  print_dialog_->UseDefaultSettings();

  return OK;
}

PrintingContext::Result PrintingContextGtk::UpdatePrinterSettings(
    const DictionaryValue& job_settings, const PageRanges& ranges) {
  DCHECK(!in_print_job_);

  if (!print_dialog_) {
    print_dialog_ = create_dialog_func_(this);
    print_dialog_->AddRefToDialog();
  }

  if (!print_dialog_->UpdateSettings(job_settings, ranges, &settings_))
    return OnError();

  return OK;
}

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

  settings_ = settings;

  return OK;
}

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

  document_name_ = document_name;

  return OK;
}

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

  // Intentional No-op.

  return OK;
}

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

  // Intentional No-op.

  return OK;
}

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

  ResetSettings();
  return OK;
}

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

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

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

}  // namespace printing

