from koko.lib.pcb import *
from koko.lib.sam import *

class TagConnectPDI(Component):
    '''
    '''
    _pad = s2d.circle(0,0,.5*.031)
    _via = s2d.circle(0,0,.5*.039)
    pins = [
        Pin(-.05,-.025,_pad,'CLK',label_size=.02),
        Pin( .00,-.025,_pad,'NC',label_size=.02),
        Pin( .05,-.025,_pad,'DAT',label_size=.02),
        Pin(-.05,.025,_pad,'VCC',label_size=.02),
        Pin( .00,.025,_pad,'NC',label_size=.02),
        Pin( .05,.025,_pad,'GND',label_size=.02)
    ]
    vias = [
        Via(-.1,0,_via),
        Via(.1,0.04,_via),
        Via(.1,-.04,_via),

    ]

class Button(Component):
    ''' SW262CT-ND 
    '''
    rect = rectangle(-.75/25.4,.75/25.4,-.5/25.4,.5/25.4)
    pins = [
        Pin(-2/25.4,.8/25.4,rect),
        Pin( 2/25.4,.8/25.4,rect),
        Pin(-2/25.4,-.8/25.4,rect),
        Pin( 2/25.4,-.8/25.4,rect)
    ]
    prefix = 'button'
    vias = []
    shadow = rectangle(-2.1/25.4,2.1/25.4,-1.4/25.4,1.4/25.4)

class TagConnectSWD(Component):
    '''
    '''
    _pad = s2d.circle(0,0,.5*.031)
    _via = s2d.circle(0,0,.5*.039)
    pins = [
        Pin(-.05,-.025,_pad,'GND',label_size=.012),
        Pin( .00,-.025,_pad,'NC',label_size=.012),
        Pin( .05,-.025,_pad,'VCC',label_size=.012),
        Pin(-.05,.025,_pad,'RST',label_size=.012),
        Pin( .00,.025,_pad,'SWDCLK',label_size=.012),
        Pin( .05,.025,_pad,'SWDIO',label_size=.012)
    ]
    vias = [
        Via(-.1,0,_via),
        Via(.1,0.04,_via),
        Via(.1,-.04,_via),

    ]


class Regulator_SOT23(Component):
    '''  SOT23 voltage regulator
    '''
    _pad_SOT23 = s2d.rectangle(-.02,.02,-.012,.012)
    pins = [
        Pin(-0.045, -0.0375, _pad_SOT23,'IN'),
        Pin(-0.045,  0.0375, _pad_SOT23,'OUT'),
        Pin(0.045, 0, _pad_SOT23,'GND')
    ]
    prefix = 'U'
    vias = []

class Crystal_FC135(Component):
    '''  CRYSTAL 32.7680KHZ 12.5PF SMT
    '''
    _pad = s2d.rectangle(-.5/25.4,.5/25.4,-.9/25.4,.9/25.4)
    pins = [
        Pin(-1.25/25.4, 0, _pad),
        Pin( 1.25/25.4, 0, _pad),
    ]
    prefix = 'U'
    vias = []


class Header_FTDI(Component):
    ''' FTDI cable header
    '''
    _pad_header = chamfered_rectangle(-0.06, 0.08,-0.035, 0.035,.007)
    pins = [
        Pin(0,  0.25, _pad_header, 'RTS'),
        Pin(0,  0.15, _pad_header, 'RX'),
        Pin(0,  0.05, _pad_header, 'TX'),
        Pin(0, -0.05, _pad_header, 'VCC'),
        Pin(0, -0.15, _pad_header, 'CTS'),
        Pin(0, -0.25, _pad_header, 'GND')
    ]
    prefix = 'J'
    vias = []
    shadow = s2d.rectangle(-.06,8/25.4,-.3,.3)
    #shadow = s2d.rectangle(-.06,8/25.4,-.3,.2)


class Header_Daughter(Component):
    ''' FTDI cable header
    '''
    _pad_header = chamfered_rectangle(-0.03, 0.03,-0.015, 0.015,.002)
    labels=['SDA','SCL','A4','A5']
    pins = [ Pin(0,.05*(i-1.5),_pad_header,l) for i,l in enumerate(labels)]
    prefix = 'J'
    vias = [Via(p.x,p.y,circle(0,0,.017)) for p in pins]
    shadow = s2d.rectangle(-.03,.03,-.1,.1)

