import os
from pathlib import Path

from ordec.lib import ihp130
from ordec.extlibrary import ExtLibrary
from ordec.layout.helpers import expand_geom
from ordec.layout.makevias import makevias
from ordec.core import *

@generate_func
def layout_xor() -> Layout:
    tech_layers = ihp130.SG13G2().layers
    lib = ExtLibrary()
    lib.read_gds(ihp130.pdk().root / "libs.ref/sg13g2_stdcell/gds/sg13g2_stdcell.gds", tech_layers)
    return lib['sg13g2_xor2_1'].layout

@generate_func
def layout_dff() -> Layout:
    tech_layers = ihp130.SG13G2().layers
    lib = ExtLibrary()
    lib.read_gds(ihp130.pdk().root / "libs.ref/sg13g2_stdcell/gds/sg13g2_stdcell.gds", tech_layers)
    return lib['sg13g2_sdfrbpq_2'].layout

@generate_func
def layout_expand_geom() -> Layout:
    layers = ihp130.SG13G2().layers
    
    l = Layout(ref_layers=layers)
    for x in (1, -1):
        for y in (1, -1):
            l % LayoutPath(
                width=100,
                endtype=PathEndType.Flush,
                layer=layers.Metal1,
                vertices=[
                    Vec2I(x*100, y*500),
                    Vec2I(x*500, y*500),
                    Vec2I(x*500, y*100),
                ],
            )

            l % LayoutPath(
                width=50,
                endtype=PathEndType.Square,
                layer=layers.Metal2,
                vertices=[
                    Vec2I(x*500, y*100),
                    Vec2I(x*500, y*500),
                    Vec2I(x*100, y*500),
                ],
            )

    l % LayoutPath(
        width=100,
        endtype=PathEndType.Flush,
        layer=layers.Metal3,
        vertices=[
            Vec2I(0, 0),
            Vec2I(0, 1000),
            Vec2I(1000, 1000),
            Vec2I(1000, 0),
            Vec2I(800, 0),
            Vec2I(800, 800),
            Vec2I(200, 800),
            Vec2I(200, -200),
            Vec2I(1200, -200),
            Vec2I(1200, 1200),
            Vec2I(-200, 1200),
            Vec2I(-200, 0)
        ],
    )

    l % LayoutRectPoly(
        layer=layers.Metal4,
        vertices = [
            Vec2I(0,0),
            Vec2I(100,100),
            Vec2I(50,50),
            Vec2I(-100, 25),
        ],
    )

    l % LayoutRectPath(
        width=80,
        endtype=PathEndType.Square,
        layer=layers.Metal5,
        vertices = [
            Vec2I(0,0),
            Vec2I(1400,1400),
            Vec2I(-400,600),
            Vec2I(100,100),
        ],
        start_direction=RectDirection.Horizontal,
    )

    return l

@generate_func
def test_gds_sref() -> Layout:
    tech_layers = ihp130.SG13G2().layers
    lib = ExtLibrary()
    lib.read_gds('tests/layout_gds/test_sref_d4.gds', tech_layers)
    return lib['TOP'].layout

@generate_func
def test_gds_aref() -> Layout:
    tech_layers = ihp130.SG13G2().layers
    lib = ExtLibrary()
    lib.read_gds('tests/layout_gds/test_aref.gds', tech_layers)
    return lib['TOP'].layout

@generate_func
def test_ihp130_nmos() -> Layout:
    return ihp130.Nmos(l="300n", w="200000n", ng=20).layout

@generate_func
def test_makevias() -> Layout:
    layers = ihp130.SG13G2().layers
    
    l = Layout(ref_layers=layers)
    a = l % LayoutRect(layer=layers.Metal1, rect=Rect4I(0, 0, 205, 800))
    b = l % LayoutRect(layer=layers.Metal2, rect=Rect4I(0, 0, 500, 800))

    makevias(l, a.rect, layers.Via1, Vec2I(80, 80), Vec2I(50, 50), Vec2I(0,0))

    return l

@generate_func
def test_tap() -> Layout:
    return ihp130.Ptap(l="0.97u", w="0.98u").layout
