// Copyright 2014 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 <memory>
#include <string>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/data_pipe_utils/data_pipe_utils.h"
#include "mojo/public/c/system/main.h"
#include "mojo/ui/choreographer.h"
#include "mojo/ui/content_viewer_app.h"
#include "mojo/ui/ganesh_view.h"
#include "mojo/ui/input_handler.h"
#include "third_party/pdfium/fpdfsdk/include/fpdf_ext.h"
#include "third_party/pdfium/fpdfsdk/include/fpdfview.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "v8/include/v8.h"

namespace examples {

namespace {
constexpr uint32_t kContentImageResourceId = 1;
constexpr uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId;
}  // namespace

class PDFLibrary;

class PDFDocument {
 public:
  PDFDocument(const std::shared_ptr<PDFLibrary>& pdf_library,
              FPDF_DOCUMENT doc,
              const std::string& data)
      : pdf_library_(pdf_library),
        doc_(doc),
        data_(data),
        page_count_(FPDF_GetPageCount(doc_)) {}

  ~PDFDocument() { FPDF_CloseDocument(doc_); }

  uint32_t page_count() { return page_count_; }

  skia::RefPtr<SkImage> DrawPage(int page_index, const mojo::Size& size) {
    FPDF_PAGE page = FPDF_LoadPage(doc_, page_index);

    double width_pts = FPDF_GetPageWidth(page);
    double height_pts = FPDF_GetPageHeight(page);

    int width, height;
    if (size.width * height_pts < size.height * width_pts) {
      width = size.width;
      height = height_pts * size.width / width_pts;
    } else {
      width = width_pts * size.height / height_pts;
      height = size.height;
    }

    int stride = width * 4;
    skia::RefPtr<SkData> pixels =
        skia::AdoptRef(SkData::NewUninitialized(stride * height));
    DCHECK(pixels);

    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(width, height, FPDFBitmap_BGRA,
                                             pixels->writable_data(), stride);
    FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
    FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
    FPDFBitmap_Destroy(bitmap);

    FPDF_ClosePage(page);

    SkImageInfo info = SkImageInfo::Make(width, height, kBGRA_8888_SkColorType,
                                         kOpaque_SkAlphaType);
    return skia::AdoptRef(SkImage::NewRasterData(info, pixels.get(), stride));
  }

 private:
  std::shared_ptr<PDFLibrary> pdf_library_;
  FPDF_DOCUMENT doc_;
  std::string data_;
  uint32_t page_count_;
};

class PDFLibrary : public std::enable_shared_from_this<PDFLibrary> {
 public:
  PDFLibrary() {
    v8::V8::InitializeICU();
    FPDF_InitLibrary();
  }

  ~PDFLibrary() { FPDF_DestroyLibrary(); }

