import { Utils } from '../common/Utils';
import { ParticleEmitter } from './ParticleEmitter';

/**
 * @class ParticleGroup
 * 粒子组。
 * @memberof THING
 * @public
 * @example
 * const group = new THING.ParticleGroup();
 * group.maxParticleCount = 200;
 * group.useMesh = false;
 * group.meshUrl = "BuildIn/Box";
 * group.texture = {
 * 	url:"./particle.png"
 * };
 * group.blendingMode = "normal";
 * group.isTransparent = true;
 * group.alphaTest = true;
 * group.depthWrite = false;
 * group.depthTest = false;
 * group.url = "./particle.png";
 */
class ParticleGroup {

	constructor(param = {}) {
		this.node = param['node'] || Utils.createObject('ParticleGroup');
	}


	/**
	 * 获取属性值。
	 * @param {THING.ADAPTER.ParticleGroupAttributeType} key 属性键。
	 * @returns {any} 返回属性值。
	 * @public
	 */
	getAttribute(key) {
		return this.node.getAttribute(key);
	}

	/**
	 * 设置属性值。
	 * @param {THING.ADAPTER.ParticleGroupAttributeType} key 属性键。
	 * @param {any} value 属性值。
	 * @public
	 */
	setAttribute(key, value) {
		if (key === "Texture") {
			this.node.setAttribute(key, value.getTextureResource());
		}
		else {
			this.node.setAttribute(key, value);
		}

		if (key === "UseMesh" || key === "MeshUrl" || key === "MeshParams") {
			this._updateEmitters()
		}
	}

	/**
	 * 添加发射器。
	 * @param {ParticleEmitter} emitter 发射器。
	 * @returns {ParticleEmitter|null} 返回添加的发射器,如果节点不存在则返回 null。
	 * @public
	 * @example
	 * const emitter = new THING.ParticelEmitter();
	 * group.addEmitter(emitter);
	 */
	addEmitter(emitter) {
		let node = emitter.node;

		if (!this.node) {
			return null;
		}

		this.node.addEmitter(node);

		this._updateEmitters();

		return this.emitters[this.emitters.length - 1];
	}

	/**
	 * 根据发射器移除发射器。
	 * @param {ParticleEmitter} emitter 发射器。
	 * @public
	 * @example
	 * const emitter = group.getEmitters();
	 * group.removeEmitter(emitter);
	 */
	removeEmitter(emitter) {
		if (!this.node) {
			return;
		}

		if (this.emitters.length == 0) {
			return;
		}

		this.node.removeEmitter(emitter.node);
		this._updateEmitters();
	}


	_updateEmitters() {
		this._emitters = [];
		const that = this;
		this.getEmitters().forEach(node => {
			const _emitter = new ParticleEmitter({ node });
			that._emitters.push(_emitter);
		})
	}

	/**
	 * Get emitters.
	 * @returns {Array<ParticleEmitter>} 返回发射器。
	 * @private
	 * @example
	 * const emitter = group.getEmitters();
	 */
	getEmitters() {
		return this.node.getEmitters();
	}

	// #region Accessor

	/**
	 * 获取发射器。
	 * @type {Array<ParticleEmitter>}
	 * @public
	 */
	get emitters() {
		if (!this._emitters) {
			this._updateEmitters();
		}

		return this._emitters;
	}


	/**
	 * 获取/设置最大粒子数。这些粒子的最大数量。
	 * @type {number}
	 * @public
	 */
	get maxParticleCount() {
		return this.getAttribute('MaxParticleCount');
	}
	set maxParticleCount(value) {
		return this.setAttribute('MaxParticleCount', value);
	}

	/**
	 * 获取/设置是否使用网格。当为true时,表示粒子使用网格而不是点。
	 * @type {boolean}
	 * @public
	 */
	get useMesh() {
		return this.getAttribute('UseMesh');
	}
	set useMesh(value) {
		this.setAttribute('UseMesh', value);
		for (let i = 0; i < this.emitters.length; i++) {
			this.emitters[i].node = this.node._emitters[i];
		}
	}

