import klayout.db as kdb
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.path import Path as MplPath

import gdsfactory as gf

def region_patch(region, **kwargs):
    dbu = gf.kcl.dbu
    vertices, codes = [], []
    for polygon in region.merged().each():
        loops = [polygon.each_point_hull()]
        loops += [polygon.each_point_hole(i) for i in range(polygon.holes())]
        for loop in loops:
            points = [(pt.x * dbu, pt.y * dbu) for pt in loop]
            vertices += [*points, points[0]]
            codes += [MplPath.MOVETO,
                      *[MplPath.LINETO] * (len(points) - 1),
                      MplPath.CLOSEPOLY]
    return PathPatch(MplPath(vertices, codes), **kwargs)

def box(x0, y0, x1, y1):
    return kdb.Region(kdb.DBox(x0, y0, x1, y1).to_itype(gf.kcl.dbu))

sim = box(0, 0, 100, 60)
etch = box(10, 10, 90, 22) + box(10, 38, 90, 50) + box(40, 22, 60, 38)
draw = box(46, 26, 54, 34)
conductor = (sim - etch) | (draw & sim)

fig, axes = plt.subplots(1, 2, figsize=(9.5, 3.2))
axes[0].add_patch(region_patch(sim, facecolor="none", edgecolor="0.45",
                               linestyle="--", linewidth=1.2,
                               label="SIM_AREA"))
axes[0].add_patch(region_patch(etch, facecolor="#d1495b", alpha=0.75,
                               edgecolor="none", label="M1_ETCH (removed)"))
axes[0].add_patch(region_patch(draw, facecolor="#1b7f9e", edgecolor="none",
                               label="M1_DRAW (added back)"))
axes[0].set_title("Subtractive: what qpdk draws")
axes[0].legend(loc="upper center", bbox_to_anchor=(0.5, -0.02), ncols=3,
               frameon=False, fontsize=8)
axes[1].add_patch(region_patch(conductor, facecolor="#c9a227",
                               edgecolor="black", linewidth=0.6))
axes[1].set_title("Positive: what the solver meshes")
for ax in axes:
    ax.set_xlim(-5, 105)
    ax.set_ylim(-8, 65)
    ax.set_aspect("equal")
    ax.axis("off")
fig.tight_layout()