#!/usr/bin/python

import numpy as np

# test data

width = 240
height = 300

a = np.array(           #  x  y
    [[[ 64, 237, 108],  # [0, 0]
      [185, 240,  68],  # [0, 1]      test five
      [ 17, 116,  55],  # [0, 2] is said to be blue (THIRD) XXX
      [107,  11, 185],  # [0, 3] is blue (SIXTH)
      [154,  30,  52]], # [0, 4]

     [[251,  73, 150],  # [1, 0]
      [ 47, 225,  97],  # [1, 1]
      [101,  91, 251],  # [1, 2] is blue (FOURTH)
      [ 61,  23,  79],  # [1, 3]
      [161,  22, 165]], # [1, 4]

     [[  4, 162, 188],  # [2, 0]
      [ 25, 131, 211],  # [2, 1] is blue (SECOND)
      [162, 112, 177],  # [2, 2]
      [169,  83, 214],  # [2, 3] is blue (not reported)
      [254, 139,  95]], # [2, 4]

     [[  2,  88, 216],  # [3, 0] is blue (FIRST)
      [230,  63, 192],  # [3, 1]
      [ 71,  78,  50],  # [3, 2] is said to be blue (FIFTH)
      [113, 151, 150],  # [3, 3] is said to be blue (SEVENTH)
      [104,  65, 250]], # [3, 4] is blue (EIGHTH)

     [[  6, 191, 220],  # [4, 0] is blue (not reported)
      [ 38, 141,   4],
      [245,  41,  23],
      [ 23, 127, 183],  # [4, 3] is blue (not reported)
      [165,  24,   5]]], np.uint8)

def color_filter(ary, f):
    """thanks to Stefan van der Walt"""
    RED, GRN, BLU = 0, 1, 2
    bluemask = (ary[...,BLU] > f*ary[...,GRN]) & \
               (ary[...,BLU] > f*ary[...,RED])
    print "color_filter with factor=%f" % f
    return np.array(bluemask.nonzero()).swapaxes(0,1).tolist()  # Wow.

def flip_Y(L):
    # wx coords have y=0 in the upper left.  ug.
    h = int(height)
    M = []
    for x, y in L:      
        x, y = int(x), int(y) # these 2 lines
        M.append([x, h-y])    # ...lock up! if you dont do the int() coersion!
    return M

def interpolate(L):
    # uniqify per X (while we are at it), bias for the first one
    # if we add the test max will be 10 passes or so, will fill across 20 pixels I think
    c = 10
    # init the seen list with the x"s that we know
    seenx = [x for x, y in L]
    if 1: print "seenx=%r" % seenx
    M = [True]  # start condition
    while M: # and c:  
        M = []  # if M doesnt get built on each pass we are done
        for i in range(len(L)-1):
            x1, y1 = L[i] 
            x2, y2 = L[i+1]
            if x2-x1 > 1:
                #mean = (int((x1+x2)/2), int((y1+y2)/2))  # error accumulates if I int(everything)
                mean = ((x1+x2)/2.0, (y1+y2)/2.0) 
                if 1: print "mean=(%i, %i)" % (mean[0], mean[1])
                if int(mean[0]) not in seenx:  # int() or it wont stop
                    #print "seenx=%r" % seenx
                    M.append(mean)
                    seenx.append(int(mean[0])) 
            L.extend(M)
            L.sort()  # sort on every pass
        if 0: print "M=%r, count=%i" % (M, c)
        c -= 1
    return L

def roundlist(L):
    M = []
    for x, y in L:
        M.append((int(x), int(y)))
    return M

def scale(L, width, height, time_coord_min, time_coord_max, world_coord_min, world_coord_max):
    # pixels to world coordinates
    spanx_in_pixels = int(width)
    spanx_in_time = float(time_coord_max) - float(time_coord_min)
    spany_in_pixels = height
    spany_in_world = float(world_coord_max) - float(world_coord_min)
    pix_per_time_unit = spanx_in_pixels/spanx_in_time
    pix_per_world_unit = spany_in_pixels/spany_in_world
    offsetx = float(time_coord_min)
    offsety = float(world_coord_min)
    if 1: print "scale: pix_per_time_unit=%f, pix_per_world_unit=%f" % (pix_per_time_unit, pix_per_world_unit)
    M = []
    for x, y in L:
        x, y = int(x), int(y)
        M.append((int(x/pix_per_time_unit) + offsetx, int(y/pix_per_world_unit) + offsety))
    return M

def uniqify(L):
    # uniqify leaves one point per X, bias for the first one
    seen = []
    M = []
    for x, y in L:
        x, y = int(x), int(y)
        if x not in seen:  # uniqify per X, bias for the first one
            M.append((x, y))
            seen.append(x)
    return M
 
def vanderWalt(a, f):
    """thanks to Stefan van der Walt"""
    RED, GRN, BLU = 0, 1, 2
    bluemask = (a[...,BLU] > f*a[...,GRN]) & \
               (a[...,BLU] > f*a[...,RED])
    print "vanderWalt called with factor=%f" % f
    return np.array(bluemask.nonzero()).swapaxes(0,1).tolist()

def test():
    #L = color_filter(a, 1.5)
    L  = [[0, 3], [5, 6], [10, 9], [15, 12], [20, 15], [20, 51]] # last val will be tossed
    M = flip_Y(L)    
    print "flipped: M=%r" % M
    N = uniqify(M)   
    print "uniq: N=%r" % N
    P = roundlist(interpolate(N))
    print "interpolated: P=%r" % P
    Q = uniqify(P) 
    print "uniq: Q=%r" % Q
 
    time_coord_min =    0
    time_coord_max =   24
    world_coord_min =   0
    world_coord_max = 100 
    #print scale(interpolate([(0, 288), (3, 292), (7, 296), (11, 300)]), time_coord_min, time_coord_max, world_coord_min, world_coord_max)
    # [(0, 96), (0, 96), (0, 97), (0, 97), (0, 97), (0, 98), (0, 98), (0, 98), (0, 99), (0, 99), (1, 99), (1, 100)]
    #print uniqify(scale(interpolate([(0, 288), (3, 292), (7, 296), (11, 300)]), time_coord_min, time_coord_max, world_coord_min, world_coord_max))
    # [(0, 96), (1, 99)]  only a coupla points left because our x numbers wre so low
    #print uniqify(scale(interpolate(color_filter(a, 1.5)), width, height, time_coord_min, time_coord_max, world_coord_min, world_coord_max))
#test()