import { Object3D } from '@uino/thing';
import { ExpandObjectsComponent } from '../components/ExpandObjectsComponent';
import { Utils } from '../common/Utils';

/**
 * @class Building
 * 建筑物。
 * @extends THING.Object3D
 * @public
 */
class Building extends Object3D {

	static defaultTagArray = ['Building'];

	constructor(param = {}) {
		super(param);

		this._constantShowStruct = Utils.parseBoolean(param['constantShowStruct'], false);
	}

	/**
	 * 建筑物是否有外立面
	 * @return {Boolean}
	 * @public
	 */
	hasFacade() {
		return this.facades.length !== 0;
	}

	/**
	 * 获取建筑物下的外立面对象集合
	 * @type {THING.Selector<THING.Entity>}
	 * @example
	 * let facades = building.facades;
	 * console.log(facades);
	 * @public
	 */
	get facades() {
		return this.children.query('tags:or(Facade)');
	}

	/**
	 * 获取建筑物下的楼层对象集合
	 * @type {THING.Selector<THING.Floor>}
	 * @example
	 * let floors = building.floors;
	 * console.log(floors);
	 * @public
	 */
	get floors() {
		return this.children.query('tags:or(Floor)');
	}

	/**
	 * 显示/隐藏所有屋顶
	 * @param {Boolean} show true 显示(默认) / false 隐藏
	 * @public
	 */
	showAllRoofs(show = true) {
		this.floors.forEach(function (floor) {
			floor.showAllRoofs(show);
		});
	}

	/**
	 * 展开楼层
	 * @param {Object} params
	 * @param {Number} [params.duration] 展开时间(毫秒)
	 * @param {Number} [params.distance] 展开间隔(米)
	 * @param {Boolean} [params.horzMode] 展开方向,默认为垂直展开(false)
	 * @param {Function} [params.onComplete] 展开完成后的回调函数
	 * @param {Function} [params.onUpdate] 展开过程中的回调函数
	 * @public
	 * @example
	 * building.expandFloors({
	 * 	duration: 1000,
	 * 	onUpdate: function (e) {
	 * 		const floor = e.floor;
	 * 		const progress = e.progress;
	 * 		console.log(floor, progress);
	 * 	},
	 * 	onComplete: function () {
	 * 		console.log('展开完成');
	 * 	}
	 * });
	 */
	expandFloors(param) {
		param = param || {};

		if (!this.expandObjectsComponent) {
			this.addComponent(ExpandObjectsComponent, 'expandObjectsComponent');
		}

		param['objects'] = this.floors.objects;
		param['hideRoof'] = Utils.parseValue(param['hideRoof'], true);

		if (param['onUpdate']) {
			const onUpdate = param['onUpdate'];
			param['onUpdate'] = function (e) {
				onUpdate({
					floor: e.object,
					progress: e.progress
				});
			}
		}

		this.expandObjectsComponent.setData(param);
		this.expandObjectsComponent.execute();

		this._expanded = true;
	}

	/**
	 * 折叠楼层
	 * @param {Object} params
	 * @param {Number} [params.duration] 折叠时间(毫秒)
	 * @param {Function} [params.onComplete] 折叠完成后的回调函数
	 * @public
	 */
	unexpandFloors(param) {
		param = param || {};

		if (!this.expandObjectsComponent) {
			this.addComponent(ExpandObjectsComponent, 'expandObjectsComponent');
			return;
		}

		if (param['hideRoof']) {
			param['hideRoof'] = !param['hideRoof'];
		}

		if (param['onUpdate']) {
			const onUpdate = param['onUpdate'];
			param['onUpdate'] = function (e) {
				onUpdate({
					floor: e.object,
					progress: e.progress
				});
			}
		}

		this.expandObjectsComponent.setData(param);
		this.expandObjectsComponent.undo();

		this._expanded = false;
	}

	/**
	 * 获取楼层是否展开
	 * @type {Boolean}
	 * @public
	 */
	get expanded() {
		return this._expanded;
	}

	/**
	 * 获取建筑物下的放置对象集合
	 * @type {THING.Selector<THING.Entity>}
	 * @example
	 * let placements = building.placements;
	 * @public
	 */
	get placements() {
		let plcs = this.queryByTags('Placement');
		return plcs;
	}
}

export { Building };