# Auto-generated by `python -m gen` — do not edit manually.

from typing import TYPE_CHECKING, Literal

import bpy

from ...builder import BaseNode, SocketAccessor

from ...types import (
    InputColor,
    InputFloat,
    InputVector,
)

from ...builder.socket import (
    ColorSocket,
    FloatSocket,
    VectorSocket,
)


class Bump(BaseNode):
    """
    Generate a perturbed normal from a height texture for bump mapping. Typically used for faking highly detailed surfaces

    Parameters
    ----------
    strength : InputFloat
        Strength
    distance : InputFloat
        Distance
    filter_width : InputFloat
        Filter Width
    height : InputFloat
        Height
    normal : InputVector
        Normal

    Inputs
    ------
    i.strength : FloatSocket
        Strength
    i.distance : FloatSocket
        Distance
    i.filter_width : FloatSocket
        Filter Width
    i.height : FloatSocket
        Height
    i.normal : VectorSocket
        Normal

    Outputs
    -------
    o.normal : VectorSocket
        Normal
    """

    _bl_idname = "ShaderNodeBump"
    node: bpy.types.ShaderNodeBump

    class _Inputs(SocketAccessor):
        strength: FloatSocket
        """Strength"""
        distance: FloatSocket
        """Distance"""
        filter_width: FloatSocket
        """Filter Width"""
        height: FloatSocket
        """Height"""
        normal: VectorSocket
        """Normal"""

    class _Outputs(SocketAccessor):
        normal: VectorSocket
        """Normal"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        strength: InputFloat = 1.0,
        distance: InputFloat = 0.001,
        filter_width: InputFloat = 0.1,
        height: InputFloat = 1.0,
        normal: InputVector = None,
        *,
        invert: bool = False,
    ):
        super().__init__()
        key_args = {
            "Strength": strength,
            "Distance": distance,
            "Filter Width": filter_width,
            "Height": height,
            "Normal": normal,
        }
        self.invert = invert
        self._establish_links(**key_args)

    @property
    def invert(self) -> bool:
        return self.node.invert

    @invert.setter
    def invert(self, value: bool):
        self.node.invert = value


class Displacement(BaseNode):
    """
    Displace the surface along the surface normal

    Parameters
    ----------
    height : InputFloat
        Height
    midlevel : InputFloat
        Midlevel
    scale : InputFloat
        Scale
    normal : InputVector
        Normal

    Inputs
    ------
    i.height : FloatSocket
        Height
    i.midlevel : FloatSocket
        Midlevel
    i.scale : FloatSocket
        Scale
    i.normal : VectorSocket
        Normal

    Outputs
    -------
    o.displacement : VectorSocket
        Displacement
    """

    _bl_idname = "ShaderNodeDisplacement"
    node: bpy.types.ShaderNodeDisplacement

    class _Inputs(SocketAccessor):
        height: FloatSocket
        """Height"""
        midlevel: FloatSocket
        """Midlevel"""
        scale: FloatSocket
        """Scale"""
        normal: VectorSocket
        """Normal"""

    class _Outputs(SocketAccessor):
        displacement: VectorSocket
        """Displacement"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        height: InputFloat = 0.0,
        midlevel: InputFloat = 0.5,
        scale: InputFloat = 0.01,
        normal: InputVector = None,
        *,
        space: Literal["OBJECT", "WORLD"] = "OBJECT",
    ):
        super().__init__()
        key_args = {
            "Height": height,
            "Midlevel": midlevel,
            "Scale": scale,
            "Normal": normal,
        }
        self.space = space
        self._establish_links(**key_args)

    @property
    def space(self) -> Literal["OBJECT", "WORLD"]:
        return self.node.space

    @space.setter
    def space(self, value: Literal["OBJECT", "WORLD"]):
        self.node.space = value


