#
# Copyright 2023, Ali Arya
# Anyone Can Code: Algorithmic Thinking
# Example 4.8p
#

# graphics.py
# http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/graphics.html 
# http://www.pas.rochester.edu/~rsarkis/csc161/python/pip-graphics.html

# graphic library
from graphics import *
# for timer and sleep functions
import time
import random
import math

#simple game

########################################################################
#global variables 
########################################################################
window = None
quit = False
win = False
playerMoveX = 0
playerMoveY = 0  
enemyMoveX = 0
enemyMoveY = 0
player = None
playerX = 0
playerY = 0
playerR = 30    
enemy = None
enemyX = 100
enemyY = 100
prize = None
prizeX = 200
prizeY = 200
distance = 0    #player to prize
state = "walk"  #guard/enemy state


########################################################################
#Modules
########################################################################
def prizeCheck():
    global playerX, playerY, prizeX, prizeY, prize, quit, win, distance
    distanceX = abs(playerX - prizeX)
    distanceY = abs(playerY - prizeY)
    distance = math.sqrt(distanceX*distanceX + distanceY*distanceY)
    if distanceX<10 and distanceY<10:
        prize.move(1000,1000)   #make it disappear (go off screen). There are other ways too!
        quit = True
        win = True

def enemyCheck():
    global playerX, playerY, enemyX, enemyY, quit
    distanceX = abs(playerX - enemyX)
    distanceY = abs(playerY - enemyY)
    if distanceX<10 and distanceY<10:
        quit = True

def playerMove():
    global window, playerX, playerY, playerMoveX, playerMoveY, quit
    key = window.checkKey()
    playerMoveX = playerMoveY = 0
    if key=='Escape':
        quit = True
    if key=='Up':
        playerMoveY -= 5
    if key=='Down':
        playerMoveY += 5
    if key=='Right':
        playerMoveX += 5
    if key=='Left':
        playerMoveX -= 5
    playerX += playerMoveX
    playerY += playerMoveY

def walk():
    global enemyMoveX, enemyMoveY
    enemyMoveX = random.randint(-2,2)
    enemyMoveY = random.randint(-2,2)
def watch():
    global enemyMoveX, enemyMoveY
    enemyMoveX = 0
    enemyMoveY = 0
def attack():
    global enemyMoveX, enemyMoveY, enemyX, enemyY, playerX, playerY
    enemyMoveX = 0
    enemyMoveY = 0
    if playerX > enemyX:
        enemyMoveX = 1
    if playerX < enemyX:
        enemyMoveX = -1
    if playerY > enemyY:
        enemyMoveY = 1
    if playerY < enemyY:
        enemyMoveY = -1
    enemyX += enemyMoveX
    enemyY += enemyMoveY

def enemyMove():
    global state
    if state == "walk":
        walk()
    elif state == "watch":
        watch()
    else:
        attack()
def init():
    global window, player, enemy, prize
    window = GraphWin('Game', 600, 600) # give title and dimensions

    #player
    player = Circle(Point(playerX,playerY), playerR) # set center and radius
    player.setFill("yellow")

    #enemy
    enemy = Image(Point(enemyX, enemyY), "enemy.png")

    #prize
    prize = Image(Point(prizeX, prizeY), "prize.png")

    #draw in the order we want to see on screen (last one will be on top)
    prize.draw(window)
    enemy.draw(window)
    player.draw(window)     

def update():
    global distance, state
    prizeCheck()
    enemyCheck()
    playerMove()
    #detect/transition state
    state = "walk"
    if distance > 200:
        state = "walk"
    elif distance > 100:
        state = "watch"
    else:
        state = "attack"
    #perform satate action
    enemyMove()

def draw():
    global playerMoveX, playerMoveY, playerX, playerY, enemyMoveX, enemyMoveY
    #if playerMoveX != 0 or playerMoveY != 0:
    player.move(playerMoveX,playerMoveY)    
    #enemy needs drawing 
    enemy.move(enemyMoveX,enemyMoveY)

def mainloop():
    global quit, win, window
    while not quit:
        update()
        draw()
        time.sleep(0.05)
    window.close()
    if win == True:
        print("you win!")
    else:
        print("you lose!")

#game main loop is called after init
init()
mainloop()