from __future__ import annotations

# SUBAXIS Create axes in tiled positions. (just like subplot)
#   Usage:
#      h=subaxis(rows,cols,cellno[,settings])
#      h=subaxis(rows,cols,cellx,celly[,settings])
#      h=subaxis(rows,cols,cellx,celly,spanx,spany[,settings])
#
# SETTINGS: Spacing,SpacingHoriz,SpacingVert
#           Padding,PaddingRight,PaddingLeft,PaddingTop,PaddingBottom
#           Margin,MarginRight,MarginLeft,MarginTop,MarginBottom
#           Holdaxis
#
#           all units are relative (e.g from 0 to 1)
#
#           Abbreviations of parameters can be used.. (Eg MR instead of MarginRight)
#           (holdaxis means that it wont delete any axes below.)
#
#
# Example:
#
#   >> subaxis(2,1,1,'SpacingVert',0,'MR',0);
#   >> imagesc(magic(3))
#   >> subaxis(2,'p',.02);
#   >> imagesc(magic(4))
#
# 2001 / Aslak Grinsted  (Feel free to modify this code.)

import matplotlib.pyplot as plt

from parseArgs import parseArgs


def subaxis(*varargin):
    f = plt.gcf()

    Args = {
        "Holdaxis": 0,
        "SpacingVertical": 0.05,
        "SpacingHorizontal": 0.05,
        "PaddingLeft": 0,
        "PaddingRight": 0,
        "PaddingTop": 0,
        "PaddingBottom": 0,
        "MarginLeft": 0.1,
        "MarginRight": 0.1,
        "MarginTop": 0.1,
        "MarginBottom": 0.1,
        "rows": None,
        "cols": None,
    }

    aliases = {
        "spacing": ["SpacingHorizontal", "SpacingVertical"],
        "padding": ["PaddingLeft", "PaddingRight", "PaddingTop", "PaddingBottom"],
        "margin": ["MarginLeft", "MarginRight", "MarginTop", "MarginBottom"],
        "p": ["PaddingLeft", "PaddingRight", "PaddingTop", "PaddingBottom"],
    }
    Args = parseArgs(varargin, Args, {"Holdaxis"}, aliases)

    NumericArguments = list(Args["NumericArguments"])
    if len(NumericArguments) > 1:
        Args["rows"] = NumericArguments[0]
        Args["cols"] = NumericArguments[1]
        NumericArguments = NumericArguments[2:]

    if len(NumericArguments) == 0:
        return None
    if len(NumericArguments) == 1:
        x1 = (NumericArguments[0] - 1) % Args["cols"] + 1
        x2 = x1
        y1 = (NumericArguments[0] - 1) // Args["cols"] + 1
        y2 = y1
    elif len(NumericArguments) == 2:
        x1 = NumericArguments[0]
        x2 = x1
        y1 = NumericArguments[1]
        y2 = y1
    elif len(NumericArguments) == 4:
        x1 = NumericArguments[0]
        x2 = x1 + NumericArguments[2] - 1
        y1 = NumericArguments[1]
        y2 = y1 + NumericArguments[3] - 1
    else:
        raise ValueError("subaxis argument error")

    cellwidth = (
        (1 - Args["MarginLeft"] - Args["MarginRight"])
        - (Args["cols"] - 1) * Args["SpacingHorizontal"]
    ) / Args["cols"]
    cellheight = (
        (1 - Args["MarginTop"] - Args["MarginBottom"])
        - (Args["rows"] - 1) * Args["SpacingVertical"]
    ) / Args["rows"]
    xpos1 = (
        Args["MarginLeft"]
        + Args["PaddingLeft"]
        + cellwidth * (x1 - 1)
        + Args["SpacingHorizontal"] * (x1 - 1)
    )
    xpos2 = (
        Args["MarginLeft"]
        - Args["PaddingRight"]
        + cellwidth * x2
        + Args["SpacingHorizontal"] * (x2 - 1)
    )
    ypos1 = (
        Args["MarginTop"]
        + Args["PaddingTop"]
        + cellheight * (y1 - 1)
        + Args["SpacingVertical"] * (y1 - 1)
    )
    ypos2 = (
        Args["MarginTop"]
        - Args["PaddingBottom"]
        + cellheight * y2
        + Args["SpacingVertical"] * (y2 - 1)
    )

    position = [xpos1, 1 - ypos2, xpos2 - xpos1, ypos2 - ypos1]
    h = f.add_axes(position)
    h.set_box_aspect(None)
    h.set_frame_on(True)
    h.set_gid("subaxis")
    return h