class Mapping(BaseNode):
    """
    Transform the input vector by applying translation, rotation, and scale

    Parameters
    ----------
    vector : InputVector
        Vector
    location : InputVector
        Location
    rotation : InputVector
        Rotation
    scale : InputVector
        Scale

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.location : VectorSocket
        Location
    i.rotation : VectorSocket
        Rotation
    i.scale : VectorSocket
        Scale

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "ShaderNodeMapping"
    node: bpy.types.ShaderNodeMapping

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        location: VectorSocket
        """Location"""
        rotation: VectorSocket
        """Rotation"""
        scale: VectorSocket
        """Scale"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        location: InputVector = None,
        rotation: InputVector = None,
        scale: InputVector = None,
        *,
        vector_type: Literal["POINT", "TEXTURE", "VECTOR", "NORMAL"] = "POINT",
    ):
        super().__init__()
        key_args = {
            "Vector": vector,
            "Location": location,
            "Rotation": rotation,
            "Scale": scale,
        }
        self.vector_type = vector_type
        self._establish_links(**key_args)

    @classmethod
    def point(
        cls,
        vector: InputVector = None,
        location: InputVector = None,
        rotation: InputVector = None,
        scale: InputVector = None,
    ) -> "Mapping":
        """Create Mapping with operation 'Point'. Transform a point"""
        return cls(
            vector_type="POINT",
            vector=vector,
            location=location,
            rotation=rotation,
            scale=scale,
        )

    @classmethod
    def texture(
        cls,
        vector: InputVector = None,
        location: InputVector = None,
        rotation: InputVector = None,
        scale: InputVector = None,
    ) -> "Mapping":
        """Create Mapping with operation 'Texture'. Transform a texture by inverse mapping the texture coordinate"""
        return cls(
            vector_type="TEXTURE",
            vector=vector,
            location=location,
            rotation=rotation,
            scale=scale,
        )

    @classmethod
    def vector(
        cls,
        vector: InputVector = None,
        rotation: InputVector = None,
        scale: InputVector = None,
    ) -> "Mapping":
        """Create Mapping with operation 'Vector'. Transform a direction vector (Location is ignored)"""
        return cls(vector_type="VECTOR", vector=vector, rotation=rotation, scale=scale)

    @classmethod
    def normal(
        cls,
        vector: InputVector = None,
        rotation: InputVector = None,
        scale: InputVector = None,
    ) -> "Mapping":
        """Create Mapping with operation 'Normal'. Transform a unit normal vector (Location is ignored)"""
        return cls(vector_type="NORMAL", vector=vector, rotation=rotation, scale=scale)

    @property
    def vector_type(self) -> Literal["POINT", "TEXTURE", "VECTOR", "NORMAL"]:
        return self.node.vector_type

    @vector_type.setter
    def vector_type(self, value: Literal["POINT", "TEXTURE", "VECTOR", "NORMAL"]):
        self.node.vector_type = value


class Normal(BaseNode):
    """
    Generate a normal vector and a dot product

    Parameters
    ----------
    normal : InputVector
        Normal

    Inputs
    ------
    i.normal : VectorSocket
        Normal

    Outputs
    -------
    o.normal : VectorSocket
        Normal
    o.dot : FloatSocket
        Dot
    """

    _bl_idname = "ShaderNodeNormal"
    node: bpy.types.ShaderNodeNormal

    class _Inputs(SocketAccessor):
        normal: VectorSocket
        """Normal"""

    class _Outputs(SocketAccessor):
        normal: VectorSocket
        """Normal"""
        dot: FloatSocket
        """Dot"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, normal: InputVector = None):
        super().__init__()
        key_args = {"Normal": normal}

        self._establish_links(**key_args)


class NormalMap(BaseNode):
    """
    Generate a perturbed normal from an RGB normal map image. Typically used for faking highly detailed surfaces

    Parameters
    ----------
    strength : InputFloat
        Strength
    color : InputColor
        Color

    Inputs
    ------
    i.strength : FloatSocket
        Strength
    i.color : ColorSocket
        Color

    Outputs
    -------
    o.normal : VectorSocket
        Normal
    """

    _bl_idname = "ShaderNodeNormalMap"
    node: bpy.types.ShaderNodeNormalMap

    class _Inputs(SocketAccessor):
        strength: FloatSocket
        """Strength"""
        color: ColorSocket
        """Color"""

    class _Outputs(SocketAccessor):
        normal: VectorSocket
        """Normal"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        strength: InputFloat = 1.0,
        color: InputColor = None,
        *,
        space: Literal[
            "TANGENT", "OBJECT", "WORLD", "BLENDER_OBJECT", "BLENDER_WORLD"
        ] = "TANGENT",
        uv_map: str = "",
        convention: Literal["OPENGL", "DIRECTX"] = "OPENGL",
        base: Literal["ORIGINAL", "DISPLACED"] = "DISPLACED",
    ):
        super().__init__()
        key_args = {"Strength": strength, "Color": color}
        self.space = space
        self.uv_map = uv_map
        self.convention = convention
        self.base = base
        self._establish_links(**key_args)

    @property
    def space(
        self,
    ) -> Literal["TANGENT", "OBJECT", "WORLD", "BLENDER_OBJECT", "BLENDER_WORLD"]:
        return self.node.space

    @space.setter
    def space(
        self,
        value: Literal["TANGENT", "OBJECT", "WORLD", "BLENDER_OBJECT", "BLENDER_WORLD"],
    ):
        self.node.space = value

    @property
    def uv_map(self) -> str:
        return self.node.uv_map

    @uv_map.setter
    def uv_map(self, value: str):
        self.node.uv_map = value

    @property
    def convention(self) -> Literal["OPENGL", "DIRECTX"]:
        return self.node.convention

    @convention.setter
    def convention(self, value: Literal["OPENGL", "DIRECTX"]):
        self.node.convention = value

    @property
    def base(self) -> Literal["ORIGINAL", "DISPLACED"]:
        return self.node.base

    @base.setter
    def base(self, value: Literal["ORIGINAL", "DISPLACED"]):
        self.node.base = value


