import { Utils } from '../common/Utils'
import { MathUtils } from '../math/MathUtils'
import { SpotLightHelperComponent } from '../components/SpotLightHelperComponent';
import { BaseShadowLight } from './BaseShadowLight';

const registerComponentParam = { isResident: true };

/**
 * SpotLight - 聚光灯
 *
 * 从一个点向一个方向发射锥形光束,类似手电筒效果,支持阴影、角度和衰减。
 * @class SpotLight
 * @memberof THING
 * @extends THING.BaseShadowLight
 * @public
 * @example
 const light = new THING.SpotLight({
   position: [0, 10, 0],
   target: [0, 0, 0],
   color: '#ff0000',
   intensity: 1.5,
   angle: 30,
   penumbra: 0.3,
   distance: 50,
 });
 */
class SpotLight extends BaseShadowLight {

	/**
	 * 构造函数
	 * @param {object} param The initial parameters.
	 * @param {number[]} param.position 灯光位置
	 * @param {number|string|number[]} param.color 光的颜色
	 * @param {number} param.intensity 光的强度
	 * @param {number} param.distance 照射距离
	 * @param {number} param.angle 照射角度
	 * @param {number} param.penumbra 不完全遮挡的范围
	 * @param {number} param.decay 衰减系数
	 * 其他参数与 {@link THING.BaseShadowLight} 的构造函数相同。
	 * @constructor
	 * @public
	 */
	constructor(param = {}) {
		super(param);
	}

	// #region Overrides

	onCopy(object) {
		super.onCopy(object);

		this.distance = object.distance;
		this.angle = object.angle;
		this.penumbra = object.penumbra;
		this.decay = object.decay;
	}

	onBeforeSetup(param) {
		param['renderableNode'] = param['renderableNode'] || Utils.createObject('SpotLight', { app: this.app });

		super.onBeforeSetup(param);
	}

	onSetupComponent(param) {
		super.onSetupComponent(param);

		this.addComponent(SpotLightHelperComponent, 'helper', registerComponentParam);
	}

	onSetupComplete(param) {
		super.onSetupComplete(param);

		// Sync options
		Utils.syncOptions(this, [
			'distance',
			'angle',
			'penumbra',
			'decay',
		], param, param['extras'] || param['external']);
	}

	onExportExternalData() {
		let external = Object.assign({}, super.onExportExternalData());
		Utils.setAttributeIfExist(external, 'distance', this);
		Utils.setAttributeIfExist(external, 'angle', this);
		Utils.setAttributeIfExist(external, 'penumbra', this);
		Utils.setAttributeIfExist(external, 'decay', this);
		return external;
	}

	// #endregion

	// #region Accessor

	/**
	 * 照射距离
	 * @type {number}
	 * @public
	 */
	get distance() {
		return this.bodyNode.getDistance();
	}
	set distance(value) {
		this.bodyNode.setDistance(value);
	}

	/**
	 * 照射角度
	 * @type {number}
	 * @public
	 */
	get angle() {
		return MathUtils.radToDeg(this.bodyNode.getAngle());
	}
	set angle(value) {
		this.bodyNode.setAngle(MathUtils.degToRad(value));
	}

	/**
	 * 不完全遮挡的范围
	 * @type {number}
	 * @public
	 */
	get penumbra() {
		return this.bodyNode.getPenumbra();
	}
	set penumbra(value) {
		this.bodyNode.setPenumbra(value);
	}

	/**
	 * 衰减系数
	 * @type {number}
	 * @public
	 */
	get decay() {
		return this.bodyNode.getDecay();
	}
	set decay(value) {
		this.bodyNode.setDecay(value);
	}

	// #endregion

	get isSpotLight() {
		return true;
	}

}

export { SpotLight }