	/**
	 * 获取/设置网格URL。当UseMesh为true时生效,表示粒子网格类型的属性。可选值为'BuildIn/Box'、'BuildIn/Plane'、'BuildIn/Sphere'。
	 * @type {string}
	 * @public
	 */
	get meshUrl() {
		return this.getAttribute('MeshUrl');
	}
	set meshUrl(value) {
		this.setAttribute('MeshUrl', value);
	}

	/**
	 * 获取/设置网格参数。当UseMesh为true时生效,表示粒子网格类型的属性。
	 * @type {Array}
	 * @public
	 */
	get meshParams() {
		return this.getAttribute('MeshParams');
	}
	set meshParams(value) {
		this.setAttribute('MeshParams', value);
	}

	/**
	 * 获取/设置纹理。粒子的图像值。
	 * @type {THING.ImageTexture}
	 * @public
	 */
	get texture() {
		return this.getAttribute('Texture');
	}
	set texture(value) {
		this.setAttribute('Texture', value);
	}

	/**
	 * The texture's animation attribute.
	 * @typedef {object} TextureAnimation
	 * @property {Array<number>} frames The number of frames on the x- and y-axis of the given texture.
	 * @property {number} frameCount The total number of frames in the sprite-sheet.
	 * @property {number} loop The number of loops through the sprite-sheet that should be performed over the course of a single particle's lifetime.
	 */

	/**
	 * 获取/设置纹理动画。
	 * @type {TextureAnimation}
	 * @public
	 */
	get textureAnimation() {
		return this.getAttribute('TextureAnimation');
	}
	set textureAnimation(value) {
		this.setAttribute('TextureAnimation', value);
	}

	/**
	 * 获取/设置混合模式。粒子的混合模式。可选值为'none'、'normal'、'add'、'sub'、'mul'、'custom'。
	 * @type {string}
	 * @public
	 */
	get blendingMode() {
		return this.getAttribute('BlendingMode');
	}
	set blendingMode(value) {
		this.setAttribute('BlendingMode', value);
	}

	/**
	 * 获取/设置是否透明。表示这些粒子是否应该以透明方式渲染。
	 * @type {boolean}
	 * @public
	 */
	get isTransparent() {
		return this.getAttribute('IsTransparent');
	}
	set isTransparent(value) {
		this.setAttribute('IsTransparent', value);
	}

	/**
	 * 获取/设置是否着色。表示这些粒子是否应该以颜色渲染,或者粒子的颜色仅来自提供的纹理。
	 * @type {boolean}
	 * @public
	 */
	get isColorize() {
		return this.getAttribute('IsColorize');
	}
	set isColorize(value) {
		this.setAttribute('IsColorize', value);
	}

	/**
	 * 获取/设置alpha测试。设置粒子的alpha值。取值范围为0到1。
	 * @type {number}
	 * @public
	 */
	get alphaTest() {
		return this.getAttribute('AlphaTest');
	}
	set alphaTest(value) {
		this.setAttribute('AlphaTest', value);
	}

	/**
	 * 获取/设置深度写入。设置粒子的深度写入。
	 * @type {boolean}
	 * @public
	 */
	get depthWrite() {
		return this.getAttribute('DepthWrite');
	}
	set depthWrite(value) {
		this.setAttribute('DepthWrite', value);
	}

	/**
	 * 获取/设置深度测试。设置粒子的深度测试。
	 * @type {boolean}
	 * @public
	 */
	get depthTest() {
		return this.getAttribute('DepthTest');
	}
	set depthTest(value) {
		this.setAttribute('DepthTest', value);
	}

	/**
	 * 获取/设置纹理URL。粒子的图像URL。
	 * @type {string}
	 * @public
	 */
	get url() {
		return this.getAttribute('Url');
	}
	set url(value) {
		this.setAttribute('Url', value);
	}

	/**
	 * 获取/设置雾效。表示这些粒子是否受到场景雾效的影响。
	 * @type {boolean}
	 * @public
	 */
	get fog() {
		return this.getAttribute('Fog');
	}
	set fog(value) {
		this.setAttribute('Fog', value);
	}

	// #endregion

}


export { ParticleGroup }