#coding:utf-8
"""

Author's Twitter: TonyMooori

基本，自分のメモ用です．

Win10のmspaint.exe上で画像を描画するプログラムでうｓ

同一ディレクトリにペイントのボタンの画像が無いと動かないので
試しにやってみようとか思ってもだいぶ頑張らないと動きません．ゴメンナサイ．

ただreduce_color関数だけは
画像の色をMiniBatchKMeansで減色してるので，そこだけは多少使えるかと思います

"""
import numpy as np
import cv2
import time
import pyautogui as pa

def set_size(src):
	# 対角線の長さが200になるようなスケールを計算
	h,w,c = src.shape
	scale = 200.0 / np.sqrt( h**2 + w**2 )
	h = int(h*scale)
	w = int(w*scale)
	
	# リサイズ
	return cv2.resize(src,(w,h))

def reduce_color(src):
	# k-meansでクラスタリング
	# -> 代表値に置き換えることで自然?な減色をする
	from sklearn.cluster import MiniBatchKMeans
	X = src.reshape(src.shape[0]*src.shape[1],3)
	clf = MiniBatchKMeans(16)
	y = clf.fit_predict(X)
	return clf.cluster_centers_[y].reshape(src.shape).astype(np.uint8)

def to_num(c):
	# uint8 x 3 の色データを int 型にする
	return c[:,:,0] * ( 2 ** 16 ) + c[:,:,1] * ( 2 ** 8 ) + c[:,:,2]

def to_col(c):
	# int型のデータを分割してr,g,bに分ける
	r = c % 256
	g = ( c//( 2 ** 8 ) ) % 256
	b = ( c//( 2 ** 16 ) ) % 256
	return np.array([r,g,b])

def img_click(path):
	# 指定の画像の場所をクリックする
	while True:
		pos = pa.locateCenterOnScreen(path)
		if pos != None:
			pa.click(pos)
			return

def change_color(color):
	# ペイントの各ボタンを順番にクリックする
	r = color[0]
	g = color[1]
	b = color[2]
	
	# 真っ白とか描画する必要ない
	if r > 250 and g > 250 and b > 250:
		return True
	
	# ボタンを順にクリックしてく
	img_click("color_edit.png")
	pos = None
	while pos == None:
		pos = pa.locateCenterOnScreen("red.png")
	pa.click( (pos[0]+30,pos[1]) )
	pa.hotkey('ctrl', 'a') 
	pa.typewrite(str(r))
	pa.click( (pos[0]+30,pos[1]+27) )
	pa.hotkey('ctrl', 'a') 
	pa.typewrite(str(g))
	pa.click( (pos[0]+30,pos[1]+60) )
	pa.hotkey('ctrl', 'a') 
	pa.typewrite(str(b))
	img_click("ok.png")
	
	return False

def draw_img(src):
	# 画像を描画する
	
	# 色を抽出してピクセル数が大きい順にソート
	# 多分もっとスマートな書き方がある
	img = to_num(src)
	color_list = np.unique(img)
	color_num = np.zeros(len(color_list))
	for i in range(len(color_list)):
		col = color_list[i]
		color_num[i] = len(np.where( img == col )[0])
	arg_list = np.argsort(color_num)[::-1]
	color_list = color_list[arg_list]
	
	# 高さ・幅を抽出
	h,w = img.shape
	
	# 5秒待って
	time.sleep(5)
	
	# 初期のマウスの座標を取得
	x0 = pa.position()[0]
	y0 = pa.position()[1]
	
	# ピクセル間の距離
	side = 5
	
	# Python夢の重ループ！！！！
	# 色を順番に描画してくよ！！
	for col in color_list:
		
		# 色をセットする
		if change_color(to_col(col)):
			continue
		
		# ドラッグ中ならTrueになるフラグ
		isDragging = False
		
		for j in range(h):
			for i in range(w):
				# 現在の座標取得
				x = x0 + side * i
				y = y0 + side * j
				
				if col == img[j,i]:
					# ドラッグスタート
					if isDragging == False:
						pa.moveTo(x,y)
						pa.mouseDown()
						isDragging = True
				
				elif isDragging == True:
					# ドラッグ終了
					pa.moveTo(x,y)
					pa.mouseUp()
					isDragging = False
			
			# 一行書いたらmouseUp
			pa.mouseUp()
	
if __name__=="__main__":
	pa.PAUSE = 0.000001
	src = cv2.imread("miku.jpg")
	src = set_size(src)			# 大きさ調節
	src = reduce_color(src)		# k-meansで減色
	draw_img(src) 				# 描画
