"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMainLightModeFromNative = exports.SceneLightingController = exports.EMainLightMode = void 0;
var Guard_1 = require("../Core/Guard");
var Deleter_1 = require("../Core/Deleter");
var Vector3_1 = require("./Vector3");
/**
 * Defines how the main scene light is positioned for a 3D chart.
 */
var EMainLightMode;
(function (EMainLightMode) {
    /**
     * The main light direction follows the camera forward direction.
     */
    EMainLightMode["CameraForward"] = "CameraForward";
    /**
     * The main light uses a fixed direction in global 3D world space.
     */
    EMainLightMode["GlobalSpace"] = "GlobalSpace";
    /**
     * The main light is disabled.
     */
    EMainLightMode["None"] = "None";
})(EMainLightMode = exports.EMainLightMode || (exports.EMainLightMode = {}));
var mainLightModeToNative = new Map([
    [EMainLightMode.CameraForward, 0],
    [EMainLightMode.GlobalSpace, 1],
    [EMainLightMode.None, 2]
]);
var nativeToMainLightMode = new Map([
    [0, EMainLightMode.CameraForward],
    [1, EMainLightMode.GlobalSpace],
    [2, EMainLightMode.None]
]);
/**
 * The {@link SceneLightingController} provides control over the main 3D scene light.
 */
var SceneLightingController = /** @class */ (function () {
    /**
     * Creates an instance of {@link SceneLightingController}.
     * @param webAssemblyContext The {@link TSciChart3D | SciChart 3D WebAssembly Context}
     * @param sceneWorld The native 3D scene world to update
     * @param invalidateParentCallback Callback to redraw the parent chart
     * @param options Optional lighting options
     */
    function SceneLightingController(webAssemblyContext, sceneWorld, invalidateParentCallback, options) {
        this.lightModeProperty = EMainLightMode.CameraForward;
        this.lightDirectionProperty = new Vector3_1.Vector3(-0.25, 0.5, -0.25);
        this.ambientLightProperty = 0.05;
        Guard_1.Guard.notNull(webAssemblyContext, "webAssemblyContext");
        Guard_1.Guard.notNull(sceneWorld, "sceneWorld");
        this.webAssemblyContext = webAssemblyContext;
        this.sceneWorld = sceneWorld;
        this.invalidateParentCallback = invalidateParentCallback;
        this.applyOptions(options);
    }
    Object.defineProperty(SceneLightingController.prototype, "lightMode", {
        /**
         * @inheritDoc
         */
        get: function () {
            return this.lightModeProperty;
        },
        /**
         * @inheritDoc
         */
        set: function (value) {
            var _a;
            if (this.lightModeProperty === value) {
                return;
            }
            this.lightModeProperty = value !== null && value !== void 0 ? value : EMainLightMode.CameraForward;
            this.syncLightToNative();
            (_a = this.invalidateParentCallback) === null || _a === void 0 ? void 0 : _a.call(this);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SceneLightingController.prototype, "lightDirection", {
        /**
         * @inheritDoc
         */
        get: function () {
            return this.lightDirectionProperty;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * @inheritDoc
     */
    SceneLightingController.prototype.setLightDirection = function (lightDirection) {
        var _a;
        Guard_1.Guard.notNull(lightDirection, "lightDirection");
        var hydratedLightDirection = Vector3_1.Vector3.hydrate(lightDirection);
        if (Vector3_1.Vector3.isEqual(this.lightDirectionProperty, hydratedLightDirection)) {
            return;
        }
        if (hydratedLightDirection.length === 0) {
            throw new Error("SceneLightingController.lightDirection magnitude is zero, cannot set light direction");
        }
        this.lightDirectionProperty = hydratedLightDirection;
        this.syncLightToNative();
        if (this.lightMode === EMainLightMode.GlobalSpace) {
            (_a = this.invalidateParentCallback) === null || _a === void 0 ? void 0 : _a.call(this);
        }
    };
    Object.defineProperty(SceneLightingController.prototype, "ambientLight", {
        /**
         * @inheritDoc
         */
        get: function () {
            return this.ambientLightProperty;
        },
        /**
         * @inheritDoc
         */
        set: function (value) {
            var _a;
            var nextAmbientLight = SceneLightingController.normalizeLightValue(value, 0.05);
            if (this.ambientLightProperty === nextAmbientLight) {
                return;
            }
            this.ambientLightProperty = nextAmbientLight;
            this.syncAmbientToNative();
            (_a = this.invalidateParentCallback) === null || _a === void 0 ? void 0 : _a.call(this);
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Applies lighting options.
     * @param options Optional lighting options
     */
    SceneLightingController.prototype.applyOptions = function (options) {
        if ((options === null || options === void 0 ? void 0 : options.ambientLight) != null) {
            this.ambientLightProperty = SceneLightingController.normalizeLightValue(options.ambientLight, 0.05);
        }
        if (options === null || options === void 0 ? void 0 : options.lightDirection) {
            this.lightDirectionProperty = Vector3_1.Vector3.hydrate(options.lightDirection);
            if (this.lightDirectionProperty.length === 0) {
                throw new Error("SceneLightingController.lightDirection magnitude is zero, cannot set light direction");
            }
        }
        if ((options === null || options === void 0 ? void 0 : options.lightMode) != null) {
            this.lightModeProperty = options.lightMode;
        }
        this.syncAmbientToNative();
        this.syncLightToNative();
    };
    /**
     * @inheritDoc
     */
    SceneLightingController.prototype.toJSON = function () {
        return {
            lightMode: this.lightMode,
            lightDirection: this.lightDirection,
            ambientLight: this.ambientLight
        };
    };
    SceneLightingController.prototype.syncAmbientToNative = function () {
        this.sceneWorld.SetAmbientLightIntensity(this.ambientLightProperty);
    };
    SceneLightingController.prototype.syncLightToNative = function () {
        var _a;
        this.sceneWorld.SetMainLightMode((_a = mainLightModeToNative.get(this.lightModeProperty)) !== null && _a !== void 0 ? _a : 0);
        var tsrLightDirection;
        try {
            tsrLightDirection = this.lightDirectionProperty.toTsrVector3(this.webAssemblyContext);
            this.sceneWorld.SetMainLightDirection(tsrLightDirection);
        }
        finally {
            (0, Deleter_1.deleteSafe)(tsrLightDirection);
        }
    };
    SceneLightingController.normalizeLightValue = function (value, defaultValue) {
        if (value == null || Number.isNaN(value)) {
            return defaultValue;
        }
        return Math.max(0, value);
    };
    return SceneLightingController;
}());
exports.SceneLightingController = SceneLightingController;
/** @ignore */
var getMainLightModeFromNative = function (mode) { var _a; return (_a = nativeToMainLightMode.get(mode)) !== null && _a !== void 0 ? _a : EMainLightMode.CameraForward; };
exports.getMainLightModeFromNative = getMainLightModeFromNative;
