#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-

'''

A Face tracker 
v0.1.0

Get all points fom redis /trckr/frame/WSclientID points

LICENCE : CC

by cocoa and Sam Neurohack

'''

from __future__ import print_function
import time
import argparse
import sys
import redis
import ast

name="generator::trckr"


def debug(*args, **kwargs):
    if( verbose == False ):
        return
    print(*args, file=sys.stderr, **kwargs)


argsparser = argparse.ArgumentParser(description="Face tracking generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
argsparser.add_argument("-i","--id",help="Trckr client ID",default="0",type=str)
argsparser.add_argument("-s","--server",help="redis server IP (127.0.0.1 by default)", type=str)
args = argsparser.parse_args()

fps=args.fps
verbose=args.verbose
idclient = args.id

if args.server:
    redisIP = args.server
else:
    redisIP = "127.0.0.1"



optimal_looptime = 1 / fps
debug(name+" optimal looptime "+str(optimal_looptime))

color = 65280


def rgb2int(rgb):
    return int('0x%02x%02x%02x' % tuple(rgb),0)

# Useful variables init.
white = rgb2int((255,255,255))
red = rgb2int((255,0,0))
blue = rgb2int((0,0,255))
green = rgb2int((0,255,0))

#
# Redis functions
#

r = redis.StrictRedis(host=redisIP , port=6379, db=0)

# read from redis key
def fromKey(keyname):

   return r.get(keyname)

# Write to redis key 
def toKey(keyname,keyvalue):
   return r.set(keyname,keyvalue)

#
# Trckr faces
# 

TrckrPts = [[159.39, 137.68], [155.12, 159.31], [155.56, 180.13], [159.81, 201.6], [170.48, 220.51], [187.46, 234.81], [208.4, 244.68], [229.46, 248.21], [246.44, 244.91], [259.69, 234.83], [270.95, 221.51], [278.54, 204.66], [283.53, 185.63], [286.27, 165.79], [284.72, 144.84], [280.06, 125.01], [274.35, 118.7], [260.71, 117.23], [249.52, 118.86], [182.04, 121.5], [193.63, 114.79], [210.24, 114.77], [222.35, 117.57], [190.6, 137.49], [203.59, 132.42], [214.75, 137.58], [203.04, 140.46], [203.32, 136.53], [272.45, 141.57], [263.33, 135.42], [250.31, 138.89], [262.15, 143.27], [261.99, 139.37], [235.82, 131.74], [221.87, 156.09], [213.66, 165.88], [219.28, 173.53], [236.3, 175.25], [249.02, 174.4], [254.22, 167.81], [248.83, 157.39], [237.94, 147.51], [227.01, 168.39], [245.68, 170.02], [204.94, 197.32], [217.56, 192.77], [228.27, 190.55], [234.66, 192.19], [240.47, 191.09], [247.96, 193.87], [254.52, 199.19], [249.35, 204.25], [242.74, 207.16], [233.2, 207.87], [222.13, 206.52], [212.44, 203.09], [220.34, 198.74], [233.31, 200.04], [244.0, 199.6], [244.27, 197.8], [233.81, 197.44], [220.88, 196.99], [239.57, 162.69], [196.52, 133.86], [210.2, 133.98], [209.43, 139.41], [196.59, 139.47], [268.99, 137.59], [256.36, 136.02], [255.95, 141.5], [267.9, 142.85]]
toKey('/trckr/frame/0',str(TrckrPts))

# get absolute face position points 
def getPART(TrckrPts, pose_points):

    dots = []
    #debug(pose_points)
    #debug(TrckrPts)
    for dot in pose_points:
      dots.append((TrckrPts[dot][0], TrckrPts[dot][1],0))
    #debug(dots)
    return dots


# Face keypoints
def face(TrckrPts):
    pose_points = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
    return getPART(TrckrPts, pose_points)

def browL(TrckrPts):
    pose_points = [15,16,17,18]
    return getPART(TrckrPts, pose_points)

def browR(TrckrPts):
    pose_points = [22,21,20,19]
    return getPART(TrckrPts, pose_points)

def eyeR(TrckrPts):
    pose_points = [25,64,24,63,23,66,26,65,25]
    return getPART(TrckrPts, pose_points)

def eyeL(TrckrPts):
    pose_points = [28,67,29,68,30,69,31,28]
    return getPART(TrckrPts, pose_points)

def pupR(TrckrPts):
    pose_points = [27]
    return getPART(TrckrPts, pose_points)

def pupL(TrckrPts):
    pose_points = [32]
    return getPART(TrckrPts, pose_points)


def nose1(TrckrPts):
    pose_points = [62,41,33]
    return getPART(TrckrPts, pose_points)

def nose2(TrckrPts):
    pose_points = [40,39,38,43,37,42,36,35,34]
    return getPART(TrckrPts, pose_points)

def mouth(TrckrPts):
    pose_points = [50,49,48,47,46,45,44,55,54,53,52,51,50]
    return getPART(TrckrPts, pose_points)

def mouthfull(TrckrPts):
    pose_points = [50,49,48,47,46,45,44,55,54,53,52,51,50,59,60,61,44,56,57,58,50]
    return getPART(TrckrPts, pose_points)


while True:

  start = time.time()
  shape =[]
  points = ast.literal_eval(fromKey('/trckr/frame/'+idclient).decode('ascii'))
  shape.append(browL(points))
  shape.append(eyeL(points))
  shape.append(browR(points))
  shape.append(eyeR(points))
  shape.append(pupL(points))
  shape.append(pupR(points))
  shape.append(nose1(points))
  shape.append(nose2(points))
  shape.append(mouthfull(points))
  line = str(shape)
  line = line.replace("(",'[')
  line = line.replace(")",']')
  line = "[{}]".format(line)
  print(line, flush=True);
  #debug(shape)
  #print(shape, flush=True);

  looptime = time.time() - start
  if( looptime < optimal_looptime ):
    time.sleep( optimal_looptime - looptime)
    debug(name+" micro sleep:"+str( optimal_looptime - looptime))
  

