/**
 * Advanced Math Blocks Definitions
 *
 * Note:
 * - All blocks except 'math_operation' accept a 'dynamic_value' input containing one or more numbers.
 *   - If no values are provided, the result is invalid.
 *   - Each block uses the required number of values from the input.
 *   - If more values are provided than needed, unused values are included in the output.
 * - The output is a 'dynamic_value' containing the result and any unused input values.
 */

export function defineAdvancedMathBlocks() {

    /**
     * Power Block
     *
     * Raises a base number to the power of an exponent.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "power",
        "message0": "Power %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Raise a connected number to a power. Attach a second value to specify the exponent.",
        "helpUrl": ""
    }]);

    /**
     * Modulo Block
     *
     * Computes the remainder of the division of two numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "modulo",
        "message0": "Modulo %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Find the remainder after division. Attach a second value to specify the divisor.",
        "helpUrl": ""
    }]);

    /**
     * Square Root Block
     *
     * Calculates the square root of a number.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "sqrt",
        "message0": "Square Root of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the square root of a connected number.",
        "helpUrl": ""
    }]);

    /**
     * Absolute Value Block
     *
     * Calculates the absolute value of a number.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "abs",
        "message0": "Absolute Value of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Get the absolute value of a connected number.",
        "helpUrl": ""
    }]);

    /**
     * Max Block
     *
     * Finds the maximum value among given numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "max",
        "message0": "Max of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Determine the maximum value among connected numbers.",
        "helpUrl": ""
    }]);

    /**
     * Min Block
     *
     * Finds the minimum value among given numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "min",
        "message0": "Min of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Determine the minimum value among connected numbers.",
        "helpUrl": ""
    }]);

    /**
     * Factorial Block
     *
     * Calculates the factorial of a number.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "factorial",
        "message0": "Factorial of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the factorial of a connected number.",
        "helpUrl": ""
    }]);

    /**
     * Log Block
     *
     * Calculates the base 10 logarithm of a number.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "log",
        "message0": "Log base 10 of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the base 10 logarithm of a connected number.",
        "helpUrl": ""
    }]);

    /**
     * Natural Log Block
     *
     * Calculates the natural logarithm (base e) of a number.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "ln",
        "message0": "Natural Log of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the natural logarithm of a connected number.",
        "helpUrl": ""
    }]);

    /**
     * Trigonometry Block
     *
     * Calculates the sine, cosine, or tangent of an angle.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "trig",
        "message0": "Trig: %1 of %2",
        "args0": [
            {
                "type": "field_dropdown",
                "name": "operator",
                "options": [
                    ["sin", "sin"],
                    ["cos", "cos"],
                    ["tan", "tan"],
                ]
            },
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the sine, cosine, or tangent of a connected angle (in radians).",
        "helpUrl": ""
    }]);

    /**
     * Mean Block
     *
     * Calculates the mean (average) of given numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "mean",
        "message0": "Mean of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the mean of connected numbers.",
        "helpUrl": ""
    }]);

    /**
     * Median Block
     *
     * Calculates the median of given numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "median",
        "message0": "Median of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the median of connected numbers.",
        "helpUrl": ""
    }]);

    /**
     * Standard Deviation Block
     *
     * Calculates the standard deviation of given numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "std_dev",
        "message0": "Standard Deviation of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Calculate the standard deviation of connected numbers.",
        "helpUrl": ""
    }]);

    /**
     * Round Block
     *
     * Rounds a number to a specified number of decimal places.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "round",
        "message0": "Round %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Round a connected number. Attach a second value to specify the decimal places.",
        "helpUrl": ""
    }]);

    /**
     * Floor Block
     *
     * Rounds a number down to the nearest integer.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "floor",
        "message0": "Floor of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Round down a connected number to the nearest integer.",
        "helpUrl": ""
    }]);

    /**
     * Ceil Block
     *
     * Rounds a number up to the nearest integer.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "ceil",
        "message0": "Ceil of %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Round up a connected number to the nearest integer.",
        "helpUrl": ""
    }]);

    /**
     * Random Number Block
     *
     * Generates a random number within a specified range.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "random",
        "message0": "Random Number %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Generate a random number. Attach one value to specify the maximum, or two value to specify minimum(first value) and maximum(second value).",
        "helpUrl": ""
    }]);

    /**
     * Clamp Block
     *
     * Clamps a number between optional minimum and maximum values.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "clamp",
        "message0": "Clamp %1",
        "args0": [
            {
                "type": "input_value",
                "name": "VALUES",
                "check": "dynamic_value"
            }
        ],
        "output": "dynamic_value",
        "maxNestingDepth": 3,
        "colour": 60,
        "tooltip": "Clamp a connected number. Attach a second value for minimum and a third for maximum.",
        "helpUrl": ""
    }]);

    /**
     * Math Operation Block
     *
     * Performs basic arithmetic operations between two numbers.
     */
    Blockly.defineBlocksWithJsonArray([{
        "type": "math_operation",
        "message0": "%1 %2 %3",
        "args0": [
            {
                "type": "input_value",
                "name": "LEFT",
                "check": ["number", "dynamic_value"]
            },
            {
                "type": "field_dropdown",
                "name": "operator",
                "options": [
                    ["+", "ADD"],
                    ["-", "SUBTRACT"],
                    ["*", "MULTIPLY"],
                    ["/", "DIVIDE"]
                ]
            },
            {
                "type": "input_value",
                "name": "RIGHT",
                "check": ["number", "dynamic_value"]
            }
        ],
        "inputsInline": true,
        "output": "dynamic_value",
        "maxNestingDepth": 5,
        "colour": 160,
        "tooltip": "Perform basic arithmetic operations between two connected numbers.",
        "helpUrl": ""
    }]);
}
