Source: resources/BaseTexture.js

import { Flags, MathUtils, RefCountObject, ResolvablePromise } from '@uino/base-thing';
import { Utils } from '../common/Utils'
import { ImageWrapType, ImageMappingType, ImageFilterType, ImageColorFormat, ImageEncodingType } from '../const';
import { BaseResource } from './BaseResource';

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

const Flag = {
	Loaded: 1 << 0,
}

/**
 * @class BaseTexture
 * The base texture resource.
 * @memberof THING
 * @extends THING.BaseResource
 */
class BaseTexture extends BaseResource {

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

		this[__.private] = {};
		let _private = this[__.private];
		let app = Utils.getCurrentApp();

		_private.colorFormat = Utils.parseValue(param['colorFormat'], ImageColorFormat.RGBA);
		_private.anisotropy = Utils.parseValue(param['anisotropy'], app.renderCapabilities.maxAnisotropy);
		_private.wrapTypeS = Utils.parseValue(param['wrapTypeS'] || param['wrapType'], ImageWrapType.Repeat);
		_private.wrapTypeT = Utils.parseValue(param['wrapTypeT'] || param['wrapType'], ImageWrapType.Repeat);
		_private.mappingType = Utils.parseValue(param['mappingType'], ImageMappingType.UV);
		_private.flipY = Utils.parseValue(param['flipY'], true);
		_private.premultiplyAlpha = Utils.parseValue(param['premultiplyAlpha'], false);
		_private.generateMipmaps = Utils.parseValue(param['generateMipmaps'], true);
		_private.minFilterType = Utils.parseValue(param['minFilterType'], _private.generateMipmaps ? ImageFilterType.LinearMipmapLinearFilter : ImageFilterType.LinearFilter);
		_private.magFilterType = Utils.parseValue(param['magFilterType'], ImageFilterType.LinearFilter);
		_private.encoding = Utils.parseValue(param['encoding'], null);

