# for python 3
# You'll need to customize this according to your needs. Proper orientation of
# the kinect is vital; if participants are able to maintain their head or wrists
# continuously inside the word rects, they will repeatedly trigger the collision
# detection
from pykinect2 import PyKinectV2
from pykinect2.PyKinectV2 import *
from pykinect2 import PyKinectRuntime

import pygame
import random
import sys

TRACKING_COLOR = pygame.color.Color("green")
HIGHLIGHT_COLOR = pygame.color.Color("red")
BG_COLOR = pygame.color.Color("white")
GAME_TIME = 60# seconds


class BodyGameRuntime(object):
    def __init__(self):
        pygame.init()
        pygame.mixer.init()

        self.beep_sound = pygame.mixer.Sound('audio\\beep.ogg')
        self.buzz_sound = pygame.mixer.Sound('audio\\buzz.ogg')
        self._infoObject = pygame.display.Info()
        self._screen = pygame.display.set_mode((self._infoObject.current_w >> 1,
                                                self._infoObject.current_h >> 1),
                                               pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE, 32)

        pygame.display.set_caption("Kinect Game Framework Test")

        self.finished = False
        self._clock = pygame.time.Clock()
        self._kinect = PyKinectRuntime.PyKinectRuntime(PyKinectV2.FrameSourceTypes_Color |
                                                       PyKinectV2.FrameSourceTypes_Body)
        self._frame_surface = pygame.Surface((self._kinect.color_frame_desc.Width,
                                              self._kinect.color_frame_desc.Height), 0, 32)
        self._bodies = None

        self.score = 0

        self.vocab_dict = {"People drive ____ these days.":["quickly", "quick"],
                           "She has an ____ dog.":["active", "actively"],
                           "He ____ opens the mail.":["carefully", "careful"],
                           "The man ____ greets his friends.":["cheerfully", "cheerful"],
                           "That is a ____ sofa!":["comfortable", "comfortably"],
                           "The alarm sounds ____.":["continuously", "continuous"],
                           "That woman is ____!":["crazy", "crazily"],
                           "The woman speaks ____.":["delightfully", "delightful"],
                           "Juan is a very ____ carpenter.":["creative", "creatively"],
                           "Wow! That is a ____ storm!":["destructive", "destructively"],
                           "The racecar drove ____ by the school.":["powerfully", "powerful"],
                           "Juana ____ said NO!":["firmly", "firm"],
                           "He ____ opened the door.":["forcefully", "forceful"],
                           "It was a ____ day.":["glorious", "gloriously"],
                           "Maria ____ observed her ex-boyfriend.":["hatefully", "hateful"],
                           "He had a ___ idea.":["hopeful", "hopefully"],
                           "It was an ____ phrase.":["insulting", "insultingly"],
                           "Jenny ____ ate the last cookie.":["intentionally", "intentional"],
                           "He likes ____ music.":["irritating", "irritatingly"],
                           "Careful! That is a ___ dog!":["bad", "badly"],
                           "The man reacted ___ to the good news.":["speedily", "speedy"],
                           "Susana has always been a ____ girl.":["nice", "nicely"],
                           "The boys plunged into the ____ water.":["deep", "deeply"],
                           "The girl ____ saved her cat from the fire.":["bravely", "brave"],
                           "The man ____ drank too much alcohol.":["foolishly", "foolish"],
                           "Mario is ____ and never does his homework.":["lazy", "lazily"],
                           "The teacher is very ____.":["rude", "rudely"],
                           "The girl plays soccer ____.":["perfectly", "perfect"],
                           "It was an ____ crash.":["accidental", "accidentally"],
                           "That is an ____ turtle!.":["angry", "angrily"],
                           "She ____ ate her beans.":["happily", "happy"],
                           "John spoke ____.":["seriously", "serious"],
                           "Firulais is a ____ dog.":["loyal", "loyally"],
                           "Margie yelled ____ into the night.":["blindly", "blind"],
                           "He ran ____ toward me.":["wildly", "wild"],
                           "Pedro is ____!":["innocent", "innocently"],
                           "The gross man winked at her ____.":["sexually", "sexual"],
                           "Concepcion is a ____ girlfriend.":["jealous", "jealously"],
                           "Luis ____ goes to the bar.":["frequently", "frequent"],
                           "We didn't go out because it was raining ____.":["heavily", "heavy"],
                           "Our team lost the game because we played ____.":["badly", "bad"],
                           "We waited ____.":["patiently", "patient"],
                           "Jimmy arrived ____.":["unexpectedly", "unexpected"],
                           "Mike stays fit by playing tennis ____.":["regularly", "regular"],
                           "The driver of the car was ____ injured.":["seriously", "serious"],
                           "The driver of the car had ____ injuries.":["serious", "seriously"],
                           "Ismael looked ____ at Eleazar.":["hungrily", "hungry"],
                           "She is a ____ driver.":["dangerous", "dangerously"]}

        self._frame_surface.fill((255, 255, 255))

    def text_objects(self, text, font):
        text_surface = font.render(text, True, (0, 0, 0))
        return text_surface, text_surface.get_rect()

    def message_display(self, text, loc_tuple, loc_int):
        # loc_int: 1 center, 2 top left, 3 bottom left, 4 bottom right, 5 top right
        text_surf, text_rect = self.text_objects(text, pygame.font.Font(None, 64))
        loc_dict = {1:'text_rect.center', 2:'text_rect.topleft', 3:'text_rect.bottomleft',
                    4:'text_rect.bottomright', 5:'text_rect.topright'}
        exec(loc_dict[loc_int] + ' = loc_tuple')
        self._frame_surface.blit(text_surf, text_rect)
        return text_rect 

    def draw_ind_point(self, joints, jointPoints, color, highlight_color, rect0, rect1, joint0, words, sentence, correct_word):
        joint0State = joints[joint0].TrackingState;
        
        if (joint0State == PyKinectV2.TrackingState_NotTracked or
            joint0State == PyKinectV2.TrackingState_Inferred):
            return

        center = (int(jointPoints[joint0].x), int(jointPoints[joint0].y))

        if (rect0.collidepoint(center) and words[0] == correct_word) or (rect1.collidepoint(center) and words[1] == correct_word):
            self.score += 1
            self.beep_sound.play()
            pygame.time.delay(500)
            self.new_round()
        elif rect0.collidepoint(center) or rect1.collidepoint(center):
            try:
                pygame.draw.circle(self._frame_surface, highlight_color, center, 20, 0)
                self.score -= 1
                self.buzz_sound.play()
                pygame.time.delay(500)
                self.new_round()
            except: # need to catch it due to possible invalid positions (with inf)
                pass
        else:
            try:
                pygame.draw.circle(self._frame_surface, color, center, 20, 0)
            except:
                pass

    def draw_ind_intro_point(self, joints, jointPoints, color, joint0):
        joint0State = joints[joint0].TrackingState;
        
        if (joint0State == PyKinectV2.TrackingState_NotTracked or
            joint0State == PyKinectV2.TrackingState_Inferred):
            return

        center = (int(jointPoints[joint0].x), int(jointPoints[joint0].y))

        try:
            pygame.draw.circle(self._frame_surface, color, center, 20, 0)
        except:
            pass

    def update_intro_screen(self, joints, jointPoints, color):
        self._frame_surface.fill(BG_COLOR)# blank screen before drawing points

        self.draw_ind_intro_point(joints, jointPoints, color, PyKinectV2.JointType_Head)
        self.draw_ind_intro_point(joints, jointPoints, color, PyKinectV2.JointType_WristLeft)
        # may change PyKinectV2.JointType_WristRight to PyKinectV2.JointType_ElbowRight
        self.draw_ind_intro_point(joints, jointPoints, color, PyKinectV2.JointType_WristRight)

    def update_screen(self, joints, jointPoints, color, highlight_color, words, sentence, correct_word, seconds):
        self._frame_surface.fill(BG_COLOR)# blank screen before drawing points

        self.message_display(sentence, (300, 900), 2)
        rect0 = self.message_display(words[0], (400, 300), 1)
        rect1 = self.message_display(words[1], (self._frame_surface.get_width() - 400, 300), 1)
        self.message_display(str(self.score), (self._frame_surface.get_width() / 2, 800), 1)
        self.message_display(str(seconds), (self._frame_surface.get_width() - 300, 800), 1)

        self.draw_ind_point(joints, jointPoints, color, highlight_color, rect0,
                            rect1, PyKinectV2.JointType_Head, words, sentence, correct_word)
        self.draw_ind_point(joints, jointPoints, color, highlight_color, rect0,
                            rect1, PyKinectV2.JointType_WristRight, words, sentence, correct_word)
        # may change PyKinectV2.JointType_WristRight to PyKinectV2.JointType_ElbowRight
        self.draw_ind_point(joints, jointPoints, color, highlight_color, rect0,
                            rect1, PyKinectV2.JointType_WristLeft, words, sentence, correct_word)