import { DefaultLevelControl } from "./DefaultLevelControl";
import { LevelControlHelper } from "../LevelControlHelper";

const __ = {
    private: Symbol('private'),
}

/**
 * @class PlacementLevelControl
 * 园区的放置级别控制类。
 * @extends THING.DefaultLevelControl
 * @public
 */
class PlacementLevelControl extends DefaultLevelControl {

    static levelCondition = 'tags:or(Placement,Group,Entity,Line,Geometry,Region,Window,Door)';

    static levelName = 'placement';

    constructor(options) {
        super(options);
        let _private = this[__.private] = {};
        _private.isAllObjectsTransparent = false;
        _private.transparentObjects = [];

        _private.filterBuildingElementOfIndoor = (object) => {
            let current = object.app.level.current;
            if (current.parents.find('tags:or(Floor)')) {
                let tags = object.tags;
                if (tags.has('RoomFloor')) {
                    return true;
                }
                if (tags.has('RoomCeiling')) {
                    return true;
                }
                if (tags.has('RoomRoof')) {
                    return true;
                }
                if (tags.has('Wall')) {
                    return true;
                }
            }

            return false;
        }
    }

    onSetEffect(param) {
        let _private = this[__.private];
        if (_private.isAllObjectsTransparent === true) {
            this._setEffect_transparentAll(param);
        } else {
            this._setEffect_self(param);
        }
    }

    _setEffect_self(param) {
        let _private = this[__.private];

        // Reset object array
        _private.transparentObjects.length = 0;

        const object = param.current;
        if (object) {
            const brothers = object.brothers;

            LevelControlHelper.traverseByIgnore(object, 'ignoreStyle', (child) => {
                const style = child.body.style;
                if (style) {
                    style.opacity = null;
                    style.transparent = null;
                }
            })

            brothers.forEach(brother => {
                if (brother.tags.has('Misc')) {
                    return;
                }

                LevelControlHelper.traverseByIgnore(brother, 'ignoreStyle', (child) => {
                    if (LevelControlHelper.isGeneralObject(child.tags)) {
                        if (!child.destroyed) {
                            const style = child.body.style;
                            if (style) {
                                style.opacity = 0.25;
                                style.transparent = true;
                            }
                            _private.transparentObjects.push(child);
                        }
                    }
                })
            });
        }
    }

    _setEffect_transparentAll(param) {
        let _private = this[__.private];

        // Reset object array
        _private.transparentObjects.length = 0;

        const current = param.current;
        if (!current) {
            return;
        }

        let isCampusParent = false;
        let parent = current.parents.find('tags:or(Floor)');
        if (!parent) {
            parent = current.parents.find('tags:or(Campus)');
            isCampusParent = true;
        }

        // 如果没有找到楼层或园区,执行默认逻辑即可
        if (!parent) {
            this._setEffect_self(param);
            return
        }

        LevelControlHelper.traverseBranchByIgnore(parent, 'ignoreStyle', (child) => {
            // 如果在园区下,不能处理建筑、楼层内的物体
            if (isCampusParent) {
                if (child.tags.has('Building') || child.tags.has('Floor')) {
                    return false;
                }
            }

            // Misc和Ground不递归
            if (child.tags.has('Misc') || child.tags.has('Ground')) {
                return false;
            }

            // 不处理自身
            if (child === current) {
                return false;
            }

            // 只处理 placement
            if (LevelControlHelper.isGeneralObject(child.tags)) {
                if (!child.destroyed) {
                    const style = child.body.style;
                    if (style) {
                        style.opacity = 0.25;
                        style.transparent = true;
                    }
                    _private.transparentObjects.push(child);
                }
            }

            // 继续递归
            return true;
        })
    }

    onResetEffect(param) {
        let _private = this[__.private];
        if (param.next && param.current) {
            if (param.current.isChildOf(param.next)) {
                _private.transparentObjects.forEach(element => {
                    LevelControlHelper.traverseByIgnore(element, 'ignoreStyle', (child) => {
                        if (!child.destroyed) {
                            const style = child.body.style;
                            if (style) {
                                style.opacity = null;
                                style.transparent = null;
                            }
                        }
                    });
                });
            }
        }
        _private.transparentObjects.length = 0;
    }

    filterObject(object) {
        let _private = this[__.private];
        if (object.parents.find('tags:or(Misc,Ground)')) {
            return null;
        }

        if (_private.filterBuildingElementOfIndoor(object)) {
            return null;
        }

        return super.filterObject(object);
    }

    /**
     * 开启/关闭 所有物体半透明。(默认关闭,只半透明所在层级的其它兄弟物体。开启后将半透明所处园区或楼层下所有的物体。)
     */
    get isAllObjectsTransparent() {
        const _private = this[__.private];
        return _private.isAllObjectsTransparent;
    }
    set isAllObjectsTransparent(val) {
        const _private = this[__.private];
        _private.isAllObjectsTransparent = !!val;
    }
}

export { PlacementLevelControl };