// Algorythm should not change. Use fixtures to check.
//
'use strict';

const Canvas     = require('canvas');
const Image      = Canvas.Image;
const fs         = require('fs');
const path       = require('path');
const pica       = require('../');
const pixelmatch = require('pixelmatch');

const ppm        = require('./ppm');

const FIXTURES_DIRECTORY = path.join(__dirname, 'fixtures');
const OUTPUT_DIRECTORY   = path.join(__dirname, '..');

//
// Shim browser method
//
global.document = global.document || {};
global.document.createElement = global.document.createElement || function (name) {
  if (name === 'canvas') return new Canvas();
  throw new Error('createElement(' + name + ') not shimmed');
};


describe('Fixture resize', function () {

  it('.resizeCanvas() should be correct for the given fixture', function () {
    this.timeout(3000);

    let srcImage = new Image();

    srcImage.src = fs.readFileSync(path.join(FIXTURES_DIRECTORY, 'original.jpg'));

    let srcCanvas = new Canvas();

    srcCanvas.width = srcImage.width;
    srcCanvas.height = srcImage.height;

    let srcCtx = srcCanvas.getContext('2d');

    srcCtx.drawImage(srcImage, 0, 0);

    let fixtureImage = new Image();

    fixtureImage.src = fs.readFileSync(path.join(FIXTURES_DIRECTORY, 'resized.png'));

    let fixtureCanvas = new Canvas();

    fixtureCanvas.width = fixtureImage.width;
    fixtureCanvas.height = fixtureImage.height;

    let fixtureCtx = fixtureCanvas.getContext('2d');

    fixtureCtx.drawImage(fixtureImage, 0, 0);

    let fixtureImageData = fixtureCtx.getImageData(0, 0, fixtureCanvas.width, fixtureCanvas.height);
    let destCanvas = new Canvas();

    destCanvas.width = fixtureImage.width;
    destCanvas.height = fixtureImage.height;

    let destCtx = destCanvas.getContext('2d');
    let diffCanvas = new Canvas();

    diffCanvas.width = fixtureImage.width;
    diffCanvas.height = fixtureImage.height;

    let diffCtx = diffCanvas.getContext('2d');
    let diffImageData = diffCtx.createImageData(diffCanvas.width, diffCanvas.height);

    return pica({ features: [ 'js' ] })
      .resize(srcCanvas, destCanvas, { quality: 3, unsharpAmount: 0 })
      .then(() => {
        let destImageData = destCtx.getImageData(0, 0, destCanvas.width, destCanvas.height);

        let numDiffPixels = pixelmatch(
          destImageData.data,
          fixtureImageData.data,
          diffImageData.data,
          fixtureCanvas.width,
          fixtureCanvas.height,
          { threshold: 0, includeAA: true }
        );

        if (numDiffPixels > 0) {
          diffCtx.putImageData(diffImageData, 0, 0);
          diffCanvas
            .pngStream()
            .pipe(fs.createWriteStream(path.join(OUTPUT_DIRECTORY, 'fixture-test-diff.png')));
          destCanvas
            .pngStream()
            .pipe(fs.createWriteStream(path.join(OUTPUT_DIRECTORY, 'fixture-test-output.png')));
          fixtureCanvas
            .pngStream()
            .pipe(fs.createWriteStream(path.join(OUTPUT_DIRECTORY, 'fixture-test-expected.png')));

          throw new Error(`Images mismatch in ${numDiffPixels} pixels`);
        }
      });
  });


  it('.resizeBuffer() should be correct for the given fixture', function () {
    let src     = ppm.decode(fs.readFileSync(path.join(FIXTURES_DIRECTORY, 'original.ppm')));
    let fixture = ppm.decode(fs.readFileSync(path.join(FIXTURES_DIRECTORY, 'resized.ppm')));

    let dest = new Uint8Array(fixture.buffer.length);
    let diff = new Uint8Array(fixture.buffer.length);

    return pica({ features: [ 'js' ] })
      .resizeBuffer({
        src:      src.buffer,
        width:    src.width,
        height:   src.height,
        dest:     dest,
        toWidth:  fixture.width,
        toHeight: fixture.height
      })
      .then(() => {
        let numDiffPixels = pixelmatch(
          dest,
          fixture.buffer,
          diff,
          fixture.width,
          fixture.height,
          { threshold: 0, includeAA: true }
        );

        if (numDiffPixels > 0) {
          fs.writeFileSync(
            path.join(OUTPUT_DIRECTORY, 'fixture-test-diff.ppm'),
            Buffer.from(ppm.encode(diff, fixture.width, fixture.height))
          );
          fs.writeFileSync(
            path.join(OUTPUT_DIRECTORY, 'fixture-test-output.ppm'),
            Buffer.from(ppm.encode(dest, fixture.width, fixture.height))
          );
          fs.writeFileSync(
            path.join(OUTPUT_DIRECTORY, 'fixture-test-expected.ppm'),
            Buffer.from(ppm.encode(fixture.buffer, fixture.width, fixture.height))
          );
          throw new Error(`Images mismatch in ${numDiffPixels} pixels`);
        }
      });
  });

});

@@ -70,79 +70,8 @@
 ';%0A%0A
-const Canvas     = require('canvas');%0Aconst Image      = Canvas.Image;%0A
 cons
@@ -369,19 +369,227 @@
 '..');%0A%0A
-//%0A
+%0Adescribe('Fixture resize', function () %7B%0A%0A  it('.resizeCanvas() should be correct for the given fixture', function () %7B%0A    const Canvas     = require('canvas');%0A    const Image      = Canvas.Image;%0A    //%0A    
 // Shim 
@@ -603,19 +603,27 @@
  method%0A
-//%0A
+    //%0A    
 global.d
@@ -655,16 +655,20 @@
  %7C%7C %7B%7D;%0A
+    
 global.d
@@ -742,16 +742,20 @@
 name) %7B%0A
+    
   if (na
@@ -792,16 +792,20 @@
 nvas();%0A
+    
   throw 
@@ -862,132 +862,16 @@
 ');%0A
+    
 %7D;%0A%0A
-%0Adescribe('Fixture resize', function () %7B%0A%0A  it('.resizeCanvas() should be correct for the given fixture', function () %7B
 %0A   

Make node_canvas use more local