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


'''

anaglyph
v0.1.0

Attempts to create a valid 3D-glasses structure

LICENCE : CC

by cocoa 


'''
from __future__ import print_function
import argparse
import ast
import math
import os
import random
import sys
import time 
name = "filters::cycle"

maxDist = 300

argsparser = argparse.ArgumentParser(description="Redis exporter LJ")
argsparser.add_argument("-x","--centerX",help="geometrical center X position",default=400,type=int)
argsparser.add_argument("-y","--centerY",help="geometrical center Y position",default=400,type=int)
argsparser.add_argument("-m","--min",help="Minimal displacement (default:2) ",default=1,type=int)
argsparser.add_argument("-M","--max",help="Maximal displacement (default:20) ",default=5,type=int)
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose")

args    = argsparser.parse_args()
fps     = args.fps
minVal  = args.min
maxVal  = args.max
centerX = args.centerX
centerY = args.centerY
verbose = args.verbose

optimal_looptime = 1 / fps
name    = "filters::anaglyph"

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

def rgb2int(rgb):
    #debug(name,"::rgb2int rbg:{}".format(rgb))
    return int('0x%02x%02x%02x' % tuple(rgb),0)

def isValidColor( color, intensityColThreshold  ):
    if color[0] + color[1] + color[2] > intensityColThreshold:
        return True
    return False

# These are paper colors
red     = (41,24,24)
white   = (95,95,95)
blue    = (0,41,64)

red     = (255,0,0)
blue    = (0,255,255)
white   = (255,255,255)
def anaglyph( pl ):

    debug(name,'--------------- new loop ------------------')
    # We will send one list after the other to optimize color change
    blueList        = list()
    redList         = list()
    whiteList       = list()
    out = []
    out1 = []
    out2 = []
    out3 = []

    # The anaglyphic effect will be optained by :
    # * having close objects appear as white
    # * having distant objects appear as blue + red 
    # * having in between objects appear as distanceDecreased(white) + blue + red 
    for i, point in enumerate(pl):
        ref_x       = point[0]-centerX
        ref_y       = point[1]-centerY
        ref_color   = point[2]
        angle       = math.atan2( ref_x  , ref_y )
        dist        = ref_y / math.cos(angle)
        white_rvb   = (0,0,0)
        blue_rvb    = (0,0,0)
        red_rvb     = (0,0,0)

        # Calculate the point's spread factor (0.0 to 1.0) 
        # The spread is high if the point is close to center
        """
        dist = 0 :      spread = 1.0
        dist = maxDist  spread = 0.0
        """
        if dist == 0:
            spread      = 1.0
        else : 
            spread      =( maxDist - dist ) / maxDist
        if spread < 0.0: 
            spread      = 0.0

        #debug(name,"dist:{} spread:{}".format(dist,spread))

        # White color is high if spread is low, i.e. point away from center 
        """ 
        spread = 1.0 : white_c = 0.0
        spread = 0.0 : whice_c = 1.0
        """
        if point[2] == 0:
            white_color = 0
        else:
            white_factor    = 1.0 - math.pow(spread,0.5)
            white_rvb       = tuple(map( lambda a: int(white_factor* a), white))
            white_color     = rgb2int( white_rvb)
            #debug(name,"spread:{}\t white_rvb:{}\t white_color:{}".format(spread, white_rvb, white_color))

        # Blue and Red colors are high if spread is high, i.e. close to center
        """
        spread = 1.0 : red_c = 1.0
        spread = 0.0 : red_c = 0.0
        """
        color_factor        = math.pow(spread,1)
        if point[2] == 0:
            blue_color      = 0 
            red_color       = 0 
        else:
            blue_rvb        = tuple(map( lambda a: int(color_factor * a), blue))
            blue_color      = rgb2int( blue_rvb)
            red_rvb         = tuple(map( lambda a: int(color_factor * a), red))
            red_color       = rgb2int( red_rvb)
        
        #debug(name,"color_factor:{}\t\t blue_color:{}\t\t red_color:{}".format(color_factor,blue_color,red_color))

        # Blue-to-Red spatial spread is high when spread is high, i.e. point close to center
        """
        spread = 1.0 : spatial_spread = maxVal 
        spread = 0.0 : spatial_spread = minVal
        """
        spatial_spread = minVal + spread * (maxVal - minVal)
        #debug(name,"spatial_spread:{}".format(spatial_spread))
        red_x       = int(point[0] + spatial_spread)
        blue_x      = int(point[0] - spatial_spread ) 
        red_y       = int(point[1] )
        blue_y      = int(point[1])

        white_point     = [point[0], point[1], white_color]
        blue_point      = [blue_x,blue_y,blue_color]
        red_point      = [red_x,red_y,red_color]

        #debug(name,"white[x,y,c]:{}".format(white_point))
        #debug(name,"blue[x,y,c]:{}".format(blue_point))
        #debug(name,"red[x,y,c]:{}".format(red_point))
        # Do not append "black lines" i.e. a color where each composent is below X
#        if isValidColor(white_rvb, 150):
#            out1.append(white_point)
#        if isValidColor(blue_rvb, 50):
#            out2.append(blue_point)
#        if isValidColor(red_rvb, 30):
#            out3.append(red_point)
        out1.append(white_point)
        out2.append(blue_point)
        out3.append(red_point)
        
    #debug(name,"source pl:{}".format(pl))
    debug(name,"whiteList:{}".format(out1))
    debug(name,"blueList:{}".format(out2))
    debug(name,"redList:{}".format(out3))
    return out3 + out2
    return out1 + out3 + out2
    #return out1 + out2 + out3 


  
try:
    while True:
      start = time.time()
      line = sys.stdin.readline()
      if line == "":
         time.sleep(0.01)
      line = line.rstrip('\n')
      pointsList = ast.literal_eval(line)
      # Do the filter
      result = anaglyph( pointsList ) 
      print( result, flush=True )
      looptime = time.time() - start
      # debug(name+" looptime:"+str(looptime))
      if( looptime < optimal_looptime ):
        time.sleep( optimal_looptime - looptime)
        # debug(name+" micro sleep:"+str( optimal_looptime - looptime))
except EOFError:
    debug(name+" break")# no more information

