import pygame
from pygame.display import message_box
from pygame.event import add_event_watcher, get, pump, post, Event
from pygame import Window, Clock, VIDEOEXPOSE, QUIT, KEYDOWN, K_ESCAPE, MOUSEMOTION, WINDOWRESIZED, VIDEORESIZE

pygame.init()

"""
A demo of add_event_watcher and it's advantages
"""

def eventWatcherDemo():
    """This function uses event watchers to bypass the windows SDL limitation for redrawing while moving the window"""
    window = Window("pygame", (720, 720), resizable=True)
    clock = Clock()

    #A frame counter to decide which shade of red to use
    r = 0
    g = window.size[0]

    @add_event_watcher
    def renderEventHandler(ev):
        """This event handler will be called when pygame detects a VIDEOEXPOSE event.
            This is one of the primary advantages of this approach as VIDEOEXPOSE events are received constantly when moving or resizing windows.
        """
        if window and ev.type == VIDEOEXPOSE:
            nonlocal r
            window.get_surface().fill((r, 0, 0), (0, 0, window.size[0], window.size[1]/2))
            window.get_surface().fill((0, g % 255, 0), (0, window.size[1]/2, window.size[0], window.size[1]/2))
            window.flip()

            r += 1
            r %= 255

    @add_event_watcher
    def quitEventHandler(ev):
        """This event handler will be called when pygame detects a quit event.
            This is mostly pointless and could easily be done using the standard event loop
            This is just an example
        """
        if ev.type == QUIT:
            pygame.quit()
            quit()
        elif ev.type == KEYDOWN:
            if ev.key == K_ESCAPE:
                pygame.quit()
                quit()

    @add_event_watcher
    def resizeEventHandler(ev):
        if ev.type == WINDOWRESIZED:
            nonlocal g
            g = ev.x

    while True:
        # Calling pump or get is still required for pygame and SDL internal stuff
        pump()

        # Send a VIDEOEXPOSE event to redraw using the event watcher
        post(Event(VIDEOEXPOSE))
        clock.tick(60)

def notUsingEventWatcherDemo():
    """This function demonstrates the windows SDL limitation for redrawing while moving the window"""
    window = Window("pygame", (720, 720), resizable=True)
    clock = Clock()

    #A frame counter to decide which shade of red to use
    r = 0

    while True:
        # Standard event loop
        for ev in get():
            if ev.type == QUIT:
                pygame.quit()
                quit()
            elif ev.type == KEYDOWN:
                if ev.key == K_ESCAPE:
                    pygame.quit()
                    quit()

        # Redraw the window with a new shade of red and green
        if window:
            window.get_surface().fill((r, 0, 0), (0, 0, window.size[0], window.size[1]/2))
            window.get_surface().fill((0, window.size[0] % 255, 0), (0, window.size[1]/2, window.size[0], window.size[1]/2))
            window.flip()

            r += 1
            r %= 255

        clock.tick(60)

def main():
    choice = message_box("Demo selection", "Please choose a demo", "info", None, ("Event Watcher Demo", "Not using Event Watcher Demo"))
    if choice == 0:
        eventWatcherDemo()
    elif choice == 1:
        notUsingEventWatcherDemo()

if __name__ == "__main__":
    main()