
// Использует Image Magick для автоматической перекраски текстур

const fs = require('fs')
const root_main = './src/main/resources/assets/overdrive_that_matters/textures/'
const child_process = require('child_process')

const args = process.argv.slice(2)

if (args.length == 0) {
	console.error('No texture(s) names specified. Valid arguments are: <texture> [mask over]')
	process.exit(2)
} else if (args.length > 2) {
	console.error('Too many textures specified! Valid arguments are: <texture> [mask over]')
	process.exit(2)
}

const colors = [
	['orange', [245, 116, 16]],
	['magenta', [186, 63, 175]],
	['light_blue', [59, 180, 219]],
	['yellow', [252, 199, 36]],
	['lime', [111, 187, 24]],
	['pink', [243, 139, 170]],
	['gray', [62, 66, 70]],
	['light_gray', [140, 140, 131]],
	['cyan', [22, 134, 145]],
	['purple', [116, 38, 169]],
	['blue', [51, 53, 155]],
	['brown', [114, 71, 40]],
	['green', [84, 109, 28]],
	['red', [156, 37, 34]],
	['black', [31, 31, 35]],
]

process.stderr.setMaxListeners(40)
process.stdout.setMaxListeners(40)

async function size(path) {
	const identify = child_process.spawn('magick', [
		'identify',
		path,
	])

	identify.stderr.pipe(process.stderr)

	const chunks = []
	identify.stdout.on('data', (a) => chunks.push(a))

	await new Promise((resolve) => {
		identify.on('close', () => resolve())
	})

	const chunk = chunks[0].toString('utf-8')
	const size = chunk.match(/PNG ([0-9]+)x([0-9]+)/)
	const width = parseInt(size[1])
	const height = parseInt(size[2])

	return [width, height]
}

(async function() {
	if (args.length == 1) {
		const texture = args[0]

		if (!fs.existsSync(`${root_main}${texture}.png`)) {
			process.stderr.write(`${texture}.png does not exist\n`)
			process.exit(1)
		}

		const splitted = texture.split('/')
		const last = splitted.pop()

		if (last.indexOf('_white') == -1) {
			colors.push(['white', [235, 235, 235]])
		}

		const combined = splitted.join('/')

		const basedir = `${root_main}${combined}`
		const [width, height] = await size(`${root_main}${texture}.png`)

		for (const color of colors) {
			const name = color[0]
			const rgb = color[1]
			const magick = child_process.spawn('magick', [
				'convert',
				`${root_main}${texture}.png`,
				'-size', `${width}x${height}`,
				`xc:rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`,
				'-channel', 'rgb',
				'-compose', 'Multiply',
				'-composite',
				`${basedir}/${last.replace(/_colorless/, '').replace(/_white/, '')}_${name}.png`])

			magick.stdout.pipe(process.stdout)
			magick.stderr.pipe(process.stderr)
		}
	} else {
		const textureColor = args[0]
		const textureOverlay = args[1]

		if (!fs.existsSync(`${root_main}${textureColor}.png`)) {
			process.stderr.write(`${textureColor}.png does not exist\n`)
			process.exit(1)
		}

		if (!fs.existsSync(`${root_main}${textureOverlay}.png`)) {
			process.stderr.write(`${textureOverlay}.png does not exist\n`)
			process.exit(1)
		}

		const splitted = textureColor.split('/')
		const last = splitted.pop()

		if (last.indexOf('_white') == -1) {
			colors.push(['white', [235, 235, 235]])
		}

		const combined = splitted.join('/')

		const basedir = `${root_main}${combined}`

		const [widthOverlay, heightOverlay] = await size(`${root_main}${textureOverlay}.png`)
		const [width, height] = await size(`${root_main}${textureColor}.png`)

		if (widthOverlay != width || heightOverlay != height) {
			process.stderr.write(`${textureColor}.png has size of ${width}x${height}, overlay has size of ${widthOverlay}x${heightOverlay}!\n`)
			process.exit(3)
		}

		for (const color of colors) {
			const name = color[0]
			const rgb = color[1]
			const magick = child_process.spawn('magick', [
				'convert',

				'(',
					`${root_main}${textureColor}.png`,
					'-size', `${width}x${height}`,
					`xc:rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`,
					'-channel', 'rgb',
					'-compose', 'Multiply',
					'-composite',
				')',

				`${root_main}${textureOverlay}.png`,

				'-compose', 'Over',
				'-composite',

				`${basedir}/${last.replace(/_colorless/, '').replace(/_white/, '')}_${name}.png`])

			magick.stdout.pipe(process.stdout)
			magick.stderr.pipe(process.stderr)
		}
	}
})()
