# 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 (
    InputFloat,
    InputVector,
)

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


class RadialTiling(BaseNode):
    """
    Transform Coordinate System for Radial Tiling

    Parameters
    ----------
    vector : InputVector
        Vector
    sides : InputFloat
        Sides
    roundness : InputFloat
        Roundness

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.sides : FloatSocket
        Sides
    i.roundness : FloatSocket
        Roundness

    Outputs
    -------
    o.segment_coordinates : VectorSocket
        Segment Coordinates
    o.segment_id : FloatSocket
        Segment ID
    o.segment_width : FloatSocket
        Segment Width
    o.segment_rotation : FloatSocket
        Segment Rotation
    """

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

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        sides: FloatSocket
        """Sides"""
        roundness: FloatSocket
        """Roundness"""

    class _Outputs(SocketAccessor):
        segment_coordinates: VectorSocket
        """Segment Coordinates"""
        segment_id: FloatSocket
        """Segment ID"""
        segment_width: FloatSocket
        """Segment Width"""
        segment_rotation: FloatSocket
        """Segment Rotation"""

    if TYPE_CHECKING:

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

    def __init__(
        self,
        vector: InputVector = None,
        sides: InputFloat = 5.0,
        roundness: InputFloat = 0.0,
        *,
        normalize: bool = False,
    ):
        super().__init__()
        key_args = {"Vector": vector, "Sides": sides, "Roundness": roundness}
        self.normalize = normalize
        self._establish_links(**key_args)

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

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


