# DIG_SSAO_TuneUp.py
# Python port of DIG_SSAO_TuneUp.rvb for Rhino Windows / Mac

import re
import rhinoscriptsyntax as rs

SECTION = "SSAO"


def _run_ssao(radius=None, intensity=None, echo=False):
    """Run Rhino's hidden TestSSAOOptions command."""
    if radius is not None:
        return rs.Command("_TestSSAOOptions _RadiusMultiplier={} _Enter".format(radius), echo)
    if intensity is not None:
        return rs.Command("_TestSSAOOptions _Intensity={} _Enter".format(intensity), echo)
    return rs.Command("_TestSSAOOptions _Enter", echo)


def _read_current_ssao_settings():
    """Read current SSAO values by capturing TestSSAOOptions command output."""
    rs.ClearCommandHistory()
    _run_ssao(echo=True)
    history = rs.CommandHistory() or ""
    rs.ClearCommandHistory()

    # Be tolerant of differences in line endings, spacing, and output order
    radius_match = re.search(r"RadiusMultiplier\s*=\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)", history, re.I)
    intensity_match = re.search(r"Intensity\s*=\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)", history, re.I)

    radius = float(radius_match.group(1)) if radius_match else None
    intensity = float(intensity_match.group(1)) if intensity_match else None
    return radius, intensity


def _save_settings(radius, intensity):
    rs.SetDocumentData(SECTION, "Radius", str(radius))
    rs.SetDocumentData(SECTION, "Intensity", str(intensity))


def DIG_SSAO_TuneUp():
    radius, intensity = _read_current_ssao_settings()

    # If Rhino's command output could not be parsed, fall back to saved document
    # settings, then to conservative defaults.
    if radius is None:
        saved = rs.GetDocumentData(SECTION, "Radius")
        radius = float(saved) if saved is not None else 1.0

    if intensity is None:
        saved = rs.GetDocumentData(SECTION, "Intensity")
        intensity = float(saved) if saved is not None else 1.0

    options = [
        "Radius",
        "Intensity",
        "RadMORE",
        "RadLESS",
        "IntMORE",
        "IntLESS",
        "ReadDocSettings",
        "DONE",
    ]

    while True:
        print("\n\n\n\n\n")
        print("Radius : {}   |   Intensity : {}".format(radius, intensity))

        result = rs.GetString("SSAO TuneUp", "", options)
        if result is None or result == "" or result == "DONE":
            break

        if result == "Radius":
            new_radius = rs.GetReal("Radius?", radius, 0.0)
            if new_radius is not None:
                radius = new_radius
                rs.SetDocumentData(SECTION, "Radius", str(radius))
                _run_ssao(radius=radius)

        elif result == "RadMORE":
            radius += 1.0
            rs.SetDocumentData(SECTION, "Radius", str(radius))
            _run_ssao(radius=radius)

        elif result == "RadLESS":
            radius = max(0.0, radius - 1.0)
            rs.SetDocumentData(SECTION, "Radius", str(radius))
            _run_ssao(radius=radius)

        elif result == "IntMORE":
            if abs(intensity - 0.01) < 1e-9:
                intensity = 1.0
            else:
                intensity = min(10.0, intensity + 1.0)
            rs.SetDocumentData(SECTION, "Intensity", str(intensity))
            _run_ssao(intensity=intensity)

        elif result == "IntLESS":
            intensity = max(0.01, intensity - 1.0)
            rs.SetDocumentData(SECTION, "Intensity", str(intensity))
            _run_ssao(intensity=intensity)

        elif result == "Intensity":
            new_intensity = rs.GetReal("Intensity?", intensity, 0.01, 10.0)
            if new_intensity is not None:
                intensity = new_intensity
                rs.SetDocumentData(SECTION, "Intensity", str(intensity))
                _run_ssao(intensity=intensity)

        elif result == "ReadDocSettings":
            saved_radius = rs.GetDocumentData(SECTION, "Radius")
            if saved_radius is not None:
                radius = float(saved_radius)
                _run_ssao(radius=radius)

            saved_intensity = rs.GetDocumentData(SECTION, "Intensity")
            if saved_intensity is not None:
                intensity = float(saved_intensity)
                _run_ssao(intensity=intensity)

        else:
            rs.Command(result, False)


if __name__ == "__main__":
    DIG_SSAO_TuneUp()
