# -*- coding: utf-8 -*-
"""
マウスやキーボードでのキャラクター操作
"""

import tkinter as tk
import math


class Field(tk.Canvas):

    def __init__(self, master):
        super().__init__(master, width=400, height=300, bg="green")
        # Canvasはキー入力のフォーカス（受け付け）が通常できない
        # そこで，上位（ウィンドウやFrame）の方に紐づけて伝達
        master.bind("<KeyPress>",   self.keys_on_off)
        master.bind("<KeyRelease>", self.keys_on_off)
        # マウスの方は大丈夫
        self.bind("<Button>", self.click)

        # 画像の初期位置
        self.x = 150
        self.y = 100
        # クリック位置の初期位置
        self.x_to = -1
        self.y_to = -1
        # 押されたキーをkeyとするdict型で管理
        self.keysyms = {"None":False, "Down":False, "Left":False, "Right":False, "Up":False}
        # 画像を読み込んでdict型で管理
        self.imgs:tk.PhotoImage = {}
        for k in self.keysyms:
            self.imgs[k] = tk.PhotoImage(file=f"img_{k}.png")
        # 画像idの取得のみ
        self.id_img = self.create_image(self.x, self.y)
        # 描画用メソッドの呼び出し
        self.move_img()

    def move_img(self):
        now_img = self.imgs["None"]
        # 押されているキーに応じて画像の縦横の移動量を決定
        # 画像は下の方ほど優先されるが，移動量は和
        if self.keysyms["Left"]:
            now_img = self.imgs["Left"]
            self.x -= 10
        if self.keysyms["Right"]:
            now_img = self.imgs["Right"]
            self.x += 10
        
        """ 指示ここから """
        # このコメントブロックの下に，
        # 上下にも移動させられるような命令文を書きなさい．

        """ 指示ここまで """

        # マウスで指示した位置に引っ張られる
        if (self.x_to >= 0) and (self.y_to >= 0):
            # 位置は画像の大きさ分を補正
            dx = self.x_to - self.x - 50
            dy = self.y_to - self.y - 50
            # 5ピクセル分移動するための計算
            dd = 5.0 / math.sqrt(dx**2 + dy**2)
            # 2.5ピクセル以内なら停止
            if dd >= 2.0:
                self.x_to = -1
                self.y_to = -1
            else:
                self.x += dx * dd
                self.y += dy * dd

        # 画像の更新
        self.itemconfig(self.id_img, image=now_img)
        # 画像の移動，振動させないように整数化
        self.moveto(self.id_img, int(self.x), int(self.y))
        # 50ミリ秒後にもう一度
        self.after(50, self.move_img)

    # キーのON/OFFをdictに登録
    def keys_on_off(self, event:tk.Event):
        self.keysyms[event.keysym] = (event.type == tk.EventType["Key"])

    # クリックされたらその位置を登録
    def click(self, event:tk.Event):
        if event.num == 1:
            self.x_to = event.x
            self.y_to = event.y
        else:
            self.x_to = -1
            self.y_to = -1


def main():
    base = tk.Tk()
    base.title("$u_id")

    canvas = Field(base)
    canvas.pack()

    base.mainloop()  # GUIを待機


if __name__ == "__main__":
    main()
