#usage python <draw_tracks_v2.py> <.brd file> <STEP>

#V2 speed the calculation by using lists instead of iterations on etree to get wires
#draw tracks with wires in plain
# importing the module.
from typing import Type
import xml.etree.ElementTree as ET

from distance import *
import time, sys

print('File Name: %s' % sys.argv[1])
print('STEP RESOLUTION: %s'% sys.argv[2])

# parsing directly.
tree = ET.parse(str(sys.argv[1]))
root = tree.getroot()
print('Eagle Version: ', end=' ')
print(root.get('version'))
#print('Xml root: ',root.tag)

#get the plain item
plain = root.find('drawing').find('board').find('plain')

#get the outbounds of the board
boundaries = plain.iterfind('wire')
wire = next(boundaries)
X_UP_LEFT_CORNER = float(wire.get('x1'))
Y_UP_LETF_CORNER = float(wire.get('y1'))
X_DW_RGT_CORNER = float(wire.get('x1'))
Y_DW_RGT_CORNER = float(wire.get('y1'))

for wire in boundaries:
   x1=float(wire.get('x1'))
   y1=float(wire.get('y1'))
   x2=float(wire.get('x2'))
   y2=float(wire.get('y2'))
   if x1<X_UP_LEFT_CORNER:
      X_UP_LEFT_CORNER=x1
   if x2<X_UP_LEFT_CORNER:
      X_UP_LEFT_CORNER=x2
   if x1>X_DW_RGT_CORNER:
      X_DW_RGT_CORNER=x1
   if x2>X_DW_RGT_CORNER:
      X_DW_RGT_CORNER=x2
   if y1>Y_UP_LETF_CORNER:
      Y_UP_LETF_CORNER=y1 
   if y2>Y_UP_LETF_CORNER:
      Y_UP_LETF_CORNER=y2
   if y1<Y_DW_RGT_CORNER:
      Y_DW_RGT_CORNER=y1
   if y2<Y_DW_RGT_CORNER:
      Y_DW_RGT_CORNER=y2 

print('Board size: %s * %s' % (abs(X_DW_RGT_CORNER-X_UP_LEFT_CORNER),abs(Y_DW_RGT_CORNER-Y_UP_LETF_CORNER)))

#put all the wires in a list to speed up further calculations
#wire=('signal number',x1,y1,x2,y2)
wires = list()
xml_signals = root.iter('signal')
row = 0
for sig in xml_signals:
    xml_wires = sig.iter('wire')
    for wire in xml_wires:
       item= list()
       item.append(sig.get('name'))
       item.append(float(wire.get('x1')))
       item.append(float(wire.get('y1')))
       item.append(float(wire.get('x2')))
       item.append(float(wire.get('y2')))
       wires.append(item)              
       row=row+1
print(row,end=' ')
print("detected wires")
#for x in range(len(wires)):
    #print(wires[x])

#evaluate the separations
#run through dot (STEP mm), let simply by considering board is rectangular
#vertical scanning
STEP = float(sys.argv[2])
x=X_UP_LEFT_CORNER
y=Y_DW_RGT_CORNER
count=0
A=[0,0]
B=[0,0]
E=[0,0]
min=100 #absurde distance
closest_signal_name='99' #fake signal name, closest signal from the last evaluated point
closer_signal_name='00' #new signal closer than the closest
t_start = time.time()
while x<=X_DW_RGT_CORNER:      
   while y<=Y_UP_LETF_CORNER:      
      #from here we have the next point to evaluate
      #run through the tracks 
      #signals = root.iter('signal')              
      for i in range(len(wires)):                               
         A[0]=wires[i][1]
         A[1]=wires[i][2]
         B[0]=wires[i][3]
         B[1]=wires[i][4]
         E=[x,y]
         #do we get a new closer signal ?
         if (minDistance(A,B,E)<min):                            
            #new closer signal found
            closer_signal_name=wires[i][0]                                    
            min= minDistance(A,B,E)
            count=count+1          
      #from here we have compared the point with the all signals
      if closer_signal_name!=closest_signal_name:
          #print('new mark ',closer_signal_name,x,y)
          #copy names
          closest_signal_name=closer_signal_name
          #create a new element and add it to plain node
          new_elt = ET.Element('wire')
          new_elt.tail='\n'
          new_elt.set('x1',str(round(x,2)))
          new_elt.set('y1',str(round(y,2)))
          new_elt.set('x2',str(round(x+0.01,2)))
          new_elt.set('y2',str(round(y,2)))
          new_elt.set('layer','46')
          plain.insert(0,new_elt)
      y=y+STEP  
      min=100 #reset the distance when the point changes    
   y=Y_DW_RGT_CORNER
   x = x + STEP   
   min=100 #reset the distance when the point changes
print("vertical count %s"% count)

#run through dot (1/10mm), let simply by considering board is rectangular
#horizontal scanning
x=X_UP_LEFT_CORNER
y=Y_DW_RGT_CORNER
count=0
A=[0,0]
B=[0,0]
E=[0,0]
min=100 #absurde distance
closest_signal_name='99' #fake signal name, closest signal from the last evaluated point
closer_signal_name='00' #new signal closer than the closest
while y<=Y_UP_LETF_CORNER: 
   while x<=X_DW_RGT_CORNER:            
      #from here we have the next point to evaluate
      #run through the tracks 
      signals = root.iter('signal')          
      for i in range(len(wires)):                               
         A[0]=wires[i][1]
         A[1]=wires[i][2]
         B[0]=wires[i][3]
         B[1]=wires[i][4]
         E=[x,y]
         #do we get a new closer signal ?
         if (minDistance(A,B,E)<min):                            
            #new closer signal found
            closer_signal_name=wires[i][0]                                    
            min= minDistance(A,B,E)
            count=count+1                
      #from here we have compared the point with the all signals
      if closer_signal_name!=closest_signal_name:
          #print('new mark ',closer_signal_name,x,y)
          #copy names
          closest_signal_name=closer_signal_name
          #create a new element and add it to plain node
          new_elt = ET.Element('wire')
          new_elt.tail='\n'
          new_elt.set('x1',str(round(x,2)))
          new_elt.set('y1',str(round(y,2)))
          new_elt.set('x2',str(round(x+0.01,2)))
          new_elt.set('y2',str(round(y,2)))
          new_elt.set('layer','46')
          plain.insert(0,new_elt)
      x=x+STEP  
      min=100 #reset the distance when the point changes    
   x=X_UP_LEFT_CORNER
   y = y + STEP   
   min=100 #reset the distance when the point changes
print("horizontal count %s"% count)
print('calculation seconds: %s'% (time.time()-t_start)) 
print('done check layer 46 on your board for cnc separations')
tree.write(str(sys.argv[1]))