
const Handler = require("./documentHandler.js").DocumentHandler,
    pdfJs = require("pdfjs-dist"),
    assert = require("assert"),
    Canvas = require("canvas");

function NodeCanvasFactory() {}
NodeCanvasFactory.prototype = {
  create: function NodeCanvasFactory_create(width, height) {
    assert(width > 0 && height > 0, 'Invalid canvas size from Create ' +width +'x' +height);
    var canvas = Canvas.createCanvas(width, height);
    return {
      canvas: canvas,
      context: canvas.getContext('2d')
    };
  },

  reset: function NodeCanvasFactory_reset(canvasAndContext, width, height) {
    assert(canvasAndContext.canvas, 'Canvas is not specified');
    assert(width > 0 && height > 0, 'Invalid canvas size for reset');
    canvasAndContext.canvas.width = width;
    canvasAndContext.canvas.height = height;
  },

  destroy: function NodeCanvasFactory_destroy(canvasAndContext) {
    assert(canvasAndContext.canvas, 'Canvas is not specified');

    // Zeroing the width and height cause Firefox to release graphics
    // resources immediately, which can greatly reduce memory consumption.
    canvasAndContext.canvas.width = 0;
    canvasAndContext.canvas.height = 0;
    canvasAndContext.canvas = null;
    canvasAndContext.context = null;
  },
};

function PdfHandler(doc) {
    Handler.call(this, doc);
    this.pdfData = null;
    this.loading = null;
}
PdfHandler.prototype = Object.create(Handler.prototype);

PdfHandler.prototype.loadDocument = function() {
    return new Promise(((res, rej) => {
        if (this.pdfData) {
            res(this.pdfData);
        } else {
            if (this.loading)
                this.loading = this.loading.then((() => res(this.pdfData)).bind(this));
            else
                this.loading = pdfJs.getDocument(this.doc.path).then((doc => {
                    res(this.pdfData = doc);
                }).bind(this));
        }
    }).bind(this));
}

PdfHandler.prototype.getPageCount = function() {
    return new Promise((async (res, rej) => {
        var doc = await this.loadDocument();
        res(doc ? doc.numPages : 0);
    }).bind(this));
};

PdfHandler.prototype.getThumbmailViewport = function(page) {
    const maxSize = require("../config").thumbmailMaxSize;
    var fullSize = page.getViewport(1),
        ratio = Math.min(maxSize /fullSize.height, maxSize /fullSize.width);
    return page.getViewport(ratio);
};

PdfHandler.prototype.getPngPage = function(page, isThumbmail) {
    return new Promise((async (res, rej) => {
        var doc = await this.loadDocument();
        if (!doc) {
            res(null);
            return;
        }
        var pageContent = await doc.getPage(page),
            viewport = isThumbmail ? this.getThumbmailViewport(pageContent) : pageContent.getViewport(1),
            canvasFactory = new NodeCanvasFactory(),
            canvas = canvasFactory.create(viewport.width, viewport.height);
        pageContent.render({
            canvasContext: canvas.context,
            viewport: viewport,
            canvasFactory: canvasFactory
        }).promise.then(() => {
            canvas.canvas.toBuffer((err, buf) => res(buf), "image/png");
        });
    }).bind(this));
};

module.exports.PdfHandler = PdfHandler;

