import { Object3D, Selector } from '@uino/thing';

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

/**
 * @class Campus
 * 园区
 * @extends THING.Object3D
 * @public
 */
class Campus extends Object3D {

	static defaultTagArray = ['Campus'];

	constructor(params) {
		super(params);

		let _private = this[__.private] = {};
		_private.autoEnvMap = null;
	}

	onLoadRenderableResource(options, resolve, reject) {
		if (this.destroyed) {
			reject(`The object had been destroyed, skip to load resources`);
			return
		}

		// Load resouce as entity
		const nodeName = options['nodeName'];
		if (nodeName) {
			super.onLoadRenderableResource(options, resolve, reject);
			return
		}

		// Load resource as campus
		let loadOptions = Object.assign({}, options);
		loadOptions['onComplete'] = loadOptions['complete'] = resolve;
		loadOptions['onError'] = loadOptions['error'] = reject;
		loadOptions['owner'] = this;
		delete loadOptions.url;

		this.app.load(this.resource.url, loadOptions);
	}

	onBeforeDestroy() {
		this.setAutoEnvMap(null);
		return super.onBeforeDestroy();
	}

	setAutoEnvMap(envMap) {
		let _private = this[__.private];
		if (_private.autoEnvMap) {
			if (_private.autoEnvMap.outer) {
				_private.autoEnvMap.outer.dispose();
			}

			if (_private.autoEnvMap.inner) {
				_private.autoEnvMap.inner.dispose();
			}
		}
		_private.autoEnvMap = envMap;
	}

	getAutoEnvMap() {
		let _private = this[__.private];
		return _private.autoEnvMap;
	}

	/**
	 * 获取园区下的放置物对象集合
	 * @type {THING.Selector<THING.Entity>}
	 * @example
	 * let placements = campus.placements;
	 * @public
	 */
	get placements() {
		let placements = new Selector();
		this.children.forEach(child => {
			let tags = child.tags;
			if (tags.has('Placement')) {
				placements.push(child);
			}
			else if (tags.has('Group')) {
				placements.push(child.queryByTags('Placement'));
			}
		});
		return placements;
	}

	/**
	 * 获取园区下的建筑物对象集合
	 * @type {THING.Selector<THING.Building>}
	 * @example
	 * let buildings = campus.buildings;
	 * @public
	 */
	get buildings() {
		return this.children.query('tags:or(Building)');
	}

	/**
	 * 获取园区下的地面对象集合
	 * @type {THING.Object3D}
	 * @example
	 * let ground = campus.ground;
	 * @public
	 */
	get ground() {
		const result = this.children.find('tags:or(Ground)');
		return result;
	}

	/**
	 * 获取杂项对象
	 * @type {THING.Object3D}
	 * @example
	 * let misc = campus.misc;
	 * console.log(misc);
	 * @public
	 */
	get misc() {
		return this.children.find('tags:or(Misc)');
	}

}

export { Campus }