"use strict";
/*!
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("..");
const internal_1 = require("../internal");
const assetInternal_1 = require("./assetInternal");
// break import cycle
const asset_1 = require("./asset");
/** How a material should interpret UV coordinates outside the [0,1) range. */
var TextureWrapMode;
(function (TextureWrapMode) {
    /** The texture is tiled for every 1 unit in the UVs. */
    TextureWrapMode["Repeat"] = "repeat";
    /** The edge pixels of the texture are stretched out to the bounds of the UVs. */
    TextureWrapMode["Clamp"] = "clamp";
    /** The texture is tiled and flipped for every 1 unit in the UVs. */
    TextureWrapMode["Mirror"] = "mirror";
})(TextureWrapMode = exports.TextureWrapMode || (exports.TextureWrapMode = {}));
class Texture extends asset_1.Asset {
    /** INTERNAL USE ONLY. To load a new texture from scratch, use [[AssetManager.createTexture]] */
    constructor(container, def) {
        super(container, def);
        this._resolution = __1.Vector2.One();
        this._wrapU = TextureWrapMode.Repeat;
        this._wrapV = TextureWrapMode.Repeat;
        this._internal = new assetInternal_1.AssetInternal(this);
        if (!def.texture) {
            throw new Error("Cannot construct texture from non-texture definition");
        }
        this.copy(def);
    }
    /** @hidden */
    get internal() { return this._internal; }
    /** The URI, if any, this texture was loaded from */
    get uri() { return this._uri; }
    /** The pixel dimensions of the loaded texture */
    get resolution() { return this._resolution; }
    /** How overflowing UVs are handled horizontally. */
    get wrapU() { return this._wrapU; }
    set wrapU(val) { this._wrapU = val; this.textureChanged('wrapU'); }
    /** How overflowing UVs are handled vertically. */
    get wrapV() { return this._wrapV; }
    set wrapV(val) { this._wrapV = val; this.textureChanged('wrapV'); }
    /** @inheritdoc */
    get texture() { return this; }
    copy(from) {
        if (!from) {
            return this;
        }
        // Pause change detection while we copy the values into the actor.
        const wasObserving = this.internal.observing;
        this.internal.observing = false;
        super.copy(from);
        if (from.texture && from.texture.uri) {
            this._uri = from.texture.uri;
        }
        if (from.texture && from.texture.resolution) {
            this._resolution = new __1.Vector2(from.texture.resolution.x, from.texture.resolution.y);
        }
        if (from.texture && from.texture.wrapU) {
            this.wrapU = from.texture.wrapU;
        }
        if (from.texture && from.texture.wrapV) {
            this.wrapV = from.texture.wrapV;
        }
        this.internal.observing = wasObserving;
        return this;
    }
    /** @hidden */
    toJSON() {
        return Object.assign(Object.assign({}, super.toJSON()), { texture: {
                uri: this.uri,
                resolution: this.resolution.toJSON(),
                wrapU: this.wrapU,
                wrapV: this.wrapV
            } });
    }
    textureChanged(...path) {
        if (this.internal.observing) {
            this.container.context.internal.incrementGeneration();
            this.internal.patch = this.internal.patch || { texture: {} };
            internal_1.readPath(this, this.internal.patch.texture, ...path);
        }
    }
    /** @hidden */
    breakReference(ref) {
        if (!(ref instanceof __1.Material)) {
            return;
        }
        if (ref.mainTexture === this) {
            ref.mainTexture = null;
        }
        else if (ref.emissiveTexture === this) {
            ref.emissiveTexture = null;
        }
    }
}
exports.Texture = Texture;
//# sourceMappingURL=texture.js.map