import display
import bhi160

SENSITIVITY=20
FRICTION=0.97
BOUNCE=0.2
HIGHPASS=0.4

COL_BACKGROUND=[70,0,70]
COL_EYEWEISS=[255,255,255]
COL_PUPILS=[0,0,0]
COL_PUPILSHADOW=[255,255,255]
COL_EYELINER=[0,0,0]

EYEPOS=[[52,40],[108,40]]

SIZE_PUPILS=[5,7]
SIZE_EYEWEISS=[23,32]
DRAMA_EYELINER=[28,40]

ROOTTWO=2**(-1/2)
RANGE_CENTER=[SIZE_EYEWEISS[x]-SIZE_PUPILS[x]-1 for x in range(2)]

def in_ellipse(size,center,point):
    rel_dx = ((point[0]-center[0])/size[0])**2
    rel_dy = ((point[1]-center[1])/size[1])**2
    if rel_dy+rel_dx<=1:
        return True
    return False

def draw_ellipse(disp, size, center, color):
    rounded_pos=[int(x) for x in center]
    inner_rect=[[rounded_pos[x]-int(size[x]*ROOTTWO),rounded_pos[x]+int(size[x]*ROOTTWO)] for x in range(2)]
    disp.rect(inner_rect[0][0],inner_rect[1][0],inner_rect[0][1],inner_rect[1][1],col=color)
    for x in list(range(rounded_pos[0]-size[0],rounded_pos[0]+size[0])):
        for y in list(range(rounded_pos[1]-size[1],rounded_pos[1]+size[1])):
            if not (x in range(inner_rect[0][0],inner_rect[0][1]+1) and y in range(inner_rect[1][0],inner_rect[1][1]+1)):
                if in_ellipse(size,rounded_pos,(x,y)):
                    disp.pixel(x,y,col=color)

def hardcoded_shitty_fake_ellipse(disp, center, color):
    disp.circ(int(center[0]),int(center[1]+3),4,col=color)
    disp.circ(int(center[0]),int(center[1]),5,col=color)
    disp.circ(int(center[0]),int(center[1]-3),4,col=color)

class pupil:
    def __init__(self,disp,eyed):
        self.disp=disp
        self.eyed=eyed
        self.velocity=[0.,0.]
        self.center=EYEPOS[self.eyed]
        self.position=EYEPOS[self.eyed]
        self.draw(self.position)
    
    def draw(self,position):
        while not in_ellipse(RANGE_CENTER,self.center,position):
            posdash=[((position[x]-self.center[x])/RANGE_CENTER[x])**2 for x in range(2)]
            lengthdash = sum(posdash)**(1/2)
            position=[self.center[x]+0.9*(position[x]-self.center[x])/lengthdash for x in range(2)]
            self.velocity=[0.,0.]
        hardcoded_shitty_fake_ellipse(self.disp,self.position,COL_PUPILSHADOW)
        hardcoded_shitty_fake_ellipse(self.disp,position,COL_PUPILS)

        self.disp.update()
        self.position=position

    def update_position(self, accel):
        self.velocity = [FRICTION*self.velocity[x]+SENSITIVITY*accel[x]-BOUNCE*(self.position[x]-self.center[x]) for x in range(2)]
        self.draw([self.position[x]+self.velocity[x] for x in range (2)])

class unnerving_void:
    def __init__(self):
        self.disp = display.open()
        self.disp.clear(col=COL_BACKGROUND)
        for x in EYEPOS:
            draw_ellipse(self.disp,DRAMA_EYELINER,x,COL_EYELINER)
            draw_ellipse(self.disp,SIZE_EYEWEISS,x,COL_EYEWEISS)
        self.left=pupil(self.disp,0)
        self.right=pupil(self.disp,1)
        self.bhi = bhi160.BHI160Accelerometer(sample_rate=60)
    
    def run(self):
        initsample=[]
        while not len(initsample):
            initsample=self.bhi.read()
        avg=[initsample[-1][x] for x in range(2)]
        update_left=True
        while True:
            samples=self.bhi.read()
            if len(samples):
                sample=samples[-1]
                sample=[sample[0],-sample[1]]
                delta=[sample[x]-avg[x] for x in range(2)]
                avg=[avg[x]+HIGHPASS*delta[x] for x in range(2)]
                if update_left:
                    self.left.update_position(delta)
                else:
                    self.right.update_position(delta)
                update_left = not update_left

    def close(self):
        self.bhi.close()
        self.disp.close()

a=unnerving_void()
a.run()