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

import { BaseStaticTexture } from './BaseStaticTexture';



const __ = {

	private: Symbol('private'),

}



/**
 * VideoTexture - 视频纹理
 *
 * 可以播放视频流,并用于对象的样式,支持从 URL 或 video 元素创建。
 * @class VideoTexture
 * @memberof THING
 * @extends THING.BaseStaticTexture
 * @public
 * @example
 const videoTexture = new THING.VideoTexture({
   url: 'example.mp4',
 });
 */
class VideoTexture extends BaseStaticTexture {



	/**
	 视频纹理,可以播放视频流,并可以用于对象的样式。
	 * @param {object} param 初始参数。
	 * @param {string} [param.url] 视频文件的url。
	 * @param {object} [param.video] 视频元素。
	 * @param {Function} param.onLoad 加载完成后的回调函数。
	 * @constructor
	 * @public
	 */

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



		this[__.private] = {};

		let _private = this[__.private];



		_private.url = '';

		_private.resource = null;



		this._load(param);
	}



	// #region Private



	_load(param) {
		let _private = this[__.private];



		// Load from video element

		if (param.video && Utils.isVideoResource(param.video)) {
			_private.resource = param.video;

			this.onNotifyComplete();
		}

		// Load from video element (legacy support)

		else if (Utils.isVideoResource(param)) {
			_private.resource = param;

			this.onNotifyComplete();
		}

		// Load from url

		else {
			let onLoad = Utils.parseValue(param['onLoad'], null);

			let url = Utils.parseValue(param['url'], '');



			if (Utils.isString(url)) {
				_private.url = url;

				_private.resource = Utils.loadVideoFile(_private.url,

					// Load

					(ev) => {
						// Check whether it had been disposed

						if (!this.refCount) {
							return;
						}



						// Check whether has changed url

						if (url != _private.url) {
							return;
						}



						if (onLoad) {
							onLoad({ image: this });
						}



						this.onNotifyComplete();
					}

				);
			}
		}
	}



	// #endregion



	// #region Overrides



	onDispose() {
		let _private = this[__.private];



		if (_private.resource) {
			_private.resource.dispose();

			_private.resource = null;
		}



		super.onDispose();
	}



	onCreateTextureResource() {
		let _private = this[__.private];



		let resource = _private.resource;

		if (!resource) {
			return null;
		}



		let videoTexture = Utils.createObject('VideoTextureResource', { app: this.app, data: resource });



		return videoTexture;
	}



	// #endregion



	/**

	 从视频纹理复制。
	 * @param {THING.VideoTexture} source 源视频纹理。
	 * @returns {THING.VideoTexture} 返回一个新的视频纹理实例。
	 */

	copy(source) {
		super.copy(source);



		this.url = source.url;



		return this;
	}



	/**

	 克隆视频纹理。
	 * @returns {THING.VideoTexture} 返回一个新的视频纹理实例。
	 */

	clone() {
		let videoTexture = new VideoTexture({ url: this.url });

		videoTexture.copy(this);



		return videoTexture;
	}



	// #region Accessors



	/**

	 获取/设置视频元素
	 * @type {object}
	 * @public
	 */

	get resource() {
		let _private = this[__.private];

		return _private.resource;
	}



	set resource(value) {
		if (!Utils.isVideoResource(value)) {
			console.warn('Invalid video element provided');

			return;
		}



		this.waitForComplete().then(() => {
			this.unloadResource();



			let _private = this[__.private];

			_private.resource = value;

			_private.url = '';



			if (this.textureResource) {
				this.textureResource.setImage(_private.resource);
			}



			this.onNotifyComplete();
		});
	}



	/**

	 获取/设置url
	 * @type {string}
	 * @public
	 */

	get url() {
		let _private = this[__.private];



		return _private.url;
	}

	set url(value) {
		this.waitForComplete().then(() => {
			this.unloadResource();



			this._load({ url: value });



			if (this.textureResource) {
				let _private = this[__.private];



				this.textureResource.setImage(_private.resource);
			}
		});
	}



	// #endregion



	/**

	 检查类类型。
	 * @type {boolean}
	 */

	get isVideoTexture() {
		return true;
	}



	// #endregion



}



export { VideoTexture }