import pyautogui

"""
Explanation: Lesson 48:
Controlling the Mouse with Python
Python can be used to control the keyboard and mouse, which allows us to automate any program that uses these as inputs. 
Graphical User Interface (GUI) Automation is particularly useful for repetative clicking or keyboard entry. The program's own module will probably deliver better programmatic performance, but GUI automation is more broadly applicable. 
We will be using the pyautogui module. The documentation is available here.
You can follow instructions on this page to install the necessary packages. (I had particular trouble installing the pyobjc dependency, so if you have similar issues in your environment, it might be useful to install it from source using Mercurial. You may also need the pillow module.)
End of explanation
"""


pyautogui.size()

"""
Explanation: This lesson will control all the mouse controlling functions in this module. 
The module treats the screen as cartesian coordinates of pixels, with x referencing a point on the horizontal line, and y referencing a point on the vertical line. 

We can examine the available screen size using the size() function, with variables returned as an (x,y) pair.
End of explanation
"""


width, height = pyautogui.size()

"""
Explanation: We can store this tuple in two variables, width and height:
End of explanation
"""


pyautogui.position()

"""
Explanation: Similarly, the position() function returns the current position of the mouse cursor.
End of explanation
"""


# left corner
print(pyautogui.position())

# right corner
print(pyautogui.position())

"""
Explanation: The left and right most corners are 1 less than the maximum.
End of explanation
"""


pyautogui.moveTo(10,10)

"""
Explanation: The first function to control the mouse is the moveTo() function, which moves the mouse immediately to an absolute location.
End of explanation
"""


pyautogui.moveTo(10,10, duration=2)

"""
Explanation: We can pass the duration parameter to this function slow down this process to simulate human activity over the duration defined.
End of explanation
"""


pyautogui.moveRel(200, 0, duration=2)

"""
Explanation: We can also use the moveRel() function to move the mouse relative to a certain position.
End of explanation
"""


pyautogui.moveRel(0, -100, duration=1.5)

"""
Explanation: We can also pass in y coordinates to move up or down, but we have to use negative values to move 'up' in a relative way.
End of explanation
"""


# Find the 'Help' button in the top Jupyter Navigation
# helpCoordinates = pyautogui.position()

helpCoordinates = (637, 126)

# Click at those coordinates
pyautogui.click(helpCoordinates)

"""
Explanation: Now that we have mastered movement, we can now use click() functions to interact with objects.
End of explanation
"""


pyautogui.moveRel(0, -100, duration=1.5)

"""
Explanation: We can use functions like rightClick(), doubleClick(), or middleClick() for similar behavior. We can even run these functions without any coordinates, which will click at any particular location. 
We also have dragRel() and dragTo() functions, which can be used to click and drag; used here to draw in a paint program.

An important thing to note is that during automation, the script will control your mouse and keyboard, which may affect your ability to interact with the computer (like what happened in Fantasia).
To avoid this pyautogui has a built in fail safe, which checks if the mouse is in coordinate (0,0); the top left of the screen. If it is, the script terminates. Commands take a tenth of a second between commands to run, so any indicator in that period will raise an error.
End of explanation
"""


# Not run here, just keeps spitting out print functions. Much more useful in the terminal.
pyautogui.displayMousePosition()

"""
Explanation: To make pyautogui useful, you need to know the coordinates on the screen at any given time, and interact with them. The module contains a useful sub program, called displayMousePosition, which can be run via the terminal to track the position of the real-time mouse at any given time (it also returns RGB values.)
End of explanation
"""