class VectorDisplacement(BaseNode):
    """
    Displace the surface along an arbitrary direction

    Parameters
    ----------
    vector : InputColor
        Vector
    midlevel : InputFloat
        Midlevel
    scale : InputFloat
        Scale

    Inputs
    ------
    i.vector : ColorSocket
        Vector
    i.midlevel : FloatSocket
        Midlevel
    i.scale : FloatSocket
        Scale

    Outputs
    -------
    o.displacement : VectorSocket
        Displacement
    """

    _bl_idname = "ShaderNodeVectorDisplacement"
    node: bpy.types.ShaderNodeVectorDisplacement

    class _Inputs(SocketAccessor):
        vector: ColorSocket
        """Vector"""
        midlevel: FloatSocket
        """Midlevel"""
        scale: FloatSocket
        """Scale"""

    class _Outputs(SocketAccessor):
        displacement: VectorSocket
        """Displacement"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputColor = None,
        midlevel: InputFloat = 0.0,
        scale: InputFloat = 0.01,
        *,
        space: Literal["TANGENT", "OBJECT", "WORLD"] = "TANGENT",
    ):
        super().__init__()
        key_args = {"Vector": vector, "Midlevel": midlevel, "Scale": scale}
        self.space = space
        self._establish_links(**key_args)

    @property
    def space(self) -> Literal["TANGENT", "OBJECT", "WORLD"]:
        return self.node.space

    @space.setter
    def space(self, value: Literal["TANGENT", "OBJECT", "WORLD"]):
        self.node.space = value


class VectorTransform(BaseNode):
    """
    Convert a vector, point, or normal between world, camera, and object coordinate space

    Parameters
    ----------
    vector : InputVector
        Vector

    Inputs
    ------
    i.vector : VectorSocket
        Vector

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "ShaderNodeVectorTransform"
    node: bpy.types.ShaderNodeVectorTransform

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        *,
        vector_type: Literal["POINT", "VECTOR", "NORMAL"] = "VECTOR",
        convert_from: Literal["WORLD", "OBJECT", "CAMERA"] = "WORLD",
        convert_to: Literal["WORLD", "OBJECT", "CAMERA"] = "OBJECT",
    ):
        super().__init__()
        key_args = {"Vector": vector}
        self.vector_type = vector_type
        self.convert_from = convert_from
        self.convert_to = convert_to
        self._establish_links(**key_args)

    @classmethod
    def point(cls, vector: InputVector = None) -> "VectorTransform":
        """Create Vector Transform with operation 'Point'. Transform a point"""
        return cls(vector_type="POINT", vector=vector)

    @classmethod
    def vector(cls, vector: InputVector = None) -> "VectorTransform":
        """Create Vector Transform with operation 'Vector'. Transform a direction vector"""
        return cls(vector_type="VECTOR", vector=vector)

    @classmethod
    def normal(cls, vector: InputVector = None) -> "VectorTransform":
        """Create Vector Transform with operation 'Normal'. Transform a normal vector with unit length"""
        return cls(vector_type="NORMAL", vector=vector)

    @property
    def vector_type(self) -> Literal["POINT", "VECTOR", "NORMAL"]:
        return self.node.vector_type

    @vector_type.setter
    def vector_type(self, value: Literal["POINT", "VECTOR", "NORMAL"]):
        self.node.vector_type = value

    @property
    def convert_from(self) -> Literal["WORLD", "OBJECT", "CAMERA"]:
        return self.node.convert_from

    @convert_from.setter
    def convert_from(self, value: Literal["WORLD", "OBJECT", "CAMERA"]):
        self.node.convert_from = value

    @property
    def convert_to(self) -> Literal["WORLD", "OBJECT", "CAMERA"]:
        return self.node.convert_to

    @convert_to.setter
    def convert_to(self, value: Literal["WORLD", "OBJECT", "CAMERA"]):
        self.node.convert_to = value
