Source: resources/VideoTexture.js

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

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

/**
 * @class VideoTexture
 * The video texture resource.
 * @memberof THING
 * @extends THING.BaseStaticTexture
 * @public
 */
class VideoTexture extends BaseStaticTexture {

	/**
	 * The video texture what can play video stream and can be used by object's style.
	 * @param {Object} param The initial parameters.
	 */
	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 (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', { data: resource });

		return videoTexture;
	}

	// #endregion

	/**
	 * Copy from image.
	 * @param {THING.VideoTexture} source The image.
	 * @returns {THING.VideoTexture}
	 * @public
	 */
	copy(source) {
		super.copy(source);

		this.url = source.url;

		return this;
	}

	/**
	 * Clone image.
	 * @returns {THING.VideoTexture}
	 * @public
	 */
	clone() {
		let videoTexture = new VideoTexture({ url: this.url });
		videoTexture.copy(this);

		return videoTexture;
	}

	// #region Accessors

	/**
	 * Get/Set 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

	/**
	 * Check class type.
	 * @type {Boolean}
	 */
	get isVideoTexture() {
		return true;
	}

	// #endregion

}

export { VideoTexture }