import { __assign, __extends, __read, __rest, __spread, __values } from "tslib";
import { Obj } from "@intelligentgraphics/ig.utilities";
import { No_API } from "../No_API";
import * as Hierarchy from "../Hierarchy";
import { processIGXC } from "../Loader";
import { createObjectLoader } from "./objectLoader";
var DEFAULT_SCALE = {
    x: 1,
    y: 1,
    z: 1,
};
var ZERO_VECTOR = {
    x: 0,
    y: 0,
    z: 0,
};
var TestApi = /** @class */ (function (_super) {
    __extends(TestApi, _super);
    function TestApi(demoScene) {
        var _this = _super.call(this) || this;
        _this.RegionManager = {
            updateComponentRegions: function () { return undefined; },
        };
        _this.components = new Map();
        _this.roots = new Set();
        _this.rootIndex = 0;
        _this.objectLoader = createObjectLoader(function (component) {
            return _this.components.set(component.componentId, component);
        });
        if (demoScene !== undefined) {
            var sceneData = Obj.deepClone(demoScene);
            _this.buildScene(sceneData.articles);
        }
        return _this;
    }
    TestApi.prototype.GetRoots = function () {
        return __spread(this.roots);
    };
    TestApi.prototype.CreateSuperRoot = function () {
        var superRootId = "t" + ++this.rootIndex;
        var superRoot = this.buildArticle(superRootId, {
            position: { x: 0, y: 0, z: 0 },
            size: { x: 0, y: 0, z: 0 },
        }, undefined);
        this.components.set(superRootId, superRoot);
        this.roots.add(Hierarchy.getRootGfxId(superRootId));
        return superRootId;
    };
    TestApi.prototype.ProcessIGXC = function (superRoot, igxc, igxcBasePath) {
        return processIGXC(this, this.objectLoader, superRoot, igxc, igxcBasePath);
    };
    TestApi.prototype.SetPosition = function (componentId, position) {
        var component = this.GetComponent(componentId);
        component.position = __assign({}, position);
    };
    TestApi.prototype.GetPosition = function (componentId) {
        return this.GetComponent(componentId).position;
    };
    TestApi.prototype.GetBounds = function (componentId, context, considerScaleForLocalContext) {
        //TODO: rotation
        if (context === void 0) { context = "Local"; }
        if (considerScaleForLocalContext === void 0) { considerScaleForLocalContext = true; }
        var component = this.GetComponent(componentId);
        var scale = considerScaleForLocalContext && context === "Local"
            ? this.GetScaling(componentId)
            : DEFAULT_SCALE;
        if (context === "Local") {
            return {
                min: {
                    x: 0,
                    y: 0,
                    z: 0,
                },
                max: {
                    x: component.size.x * scale.x,
                    y: component.size.y * scale.y,
                    z: component.size.z * scale.z,
                },
            };
        }
        return {
            min: component.position,
            max: {
                x: component.position.x + component.size.x * scale.x,
                y: component.position.y + component.size.y * scale.y,
                z: component.position.z + component.size.z * scale.z,
            },
        };
    };
    TestApi.prototype.SetScaling = function (componentId, scale) {
        var component = this.GetComponent(componentId);
        component.scale = __assign({}, scale);
    };
    TestApi.prototype.GetScaling = function (componentId) {
        return this.GetComponent(componentId).scale;
    };
    TestApi.prototype.SetTransformation = function (componentId, transformation) {
        var component = this.GetComponent(componentId);
        component.position = __assign({}, transformation.position);
        component.rotation = __assign({}, transformation.rotation);
    };
    TestApi.prototype.GetComponent = function (componentId) {
        if (!this.components.has(componentId)) {
            return null;
        }
        return this.components.get(componentId);
    };
    TestApi.prototype.GetComponentData = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.data;
    };
    TestApi.prototype.SetComponentData = function (componentId, key, value) {
        this.GetComponentData(componentId)[key] = value;
    };
    TestApi.prototype.SetVisibility = function (componentId, visible) {
        var component = this.GetComponent(componentId);
        component.visible = visible;
    };
    TestApi.prototype.GetVisibility = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.visible;
    };
    TestApi.prototype.SetCommercialId = function (componentId, comId) {
        var component = this.GetComponent(componentId);
        component.comId = comId;
        return comId;
    };
    TestApi.prototype.GetCommercialId = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.comId;
    };
    TestApi.prototype.SetHash = function (componentId, hash) {
        var component = this.GetComponent(componentId);
        component.data.productHash = hash;
    };
    TestApi.prototype.GetHash = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.data.productHash;
    };
    TestApi.prototype.SetCategories = function (componentId, categories) {
        var component = this.GetComponent(componentId);
        component.data.categories = !categories ? undefined : categories;
    };
    TestApi.prototype.GetCategories = function (componentId) {
        var component = this.GetComponent(componentId);
        var result = component.data.categories === undefined
            ? []
            : Object.freeze(component.data.categories);
        return result;
    };
    TestApi.prototype.GetPoints = function (componentId) {
        return [];
    };
    TestApi.prototype.GetIGXCPoints = function (componentId) {
        return [];
    };
    TestApi.prototype.SetIGXCPoints = function (componentId, attachPoints) { };
    TestApi.prototype.SetSelectionMode = function (componentId, selectionMode) {
        var component = this.GetComponent(componentId);
        component.selectionMode = selectionMode;
    };
    TestApi.prototype.GetSelectionMode = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.selectionMode;
    };
    TestApi.prototype.GetAllSelectedComponents = function () {
        return [];
    };
    TestApi.prototype.GetXRotation = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.rotation.x;
    };
    TestApi.prototype.GetYRotation = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.rotation.y;
    };
    TestApi.prototype.GetZRotation = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.rotation.z;
    };
    TestApi.prototype.GetGeometry = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.geometry;
    };
    TestApi.prototype.GetLayer = function (componentId) {
        var component = this.GetComponent(componentId);
        //TODO: ??
        return null;
    };
    TestApi.prototype.GetMaterial = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.material;
    };
    TestApi.prototype.GetInteractor = function (componentId) {
        var component = this.GetComponent(componentId);
        //TODO: ??
        return null;
    };
    TestApi.prototype.GetChildren = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.children.map(function (child) { return child.componentId; });
    };
    TestApi.prototype.GetMaterialCategory = function (componentId) {
        var component = this.GetComponent(componentId);
        return component.materialCategory;
    };
    TestApi.prototype.GetEvaluator = function (componentId) {
        var component = this.GetComponent(componentId);
        //TODO: ??
        return null;
    };
    TestApi.prototype.buildScene = function (articles) {
        var e_1, _a;
        try {
            for (var articles_1 = __values(articles), articles_1_1 = articles_1.next(); !articles_1_1.done; articles_1_1 = articles_1.next()) {
                var data = articles_1_1.value;
                var superRootId = this.CreateSuperRoot();
                var superRoot = this.GetComponent(superRootId);
                var rootId = Hierarchy.getRootGfxId(superRootId);
                superRoot.children = [this.buildArticle(rootId, data, rootId)];
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (articles_1_1 && !articles_1_1.done && (_a = articles_1.return)) _a.call(articles_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
    };
    TestApi.prototype.buildArticle = function (id, _a, parentId) {
        var _this = this;
        var scale = _a.scale, rotation = _a.rotation, position = _a.position, data = _a.data, selectionMode = _a.selectionMode, children = _a.children, size = _a.size, rest = __rest(_a, ["scale", "rotation", "position", "data", "selectionMode", "children", "size"]);
        var articleData = __assign(__assign({}, rest), { size: size !== undefined ? size : __assign({}, DEFAULT_SCALE), componentId: id, position: position !== undefined ? position : __assign({}, ZERO_VECTOR), scale: scale !== undefined ? scale : __assign({}, DEFAULT_SCALE), rotation: rotation !== undefined ? rotation : __assign({}, ZERO_VECTOR), visible: true, data: __assign({}, data), selectionMode: selectionMode || "Self", children: [], parentId: parentId });
        var childBasePath = Hierarchy.isRootGfxId(id)
            ? id.slice(0, -1)
            : id + ".";
        if (children) {
            articleData.children = children.map(function (data, index) {
                return _this.buildArticle(childBasePath + "o" + (index + 1), data, id);
            });
        }
        this.components.set(id, articleData);
        return articleData;
    };
    return TestApi;
}(No_API));
export { TestApi };
