# coding: utf-8
""" Converts pixel-art images into cross-stitch patterns.

	This tool assumes that 1px = 1 stitch.

	TODO:
		* Accept image name from command line. (DONE)
		* Change characters to symbols for ease of reading.
		* Expand number of symbols.
		* Create image from symbolized pixels instead of just printing to screen. (DONE)
		* Add grid lines and edge labels to image. (DONE)
		* Add legend to image, based on the `symbols` dictionary. (DONE)
		* Correspond hex colors to floss colors, where possible.
		* (Maybe) add stitch count for each color. (DONE)	
		* (Maybe) add GUI. (DONE)
		* Make sure legend width doesn't exceed image width.
"""

__author__ = "Noëlle Anthony"
__version__ = "0.4.0"

import sys
from PIL import Image, ImageDraw
from collections import defaultdict

def create_stitch(img_name):
	try:
		img = Image.open("/var/www/noelle.codes/node/stitchimg/" + img_name)
		oimg_name_bits = img_name.split("/")[-1].split(".")
		oimg_name = "".join(oimg_name_bits[:-1]) + "_pattern." + oimg_name_bits[-1]
		oimg_fullpath = "/var/www/noelle.codes/node/stitchimg/" + oimg_name
		w,h = img.size

		symbols = defaultdict(str)
		symbols["transparent"] = " "
		characters = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
		symbol_counts = defaultdict(int)
	#	l = 0
		lines = []
		for i in range(h):
			line = []
	#		k = 0
			for j in range(w):
				c = "".join(["{}{}".format(hex(x//16).split('x')[-1], hex(x%16).split('x')[-1]) for x in list(img.getpixel((j,i)))])
				d = " "
				if c[-2:] == "ff":
					cs = c[:-2]
					if cs not in symbols.keys():
						symbols[cs] = characters[0]
						characters = characters[1:]
					symbol_counts[cs] += 1
					d = symbols[cs]
				line.append(d)
	#			print(d, end="")
	#			k += 1
	#			if k == 9:
	#				print("|", end="")
	#				k = 0
			lines.append(line)
	#		print()
	#		l += 1
	#		if l == 9:
	#			for ww in range(int(w*1.1)+1):
	#				if (ww+1)%10 == 0:
	#					print("+", end="")
	#				else:
	#					print("-", end="")
	#			l = 0
	#			print()
		
	#	print("\nLEGEND")
		legend = []
		keys = 0
		for k,v in symbols.items():
			if v != " ":
				keys += 1
				legend.append("{}: #{} ({}ct)".format(v, k, symbol_counts[k]))
		#print("{} keys".format(keys))
	#	print("\n".join(legend))

		owid, ohgt = (w*10)+10, (h*10)+20+(15*(int(keys/3)+1))
		#print((owid, ohgt))
		oimg = Image.new("RGB", (owid, ohgt), "white")
		draw = ImageDraw.Draw(oimg)
		woff, hoff = int(((w)%10)/2)+1, int(((h)%10)/2)+1
		for ww in range(1, w+1):
			posx = ww * 10
			linecolor = 0 if (posx-(woff*10)) % 100 == 0 else (128,128,128)
			linewidth = 2 if (posx-(woff*10)) % 100 == 0 else 1
			draw.line((posx, 10, posx, ((h+1)*10)), fill=linecolor, width=linewidth)
		for hh in range(1, h+2):
			posy = hh * 10
			linecolor = 0 if (posy-(hoff*10)) % 100 == 0 else (128,128,128)
			linewidth = 2 if (posy-(hoff*10)) % 100 == 0 else 1
			draw.line((10, posy, owid, posy), fill=linecolor, width=linewidth)
		char_positions = [x*10+4 for x in range(1,max(h,w)+1)]
	#	print(char_positions)
		#char_colors = {" ": (0,0,0), "A": (0,0,0), "B": (128,0,0), "C": (0,128,0), "D": (0,255,255), "E": (128,128,0), "F": (128,0,128), "G": (0,0,0)}
		adjust = 0
		for line in lines:
			for char in range(len(line)):
		#		print(char_positions[char])
		#		print(line[char])
				try:
					draw.text((char_positions[char], char_positions[0]-4+adjust), line[char], fill=0)
				except:
					pass
			adjust += 10
		legend_out = ""
		item_ct = 0
		for item in legend:
			item_ct += 1
			legend_out += item
			if item_ct % 3 == 0:
				legend_out += "\n"
			else:
				legend_out += "    "
		draw.text((20, (h*10)+20), legend_out, fill=0)
		oimg.save(oimg_fullpath)
		print("{}".format(oimg_name))
		sys.stdout.flush()
	#	if display: 
	#		oimg.show()
	except Exception as err:
		with open("stitchify_err.log", "a") as log:
			log.write("Error: {}\n".format(str(err)))
		ostr = "stitchify_error.png"
		print(ostr)
		sys.stdout.flush()

if __name__ == "__main__":
	create_stitch(sys.argv[1])

