import pya
import os
from PIL import Image

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

#for some reason pya is not getting the size so using PIL
im = Image.open(os.path.join(base_dir, "..", "visualizations", "11735", "shadow_img_0_final.png"))
#width, height = [100, 100] 
width, height = im.size
im.close()

# create layout
layout = pya.Layout()
layout.dbu = 0.01
image = layout.create_cell("Image")
layer1_index = layout.insert_layer(pya.LayerInfo.new(1, 0))
layer2_index = layout.insert_layer(pya.LayerInfo.new(2, 0))

image1 = pya.Image(os.path.join(base_dir, "..", "visualizations", "11735", "shadow_img_0_final.png"))

# The dimension of one pixel 
pixelSize = 2000
# image distance in pixels minus the 2 pixel offset
shift_mult = 5
image_dist = (shift_mult * 3 * 2)

image1_region = pya.Region()
image2_region = pya.Region()
image1_region_bb = pya.Region()
image2_region_bb = pya.Region()
final_region = pya.Region()

# Iterate over all rows in image1
for y in range(height):
  # Iterate over all columns in image1
  for x in range(width):
  
    # Use each channel for a different layer
    # d > 0.5 selects all pixels with a level > 50% in that channel
    d = image1.get_pixel(x, y, 0)
    if d < 0.5:
      # Create a polygon corresponding to one pixel
      p1 = pya.DPoint((x * pixelSize) - (0.5 * width * pixelSize), (y * pixelSize) - (0.5 * width * pixelSize))
      p2 = pya.DPoint(((x + 1) * pixelSize) - (0.5 * width * pixelSize), ((y + 1) * pixelSize) - (0.5 * width * pixelSize))
      dbox = pya.DBox(p1, p2)
      box = pya.Box.from_dbox(dbox)
      poly = pya.Polygon(box)
      image1_region.insert(poly)      

image1._destroy()
image2 = pya.Image(os.path.join(base_dir, "..", "visualizations", "11735", "shadow_img_1_final.png"))
      
# Iterate over all rows in image2
for y in range(image_dist, height - image_dist):
  # Iterate over all columns in image2
  for x in range(image_dist, width - image_dist):
  
    # Use each channel for a different layer
    # d > 0.5 selects all pixels with a level > 50% in that channel
    d = image2.get_pixel(x, y, 0)
    if d < 0.5:
      # Create a polygon corresponding to one pixel
      p1 = pya.DPoint((x * pixelSize) - (0.5 * width * pixelSize), (y * pixelSize) - (0.5 * width * pixelSize))
      p2 = pya.DPoint(((x + 1) * pixelSize) - (0.5 * width * pixelSize), ((y + 1) * pixelSize) - (0.5 * width * pixelSize))
      dbox = pya.DBox(p1, p2)
      box = pya.Box.from_dbox(dbox)
      poly = pya.Polygon(box)
      image2_region.insert(poly)
      
print("pixel import finished")
image2._destroy()
   
image1_bb = pya.Box(-0.5 * width * pixelSize, -0.5 * height * pixelSize, 0.5 * width * pixelSize, 0.5 * width * pixelSize)
image2_bb = pya.Box(((-0.5 * width) + image_dist) * pixelSize, ((-0.5 * height) + image_dist) * pixelSize, ((0.5 * width) - image_dist) * pixelSize, ((0.5 * height) - image_dist) * pixelSize)
image1_region_bb.insert(image1_bb)
image2_region_bb.insert(image2_bb)

#if you resize image1, you must sent merged_semantics to True!!!!
#image1_region.merged_semantics = False
#image2_region.merged_semantics = False
#image1_region_inverse.merged_semantics = False
#image2_region_inverse.merged_semantics = False
#image1_region_bb.merged_semantics = False
#image2_region_bb.merged_semantics = False
#final_region.merged_semantics = False

#image1_region.strict_handling = True
#image2_region.strict_handling = True
#image1_region_inverse.strict_handling = True
#image2_region_inverse.strict_handling = True
#image2_region.strict_handling = True
#image1_region_bb.strict_handling = True
#image2_region_bb.strict_handling = True
#final_region.strict_handling = True

#image1_region.size(25) #opting not to resize image1
image2_region.size(150)
print("resize finished")

image_layout = pya.Layout()
image = image_layout.create_cell("Image")
image_layout.dbu = 0.01
layer1_image_index = image_layout.insert_layer(pya.LayerInfo.new(1, 0))
layer2_image_index = image_layout.insert_layer(pya.LayerInfo.new(2, 0))

print("finalizing layout for image_overlapped.gds")
#normal
image.shapes(layer1_index).insert(image1_region)
image_layout.clip(image.cell_index(), image1_bb)
processor = pya.ShapeProcessor()
processor.merge(image_layout, image, layer1_image_index, image.shapes(layer1_image_index), False, 0, False, True)
print("layer1 finished")
image.shapes(layer2_image_index).insert(image2_region_bb & image2_region)
print("layer2 finished")
print("layout for image_overlapped.gds finished")

image_layout.write(os.path.join(base_dir, "..", "gds", "image_overlapped.gds"))
print("image_overlapped.gds written")


image_inv_layout = pya.Layout()
image_inv = image_inv_layout.create_cell("Image_Inverse")
image_inv_layout.dbu = 0.01
layer1_image_inv_index = image_inv_layout.insert_layer(pya.LayerInfo.new(1, 0))
layer2_image_inv_index = image_inv_layout.insert_layer(pya.LayerInfo.new(2, 0))

print("finalizing layout for image_overlapped_inverse.gds")
#inverted
#image_inv.shapes(layer1_index).insert(pya.Box(-7500000, -6850000, 7500000, 6850000 - 1850000)) #printable area wafer 1
#image_inv.shapes(layer2_index).insert(pya.Box(-7500000, 6850000, 7500000, -1 * (6850000 - 1850000))) #printable area wafer 2

#the printable areas are rotated for the overlay with the alignment marks
image_inv.shapes(layer1_index).insert(pya.Box(-7500000, -6850000, 7500000, 6850000 - 1850000).transformed(pya.Trans(1, False, 0, 0))) #printable area wafer 1
image_inv.shapes(layer2_index).insert(pya.Box(-7500000, 6850000, 7500000, -1 * (6850000 - 1850000)).transformed(pya.Trans(1, False, 0, 0))) #printable area wafer 2

processor = pya.ShapeProcessor()
processor.boolean(image_layout, image, layer1_image_index, image_inv_layout, image_inv, layer1_image_inv_index, image_inv.shapes(layer1_image_inv_index), 3, False, False, True)
print("layer1 finished")
processor = pya.ShapeProcessor()
processor.boolean(image_layout, image, layer2_image_index, image_inv_layout, image_inv, layer2_image_inv_index, image_inv.shapes(layer2_image_inv_index), 3, False, False, True)
print("layer2 finished")
print("layout for image_overlapped_inverse.gds finished")

image_inv_layout.write(os.path.join(base_dir, "..", "gds", "inverted_tonality", "image_overlapped_inverse.gds"))
print("image_overlapped_inverse.gds written")