def bot_chamfered_rectangle(x0,x1,y0,y1,c):
    r = rectangle(x0,x1,y0,y1)
    c1 = triangle(x0,y0,x0,y0+c,x0+c,y0)
    c2 = triangle(x1,y1, x1, y1-c, x1-c, y1)
    c3 = triangle(x0,y1, x0+c, y1, x0, y1-c)
    c4 = triangle(x1,y0, x1-c, y0, x1, y0+c)
    return r-c2-c3

class CR20XX(Component):
    #coin cell battery, e.g. 2032
    pins = [
        Pin(0,0,circle(0,0,5./25.4),'-')
    ]
    shadow = circle(0,0,10./25.4)
    vias = []

class AAA(Component):
    #AAA battery smd holder
    pad = chamfered_rectangle(-.125,.125,-.12,.12,.05)
    pins = [
        Pin(1.21-.125,0,pad,'+',label_size=.08),
        Pin(-1.21+.125,0,pad,'-',label_size=.08),
    ]
    shadow = rectangle(-1.07,1.07,-.25,.25)
    vias = [
        Via(-1.21+.25,.209,circle(0,0,.039))
    ]

class MDBT42(Component):
    #Raytach nrf52 module
    p = .7/25.4
    pad_hw = .15/25.4
    pad_hh = .8/25.4
    _padv = rectangle(-pad_hw,pad_hw,-pad_hh,pad_hh)
    _padh = rectangle(-pad_hh,pad_hh,-pad_hw,pad_hw)
    _padg = rectangle(-pad_hh,pad_hh,-.35/25.4,.4/25.4)
    c= 5/25.4
    start_y = 11.8/25.4
    start_x = .8/25.4
    y_os = .25
    names = [
        'GND1','SDA','SCL','P27','A4','A5','A6','A7','DEC4','DCC','VDD',
        'GND2','XL1','XL2','P2','P3','P4','P5','P6','P7','P8','P9','P10','GND3',
        'P11','P12','P13','P14','P15','P16','P17','P18','P19','P20','RESET','SWDCLK','SWDIO','P22','GND4'
    ]
    pins = [Pin(-c,start_y-y_os,_padg,n,label_size=.018) for i,n in enumerate(names[:1])]
    pins += [Pin(-c,start_y-3./25.4-i*p-y_os,_padh,n,label_size=.018) for i,n in enumerate(names[1:11])]
    pins += [Pin(-c+start_x+i*p,-y_os,_padv,n,label_size=.018,label_rot=-90) for i,n in enumerate(names[11:24])]
    pins += [Pin(c,start_y-.9/25.4-i*p-y_os,_padh,n,label_size=.018) for i,n in enumerate(names[24:38][::-1])]
    pins += [Pin(c,start_y-y_os,_padg,n,label_size=.018) for i,n in enumerate(names[38:])]
    vias = []
    shadow = rectangle(-c,c,-y_os,start_y+4.2/25.4-y_os)


class BT832(Component):
    #Fanstel BT832 nrf52 module
    p = 1.1/25.4
    pad_hw = .7/25.4
    pad_hh = .35/25.4
    _pad = rectangle(-pad_hw,pad_hw,-pad_hh,pad_hh)
    c= 7/25.4
    start_y = 1.1/25.4
    y_os = .25
    names = [
        'SDA','SCL','XL1','XL2','AIN0','AIN1','NFC1','NFC2',
        'VCC','GND','P13','P18','P20','RESET','SWDCLK','SWDIO'
    ]
    pins = [Pin(-c,start_y+i*p-y_os,_pad,n,label_size=.018) for i,n in enumerate(names[:8][::-1])]
    pins += [Pin(c,start_y+i*p-y_os,_pad,n,label_size=.018) for i,n in enumerate(names[8:16])]
    vias = []
    shadow = rectangle(-c,c,-y_os,16/25.4-y_os)

