# RFX_GLTF_Exporter settings
# Plugin metadata, theme tokens, glTF constants, defaults.
# No f-strings. No unicode. ASCII only.

import os
import json


PLUGIN_NAME = "RFX_GLTF_Exporter"
PLUGIN_LABEL = "glTF Exporter"
PLUGIN_TITLE = "RFX glTF Exporter"
PLUGIN_VERSION = "1.3.0"
GENERATOR_STRING = "RFX glTF Exporter for Maya"

# About / credits
AUTHOR = "Amar Shinde"
STUDIO = "Reimagine Fx"
WEBSITE = "www.reimaginefx.com"
EMAIL = "reimaginefx@gmail.com"
SUPPORT = "Reimagine Fx Community (Discord)"
COPYRIGHT = "Copyright 2026 Reimagine Fx. All rights reserved."
ABOUT_TEXT = (
    "RFX glTF Exporter imports and exports clean glTF 2.0 and GLB files for "
    "the web, AR, real-time engines, and Maya look development. It resolves textures "
    "from Arnold, openPBR, standardSurface, and MaterialX materials into portable "
    "metallic-roughness PBR, embeds images, packs and converts maps, and preserves "
    "geometry, UVs, tangents, and hierarchy. Built for Maya 2026 with MtoA "
    "integration."
)

# RFX brand palette
COLOR_BG = "#161616"
COLOR_PANEL = "#1d1d1d"
COLOR_PANEL_ALT = "#222222"
COLOR_BORDER = "#2d2d2d"
COLOR_TEXT = "#dcdcdc"
COLOR_TEXT_DIM = "#909090"
COLOR_ACCENT = "#EF9F27"
COLOR_ACCENT_HOVER = "#f7b04a"
COLOR_ACCENT_PRESSED = "#c47d12"
COLOR_GOOD = "#4fcb83"
COLOR_WARN = "#f0b23c"
COLOR_BAD = "#e5554f"

# glTF 2.0 component types
COMPONENT_TYPE_BYTE = 5120
COMPONENT_TYPE_UNSIGNED_BYTE = 5121
COMPONENT_TYPE_SHORT = 5122
COMPONENT_TYPE_UNSIGNED_SHORT = 5123
COMPONENT_TYPE_UNSIGNED_INT = 5125
COMPONENT_TYPE_FLOAT = 5126

TYPE_SCALAR = "SCALAR"
TYPE_VEC2 = "VEC2"
TYPE_VEC3 = "VEC3"
TYPE_VEC4 = "VEC4"
TYPE_MAT4 = "MAT4"

TARGET_ARRAY_BUFFER = 34962
TARGET_ELEMENT_ARRAY_BUFFER = 34963

BUFFER_ALIGNMENT = 4
GLB_MAGIC = 0x46546C67          # "glTF"
GLB_VERSION = 2
GLB_CHUNK_JSON = 0x4E4F534A     # "JSON"
GLB_CHUNK_BIN = 0x004E4942      # "BIN\0"

# Material attribute candidates per renderer family
BASE_COLOR_ATTRS = (
    "baseColor",
    "color",
    "diffuseColor",
    "diffuse_color",
    "diffuseColorIn",
    "Color",
    "albedoColor",
    "base_color",
)

