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

/**
 * @class CampusLevelControl
 * 园区级别控制类,用于控制园区场景。
 * @extends THING.DefaultLevelControl
 * @public
 */
class CampusLevelControl extends DefaultLevelControl {

    static levelCondition = 'tags:or(Campus)';

    static levelName = 'campus';

    constructor(options) {
        super(options);
    }

    onEnter(param) {
        let campus = param.current;

        LevelControlHelper.setEnvMap(campus, 'outer');

        return super.onEnter(param);
    }

    onSetEffect(param) {
        let object = param.current;
        if (!object) {
            return;
        }

        this.showCampus(object);
    }

    onBackToParentLevel() {
        // 如果campus的父是root 就不要再退了
        if (this.app.level.current.parent === this.app.root) {
            return;
        }

        super.onBackToParentLevel();
    }

    filterObject(object) {
        if (object.tags.has('Ground') || object.tags.has('Misc')) {
            return null;
        }

        const parents = object.parents;

        let campus = parents.find('tags:or(Campus)');
        if (!campus) {
            return null;
        }

        if (campus != campus.app.level.current) {
            return null;
        }

        if (parents.find('tags:or(Misc,Ground)')) {
            return null;
        }

        return super.filterObject(object);
    }

    /**
     * 显示园区
     * @param {THING.Campus} campus
     * @public
     */
    showCampus(campus) {
        campus.children.forEach(child => {
            if (child.tags.has('Building')) {
                const building = child;

                building.setVisible(true, false);

                const hasFacades = building.find('tags:or(Facade,Roof)');
                const showStruct = LevelControlHelper.compatibilityConstantShowStruct(building);

                building.children.forEach(buildingChild => {

                    const objTags = buildingChild.tags;

                    if (objTags.has('Floor')) {
                        LevelControlHelper.setFloorVisibleInCampusLevel(buildingChild, hasFacades, showStruct);
                    }
                    else if (objTags.has('Facade') || objTags.has('Roof')) {
                        LevelControlHelper.traverseByIgnore(buildingChild, 'ignoreVisible', (facade) => {
                            facade.setVisible(true, false);
                        });
                    }
                    else {
                        LevelControlHelper.traverseByIgnore(buildingChild, 'ignoreVisible', (other) => {
                            other.setVisible(false, false);
                        });
                    }
                });
            }
            else {
                LevelControlHelper.traverseByIgnore(child, 'ignoreVisible', (elememt) => {
                    elememt.setVisible(true, false);
                });
            }
        });
    }

    onFlyTo(flyParam) {
        const target = flyParam.target;

        if (target && target.isObject3D) {
            const boundingBox = target.boundingBox;

            flyParam.position = LevelControlHelper.getNearestObjectPosition({
                target: target,
                boundingBox: boundingBox,
                radius: Math.min(boundingBox.radius, 300),
                camera: this.app.camera,
            });

            flyParam.target = boundingBox.center;
        }

        return super.onFlyTo(flyParam);
    }

}

export { CampusLevelControl };