"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var igd_productdata_1 = require("@intelligentgraphics/igd.productdata");
var ig_gfx_threejs_1 = require("@intelligentgraphics/ig.gfx.threejs");
var ig_utilities_1 = require("@intelligentgraphics/ig.utilities");
var Planning = require("@intelligentgraphics/ig.gfx.planning");
var ig_gfx_core_1 = require("@intelligentgraphics/ig.gfx.core");
var THREE = require("@intelligentgraphics/three");
var ig_utilities_2 = require("@intelligentgraphics/ig.utilities");
var BlueprintModelIGXCBuilder_1 = require("./BlueprintModelIGXCBuilder");
var BlueprintRoomContainer = /** @class */ (function () {
    function BlueprintRoomContainer(_a) {
        var _this = this;
        var session = _a.session, roomCatalogSourceId = _a.roomCatalogSourceId, api = _a.api, _b = _a.environment, environment = _b === void 0 ? {
            createFloorArticle: session.createArticleFromArticleNumber,
            createWallArticle: session.createArticleFromArticleNumber,
        } : _b, defaultConfiguration = _a.defaultConfiguration;
        this.wallImportIndex = 0;
        this.handleBPPartImported = function (component, kindIndex, configuration) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var rawCategories, categories, isWall, isFloor, index, comId, initialConfiguration, comId, area;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        rawCategories = component.userData.categories || "";
                        categories = Array.isArray(rawCategories)
                            ? rawCategories
                            : rawCategories.split(",");
                        isWall = categories.indexOf(ig_gfx_core_1.Category.Wall) > -1;
                        isFloor = !isWall && categories.indexOf(ig_gfx_core_1.Category.Floor) > -1;
                        if (!isWall) return [3 /*break*/, 3];
                        index = kindIndex;
                        if (index === undefined) {
                            index = this.wallImportIndex;
                            this.wallImportIndex++;
                        }
                        return [4 /*yield*/, this.environment.createWallArticle({
                                source: this.roomCatalogSourceId,
                                articleNumber: {
                                    baseArticleNumber: "WALL",
                                    itemType: igd_productdata_1.IGXA.EItemType.ArticleGfx,
                                },
                                gfxId: component.name,
                            })];
                    case 1:
                        comId = _a.sent();
                        this.api.SetCommercialId(component.name, comId);
                        initialConfiguration = this.getInitialConfig("Wall", index, configuration) || {};
                        if (component.userData.wallInfo) {
                            if (component.userData.wallInfo.Height) {
                                initialConfiguration["wall.height"] =
                                    component.userData.wallInfo.Height;
                            }
                            if (component.userData.wallInfo.Thickness) {
                                initialConfiguration["wall.thickness"] =
                                    component.userData.wallInfo.Thickness;
                            }
                            if (component.userData.wallInfo.WallPaperWidth) {
                                initialConfiguration["wall.length"] =
                                    component.userData.wallInfo.WallPaperWidth;
                            }
                        }
                        return [4 /*yield*/, this.session.changeArticleProperties(comId, initialConfiguration)];
                    case 2:
                        _a.sent();
                        _a.label = 3;
                    case 3:
                        if (!isFloor) return [3 /*break*/, 6];
                        return [4 /*yield*/, this.environment.createFloorArticle({
                                source: this.roomCatalogSourceId,
                                articleNumber: {
                                    baseArticleNumber: "FLOOR",
                                    itemType: igd_productdata_1.IGXA.EItemType.ArticleGfx,
                                },
                                gfxId: component.name,
                            })];
                    case 4:
                        comId = _a.sent();
                        this.api.SetCommercialId(component.name, comId);
                        area = this.calculateFloorComponentArea(component);
                        return [4 /*yield*/, this.session.changeArticleProperties(comId, tslib_1.__assign(tslib_1.__assign({}, this.getInitialConfig("Floor", 0, configuration)), { "floor.area": area }))];
                    case 5:
                        _a.sent();
                        return [2 /*return*/];
                    case 6: return [2 /*return*/];
                }
            });
        }); };
        this.session = session;
        this.roomCatalogSourceId = roomCatalogSourceId;
        this.api = api;
        this.environment = environment;
        this.defaultConfiguration = defaultConfiguration;
        var catalogManager = session.getCatalogManagerForSourceId(roomCatalogSourceId);
        if (catalogManager === undefined) {
            throw new Error("Could not find a catalogManager for \"" + roomCatalogSourceId + "\"");
        }
        this.catalogManager = catalogManager;
    }
    BlueprintRoomContainer.prototype.getItemById = function (id) {
        return this.catalogManager.getIGXAArticle(id);
    };
    BlueprintRoomContainer.prototype.getItems = function () {
        return this.catalogManager.getIGXAFolder(undefined)
            .SubItems;
    };
    BlueprintRoomContainer.prototype.getRoomConfig = function () {
        var _this = this;
        var floorComId = this.getFloorComId();
        var articleIds = tslib_1.__spread([floorComId], this.getWallComIds());
        if (articleIds.filter(Boolean).length === 0) {
            return {
                floor: {},
                walls: [],
                wallHeight: 0,
            };
        }
        var _a = tslib_1.__read(articleIds.map(function (comId) {
            if (comId === undefined) {
                return undefined;
            }
            var _a = _this.session.getArticleByComId(comId), configuration = _a.configuration, properties = _a.properties;
            var clonedConfig = tslib_1.__assign({}, configuration);
            var _loop_1 = function (propertyKey) {
                var prop = properties.find(function (property) { return property.Key === propertyKey; });
                if (prop && prop.ValueType !== igd_productdata_1.IGXE.EPropertyType.Material) {
                    delete clonedConfig[propertyKey];
                }
            };
            for (var propertyKey in configuration) {
                _loop_1(propertyKey);
            }
            return clonedConfig;
        })), floorConfig = _a[0], wallConfigs = _a.slice(1);
        var config = {
            floor: floorConfig || {},
            walls: wallConfigs.filter(ig_utilities_1.isValue),
            wallHeight: 0,
        };
        return config;
    };
    BlueprintRoomContainer.prototype.remove3D = function () {
        if (Planning.Environment.getInstance().getRoot()) {
            this.api.RemoveComponent(ig_gfx_core_1.Hierarchy.getSuperRootGfxId(Planning.Environment.getInstance().getRoot()));
            this.api.RedrawScene();
        }
    };
    BlueprintRoomContainer.prototype.apply3D = function (_a) {
        var wallHeight = _a.wallHeight, wallThickness = _a.wallThickness, model = _a.model, configuration = _a.configuration, wallBackMaterial = _a.wallBackMaterial, wallFrontMaterial = _a.wallFrontMaterial, floorMaterial = _a.floorMaterial;
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var igxc, categoryName, materialName, material, rootId;
            var _this = this;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        this.remove3D();
                        this.wallImportIndex = 0;
                        return [4 /*yield*/, this.session.deleteArticles(tslib_1.__spread([this.getFloorComId()], this.getWallComIds()).filter(ig_utilities_1.isValue))];
                    case 1:
                        _b.sent();
                        igxc = BlueprintModelIGXCBuilder_1.createSceneFromBlueprint({
                            model: model,
                            wallHeight: wallHeight,
                            wallThickness: wallThickness,
                            wallBackMaterial: wallBackMaterial,
                            wallFrontMaterial: wallFrontMaterial,
                            floorMaterial: floorMaterial,
                        });
                        for (categoryName in igxc.Categories) {
                            materialName = igxc.Categories[categoryName];
                            material = this.api.Materials[materialName];
                            if (material !== undefined) {
                                igxc.Materials[materialName] = material;
                            }
                        }
                        ig_gfx_threejs_1.State.OnBlueprintPartImported = function (component, kindIndex) {
                            return _this.handleBPPartImported(component, kindIndex, configuration);
                        };
                        rootId = this.api.CreateSuperRoot();
                        return [4 /*yield*/, this.api.ProcessIGXC(rootId, igxc)];
                    case 2:
                        _b.sent();
                        this.api.RedrawScene();
                        ig_gfx_threejs_1.State.OnBlueprintPartImported = ig_utilities_2.noop;
                        return [2 /*return*/];
                }
            });
        });
    };
    BlueprintRoomContainer.prototype.getFloorComId = function () {
        var floorArticle = this.session
            .getAllArticles()
            .find(function (article) { return article.articleId === "FLOOR"; });
        if (floorArticle !== undefined) {
            return floorArticle.comId;
        }
        return undefined;
    };
    BlueprintRoomContainer.prototype.getWallComIds = function () {
        return this.session
            .getFilteredArticles(function (article) { return article.articleId === "WALL"; })
            .map(function (article) { return article.comId; });
    };
    BlueprintRoomContainer.prototype.getInitialConfig = function (category, categoryItemIndex, lastConfig) {
        if (lastConfig !== undefined) {
            if (category === "Floor") {
                return lastConfig.floor;
            }
            if (lastConfig.walls.length > categoryItemIndex) {
                return lastConfig.walls[categoryItemIndex];
            }
            return lastConfig.walls[0];
        }
        if (this.defaultConfiguration !== undefined) {
            if (category === "Floor") {
                return this.defaultConfiguration.floor;
            }
            return this.defaultConfiguration.wall;
        }
        return undefined;
    };
    BlueprintRoomContainer.prototype.calculateFloorComponentArea = function (component) {
        // area of floor
        var getMesh = function (parent) {
            if (parent instanceof THREE.Mesh) {
                return parent;
            }
            var mesh;
            parent.children.some(function (ch) {
                mesh = getMesh(ch);
                if (mesh !== undefined) {
                    return true;
                }
                return false;
            });
            return mesh;
        };
        var mesh = getMesh(component);
        var geometry = mesh.geometry;
        var area = 0;
        if (geometry["vertices"] && geometry["faces"]) {
            var tV_1 = geometry["vertices"];
            geometry["faces"].forEach(function (face) {
                var tAB = new THREE.Vector3().subVectors(tV_1[face.a], tV_1[face.b]);
                var tAC = new THREE.Vector3().subVectors(tV_1[face.a], tV_1[face.c]);
                var tCross = new THREE.Vector3().crossVectors(tAB, tAC);
                area += tCross.length() / 2;
            });
        }
        return area;
    };
    return BlueprintRoomContainer;
}());
exports.BlueprintRoomContainer = BlueprintRoomContainer;