  std::shared_ptr<PDFDocument> Decode(mojo::URLResponsePtr response) {
    std::string data;
    mojo::common::BlockingCopyToString(response->body.Pass(), &data);
    if (data.length() >= static_cast<size_t>(std::numeric_limits<int>::max()))
      return nullptr;

    FPDF_DOCUMENT doc = FPDF_LoadMemDocument(
        data.data(), static_cast<int>(data.length()), nullptr);
    if (!doc)
      return nullptr;

    return std::make_shared<PDFDocument>(shared_from_this(), doc, data);
  }
};

class PDFDocumentView : public mojo::ui::GaneshView,
                        public mojo::ui::ChoreographerDelegate,
                        public mojo::ui::InputListener {
 public:
  PDFDocumentView(
      mojo::ApplicationImpl* app_impl,
      mojo::InterfaceRequest<mojo::ui::ViewOwner> view_owner_request,
      const std::shared_ptr<PDFDocument>& pdf_document)
      : GaneshView(app_impl, view_owner_request.Pass(), "PDFDocumentViewer"),
        pdf_document_(pdf_document),
        choreographer_(scene(), this),
        input_handler_(GetViewServiceProvider(), this) {
    DCHECK(pdf_document_);
  }

  ~PDFDocumentView() override {}

 private:
  // |GaneshView|:
  void OnPropertiesChanged(
      uint32_t old_scene_version,
      mojo::ui::ViewPropertiesPtr old_properties) override {
    Redraw();
  }

  // |InputListener|:
  void OnEvent(mojo::EventPtr event, const OnEventCallback& callback) override {
    if (event->key_data && (event->action != mojo::EventType::KEY_PRESSED ||
                            event->key_data->is_char)) {
      callback.Run(false);
      return;
    }

    if ((event->key_data &&
         event->key_data->windows_key_code == mojo::KeyboardCode::DOWN) ||
        (event->pointer_data && event->pointer_data->vertical_wheel < 0)) {
      GotoNextPage();
      callback.Run(true);
      return;
    }

    if ((event->key_data &&
         event->key_data->windows_key_code == mojo::KeyboardCode::UP) ||
        (event->pointer_data && event->pointer_data->vertical_wheel > 0)) {
      GotoPreviousPage();
      callback.Run(true);
      return;
    }

    callback.Run(false);
  }

  // |ChoreographerDelegate|:
  void OnDraw(const mojo::gfx::composition::FrameInfo& frame_info,
              const base::TimeDelta& time_delta) override {
    if (!properties())
      return;

    auto update = mojo::gfx::composition::SceneUpdate::New();

    const mojo::Size& size = *properties()->view_layout->size;
    if (size.width > 0 && size.height > 0) {
      mojo::RectF bounds;
      bounds.width = size.width;
      bounds.height = size.height;

      mojo::gfx::composition::ResourcePtr content_resource =
          ganesh_renderer()->DrawCanvas(
              size, base::Bind(&PDFDocumentView::DrawContent,
                               base::Unretained(this)));
      DCHECK(content_resource);
      update->resources.insert(kContentImageResourceId,
                               content_resource.Pass());

      auto root_node = mojo::gfx::composition::Node::New();
      root_node->hit_test_behavior =
          mojo::gfx::composition::HitTestBehavior::New();
      root_node->op = mojo::gfx::composition::NodeOp::New();
      root_node->op->set_image(mojo::gfx::composition::ImageNodeOp::New());
      root_node->op->get_image()->content_rect = bounds.Clone();
      root_node->op->get_image()->image_resource_id = kContentImageResourceId;
      update->nodes.insert(kRootNodeId, root_node.Pass());
    } else {
      auto root_node = mojo::gfx::composition::Node::New();
      update->nodes.insert(kRootNodeId, root_node.Pass());
    }

    scene()->Update(update.Pass());

    auto metadata = mojo::gfx::composition::SceneMetadata::New();
    metadata->version = scene_version();
    scene()->Publish(metadata.Pass());
  }

  void DrawContent(const mojo::skia::GaneshContext::Scope& ganesh_scope,
                   const mojo::Size& size,
                   SkCanvas* canvas) {
    if (!cached_image_) {
      cached_image_ = pdf_document_->DrawPage(page_, size);
    }

    if (cached_image_) {
      canvas->clear(SK_ColorBLACK);
      canvas->drawImageRect(
          cached_image_.get(),
          SkRect::MakeWH(cached_image_->width(), cached_image_->height()),
          SkRect::MakeXYWH((size.width - cached_image_->width()) / 2,
                           (size.height - cached_image_->height()) / 2,
                           cached_image_->width(), cached_image_->height()),
          nullptr);
    } else {
      canvas->clear(SK_ColorBLUE);
    }
  }

  void GotoNextPage() {
    if (page_ + 1 < pdf_document_->page_count()) {
      page_++;
      Redraw();
    }
  }

  void GotoPreviousPage() {
    if (page_ > 0) {
      page_--;
      Redraw();
    }
  }

  void Redraw() {
    cached_image_.clear();
    choreographer_.ScheduleDraw();
  }

  std::shared_ptr<PDFDocument> pdf_document_;
  uint32_t page_ = 0u;
  skia::RefPtr<SkImage> cached_image_;

  mojo::ui::Choreographer choreographer_;
  mojo::ui::InputHandler input_handler_;

  DISALLOW_COPY_AND_ASSIGN(PDFDocumentView);
};

class PDFContentViewProviderApp : public mojo::ui::ViewProviderApp {
 public:
  PDFContentViewProviderApp(const std::shared_ptr<PDFLibrary>& pdf_library,
                            const std::shared_ptr<PDFDocument>& pdf_document)
      : pdf_library_(pdf_library), pdf_document_(pdf_document) {
    DCHECK(pdf_library_);
    DCHECK(pdf_document_);
  }

  ~PDFContentViewProviderApp() override {}

  void CreateView(
      const std::string& connection_url,
      mojo::InterfaceRequest<mojo::ui::ViewOwner> view_owner_request,
      mojo::InterfaceRequest<mojo::ServiceProvider> services,
      mojo::InterfaceHandle<mojo::ServiceProvider> exposed_services) override {
    new PDFDocumentView(app_impl(), view_owner_request.Pass(), pdf_document_);
  }

 private:
  std::shared_ptr<PDFLibrary> pdf_library_;
  std::shared_ptr<PDFDocument> pdf_document_;

  DISALLOW_COPY_AND_ASSIGN(PDFContentViewProviderApp);
};

class PDFContentViewerApp : public mojo::ui::ContentViewerApp {
 public:
  PDFContentViewerApp() : pdf_library_(std::make_shared<PDFLibrary>()) {}

  ~PDFContentViewerApp() override {}

  mojo::ui::ViewProviderApp* LoadContent(
      const std::string& content_handler_url,
      mojo::URLResponsePtr response) override {
    std::shared_ptr<PDFDocument> pdf_document =
        pdf_library_->Decode(response.Pass());
    if (!pdf_document) {
      LOG(ERROR) << "Could not decode PDFDocument.";
      return nullptr;
    }

    return new PDFContentViewProviderApp(pdf_library_, pdf_document);
  }

 private:
  std::shared_ptr<PDFLibrary> pdf_library_;

  DISALLOW_COPY_AND_ASSIGN(PDFContentViewerApp);
};

}  // namespace examples

MojoResult MojoMain(MojoHandle application_request) {
  mojo::ApplicationRunnerChromium runner(new examples::PDFContentViewerApp());
  return runner.Run(application_request);
}