		_private.onUpdateSampler = param['onUpdateSampler'];
	}

	// #region Private

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

		let onUpdateSampler = _private.onUpdateSampler;
		if (onUpdateSampler) {
			onUpdateSampler(this, {
				minFilter: _private.minFilterType,
				magFilter: _private.magFilterType,
				wrapS: _private.wrapTypeS,
				wrapT: _private.wrapTypeT,
			});
		}
	}

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

		let textureResource = this.context;
		if (!textureResource) {
			return;
		}

		textureResource.setWrapS(_private.wrapTypeS);
		textureResource.setWrapT(_private.wrapTypeT);
		textureResource.setMapping(_private.mappingType);
		textureResource.setColorFormat(_private.colorFormat);
		textureResource.setAnisotropy(_private.anisotropy);
		textureResource.setMinFilter(_private.minFilterType);
		textureResource.setMagFilter(_private.magFilterType);
		textureResource.enable('FlipY', _private.flipY);
		textureResource.enable('PremultiplyAlpha', _private.premultiplyAlpha);
		textureResource.enable('GenerateMipmaps', _private.generateMipmaps);

		if (_private.encoding) {
			textureResource.setEncoding(_private.encoding);
		}
	}

	// #endregion

	// #region Overrides

	onCreateTextureResource() {

	}

	// #endregion

	/**
	 * Get texture resource.
	 * @private
	 */
	getTextureResource() {
		if (!this.context) {
			this.setContext(this.onCreateTextureResource());

			this._updateTextureResource();
		}

		return this.context;
	}

	/**
	 * Copy texture.
	 * @param {THING.BaseTexture} source The texture.
	 * @returns {THING.BaseTexture}
	 */
	copy(source) {
		let _private = this[__.private];

		_private.colorFormat = source.colorFormat;
		_private.anisotropy = source.anisotropy;
		_private.wrapTypeS = source.wrapTypeS;
		_private.wrapTypeT = source.wrapTypeT;
		_private.mappingType = source.mappingType;
		_private.minFilterType = source.minFilterType;
		_private.magFilterType = source.magFilterType;
		_private.flipY = source.flipY;
		_private.premultiplyAlpha = source.premultiplyAlpha;
		_private.generateMipmaps = source.generateMipmaps;
		_private.encoding = source.encoding;

		this._updateSampler();

		return this;
	}

	// #region Accessors

	/**
	 * Get texture resource.
	 * @type {Object}
	 * @private
	 */
	get textureResource() {
		return this.context;
	}

	/**
	 * Get/Set the update sampler callback function.
	 * @type {Function}
	 * @private
	 */
	get onUpdateSampler() {
		let _private = this[__.private];

		return _private.onUpdateSampler;
	}
	set onUpdateSampler(value) {
		let _private = this[__.private];

		_private.onUpdateSampler = value;
	}

	/**
	 * Get/Set the color format.
	 * @type {Number}
	 */
	get colorFormat() {
		let _private = this[__.private];

		return _private.colorFormat;
	}
	set colorFormat(value) {
		let _private = this[__.private];

		_private.colorFormat = value;

		this._updateTextureResource();
	}

	/**
	 * Get/Set the anisotropy.
	 * @type {Number}
	 */
	get anisotropy() {
		let _private = this[__.private];

		return _private.anisotropy;
	}
	set anisotropy(value) {
		let _private = this[__.private];

		_private.anisotropy = value;

		this._updateTextureResource();
	}

	/**
	 * Get/Set the wrapping behavior for the S texture coordinate.
	 * @type {ImageWrapType}
	 */
	get wrapTypeS() {
		let _private = this[__.private];

		return _private.wrapTypeS;
	}
	set wrapTypeS(value) {
		let _private = this[__.private];

		_private.wrapTypeS = value;

		this._updateTextureResource();
		this._updateSampler();
	}

	/**
	 * Get/Set the wrapping behavior for the T texture coordinate.
	 * @type {ImageWrapType}
	 */
	get wrapTypeT() {
		let _private = this[__.private];

		return _private.wrapTypeT;
	}
	set wrapTypeT(value) {
		let _private = this[__.private];

		_private.wrapTypeT = value;

		this._updateTextureResource();
		this._updateSampler();
	}

	/**
	 * Get/Set the wrapping behavior for the both S and T texture coordinates.
	 * @type {ImageWrapType}
	 */
	set wrapType(value) {
		let _private = this[__.private];

		_private.wrapTypeS = value;
		_private.wrapTypeT = value;

		this._updateTextureResource();
		this._updateSampler();
	}

	/**
	 * Get/Set the mappingType type.
	 * @type {ImageMappingType}
	 */
	get mappingType() {
		let _private = this[__.private];

		return _private.mappingType;
	}
	set mappingType(value) {
		let _private = this[__.private];

		_private.mappingType = value;

		this._updateTextureResource();
	}

	/**
	 * Get/Set the min filter type.
	 * @type {ImageFilterType}
	 */
	get minFilterType() {
		let _private = this[__.private];

		return _private.minFilterType;
	}
	set minFilterType(value) {
		let _private = this[__.private];

		_private.minFilterType = value;

		this._updateTextureResource();
		this._updateSampler();
	}

	/**
	 * Get/Set the mag filter type.
	 * @type {ImageFilterType}
	 */
	get magFilterType() {
		let _private = this[__.private];

		return _private.magFilterType;
	}
	set magFilterType(value) {
		let _private = this[__.private];

		_private.magFilterType = value;

		this._updateTextureResource();
		this._updateSampler();
	}

	/**
	 * Enable/Disable flipY.
	 * @type {Boolean}
	 */
	get flipY() {
		let _private = this[__.private];

		return _private.flipY;
	}
	set flipY(value) {
		let _private = this[__.private];

		_private.flipY = value;

		this._updateTextureResource();
	}

	/**
	 * Enable/Disable premultiply alpha.
	 * @type {Boolean}
	 */
	get premultiplyAlpha() {
		let _private = this[__.private];

		return _private.premultiplyAlpha;
	}
	set premultiplyAlpha(value) {
		let _private = this[__.private];

		_private.premultiplyAlpha = value;

		this._updateTextureResource();
	}

	/**
	 * Enable/Disable generate mipmaps.
	 * @type {Boolean}
	 */
	get generateMipmaps() {
		let _private = this[__.private];

		return _private.generateMipmaps;
	}
	set generateMipmaps(value) {
		let _private = this[__.private];

		_private.generateMipmaps = value;

		this._updateTextureResource();
	}

	/**
	 * Get/Set the encoding.
	 * @type {ImageEncodingType}
	 */
	get encoding() {
		let _private = this[__.private];

		return _private.encoding;
	}
	set encoding(value) {
		let _private = this[__.private];

		_private.encoding = value;

		this._updateTextureResource();
	}

	// #endregion

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

	// #endregion

}

export { BaseTexture }