class BC832(Component):
    #Fanstel BC832 micro nrf52 module
    p = 1.1/25.4
    pad_hw = .7/25.4
    pad_hh = .35/25.4
    _pad = rectangle(-pad_hw,pad_hw,-pad_hh,pad_hh)
    c= 3.9/25.4
    start_y = .618/25.4
    y_os = .18
    names = [
        'P26/SDA','P27/SCL','XL1','XL2','AIN0','AIN1','P9/NFC1','P10/NFC2',
        'VCC','GND','P13','P18','P20','RESET','SWDCLK','SWDIO'
    ]
    pins = [Pin(-c,start_y+i*p-y_os,_pad,n,label_size=.018) for i,n in enumerate(names[:8][::-1])]
    pins += [Pin(c,start_y+i*p-y_os,_pad,n,label_size=.018) for i,n in enumerate(names[8:16])]
    vias = []
    shadow = rectangle(-c,c,-y_os,8.8/25.4-y_os)


class Hole(Component):
    pins = [Pin(0,0,circle(0,0,0.01))]
    vias = [Via(0,0,circle(0,0,.5*2.1/25.4))]
    tap = circle(0,0,.5*1.9/25.5)


width = 1.
height = .75
pcb = PCB(0,0,width,height,chamfer_distance=.03)


def connectG(pin,dx,dy,width=.012):
    '''
    Convenience function for connecting to ground plane
    '''
    pcb.connectD(pin,[pin.x+dx,pin.y+dy],[pin.x+dx-.0001,pin.y+dy],width=width,sides=[0,1,1])
def connectS(pin,dx,dy,width=.012):
    pcb.connectD(pin,[pin.x+dx+.0001,pin.y+dy],width=width)
def connectM(pin1,pin2,dx,width=.012):
    pcb.connectD(pin1,[pin1.x+dx,pin1.y],pin2,width=width)





ftdi = Header_FTDI(.2,.3,180,'ftdi')
pcb += ftdi
reg = Regulator_SOT23(ftdi.x+.08,ftdi['GND'].y+.14,0,'3.3v')
pcb += reg

pcb.connectV(ftdi['GND'],[ftdi['GND'].x-.08,ftdi['GND'].y],reg['GND'])
pcb.connectD(ftdi['VCC'],[ftdi['VCC'].x+.045,ftdi['VCC'].y],[ftdi['VCC'].x+.085,reg['IN'].y-.02],reg['IN'])

C_in = C_0805(reg.x-.13,reg.y-.06,180,'Cin\n.1uF',label_size=.02)
pcb += C_in
C_out = C_0805(C_in.x-.09,reg.y-.0,90,'Cout\n.1uF',label_size=.02)
pcb += C_out
pcb.connectH(C_in[0],C_out[1])
pcb.connectH(reg['IN'],C_in[1],width=.02)
pcb.connectH(reg['OUT'],C_out[0],width=.02)


#todo:
#button reset
#route analog inputs?

mdb = MDBT42(ftdi.x+.57,ftdi.y+.1,-90,'Raytac\nMDBT42Q\nNRF52')
pcb += mdb

#bt = BT832(1.5,1.2,0,'Fanstel\nBT832\nNRF52')
#pcb += bt
#bc = BC832(.6,1.2,-90,'Fanstel\nBC832\nNRF52')
#pcb += bc

pcb.connectD(ftdi['TX'],[ftdi['TX'].x+.06,ftdi['TX'].y],mdb['P8'],width=.012).add_jumper([ftdi.x+.17,mdb['P8'].y],0)
pcb.connectD(ftdi['RX'],[ftdi['RX'].x+.05,ftdi['RX'].y],[mdb['P6'].x-.15,mdb['P6'].y-.01],mdb['P6'],width=.012)


swd = TagConnectSWD(mdb.x+.07,mdb.y-.335,0,'swd')
pcb += swd
pcb.connectD(swd['RST'],[swd['RST'].x,swd['RST'].y+.02],[mdb['RESET'].x-.02,mdb['RESET'].y-.06],mdb['RESET'],width=.012)
pcb.connectD(swd['SWDCLK'],[swd['SWDCLK'].x,swd['SWDCLK'].y+.005],mdb['SWDCLK'],width=.012)
pcb.connectD(swd['SWDIO'],[swd['SWDIO'].x,swd['SWDIO'].y+.015],mdb['SWDIO'],width=.012)


