from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

def generate_sudoku():
	base  = 3
	side  = base*base

	# pattern for a baseline valid solution
	def pattern(r,c): return (base*(r%base)+r//base+c)%side

	# randomize rows, columns and numbers (of valid base pattern)
	from random import sample
	def shuffle(s): return sample(s,len(s)) 
	rBase = range(base) 
	rows  = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ] 
	cols  = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
	nums  = shuffle(range(1,base*base+1))

	# produce board using randomized baseline pattern
	board = [ [nums[pattern(r,c)] for c in cols] for r in rows ]

	# for line in board: print(line)
	# solution = board
	# print(solution)


	squares = side*side
	empties = squares * 3//5
	# empties = squares * diff
	# print(squares)
	# print(empties)
	# print(squares * 13//20)
	for p in sample(range(squares),empties):
		board[p//side][p%side] = 0

	# numSize = len(str(side))
	# for line in board:
	# 	print(*(f"{n or '.':{numSize}} " for n in line))


	def expandLine(line):
		return line[0]+line[5:9].join([line[1:5]*(base-1)]*base)+line[9:13]
		# return line[0]+line[3:7].join([line[1:3]*(base-1)]*base)+line[3:5]
		# return line[0]+line[3:5].join([line[1:3]*(base-1)]*base)+line[5:7]
		# return line[0]+line[4:7].join([line[1:4]*(base-1)]*base)+line[7:10]
	line0  = expandLine("╔═══╤═══╦═══╗")
	line1  = expandLine("║ . │ . ║ . ║")
	line2  = expandLine("╟───┼───╫───╢")
	line3  = expandLine("╠═══╪═══╬═══╣")
	line4  = expandLine("╚═══╧═══╩═══╝")
	# line0  = expandLine("╔═╤═╦═╗")
	# line1  = expandLine("║.│.║.║")
	# line2  = expandLine("╟─┼─╫─╢")
	# line3  = expandLine("╠═╪═╬═╣")
	# line4  = expandLine("╚═╧═╩═╝")
	# line0  = expandLine("╔═╤═╦═╗")
	# line1  = expandLine("║.│.║.║")
	# line2  = expandLine("╟─┼─╫─╢")
	# line3  = expandLine("╠═╪═╬═╣")
	# line4  = expandLine("╚═╧═╩═╝")	
	# line0  = expandLine("╔══╤══╦══╗")
	# line1  = expandLine("║. │. ║. ║")
	# line2  = expandLine("╟──┼──╫──╢")
	# line3  = expandLine("╠══╪══╬══╣")
	# line4  = expandLine("╚══╧══╩══╝")

	symbol = " 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	nums   = [ [""]+[symbol[n] for n in row] for row in board ]
	output = []
	# print(line0)
	output.append(line0)
	for r in range(1,side+1):
		output.append("".join(n+s for n,s in zip(nums[r-1],line1.split("."))))
		output.append([line2,line3,line4][(r%side==0)+(r%base==0)])
		# print( "".join(n+s for n,s in zip(nums[r-1],line1.split("."))) )
		# print([line2,line3,line4][(r%side==0)+(r%base==0)])

	# print('=')
	# print(output)
	# for x in output:
		# print(x)
	# print('-')
	return output



def convert_to_image(sudoku):
	# sample text and font
	# unicode_text = u"Unicode Characters: \u00C6 \u00E6 \u00B2 \u00C4 \u00D1 \u220F"
	unicode_text = sudoku[0]
	verdana_font = ImageFont.truetype("application/IBMPlexMono-Medium.ttf", 16, encoding="unic")

	# get the line size
	text_width, text_height = verdana_font.getsize(unicode_text)

	# create a blank canvas with extra space between lines
	canvas = Image.new('RGB', (text_width + 10, (text_height*(len(sudoku)-1))), (255, 255, 255))
	# canvas.convert('L')


	# draw the text onto the text canvas, and use black as the text color
	draw = ImageDraw.Draw(canvas)
	
	# for x in sudoku:
	pos = 0
	for x in sudoku:
		unicode_text = x
		draw.text((5,pos), unicode_text, font = verdana_font, fill = "#000000")
		pos += (text_height-2)

	# save the blank canvas to a file
	# fn = lambda x : 255 if x > 200 else 0
	# canvas.convert('L').point(fn, mode='1')
	canvas.save("sudoku.png", "PNG")
	# img = Image.new('RGB', (200, 100))
	# d = ImageDraw.Draw(img)
	# d.text((30, 20), sudoku[0], fill=(255, 0, 0))
	# text_width, text_height = d.textsize(sudoku[0])
	# print(text_width, text_height)

if __name__ == '__main__':
	su = generate_sudoku()
	for x in su:
		print(x)
	convert_to_image(su)
	print(su)
	# for x in generate_sudoku():
		# print(x)


# print(board)

# import random
# from itertools import islice
# print([*islice(shortSudokuSolve(board),2)][0])
# print([*islice(shortSudokuSolve(board),2)][1])
# if [*islice(shortSudokuSolve(board),2)][0] == [*islice(shortSudokuSolve(board),2)][1]:
# 	print('ay')
# else:
# 	print('er')


# while True:
# 	solved  = [*islice(shortSudokuSolve(board),2)]
# 	# print(len(solved))
# 	# print(solved)
# 	if len(solved)==1:
# 		# print('yay!')
# 		break
# 	diffPos = [(r,c) for r in range(9) for c in range(9)
# 			   if solved[0][r][c] != solved[1][r][c] ] 
# 	r,c = random.choice(diffPos)
# 	board[r][c] = solution[r][c]
# 	# print(board)
# 	print(r,c)
# 	# print(board)


# print(board)
# print(solution)
# print('ysy')

# def expandLine(line):
# 	return line[0]+line[5:9].join([line[1:5]*(base-1)]*base)+line[9:13]
# line0  = expandLine("╔═══╤═══╦═══╗")
# line1  = expandLine("║ . │ . ║ . ║")
# line2  = expandLine("╟───┼───╫───╢")
# line3  = expandLine("╠═══╪═══╬═══╣")
# line4  = expandLine("╚═══╧═══╩═══╝")

# symbol = " 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# nums   = [ [""]+[symbol[n] for n in row] for row in board ]
# output = []
# print(line0)
# output.append(line0)
# for r in range(1,side+1):
# 	output.append("".join(n+s for n,s in zip(nums[r-1],line1.split("."))))
# 	output.append([line2,line3,line4][(r%side==0)+(r%base==0)])
# 	print( "".join(n+s for n,s in zip(nums[r-1],line1.split("."))) )
# 	print([line2,line3,line4][(r%side==0)+(r%base==0)])

# print('==')
# print(output)
# for x in output:
# 	print(x)
# print('--')

	# return output

