const fs = require("fs");
const path = require('path');
const { PNG } = require("pngjs");

// Constants
const IMAGES_ROOT = path.join(...[
  '.', 
  'assets',
  'characters',
  'penny',
  'Sample sets',
  'Mouth'
]);

const FILE_OUT = path.join(...[
  '.',
  'assets',
  'characters',
  'penny',
  'textures',
  'mouth.png'
])


// Code
const imageLoad = (image) => new Promise(resolve => {
  fs.createReadStream(image)
    .pipe(new PNG({ filterType: 4 }))
    .on("parsed", function () {
      // Normalize
      const pixels = [];
      for(let y = 0; y < this.height; y++) {
        for(let x = 0; x < this.width; x++) {
          const idx = (this.width * y + x) << 2;
          const r = this.data[idx];
          const g = this.data[idx + 1];
          const b = this.data[idx + 2];
          const a = this.data[idx + 3];

          pixels.push({ r, g, b, a });
        }
      }
      resolve({ pixels, width: this.width, height: this.height });
    })
  ;
});

const imageWrite = (image, file) => new Promise(resolve => {
  const png = new PNG({ width: image.width, height: image.height });
  png.width = image.width;
  png.height = image.height;
  
  for(let y = 0; y < image.height; y++) {
    for(let x = 0; x < image.width; x++) {
      const i = (image.width * y + x);
      const idx = i << 2;

      const pixel = image.pixels[i];
      png.data[idx] = pixel.r;
      png.data[idx + 1] = pixel.g;
      png.data[idx + 2] = pixel.b;
      png.data[idx + 3] = pixel.a;
    }
  }

  png.pack().pipe(fs.createWriteStream(file))
    .on('close', () => resolve(true))
  ;
});

(async () => {
  const files = fs.readdirSync(IMAGES_ROOT);

  let stitched = null;
  let k = 0;
  
  for(let i = 0; i < files.length; i++) {
    const filePath = path.join(IMAGES_ROOT, files[i]);
    const image = await imageLoad(filePath);

    if(!stitched) {
      stitched = {  
        width: image.width,
        height: image.height * files.length,
        pixels: Array(image.width*image.height*files.length)
      }
    }

    for(let j = 0; j < image.pixels.length; j++) {
      stitched.pixels[j + (i * image.width * image.height)] = { ...image.pixels[j] };
    }
  };

  console.log('Writing');
  await imageWrite(stitched, FILE_OUT);
})().catch(console.error);