# Attribute names span standardSurface, openPBRSurface (Maya 2026 default),
# aiStandardSurface, Redshift, V-Ray, Lambert/Blinn/Phong, and MaterialX
# standard_surface nodes (snake_case long names) exposed through LookdevX.
METALLIC_ATTRS = (
    "baseMetalness",      # openPBRSurface
    "metalness",          # standardSurface / aiStandardSurface / MaterialX
    "metallic",
    "base_metalness",     # MaterialX standard_surface
    "refl_metalness",     # V-Ray
    "metalness0",
)
ROUGHNESS_ATTRS = (
    "specularRoughness",  # standardSurface / openPBRSurface / aiStandardSurface
    "specular_roughness", # MaterialX standard_surface
    "roughness",
    "reflectionRoughness",
    "refl_roughness",     # V-Ray
)
NORMAL_ATTRS = (
    "normalCamera",       # Maya 2026 openPBR / standardSurface / Lambert
    "geometryNormal",     # openPBR variant fallback
    "normal",             # MaterialX standard_surface
    "bumpNormal",
    "bump_input",         # Redshift
    "coatNormal",
    "normal_input",
)
EMISSIVE_ATTRS = (
    "emissionColor",      # standardSurface / openPBRSurface / aiStandardSurface
    "emission_color",     # MaterialX standard_surface
    "emission",
    "incandescence",      # Lambert / Blinn / Phong
    "emissive_color",     # Redshift
)
EMISSION_WEIGHT_ATTRS = (
    "emissionLuminance",  # openPBRSurface (nits)
    "emission",           # standardSurface / aiStandardSurface (0..1 weight)
    "emissionWeight",
    "emission_weight",    # MaterialX standard_surface
)
OCCLUSION_ATTRS = ("ambientOcclusion", "ao")
TRANSMISSION_ATTRS = ("transmissionWeight", "transmission", "refractionWeight", "refraction")
IOR_ATTRS = ("specularIOR", "IOR", "refractionIOR", "ior", "specular_IOR")
OPACITY_ATTRS = (
    "geometryOpacity",    # openPBRSurface
    "opacity",            # standardSurface / aiStandardSurface / MaterialX
    "outOpacity",
    "transparency",       # Lambert / Blinn / Phong (inverted)
)

# Texture path attributes used by Maya, Arnold, Redshift, V-Ray, and
# MaterialX image nodes represented in Maya's dependency graph.
TEXTURE_PATH_ATTRS = (
    "computedFileTextureNamePattern",
    "fileTextureName",
    "filename",
    "file",
    "filePath",
    "texture",
    "tex0",
    "image",
    "uri",
)

GLTF_NATIVE_IMAGE_EXTENSIONS = (".png", ".jpg", ".jpeg")

# Vertex dedup precision (decimal places)
VERTEX_KEY_PRECISION = 6

DEFAULT_MATERIAL_NAME = "RFX_Default_Material"
DEFAULT_BASE_COLOR = [0.8, 0.8, 0.8, 1.0]

# UI defaults
DEFAULT_OPTIONS = {
    "operation": "export",             # "export" or "import"
    "output_path": "",
    "input_path": "",
    "format": "gltf",                  # "gltf" or "glb"
    "export_mode": "selected",         # "selected" or "visible"
    "copy_textures": True,
    "embed_textures": False,           # for GLB only
    "max_texture_size": 2048,          # cap longest texture dimension; 0 = no limit
    "include_normals": True,
    "include_tangents": True,
    "include_uvs": True,
    "flip_uv_v": True,                 # glTF standard: v_gltf = 1 - v_maya
    "include_vertex_colors": False,
    "include_hierarchy": True,
    "include_lights": True,            # KHR_lights_punctual only
    "include_cameras": True,           # core glTF perspective / orthographic
    "split_by_material": True,
    "y_up": True,                      # both Maya default and glTF default
    "open_folder": False,
    "import_materials": True,
    "import_textures": True,
    "import_cameras": True,
    "import_lights": True,
    "import_flip_uv_v": True,
}


def plugin_dir():
    return os.path.dirname(os.path.abspath(__file__))


def icon_path():
    return os.path.join(
        plugin_dir(), "icons", "rfx_glbexporter_icon.png"
    )


def _prefs_dir():
    base = os.environ.get("MAYA_APP_DIR")
    if not base:
        base = os.path.join(os.path.expanduser("~"), "maya")
    out = os.path.join(base, "RFX", PLUGIN_NAME)
    try:
        if not os.path.isdir(out):
            os.makedirs(out)
    except Exception:
        pass
    return out


def prefs_path():
    return os.path.join(_prefs_dir(), "prefs.json")


def load_prefs():
    path = prefs_path()
    try:
        if os.path.isfile(path):
            with open(path, "r", encoding="utf-8") as f:
                return json.load(f)
    except Exception:
        pass
    return {}


def save_prefs(prefs):
    path = prefs_path()
    try:
        with open(path, "w", encoding="utf-8") as f:
            json.dump(prefs, f, indent=2)
        return True
    except Exception:
        return False
