# touch.py
# Walker M. White (wmw2)
# November 17, 2015
"""Module to show off how to process touches in game2d"""
import colormodel
from game2d import *

############# CONSTANTS #############
# Window Size
WINDOW_WIDTH  = 512
WINDOW_HEIGHT = 512

# Animation Frames that constitute a click
CLICK_SPEED = 10


############# APPLICATION STATES #############
NUM_STATES = 3
STATE_ERASE = 0
STATE_DRAW  = 1
STATE_NONE  = 2


############# CONTROLLER CLASS #############
class Touch(GameApp):
    """Tracks the mouse to draw freehand lines
    
    Instance Attributes:
        view [GView]: the view (inherited from Game) 
        last [GPoint or None if mouse was not down last frame]:
            last mouse position
        time [int >= 0, 0 if mouse state changed]:
            frames since mouse last changed (pressed, released) 
        clicks [int >= 0]: # of fast clicks in a row 
        lines [list of GLine]:  set of lines to be drawn 
    """
    
    # THREE MAIN METHODS    
    def start(self):
        """Initializes application, creating new attributes."""
        self.last   = None  # The last click
        self.time   = 0
        self.clicks = 0
        self.lines  = []
        self.state  = STATE_NONE
    
    def update(self,dt):
        """Adds new lines or erases them all.
        
        Parameter dt: The time since the last animation frame.
        Precondition: dt is a float."""
        """"""
        # helper method to detect a click
        self._determineState()
        
        # Erase on double click
        if   self.state == STATE_ERASE:
            self._eraseScreen()
        elif self.state == STATE_DRAW:
            self._drawLines()
        # Else do nothing
        
        # Update mouse position (must do last)
        self.last = self.input.touch
    
    def draw(self):
        """Draws the lines"""
        for line in self.lines:
            line.draw(self.view)
    
    
    # HELPER METHODS
    def _determineState(self):
        """Determines the current state and assigns it to self.state
        
        This method checks for either the mouse being held down (continuously) or
        a double click.  The mouse is held down if neither touch nor last are None.
        A double click occurs if the mouse was pressed and released quickly twice
        in succession."""
        touch = self.input.touch
        
        # Is this a press, release or a hold
        press   = not touch is None and self.last is None
        release = touch is None and not self.last is None
        hold    = not touch is None and not self.last is None
        
        # Increment the timer
        self.time = self.time + 1
        
        # Reset timer on a press
        if press:
            # Reset clicks if not fast enought
            if self.time >= CLICK_SPEED:
                self.clicks = 0
            self.time = 0
        
        # Reset timer on release
        if release:
            # Add click if fast enough
            if self.time < CLICK_SPEED:
                self.clicks = self.clicks + 1
            else:
                self.clicks = 1
            self.time = 0
        
        # Now determine state
        if self.clicks >= 2:
            self.state  = STATE_ERASE
        elif hold:
            self.state = STATE_DRAW
        else:
            self.state = STATE_NONE
    
    def _eraseScreen(self):
        """Clears the screen and resets the click count."""
        self.clicks = 0
        self.lines = []
    
    def _drawLines(self):
        """Adds a new line from touch to last."""
        touch = self.input.touch
        
        # Specify a line as list of two points
        points = [self.last.x,self.last.y,touch.x,touch.y]
        line = GPath(points=points,linecolor=colormodel.RED)
        self.lines.append(line)


# Script Code
if __name__ == '__main__':
    Touch(width=WINDOW_WIDTH,height=WINDOW_HEIGHT,fps=60.0).run()