#!/usr/bin/env python3

# Use the proper idiom in the main module ...
# NOTE: See https://docs.python.org/3.12/library/multiprocessing.html#the-spawn-and-forkserver-start-methods
if __name__ == "__main__":
    # Import standard modules ...
    import pathlib

    # Import special modules ...
    try:
        import cartopy
        cartopy.config.update(
            {
                "cache_dir" : pathlib.PosixPath("~/.local/share/cartopy").expanduser(),
            }
        )
    except:
        raise Exception("\"cartopy\" is not installed; run \"pip install --user Cartopy\"") from None
    try:
        import matplotlib
        matplotlib.rcParams.update(
            {
                       "axes.xmargin" : 0.01,
                       "axes.ymargin" : 0.01,
                            "backend" : "Agg",                                  # NOTE: See https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
                         "figure.dpi" : 300,
                     "figure.figsize" : (9.6, 7.2),                             # NOTE: See https://github.com/Guymer/misc/blob/main/README.md#matplotlib-figure-sizes
                          "font.size" : 8,
                "image.interpolation" : "none",                                 # NOTE: See https://matplotlib.org/stable/gallery/images_contours_and_fields/interpolation_methods.html
                     "image.resample" : False,
            }
        )
        import matplotlib.pyplot
    except:
        raise Exception("\"matplotlib\" is not installed; run \"pip install --user matplotlib\"") from None
    try:
        import numpy
    except:
        raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None
    try:
        import shapely
        import shapely.geometry
    except:
        raise Exception("\"shapely\" is not installed; run \"pip install --user Shapely\"") from None

    # Import my modules ...
    try:
        import pyguymer3
        import pyguymer3.geo
        import pyguymer3.image
    except:
        raise Exception("\"pyguymer3\" is not installed; run \"pip install --user PyGuymer3\"") from None

    # **************************************************************************

    # Define point ...
    lon = 170.0                                                                 # [°]
    lat = 10.0                                                                  # [°]

    # Define buffering parameters ...
    dist = 4000.0e3                                                             # [m]
    nAng = 9

    # Create a point based off the scalars ...
    pnt = shapely.geometry.point.Point(lon, lat)

    # **************************************************************************

    # Buffer point using PyGuymer3 ...
    multipoly = pyguymer3.geo.buffer(
        pnt,
        dist,
        fill = 1.0,
        nAng = nAng,
        simp = -1.0,
    )

    # **************************************************************************

    # Create figure ...
    fg = matplotlib.pyplot.figure()

    # Create axis ...
    ax1 = pyguymer3.geo.add_axis(
        fg,
        index = 1,
        ncols = 2,
        nrows = 2,
    )

    # Create axis ...
    ax2 = pyguymer3.geo.add_axis(
        fg,
        index = 2,
          lat = lat,
          lon = lon,
        ncols = 2,
        nrows = 2,
    )

    # Create axis ...
    ax3 = fg.add_subplot(
        2,
        2,
        (3, 4),
    )

    # Configure axis ...
    pyguymer3.geo.add_map_background(
        ax1,
        subName = "large8192px",
    )

    # Configure axis ...
    pyguymer3.geo.add_map_background(
        ax2,
        subName = "large8192px",
    )

    # Configure axis ...
    ax3.grid()
    ax3.set_aspect("equal")
    ax3.set_xlabel("Longitude [°]")
    ax3.set_xlim(-180.0, +180.0)
    ax3.set_xticks(range(-180, 225, 45))
    ax3.set_ylabel("Latitude [°]")
    ax3.set_ylim(-90.0, +90.0)
    ax3.set_yticks(range(-90, 135, 45))

    # Plot PyGuymer3 buffer thrice ...
    ax1.add_geometries(
        pyguymer3.geo.extract_polys(multipoly),
        cartopy.crs.PlateCarree(),
        edgecolor = (0.0, 1.0, 0.0, 1.0),
        facecolor = (0.0, 1.0, 0.0, 0.5),
        linewidth = 1.0,
    )
    ax2.add_geometries(
        pyguymer3.geo.extract_polys(multipoly),
        cartopy.crs.PlateCarree(),
        edgecolor = (0.0, 1.0, 0.0, 1.0),
        facecolor = (0.0, 1.0, 0.0, 0.5),
        linewidth = 1.0,
    )
    for poly in pyguymer3.geo.extract_polys(multipoly):
        coords = numpy.array(poly.exterior.coords)                              # [°]
        ax3.plot(
            coords[:, 0],
            coords[:, 1],
            color = (0.0, 1.0, 0.0, 1.0),
        )

    # Configure figure ...
    fg.suptitle(f"({lon:.1f}°,{lat:.1f}°) buffered by {0.001 * dist:,.1f} km\nPyGuymer3 in green")
    fg.tight_layout()

    # Save figure ...
    fg.savefig("working.png")
    matplotlib.pyplot.close(fg)

    # Optimise PNG ...
    pyguymer3.image.optimise_image("working.png", strip = True)
