const fs = require('fs');
const path = require("path");

const { ipcRenderer } = require('electron');

const { PNG } = require("pngjs");

const { ipcRenderer } = require('electron');

function convertSBHeightmap(inPath, outPath, width, height, min, max) {
	const data = fs.readFileSync(inPath);
	const packSizeBytes = 4;

	if (data.length != width * height * packSizeBytes) {
		throw `Incorrect parameters specified for image, size: ${data.length} and ` +
		`width: ${width}, height: ${height} and packSize: ${packSize}: ${packSizeBytes} bytes`;
	}

	const uint16Size = 2;
	const inputView = new DataView(data.buffer);
	var outBuffer = new Buffer(uint16Size * width * height);
	var bitmap = new Uint16Array(outBuffer.buffer);
	for (var y = 0; y < height; y++) {
		for (var x = 0; x < width; x++) {
			const idx = y * width + x;
			const inputIndex = idx * 4;
			const v = inputView.getFloat32(inputIndex, true);
			const scaled = (inputView.getFloat32(inputIndex, true) - min) / (max - min);
			bitmap[idx] = scaled * 65535;
		}
	}

	const png = new PNG({
		width: width,
		height: height,
		bitDepth: 16,
		colorType: 0,
		inputColorType: 0,
		inputHasAlpha: false
	});

	png.data = outBuffer;
	png.pack().pipe(fs.createWriteStream(outPath));
}

ipcRenderer.on("ConvertSBHeightmap", (e, command, writePath) => {
	const width = command.width;
	const height = command.height;
	const inPath = command.inPath;
	const outPath = path.join(writePath, command.outPath);
	const min = command.min;
	const max = command.max;
	try {
		convertSBHeightmap(inPath, outPath, width, height, min, max);
	} catch(err) {
		ipcRenderer.send("TransformSBImageFailed", err);
		return;
	}
	ipcRenderer.send("TransformSBImageFinished", outPath);
});

ipcRenderer.on("TransformSBImage", (e, command, writePath) => {
	const width = command.width;
	const height = command.height;
	const inPath = command.inPath;
	const outPath = path.join(writePath, command.outPath);
	const multiplier = command.multiplier;
	const packSize = command.packSize;

	fs.readFile(inPath, function (err, data) {
	    if (err) {
			ipcRenderer.send("TransformSBImageFailed", err);
			return;
		}

		var packSizeBytes;
		if (packSize == "float32") {
			packSizeBytes = 4;
		} else {
			packSizeBytes = 1;
		}

		if (data.length != width * height * packSizeBytes) {
			ipcRenderer.send("TransformSBImageFailed",
				`Incorrect parameters specified for image: ${inPath}, size: ${data.length} and ` +
				`width: ${width}, height: ${height} and packSize: ${packSize}: ${packSizeBytes} bytes`);
			return;
		}


	  var buffer = new Uint8ClampedArray(width * height * 4);
	  var view = new DataView(data.buffer);

	  for (var y = 0; y < height; y++) {
			for (var x = 0; x < width; x++) {
				const idx = y * width + x;
				const pos = idx * 4;
				if (packSize == 'float32') {
					buffer[pos  ] = view.getFloat32(idx * 4, true) * multiplier;
				} else {
					buffer[pos  ] = data[idx] * multiplier;
				}
				buffer[pos+1] = buffer[pos];
				buffer[pos+2] = buffer[pos];
				buffer[pos+3] = 255;
			}
	  }

	  var canvas = document.createElement('canvas'),
	  ctx = canvas.getContext('2d');

	  canvas.width = width;
	  canvas.height = height;

	  // create imageData object
	  var idata = ctx.createImageData(width, height);

	  // set our buffer as source
	  idata.data.set(buffer);

	  // update canvas with new data
	  ctx.putImageData(idata, 0, 0);

	  var url = canvas.toDataURL();
	  const base64Data = url.replace(/^data:image\/png;base64,/, "");
	  fs.writeFile(outPath, base64Data, 'base64', function (err) {
		if (err) {
		  ipcRenderer.send("TransformSBImage", err);
		  return;
		}
		ipcRenderer.send("TransformSBImageFinished", outPath);
	  });
	});
});
@@ -135,54 +135,8 @@
 );%0A%0A
-const %7B ipcRenderer %7D = require('electron');%0A%0A
 func
@@ -449,37 +449,29 @@
 and packSize
-: $%7BpackSize%7D
+Bytes
 : $%7BpackSize
@@ -675,36 +675,35 @@
 or (var 
-y
+x
  = 0; 
-y %3C height; y
+x %3C width; x
 ++) %7B%0A%09%09
@@ -711,35 +711,36 @@
 or (var 
-x
+y
  = 0; 
-x %3C width; x
+y %3C height; y
 ++) %7B%0A%09%09
@@ -793,68 +793,22 @@
 x = 
-id
 x * 
-4;%0A%09%09%09const v = inputView.getFloat32(inputIndex, true)
+height + y
 ;%0A%09%09
@@ -855,16 +855,20 @@
 putIndex
+ * 4
 , true) 
@@ -1144,16 +1144,102 @@
 h));%0A%7D%0A%0A
+// if (true) %7B%0A// %09exports.convertSBHeightmap = convertSBHeightmap;%0A// %09return;%0A// %7D%0A%0A
 ipcRende
@@ -1577,16 +1577,17 @@
 %09%7D catch
+ 
 (err) %7B%0A
@@ -1592,54 +1592,160 @@
 %7B%0A%09%09
-ipcRenderer.send(%22TransformSBImageFailed%22, err
+const msg = typeof(err) == %22string%22 ? err : err.message;%0A%09%09ipcRenderer.send(%22TransformSBImageFailed%22,%0A%09%09%09%60Failed to export heightmap with error: $%7Bmsg%7D%60
 );%0A%09

update transform_sb_image.js to something that doesn't crash launcher