#!/usr/bin/env python
# SPDX-License-Identifier: BSD-3-Clause
#
# Script to generate text graphics using the "small" (HUD) font.
#

from PIL import Image
from glob import glob
import sys
import re

from image_dimensions import *
from tint import image_tint

DIMENSION_MATCH_RE = re.compile(r'(\d+)[x,](\d+)')

class SmallTextGenerator(object):
	def __init__(self):
		self.get_font_widths()
	# Width of a space character in pixels.
	SPACE_WIDTH = 4
	# Height of the font.
	FONT_HEIGHT = 8
	# Regexp to match dimensions/x,y coordinate pair.

	def compile_kerning_table(self, kerning_table):
		"""Given a dictionary of kerning patterns, compile Regexps."""

		result = {}
		for pattern, adjust in kerning_table.items():
			result[re.compile(pattern)] = adjust
		return result

	def get_font_widths(self):
		charfiles = glob('../stcfn*.png')
		self.char_widths = {}
		for c in range(128):
			filename = self.char_filename(chr(c))
			if filename not in charfiles:
				continue
			w, _ = get_image_dimensions(filename)
			self.char_widths[chr(c)] = w

	def __contains__(self, c):
		return c in self.char_widths

	def char_width(self, c):
		return self.char_widths[c]

	def char_filename(self, c):
		return '../stcfn%03d.png' % (ord(c))

	def draw_for_text(self, image, text, x, y):
		text = text.upper()
		new_image = image.copy()
		x1, y1 = x, y

		for c in text:
			if c == '\n':
				y1 += self.FONT_HEIGHT
				x1 = x
			elif c == ' ':
				x1 += self.SPACE_WIDTH

			if c not in self:
				continue

			filename = self.char_filename(c)
			char_image = Image.open(filename)
			char_image.load()
			new_image = self.paste_image(new_image, char_image, x1, y1)
			x1 += self.char_width(c)
		return new_image

	def paste_image(self, image, src, x, y):
		int_image = Image.new("RGBA", image.size, (0, 0, 0, 0))
		int_image.paste(src, (x, y))
		new_image = Image.alpha_composite(image, int_image)
		return new_image


def parse_command_line(args):
	if len(args) < 4 or (len(args) % 2) != 0:
		return None

	result = {
		'filename': args[0],
		'background': None,
		'strings': [],
	}

	m = DIMENSION_MATCH_RE.match(args[1])
	if not m:
		return None
	result['dimensions'] = (int(m.group(1)), int(m.group(2)))

	i = 2
	while i < len(args):
		if args[i] == '-background':
			result['background'] = args[i+1]
			i += 2
			continue

		m = DIMENSION_MATCH_RE.match(args[i])
		if not m:
			return None

		xy = (int(m.group(1)), int(m.group(2)))

		result['strings'].append((xy, args[i + 1]))
		i += 2

	return result


if __name__ == '__main__':

	args = parse_command_line(sys.argv[1:])

	if not args:
		print("Usage: smtextgen <filename> <size> [...text commands...]")
		print("Where each text command looks like:")
		print("  [x,y] [text]")
		sys.exit(0)

	smallfont = SmallTextGenerator()

	if args['background'] is not None:
		background_image = Image.open(args['background'])
		background_image.load()
		background_image = background_image.convert("RGBA")

	image = Image.new("RGBA", args['dimensions'],(0,0,0,0))

	for xy, string in args['strings']:
		# Allow contents of a file to be included with special prefix:
		if string.startswith('include:'):
			with open(string[8:]) as f:
				string = f.read()

		# Allow special notation to indicate an image file to just draw
		# rather than rendering a string.
		if string.startswith('file:'):
			src_image = Image.open(string[5:])
			src_image.load()
			image = smallfont.paste_image(image, src_image, xy[0], xy[1])
		else:
			image = smallfont.draw_for_text(image, string, xy[0], xy[1])

	if args['background'] is not None:
		image = Image.alpha_composite(background_image, image)

	image.save(args['filename'])