C2 = C_0805(reg.x+.12,reg.y-.01,0,'C2\n10uF',label_size=.02)
pcb += C2
pcb.connectD(C2[1],reg['GND'])
pcb.connectD(C2[0],[C2[0].x+.01,C2[0].y-.015],mdb['VDD'],width=.012)
pcb.connectD(C2[0],[C2[0].x,C2[0].y+.04],[reg['OUT'].x+.02,reg['OUT'].y+.005],reg['OUT'])

pcb.connectD(C2[1],[C2[1].x,C2[1].y-.02],[C2[1].x+.085,C2[1].y-.05],mdb['GND2'],width=.012)


x1 = Crystal_FC135(mdb.x-.352,mdb.y+.085,90,'X1\n32.768',label_size=.025)
pcb += x1
cx1 = C_0805(x1.x-.045,x1.y+.095,0,'CX1\n22pF',label_size=.02)
cx2 = C_0805(x1.x-.08,x1.y-.0,90,'CX2\n22pF',label_size=.02)
pcb += cx1
pcb += cx2
pcb.connectV(x1[0],mdb['XL1'],width=.012)
pcb.connectD(x1[1],[x1[1].x+.03,x1[1].y],[mdb['XL2'].x-.055,mdb['XL2'].y-.015],mdb['XL2'],width=.012)
pcb.connectV(cx2[0],cx1[1])
pcb.connectV(x1[0],cx1[0])
pcb.connectV(x1[1],cx2[1])
pcb.connectD(reg['GND'],[reg['GND'].x,reg['GND'].y-.02],cx1[1])


L1 = R_0805(mdb.x-.1,mdb.y+.29,0,'L1 10uH',label_size=.02)
pcb += L1
pcb.connectD(L1[1],[L1[1].x+.0,L1[1].y],mdb['DCC'],width=.012)
pcb.connectD(L1[0],mdb['DEC4'],width=.012)
C1 = C_0805(L1.x-.105,L1.y-.005,90,'C1 1 uF',label_size=.02)
pcb += C1
pcb.connectV(L1[0],[C1[0].x,C1[0].y+.015],C1[0])
##pcb.connectD(C1[1],[C1[1].x-.02,C1[1].y+.01],reg['GND'])

connectG(C_in[0],-.025,-.03)
connectG(C2[1],-.02,-.045)
connectG(C1[1],-0.04,.01)


button = Button(swd.x-.25,swd.y,0,'reset')
pcb += button
pcb.connectD(swd['RST'],[swd['RST'].x-.01,swd['RST'].y+.01],[button[2].x,button[2].y+.02],button[2],width=.012)
pcb.connectD(swd['GND'],[button[4].x,button[4].y-.02],button[4])
pcb.connectH(button[3],button[4])
pcb.connectH(button[1],button[2])
#pcb.connectH(C2[0],[C2[0].x-.015,button[2].y],button[2])

R1 = R_0805(mdb.x-.35,mdb.y-.24,90,'R1\n10k',label_size=.02)
pcb += R1
pcb.connectV(mdb['VDD'],mdb['P10'],width=.012)
pcb.connectD(R1[0],mdb['P10'],width=.012)
pcb.connectD(R1[1],button[1],width=.012)

#grounds
connectG(mdb['GND3'],-.03,-.04)
connectG(mdb['GND1'],-0.04,.03)
connectG(mdb['GND4'],-0.005,-.065)
connectG(button[3],-.05,0)


#header
h1 = Header_Daughter(mdb.x+.07,mdb.y+.32,90,'h1')
pcb += h1
pcb.connectD(mdb['A5'],[mdb['A5'].x,mdb['A5'].y+.08],h1['A5'],width=.012)
pcb.connectD(mdb['A4'],[mdb['A4'].x,mdb['A4'].y+.06],h1['A4'],width=.012)
pcb.connectD(mdb['SCL'],[mdb['SCL'].x,mdb['SCL'].y+.06],h1['SCL'],width=.012)
pcb.connectD(mdb['SDA'],[mdb['SDA'].x,mdb['SDA'].y+.04],h1['SDA'],width=.012)

cad.shapes = pcb.layout()
#cad.shape = pcb.traces+(pcb.cutout-pcb.cutout)
#cad.shape = pcb.cutout+(pcb.traces-pcb.traces)