import pya
import os

base_dir = os.path.dirname(os.path.abspath(__file__))

# init vars
velocity_ratio1 = 2
opening1 = 8000

velocity_ratio2 = 3
opening2 = opening1 * velocity_ratio1 / velocity_ratio2


pixel_size = 20
shift_mult = 5
image_size = 4266 * pixel_size * 100 #calculate this directly (4266 and 4242 for shift_mult 5 and 3, respectively)
image_size_half = image_size / 2
image_dist = (shift_mult * 3 * 2 + 2) * pixel_size * 100
object_border = 0
#print(image_dist)


# create layout
layout = pya.Layout()
layout.dbu = 0.01
top = layout.create_cell("Top")
layer1_index = layout.insert_layer(pya.LayerInfo.new(1, 0))
layer2_index = layout.insert_layer(pya.LayerInfo.new(2, 0))
layer3_index = layout.insert_layer(pya.LayerInfo.new(3, 0))
layer4_index = layout.insert_layer(pya.LayerInfo.new(4, 0))
layer5_index = layout.insert_layer(pya.LayerInfo.new(5, 0))

y_offset = 0

# verniers md course
linear_grating_vernier_md_course = layout.create_cell("Vernier_md_course")
square_size = 650000
fray = 0
line_length = square_size / 2 + fray
pitch11 = ((square_size * 1) * (image_dist / velocity_ratio1)) / ((square_size * 1) - (image_dist / velocity_ratio1))
pitch12 = image_dist / velocity_ratio1

for i in range(-1 * int(square_size / 2 / pitch11) - 0, int(square_size / 2 / pitch11) + 0):

  line = layout.create_cell("Line")
  line.shapes(layer2_index).insert(pya.Box(opening1 / 2, -1 * line_length, pitch11 - opening1 / 2, line_length))
  linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch11, 0)))
  linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch11))))
  
for i in range(-1 * int(square_size / 2 / pitch12) - 0, int(square_size / 2 / pitch12) + 0):

  line = layout.create_cell("Line")
  line.shapes(layer1_index).insert(pya.Box(opening1 / 2, -1 * line_length, pitch12 - opening1 / 2, line_length))
  linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch12, 0)))
  linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch12))))
  
line = layout.create_cell("Line")
line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (1 * image_dist), square_size / 2 + (1 * image_dist)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))

line = layout.create_cell("Line")
line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (0 * image_dist), square_size / 2 + (1 * image_dist)))
#linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, True, 0, 0)))

line = layout.create_cell("Line")
line.shapes(layer1_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2, square_size / 2 + (1 * image_dist), square_size / 2 + (0 * image_dist)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
linear_grating_vernier_md_course.insert(pya.CellInstArray(line.cell_index(), pya.Trans(3, False, 0, 0)))
  
triangle = layout.create_cell("Triangle")
triangle.shapes(layer2_index).insert(pya.Polygon([pya.Point(-45000, -1 * image_dist), pya.Point(45000, -1 * image_dist), pya.Point(0, 0)]))
linear_grating_vernier_md_course.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(0, False, 0, -1 * (square_size / 2 + (image_dist * 1)))))
linear_grating_vernier_md_course.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(1, False, (square_size / 2 + (image_dist * 1)), 0)))

y_offset = y_offset + (square_size / 2) + (image_dist * 3)
grid_extent = 0
top.insert(pya.CellInstArray(linear_grating_vernier_md_course.cell_index(), pya.Trans(0, False, (grid_extent + fray), (y_offset + fray))))


# verniers md fine
linear_grating_vernier_md_fine = layout.create_cell("Vernier_md_fine")
square_size = 650000
fray = 0
line_length = square_size / 2 + fray
pitch21 = ((square_size * -1) * (image_dist / velocity_ratio2)) / ((square_size * -1) - (image_dist / velocity_ratio2))
pitch22 = image_dist / velocity_ratio2

for i in range(-1 * int(square_size / 2 / pitch21) - 0, int(square_size / 2 / pitch21) + 0):

  line = layout.create_cell("Line")
  line.shapes(layer2_index).insert(pya.Box(opening2 / 2, -1 * line_length, pitch21 - opening2 / 2, line_length))
  linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch21, 0)))
  linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch21))))
  
for i in range(-1 * int(square_size / 2 / pitch22) - 0, int(square_size / 2 / pitch22) + 0):

  line = layout.create_cell("Line")
  line.shapes(layer1_index).insert(pya.Box(opening2 / 2, -1 * line_length, pitch22 - opening2 / 2, line_length))
  linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(i * pitch22, 0)))
  linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, (i * pitch22))))
  
line = layout.create_cell("Line")
line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (1 * image_dist), square_size / 2 + (1 * image_dist)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))

line = layout.create_cell("Line")
line.shapes(layer2_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2 - image_dist, square_size / 2 + (0 * image_dist), square_size / 2 + (1 * image_dist)))
#linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, True, 0, 0)))

line = layout.create_cell("Line")
line.shapes(layer1_index).insert(pya.Box(-1 * (square_size / 2 + (1 * image_dist)), square_size / 2, square_size / 2 + (1 * image_dist), square_size / 2 + (0 * image_dist)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(0, 0)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(1, False, 0, 0)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(2, False, 0, 0)))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(line.cell_index(), pya.Trans(3, False, 0, 0)))
  
triangle = layout.create_cell("Triangle")
triangle.shapes(layer2_index).insert(pya.Polygon([pya.Point(-45000, -1 * image_dist), pya.Point(45000, -1 * image_dist), pya.Point(0, 0)]))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(0, False, 0, -1 * (square_size / 2 + (image_dist * 1)))))
linear_grating_vernier_md_fine.insert(pya.CellInstArray(triangle.cell_index(), pya.Trans(1, False, (square_size / 2 + (image_dist * 1)), 0)))


y_offset = y_offset + square_size + (image_dist * 1)

grid_extent = 0
top.insert(pya.CellInstArray(linear_grating_vernier_md_fine.cell_index(), pya.Trans(0, True, (grid_extent + fray), (y_offset + fray))))


top.flatten(1)

top.write(os.path.join(base_dir, "..", "gds", "md_vernier_test.gds"))

bb_region = pya.Region(pya.Box(-650000, -300000, 650000, 2000000))
wafer1 = pya.Region(top.begin_shapes_rec(layer1_index))
wafer2 = pya.Region(top.begin_shapes_rec(layer2_index))


alignment_inv_layout = pya.Layout()
alignment_inv = alignment_inv_layout.create_cell("Alignment_Inverse")
alignment_inv_layout.dbu = 0.01
layer1_index = alignment_inv_layout.insert_layer(pya.LayerInfo.new(1, 0))
layer2_index = alignment_inv_layout.insert_layer(pya.LayerInfo.new(2, 0))

alignment_inv.shapes(layer1_index).insert(bb_region - wafer1) 
alignment_inv.shapes(layer2_index).insert(bb_region - wafer2) 

alignment_inv_layout.write(os.path.join(base_dir, "..", "gds", "inverted_tonality", "md_vernier_test_inverse.gds"))