class VectorCurves(BaseNode):
    """
    Map input vector components with curves

    Parameters
    ----------
    fac : InputFloat
        Factor
    vector : InputVector
        Vector

    Inputs
    ------
    i.fac : FloatSocket
        Factor
    i.vector : VectorSocket
        Vector

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

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

    class _Inputs(SocketAccessor):
        fac: FloatSocket
        """Factor"""
        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,
        fac: InputFloat = 1.0,
        vector: InputVector = None,
    ):
        super().__init__()
        key_args = {"Fac": fac, "Vector": vector}

        self._establish_links(**key_args)


class VectorMath(BaseNode):
    """
    Perform vector math operation

    Parameters
    ----------
    vector : InputVector
        Vector
    vector_001 : InputVector
        Vector
    vector_002 : InputVector
        Vector
    scale : InputFloat
        Scale

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.vector_001 : VectorSocket
        Vector
    i.vector_002 : VectorSocket
        Vector
    i.scale : FloatSocket
        Scale

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    o.value : FloatSocket
        Value
    """

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

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        vector_001: VectorSocket
        """Vector"""
        vector_002: VectorSocket
        """Vector"""
        scale: FloatSocket
        """Scale"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        value: FloatSocket
        """Value"""

    if TYPE_CHECKING:

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

    def __init__(
        self,
        vector: InputVector = None,
        vector_001: InputVector = None,
        vector_002: InputVector = None,
        scale: InputFloat = 1.0,
        *,
        operation: Literal[
            "ADD",
            "SUBTRACT",
            "MULTIPLY",
            "DIVIDE",
            "MULTIPLY_ADD",
            "CROSS_PRODUCT",
            "PROJECT",
            "REFLECT",
            "REFRACT",
            "FACEFORWARD",
            "DOT_PRODUCT",
            "DISTANCE",
            "LENGTH",
            "SCALE",
            "NORMALIZE",
            "ABSOLUTE",
            "POWER",
            "SIGN",
            "MINIMUM",
            "MAXIMUM",
            "ROUND",
            "FLOOR",
            "CEIL",
            "FRACTION",
            "MODULO",
            "WRAP",
            "SNAP",
            "SINE",
            "COSINE",
            "TANGENT",
        ] = "ADD",
    ):
        super().__init__()
        key_args = {
            "Vector": vector,
            "Vector_001": vector_001,
            "Vector_002": vector_002,
            "Scale": scale,
        }
        self.operation = operation
        self._establish_links(**key_args)

    @classmethod
    def add(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Add'. A + B"""
        return cls(operation="ADD", vector=vector, vector_001=vector_001)

    @classmethod
    def subtract(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Subtract'. A - B"""
        return cls(operation="SUBTRACT", vector=vector, vector_001=vector_001)

    @classmethod
    def multiply(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Multiply'. Entry-wise multiply"""
        return cls(operation="MULTIPLY", vector=vector, vector_001=vector_001)

    @classmethod
    def divide(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Divide'. Entry-wise divide"""
        return cls(operation="DIVIDE", vector=vector, vector_001=vector_001)

    @classmethod
    def multiply_add(
        cls,
        vector: InputVector = None,
        vector_001: InputVector = None,
        vector_002: InputVector = None,
    ) -> "VectorMath":
        """Create Vector Math with operation 'Multiply Add'. A * B + C"""
        return cls(
            operation="MULTIPLY_ADD",
            vector=vector,
            vector_001=vector_001,
            vector_002=vector_002,
        )

    @classmethod
    def cross_product(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Cross Product'. A cross B"""
        return cls(operation="CROSS_PRODUCT", vector=vector, vector_001=vector_001)

    @classmethod
    def project(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Project'. Project A onto B"""
        return cls(operation="PROJECT", vector=vector, vector_001=vector_001)

    @classmethod
    def reflect(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Reflect'. Reflect A around the normal B. B does not need to be normalized."""
        return cls(operation="REFLECT", vector=vector, vector_001=vector_001)

    @classmethod
    def refract(
        cls,
        vector: InputVector = None,
        vector_001: InputVector = None,
        scale: InputFloat = 1.0,
    ) -> "VectorMath":
        """Create Vector Math with operation 'Refract'. For a given incident vector A, surface normal B and ratio of indices of refraction, Ior, refract returns the refraction vector, R"""
        return cls(
            operation="REFRACT", vector=vector, vector_001=vector_001, scale=scale
        )

    @classmethod
    def faceforward(
        cls,
        vector: InputVector = None,
        vector_001: InputVector = None,
        vector_002: InputVector = None,
    ) -> "VectorMath":
        """Create Vector Math with operation 'Faceforward'. Orients a vector A to point away from a surface B as defined by its normal C. Returns (dot(B, C) < 0) ? A : -A"""
        return cls(
            operation="FACEFORWARD",
            vector=vector,
            vector_001=vector_001,
            vector_002=vector_002,
        )

    @classmethod
    def dot_product(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Dot Product'. A dot B"""
        return cls(operation="DOT_PRODUCT", vector=vector, vector_001=vector_001)

    @classmethod
    def distance(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Distance'. Distance between A and B"""
        return cls(operation="DISTANCE", vector=vector, vector_001=vector_001)

    @classmethod
    def length(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Length'. Length of A"""
        return cls(operation="LENGTH", vector=vector)

    @classmethod
    def scale(cls, vector: InputVector = None, scale: InputFloat = 1.0) -> "VectorMath":
        """Create Vector Math with operation 'Scale'. A multiplied by Scale"""
        return cls(operation="SCALE", vector=vector, scale=scale)

    @classmethod
    def normalize(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Normalize'. Normalize A"""
        return cls(operation="NORMALIZE", vector=vector)

    @classmethod
    def absolute(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Absolute'. Entry-wise absolute"""
        return cls(operation="ABSOLUTE", vector=vector)

    @classmethod
    def power(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Power'. Entry-wise power"""
        return cls(operation="POWER", vector=vector, vector_001=vector_001)

    @classmethod
    def sign(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Sign'. Entry-wise sign"""
        return cls(operation="SIGN", vector=vector)

    @classmethod
    def minimum(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Minimum'. Entry-wise minimum"""
        return cls(operation="MINIMUM", vector=vector, vector_001=vector_001)

    @classmethod
    def maximum(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Maximum'. Entry-wise maximum"""
        return cls(operation="MAXIMUM", vector=vector, vector_001=vector_001)

    @classmethod
    def round(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Round'. Entry-wise round to the nearest integer. Round upward if the fraction part is 0.5"""
        return cls(operation="ROUND", vector=vector)

    @classmethod
    def floor(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Floor'. Entry-wise floor"""
        return cls(operation="FLOOR", vector=vector)

    @classmethod
    def ceil(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Ceil'. Entry-wise ceil"""
        return cls(operation="CEIL", vector=vector)

    @classmethod
    def fraction(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Fraction'. The fraction part of A entry-wise"""
        return cls(operation="FRACTION", vector=vector)

    @classmethod
    def modulo(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Modulo'. Entry-wise modulo using fmod(A,B)"""
        return cls(operation="MODULO", vector=vector, vector_001=vector_001)

    @classmethod
    def wrap(
        cls,
        vector: InputVector = None,
        vector_001: InputVector = None,
        vector_002: InputVector = None,
    ) -> "VectorMath":
        """Create Vector Math with operation 'Wrap'. Entry-wise wrap(A,B)"""
        return cls(
            operation="WRAP",
            vector=vector,
            vector_001=vector_001,
            vector_002=vector_002,
        )

    @classmethod
    def snap(
        cls, vector: InputVector = None, vector_001: InputVector = None
    ) -> "VectorMath":
        """Create Vector Math with operation 'Snap'. Round A to the largest integer multiple of B less than or equal A"""
        return cls(operation="SNAP", vector=vector, vector_001=vector_001)

    @classmethod
    def sine(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Sine'. Entry-wise sin(A)"""
        return cls(operation="SINE", vector=vector)

    @classmethod
    def cosine(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Cosine'. Entry-wise cos(A)"""
        return cls(operation="COSINE", vector=vector)

    @classmethod
    def tangent(cls, vector: InputVector = None) -> "VectorMath":
        """Create Vector Math with operation 'Tangent'. Entry-wise tan(A)"""
        return cls(operation="TANGENT", vector=vector)

    @property
    def operation(
        self,
    ) -> Literal[
        "ADD",
        "SUBTRACT",
        "MULTIPLY",
        "DIVIDE",
        "MULTIPLY_ADD",
        "CROSS_PRODUCT",
        "PROJECT",
        "REFLECT",
        "REFRACT",
        "FACEFORWARD",
        "DOT_PRODUCT",
        "DISTANCE",
        "LENGTH",
        "SCALE",
        "NORMALIZE",
        "ABSOLUTE",
        "POWER",
        "SIGN",
        "MINIMUM",
        "MAXIMUM",
        "ROUND",
        "FLOOR",
        "CEIL",
        "FRACTION",
        "MODULO",
        "WRAP",
        "SNAP",
        "SINE",
        "COSINE",
        "TANGENT",
    ]:
        return self.node.operation

    @operation.setter
    def operation(
        self,
        value: Literal[
            "ADD",
            "SUBTRACT",
            "MULTIPLY",
            "DIVIDE",
            "MULTIPLY_ADD",
            "CROSS_PRODUCT",
            "PROJECT",
            "REFLECT",
            "REFRACT",
            "FACEFORWARD",
            "DOT_PRODUCT",
            "DISTANCE",
            "LENGTH",
            "SCALE",
            "NORMALIZE",
            "ABSOLUTE",
            "POWER",
            "SIGN",
            "MINIMUM",
            "MAXIMUM",
            "ROUND",
            "FLOOR",
            "CEIL",
            "FRACTION",
            "MODULO",
            "WRAP",
            "SNAP",
            "SINE",
            "COSINE",
            "TANGENT",
        ],
    ):
        self.node.operation = value


class VectorRotate(BaseNode):
    """
    Rotate a vector around a pivot point (center)

    Parameters
    ----------
    vector : InputVector
        Vector
    center : InputVector
        Center
    axis : InputVector
        Axis
    angle : InputFloat
        Angle
    rotation : InputVector
        Rotation

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.center : VectorSocket
        Center
    i.axis : VectorSocket
        Axis
    i.angle : FloatSocket
        Angle
    i.rotation : VectorSocket
        Rotation

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

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

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        center: VectorSocket
        """Center"""
        axis: VectorSocket
        """Axis"""
        angle: FloatSocket
        """Angle"""
        rotation: VectorSocket
        """Rotation"""

    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,
        center: InputVector = None,
        axis: InputVector = None,
        angle: InputFloat = 0.0,
        rotation: InputVector = None,
        *,
        rotation_type: Literal[
            "AXIS_ANGLE", "X_AXIS", "Y_AXIS", "Z_AXIS", "EULER_XYZ"
        ] = "AXIS_ANGLE",
        invert: bool = False,
    ):
        super().__init__()
        key_args = {
            "Vector": vector,
            "Center": center,
            "Axis": axis,
            "Angle": angle,
            "Rotation": rotation,
        }
        self.rotation_type = rotation_type
        self.invert = invert
        self._establish_links(**key_args)

    @classmethod
    def axis_angle(
        cls,
        vector: InputVector = None,
        center: InputVector = None,
        axis: InputVector = None,
        angle: InputFloat = 0.0,
    ) -> "VectorRotate":
        """Create Vector Rotate with operation 'Axis Angle'. Rotate a point using axis angle"""
        return cls(
            rotation_type="AXIS_ANGLE",
            vector=vector,
            center=center,
            axis=axis,
            angle=angle,
        )

    @classmethod
    def x_axis(
        cls,
        vector: InputVector = None,
        center: InputVector = None,
        angle: InputFloat = 0.0,
    ) -> "VectorRotate":
        """Create Vector Rotate with operation 'X Axis'. Rotate a point using X axis"""
        return cls(rotation_type="X_AXIS", vector=vector, center=center, angle=angle)

    @classmethod
    def y_axis(
        cls,
        vector: InputVector = None,
        center: InputVector = None,
        angle: InputFloat = 0.0,
    ) -> "VectorRotate":
        """Create Vector Rotate with operation 'Y Axis'. Rotate a point using Y axis"""
        return cls(rotation_type="Y_AXIS", vector=vector, center=center, angle=angle)

    @classmethod
    def z_axis(
        cls,
        vector: InputVector = None,
        center: InputVector = None,
        angle: InputFloat = 0.0,
    ) -> "VectorRotate":
        """Create Vector Rotate with operation 'Z Axis'. Rotate a point using Z axis"""
        return cls(rotation_type="Z_AXIS", vector=vector, center=center, angle=angle)

    @classmethod
    def euler(
        cls,
        vector: InputVector = None,
        center: InputVector = None,
        rotation: InputVector = None,
    ) -> "VectorRotate":
        """Create Vector Rotate with operation 'Euler'. Rotate a point using XYZ order"""
        return cls(
            rotation_type="EULER_XYZ", vector=vector, center=center, rotation=rotation
        )

    @property
    def rotation_type(
        self,
    ) -> Literal["AXIS_ANGLE", "X_AXIS", "Y_AXIS", "Z_AXIS", "EULER_XYZ"]:
        return self.node.rotation_type

    @rotation_type.setter
    def rotation_type(
        self, value: Literal["AXIS_ANGLE", "X_AXIS", "Y_AXIS", "Z_AXIS", "EULER_XYZ"]
    ):
        self.node.rotation_type = value

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

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