''' Simple example of a Windows program,
with animation responding to keypresses.
It does NOT WORK INSIDE OF Idle on Windows,
but in Winows it does work from the command line,
or double-clicked in a folder window.
It provides a mouse alternate that works on a Mac or anywhere
for  small number of fixed choices.
'''

import time
from graphics import *

try:               # check operating system
   import msvcrt
   isWin = True
except:
   isWin = False  # case for a Mac


def maybeChoice(win, rects, keys):
    '''Rects is a list of rectangles on the screen
    to check for mouse clicks (on a Mac),
    and keys is a matching list of keystroke strings (for Windows).
    Return -1 if nothing selected or else return the index in a list of
    a keypress in Windows or of a mouse click on a Mac.
    '''
    if isWin:
       if msvcrt.kbhit():
           ch = msvcrt.getwch() # read first char in keyboard buffer
           if ch in 'à\x00': # two character key sequence starts
               ch += msvcrt.getwch()
##           print('|'+ch+'|') # uncomment to see arrow and function key codes
           if ch in keys:
              return keys.index(ch)
       return -1 
    pt = win.checkMouse()
    if pt is None:
       return -1
    return getRect(rects, pt)

#### supporting graphics selection with mouse
   
def isBetween(x, end1, end2):
    '''Return True if x is between the ends or equal to either.
    The ends do not need to be in increasing order.'''  
    return end1 <= x <= end2 or end2 <= x <= end1

def isInside(point, rect):
    '''Return True if the point is inside the Rectangle rect.'''  
    pt1 = rect.getP1()
    pt2 = rect.getP2()
    return isBetween(point.getX(), pt1.getX(), pt2.getX()) and \
           isBetween(point.getY(), pt1.getY(), pt2.getY())

def labelRect(corner, width, height, label, win):
    ''' Return a Rectangle drawn in win with the upper left corner
    and centered label.'''
    corner2 = corner.clone()  
    corner2.move(width, -height)
    rect = Rectangle(corner, corner2)
    center = corner.clone()
    center.move(width/2, -height/2)
    rect.draw(win)
    Text(center, label).draw(win)
    return rect

def getRect(rects, pt):     
    '''Given a list rects of Rectangles, return the index of the Rectangle
    containing pt, or -1.'''

   
    for i, r in enumerate(rects):  # i is the number of the entry, 
        if isInside(pt, r):        #    starting from 0, not 1.
            return i
    return -1
### end of graphics selection support        


def main():

   win = GraphWin("kbMouse Test", 500, 500)
   win.yUp()
   c = Circle(Point(40, 40), 10)
   c .draw(win)

   # operating system specific display
   keys = ["q", "z", "x"]
   rects = []  
   if isWin:
       directions = 'up:z down:x quit:q'
       kbText = Text(Point(65, 10), directions)
       print('\n' + directions) # shifts keyboard focus to the console!
       kbText.draw(win)                   
   else:   
       for (x, label) in [(3, "Quit"), (41, "Up"), (76, "Down")]:
           rects.append(labelRect(Point(x,20), 35, 19, label, win))

   ok = True
   while (ok):
       i = maybeChoice(win, rects, keys)
       if i == 0:
          ok = False
       elif i == 1:
           c.move(0, 10)
       elif i == 2:
           c.move(0, -10)
       c.move(2, 0)
       time.sleep(.2)
       
   win.close()        

main()
